diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-08-20 21:58:59 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-08-20 21:58:59 +0000 |
commit | 892bf98f0c04e9297979936d973c85e62a3f0b96 (patch) | |
tree | 3f9570013732b9472502e71b25d5a76591eaed9a | |
parent | d4339ea6c6ab0bdf909d587bd9c5a754e362833d (diff) |
More MIPS64 chainsawing.
80 files changed, 5156 insertions, 137 deletions
diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 43f57df7c..8bb81c48b 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -1206,7 +1206,7 @@ CONFIG_DESKSTATION_RPC44 This is a machine with a R4400 100 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - http://lena.fnet.fr/ (To browse the WWW, you need to + http://www.linux.sgi.comm/ (To browse the WWW, you need to have access to a machine on the Internet that has a program like lynx or netscape). @@ -1215,7 +1215,7 @@ CONFIG_ACER_PICA_61 This is a machine with a R4400 133/150 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - http://lena.fnet.fr/ (To browse the WWW, you need to have access to + http://www.linux.sgi.comm/ (To browse the WWW, you need to have access to a machine on the Internet that has a program like lynx or netscape). Support for Algorithmics P4032 @@ -1269,7 +1269,7 @@ CONFIG_MIPS_MAGNUM_4000 This is a machine with a R4000 100 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - http://lena.fnet.fr/ (To browse the WWW, you need to have access to + http://www.linux.sgi.comm/ (To browse the WWW, you need to have access to a machine on the Internet that has a program like lynx or netscape). Support for Olivetti M700 @@ -1277,9 +1277,14 @@ CONFIG_OLIVETTI_M700 This is a machine with a R4000 100 MHz CPU. To compile a Linux kernel that runs on these, say Y here. For details about Linux on the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - http://lena.fnet.fr/ (To browse the WWW, you need to have access to + http://www.linux.sgi.com/ (To browse the WWW, you need to have access to a machine on the Internet that has a program like lynx or netscape). +Support for SGI IP22 + This are the SGI Indy, Challenge S and Indigo2, as well as certain OEM + variants like the Tandem CMN B006S. To compile a Linux kernel that + runs on these, say Y here. + MIPS JAZZ onboard SONIC Ethernet support CONFIG_MIPS_JAZZ_SONIC This is the driver for the onboard card of of MIPS Magnum 4000, @@ -11780,7 +11785,7 @@ CONFIG_USB_ACM # LocalWords: PMAX MILO Alphas Multia Tseng linuxelf endian mipsel mips drv HT # LocalWords: kerneld callouts AdvanSys advansys Admin WDT DataStor EP verden # LocalWords: wdt hdb hdc bugfix SiS vlb Acculogic CSA DTC dtc Holtek ht QDI -# LocalWords: QD qd UMC umc ALI ali lena fnet fr azstarnet cdr fb MDA ps esdi +# LocalWords: QD qd UMC umc ALI ali www.linux.sgi.comm azstarnet cdr fb MDA ps esdi # LocalWords: Avanti XL AlphaStations Jensen DECpc AXPpci UDB Cabriolet MCA RC # LocalWords: AlphaPC mca AOUT OUTput PPro sipx gwdg lo nwe FourPort Boca unm # LocalWords: Keepalive linefill RELCOM keepalive analogue CDR conf CDI INIT @@ -163,7 +163,7 @@ ifdef CONFIG_PNP DRIVERS := $(DRIVERS) drivers/pnp/pnp.a endif -ifdef CONFIG_SGI +ifdef CONFIG_SGI_IP22 DRIVERS := $(DRIVERS) drivers/sgi/sgi.a endif diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 34e875891..e6e83b34a 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.18 1999/06/21 22:16:10 ralf Exp $ +# $Id: Makefile,v 1.19 1999/08/18 23:37:42 ralf Exp $ # # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive @@ -108,7 +108,7 @@ LIBS += arch/mips/arc/arclib.a LOADADDR += 0x80080000 endif -ifdef CONFIG_SGI +ifdef CONFIG_SGI_IP22 LIBS += arch/mips/sgi/kernel/sgikern.a arch/mips/arc/arclib.a SUBDIRS += arch/mips/sgi/kernel arch/mips/arc # diff --git a/arch/mips/arc/init.c b/arch/mips/arc/init.c index 962e57418..f90203826 100644 --- a/arch/mips/arc/init.c +++ b/arch/mips/arc/init.c @@ -1,9 +1,11 @@ -/* - * init.c: PROM library initialisation code. +/* $Id$ + * This file is subject to the terms and conditions of the GNU General Public+ + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * PROM library initialisation code. * - * $Id: init.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $ + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ #include <linux/init.h> #include <linux/kernel.h> @@ -11,7 +13,7 @@ #include <asm/sgialib.h> -/* #define DEBUG_PROM_INIT */ +#undef DEBUG_PROM_INIT /* Master romvec interface. */ struct linux_romvec *romvec; @@ -43,19 +45,10 @@ __initfunc(int prom_init(int argc, char **argv, char **envp)) prom_vers = pb->ver; prom_rev = pb->rev; prom_identify_arch(); -#ifdef CONFIG_SGI - printk("PROMLIB: SGI ARCS firmware Version %d Revision %d\n", - prom_vers, prom_rev); -#else printk("PROMLIB: ARC firmware Version %d Revision %d\n", prom_vers, prom_rev); -#endif prom_meminit(); -#if 0 - prom_testtree(); -#endif - #ifdef DEBUG_PROM_INIT { prom_printf("Press a key to reboot\n"); diff --git a/arch/mips/config.in b/arch/mips/config.in index b203f2069..f7fb7b2e9 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.28 1999/08/13 17:07:25 harald Exp $ +# $Id: config.in,v 1.29 1999/08/18 23:37:42 ralf Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -19,7 +19,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then fi bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000 bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700 -bool 'Support for SGI workstations' CONFIG_SGI +bool 'Support for SGI IP22' CONFIG_SGI_IP22 bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI # @@ -122,7 +122,7 @@ bool 'System V IPC' CONFIG_SYSVIPC bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT bool 'Sysctl support' CONFIG_SYSCTL -if [ "$CONFIG_SGI" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then +if [ "$CONFIG_SGI_IP22" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then tristate 'Parallel port support' CONFIG_PARPORT fi endmenu @@ -167,7 +167,7 @@ comment 'SCSI support' tristate 'SCSI support' CONFIG_SCSI if [ "$CONFIG_SCSI" != "n" ]; then - if [ "$CONFIG_SGI" = "y" -o "$CONFIG_DECSTATION" = "y" ]; then + if [ "$CONFIG_SGI_IP22" = "y" -o "$CONFIG_DECSTATION" = "y" ]; then comment 'SCSI support type (disk, tape, CDrom)' dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI @@ -183,7 +183,7 @@ if [ "$CONFIG_SCSI" != "n" ]; then #mainmenu_option next_comment comment 'SCSI low-level drivers' - if [ "$CONFIG_SGI" = "y" ]; then + if [ "$CONFIG_SGI_IP22" = "y" ]; then dep_tristate 'SGI wd93 Scsi Driver' CONFIG_SCSI_SGIWD93 $CONFIG_SCSI else if [ "$CONFIG_TC" = "y" ]; then @@ -203,7 +203,7 @@ if [ "$CONFIG_NET" = "y" ]; then bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then - if [ "$CONFIG_SGI" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then + if [ "$CONFIG_SGI_IP22" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then source drivers/net/Config.in else tristate 'Dummy net driver support' CONFIG_DUMMY @@ -216,7 +216,7 @@ if [ "$CONFIG_NET" = "y" ]; then if [ ! "$CONFIG_PPP" = "n" ]; then comment 'CCP compressors for PPP are only built as modules.' fi - if [ "$CONFIG_SGI" = "y" ]; then + if [ "$CONFIG_SGI_IP22" = "y" ]; then bool 'SGI Seeq ethernet controller support' CONFIG_SGISEEQ fi if [ "$CONFIG_DECSTATION" = "y" ]; then @@ -231,7 +231,7 @@ if [ "$CONFIG_NET" = "y" ]; then endmenu fi -if [ "$CONFIG_SGI" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then +if [ "$CONFIG_SGI_IP22" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then source drivers/net/hamradio/Config.in @@ -268,7 +268,7 @@ else bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE fi tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL - if [ "$CONFIG_SGI" = "y" ]; then + if [ "$CONFIG_SGI_IP22" = "y" ]; then bool 'SGI PROM Console Support' CONFIG_SGI_PROM_CONSOLE fi if [ "$CONFIG_SERIAL" = "y" ]; then @@ -295,7 +295,7 @@ source fs/Config.in if [ "$CONFIG_VT" = "y" ]; then mainmenu_option next_comment comment 'Console drivers' - if [ "$CONFIG_SGI" = "y" ]; then + if [ "$CONFIG_SGI_IP22" = "y" ]; then tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then define_bool CONFIG_DUMMY_CONSOLE y @@ -321,7 +321,7 @@ if [ "$CONFIG_DECSTATION" != "y" ]; then endmenu fi -if [ "$CONFIG_SGI" = "y" ]; then +if [ "$CONFIG_SGI_IP22" = "y" ]; then source drivers/sgi/Config.in fi diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 80285f390..828f2477e 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -13,7 +13,7 @@ # CONFIG_ACER_PICA_61 is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_OLIVETTI_M700 is not set -# CONFIG_SGI is not set +# CONFIG_SGI_IP22 is not set CONFIG_SNI_RM200_PCI=y CONFIG_PCI=y diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index a1e6a6d29..58c4b85c2 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -35,7 +35,7 @@ endif # # SGIs have very different interrupt/timer hardware. # -ifndef CONFIG_SGI +ifndef CONFIG_SGI_IP22 ifndef CONFIG_DECSTATION ifndef CONFIG_BAGET_MIPS O_OBJS += irq.o time.o diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index acc666083..f6af1d6be 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.12 1999/07/26 19:42:40 harald Exp $ +/* $Id: head.S,v 1.13 1999/08/18 23:37:43 ralf Exp $ * * arch/mips/kernel/head.S * @@ -427,7 +427,7 @@ probe_done: jal prom_init /* prom_init(argc, argv, envp); */ nop -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 jal sgi_sysinit nop #endif diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 612170b20..7d5044942 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: mips_ksyms.c,v 1.18 1999/04/05 01:30:49 ulfc Exp $ +/* $Id: mips_ksyms.c,v 1.19 1999/04/11 18:37:55 harald Exp $ * * Export MIPS-specific functions needed for loadable modules. * @@ -99,7 +99,7 @@ EXPORT_SYMBOL(vdma_free); EXPORT_SYMBOL(vdma_log2phys); #endif -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 EXPORT_SYMBOL(hpc3c0); #endif diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 5040f5f15..89e4f7b37 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.15 1999/05/01 22:40:37 ralf Exp $ +/* $Id: setup.c,v 1.16 1999/06/17 13:25:47 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -40,7 +40,7 @@ #include <asm/io.h> #include <asm/stackframe.h> #include <asm/system.h> -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 #include <asm/sgialib.h> #endif @@ -193,7 +193,8 @@ __initfunc(void setup_arch(char **cmdline_p, jazz_setup(); break; #endif -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 + /* As of now this is only IP22. */ case MACH_GROUP_SGI: sgi_setup(); break; diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 5ae85bd0a..946b73ced 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -26,7 +26,7 @@ ifdef CONFIG_CPU_R6000 O_OBJS += r6000.o endif -ifdef CONFIG_SGI +ifdef CONFIG_SGI_IP22 O_OBJS += umap.o endif diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 90342db23..b694dd80c 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.15 1999/07/05 23:09:46 ralf Exp $ +/* $Id: init.c,v 1.16 1999/08/09 19:43:16 harald Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -30,7 +30,7 @@ #include <asm/jazzdma.h> #include <asm/system.h> #include <asm/pgtable.h> -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 #include <asm/sgialib.h> #endif #include <asm/mmu_context.h> diff --git a/arch/mips/sgi/kernel/indy_timer.c b/arch/mips/sgi/kernel/indy_timer.c index 11980d75a..096069395 100644 --- a/arch/mips/sgi/kernel/indy_timer.c +++ b/arch/mips/sgi/kernel/indy_timer.c @@ -1,4 +1,4 @@ -/* $Id: indy_timer.c,v 1.11 1999/01/04 16:03:56 ralf Exp $ +/* $Id: indy_timer.c,v 1.12 1999/06/13 16:30:36 ralf Exp $ * * indy_timer.c: Setting up the clock on the INDY 8254 controller. * @@ -107,11 +107,13 @@ void indy_timer_interrupt(struct pt_regs *regs) if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 && xtime.tv_usec >= 500000 - (tick >> 1) && - xtime.tv_usec <= 500000 + (tick >> 1)) - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + xtime.tv_usec <= 500000 + (tick >> 1)) { + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec - 600; + } } static unsigned long dosample(volatile unsigned char *tcwp, diff --git a/arch/mips64/Makefile b/arch/mips64/Makefile index 4ae372e30..3e4df1276 100644 --- a/arch/mips64/Makefile +++ b/arch/mips64/Makefile @@ -1,4 +1,4 @@ -# $Id$ +# $Id: Makefile,v 1.1 1999/08/18 23:37:46 ralf Exp $ # # This file is subject to the terms and conditions of the GNU General Public # License. See the file "COPYING" in the main directory of this archive @@ -34,8 +34,7 @@ endif # crossformat linking we rely on the elf2ecoff tool for format conversion. # CFLAGS += -mabi=64 -G 0 -mno-abicalls -fno-pic -pipe -LINKFLAGS += -G 0 -LINKFLAGS = -static # -N +LINKFLAGS += -G 0 -static # -N MODFLAGS += -mlong-calls ifdef CONFIG_REMOTE_DEBUG @@ -67,41 +66,34 @@ endif # # Board-dependent options and extra files # -ifdef CONFIG_IP22 -LIBS += arch/mips/sgi/kernel/sgikern.a arch/mips/arc/arclib.a -SUBDIRS += arch/mips/sgi/kernel arch/mips/arc +ifdef CONFIG_SGI_IP22 +LIBS += arch/mips64/sgi-ip22/sgikern.a arch/mips64/arc/arclib.a +SUBDIRS += arch/mips64/sgi-ip22 arch/mips64/arc # # Set LOADADDR to >= 0x88069000 if you want to leave space for symmon, # 0x88002000 for production kernels. Note that the value must be # 8kb aligned or the handling of the current variable will break. # LOADADDR += 0x88002000 -HOSTCC = cc endif # -# Choosing incompatible machines durings configuration will result in -# error messages during linking. Select a default linkscript if -# none has been choosen above. +# Some machines like the Indy need 32-bit ELF binaries for booting purposes. +# Other need ECOFF, so we build a 32-bit ELF binary for them which we then +# convert to ECOFF using elf2ecoff. # -ifndef LINKSCRIPT -ifndef CONFIG_CPU_LITTLE_ENDIAN -LINKSCRIPT = arch/mips/ld.script.big -else -LINKSCRIPT = arch/mips/ld.script.little -endif +ifdef CONFIG_BOOT_ELF32 +CFLAGS += -Wa,-32 +LINKFLAGS += -T arch/mips64/ld.script.elf32 endif -LINKFLAGS += -T $(word 1,$(LINKSCRIPT)) -ifdef LOADADDR -LINKFLAGS += -Ttext $(word 1,$(LOADADDR)) -endif +LINKFLAGS += -Ttext $(LOADADDR) -HEAD := arch/mips/kernel/head.o arch/mips/kernel/init_task.o +HEAD := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o -SUBDIRS := $(addprefix arch/mips/, tools) $(SUBDIRS) $(addprefix arch/mips/, kernel mm lib) -CORE_FILES := arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(CORE_FILES) -LIBS := arch/mips/lib/lib.a $(LIBS) +SUBDIRS := $(addprefix arch/mips64/, tools) $(SUBDIRS) $(addprefix arch/mips64/, kernel mm lib) +CORE_FILES := arch/mips64/kernel/kernel.o arch/mips64/mm/mm.o $(CORE_FILES) +LIBS := arch/mips64/lib/lib.a $(LIBS) MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot diff --git a/arch/mips64/arc/.cvsignore b/arch/mips64/arc/.cvsignore new file mode 100644 index 000000000..857dd22e9 --- /dev/null +++ b/arch/mips64/arc/.cvsignore @@ -0,0 +1,2 @@ +.depend +.*.flags diff --git a/arch/mips64/arc/Makefile b/arch/mips64/arc/Makefile new file mode 100644 index 000000000..86a5ad8f2 --- /dev/null +++ b/arch/mips64/arc/Makefile @@ -0,0 +1,23 @@ +# $Id$ +# Makefile for the SGI arcs prom monitor library routines +# under Linux. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +OBJS = console.o init.o printf.o memory.o tree.o env.o \ + cmdline.o misc.o time.o file.o identify.o + +all: arclib.a + +arclib.a: $(OBJS) + $(AR) rcs arclib.a $(OBJS) + sync + +dep: + $(CPP) -M *.c > .depend + +include $(TOPDIR)/Rules.make diff --git a/arch/mips64/arc/cmdline.c b/arch/mips64/arc/cmdline.c new file mode 100644 index 000000000..7e58e8f7e --- /dev/null +++ b/arch/mips64/arc/cmdline.c @@ -0,0 +1,67 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * cmdline.c: Kernel command line creation using ARCS argc/argv. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/sgialib.h> +#include <asm/bootinfo.h> + +/* #define DEBUG_CMDLINE */ + +char arcs_cmdline[CL_SIZE]; + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +static char *ignored[] = { + "ConsoleIn=", + "ConsoleOut=", + "SystemPartition=", + "OSLoader=", + "OSLoadPartition=", + "OSLoadFilename=" +}; +#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0]))))) + +void __init prom_init_cmdline(void) +{ + char *cp; + int actr, i; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + for(i = 0; i < NENTS(ignored); i++) { + int len = strlen(ignored[i]); + + if(!strncmp(prom_argv[actr], ignored[i], len)) + goto pic_cont; + } + /* Ok, we want it. */ + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + + pic_cont: + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + *cp = '\0'; + +#ifdef DEBUG_CMDLINE + prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0])); +#endif +} diff --git a/arch/mips64/arc/console.c b/arch/mips64/arc/console.c new file mode 100644 index 000000000..f16d2a766 --- /dev/null +++ b/arch/mips64/arc/console.c @@ -0,0 +1,29 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * console.c: SGI arcs console code. + * + * Copyright (C) 1996 David S. Miller (dm@sgi.com) + */ +#include <linux/init.h> +#include <asm/sgialib.h> + +void __init prom_putchar(char c) +{ + long cnt; + char it = c; + + romvec->write(1, &it, 1, &cnt); +} + +char __init prom_getchar(void) +{ + long cnt; + char c; + + romvec->read(0, &c, 1, &cnt); + return c; +} diff --git a/arch/mips64/arc/env.c b/arch/mips64/arc/env.c new file mode 100644 index 000000000..55a250047 --- /dev/null +++ b/arch/mips64/arc/env.c @@ -0,0 +1,25 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * env.c: ARCS environment variable routines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/sgialib.h> + +char * __init prom_getenv(char *name) +{ + return romvec->get_evar(name); +} + +long __init prom_setenv(char *name, char *value) +{ + return romvec->set_evar(name, value); +} diff --git a/arch/mips64/arc/file.c b/arch/mips64/arc/file.c new file mode 100644 index 000000000..f609e7846 --- /dev/null +++ b/arch/mips64/arc/file.c @@ -0,0 +1,68 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * ARC firmware interface. + * + * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include <linux/init.h> +#include <asm/sgialib.h> + +long __init prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, + unsigned long num, unsigned long *cnt) +{ + return ARC_CALL4(get_vdirent, fd, ent, num, cnt); +} + +long __init prom_open(char *name, enum linux_omode md, unsigned long *fd) +{ + return ARC_CALL3(open, name, md, fd); +} + +long __init prom_close(unsigned long fd) +{ + return ARC_CALL1(close, fd); +} + +long __init prom_read(unsigned long fd, void *buf, unsigned long num, + unsigned long *cnt) +{ + return ARC_CALL4(read, fd, buf, num, cnt); +} + +long __init prom_getrstatus(unsigned long fd) +{ + return ARC_CALL1(get_rstatus, fd); +} + +long __init prom_write(unsigned long fd, void *buf, unsigned long num, + unsigned long *cnt) +{ + return ARC_CALL4(write, fd, buf, num, cnt); +} + +long __init prom_seek(unsigned long fd, struct linux_bigint *off, + enum linux_seekmode sm) +{ + return ARC_CALL3(seek, fd, off, sm); +} + +long __init prom_mount(char *name, enum linux_mountops op) +{ + return ARC_CALL2(mount, name, op); +} + +long __init prom_getfinfo(unsigned long fd, struct linux_finfo *buf) +{ + return ARC_CALL2(get_finfo, fd, buf); +} + +long __init prom_setfinfo(unsigned long fd, unsigned long flags, + unsigned long msk) +{ + return ARC_CALL3(set_finfo, fd, flags, msk); +} diff --git a/arch/mips64/arc/identify.c b/arch/mips64/arc/identify.c new file mode 100644 index 000000000..c2a6809be --- /dev/null +++ b/arch/mips64/arc/identify.c @@ -0,0 +1,71 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * identify.c: identify machine by looking up system identifier + * + * Copyright (C) 1998 Thomas Bogendoerfer + * + * This code is based on arch/mips/sgi/kernel/system.c, which is + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/string.h> + +#include <asm/sgi/sgi.h> +#include <asm/sgialib.h> +#include <asm/bootinfo.h> + +struct smatch { + char *name; + int group; + int type; + int flags; +}; + +static struct smatch mach_table[] = { + { "SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, PROM_FLAG_ARCS }, + { "Microsoft-Jazz", MACH_GROUP_JAZZ, MACH_MIPS_MAGNUM_4000, 0 }, + { "PICA-61", MACH_GROUP_JAZZ, MACH_ACER_PICA_61, 0 }, + { "RM200PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, 0 } +}; + +int prom_flags; + +static struct smatch * __init string_to_mach(char *s) +{ + int i; + + for (i = 0; i < sizeof (mach_table); i++) { + if(!strcmp(s, mach_table[i].name)) + return &mach_table[i]; + } + prom_printf("\nYeee, could not determine architecture type <%s>\n", s); + prom_printf("press a key to reboot\n"); + prom_getchar(); + romvec->imode(); + return NULL; +} + +void __init prom_identify_arch(void) +{ + pcomponent *p; + struct smatch *mach; + + /* The root component tells us what machine architecture we + * have here. + */ + p = prom_getchild(PROM_NULL_COMPONENT); + printk("ARCH: %s\n", p->iname); + mach = string_to_mach(p->iname); + + mips_machgroup = mach->group; + mips_machtype = mach->type; + prom_flags = mach->flags; +} + diff --git a/arch/mips64/arc/init.c b/arch/mips64/arc/init.c new file mode 100644 index 000000000..a94f7da27 --- /dev/null +++ b/arch/mips64/arc/init.c @@ -0,0 +1,61 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * PROM library initialisation code. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/config.h> + +#include <asm/sgialib.h> + +#undef DEBUG_PROM_INIT + +/* Master romvec interface. */ +struct linux_romvec *romvec; +struct linux_promblock *sgi_pblock; +int prom_argc; +char **prom_argv, **prom_envp; +unsigned short prom_vers, prom_rev; + +extern void prom_testtree(void); + +int __init prom_init(int argc, char **argv, char **envp) +{ + struct linux_promblock *pb; + + romvec = ROMVECTOR; + pb = sgi_pblock = PROMBLOCK; + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + if(pb->magic != 0x53435241) { + prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic); + while(1) + ; + } + + prom_init_cmdline(); + + prom_vers = pb->ver; + prom_rev = pb->rev; + prom_identify_arch(); + printk("PROMLIB: ARC firmware Version %d Revision %d\n", + prom_vers, prom_rev); + prom_meminit(); + +#ifdef DEBUG_PROM_INIT + { + prom_printf("Press a key to reboot\n"); + (void) prom_getchar(); + romvec->imode(); + } +#endif + return 0; +} diff --git a/arch/mips64/arc/memory.c b/arch/mips64/arc/memory.c new file mode 100644 index 000000000..7212b9e05 --- /dev/null +++ b/arch/mips64/arc/memory.c @@ -0,0 +1,212 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * memory.c: PROM library functions for acquiring/using memory descriptors + * given to us from the ARCS firmware. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/config.h> + +#include <asm/sgialib.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/bootinfo.h> + +#undef DEBUG + +struct linux_mdesc * __init prom_getmdesc(struct linux_mdesc *curr) +{ + return romvec->get_mdesc(curr); +} + +#ifdef DEBUG +static char *arcs_mtypes[8] = { /* convenient for debugging */ + "Exception Block", + "ARCS Romvec Page", + "Free/Contig RAM", + "Generic Free RAM", + "Bad Memory", + "Standlong Program Pages", + "ARCS Temp Storage Area", + "ARCS Permanent Storage Area" +}; + +static char *arc_mtypes[8] = { + "Exception Block", + "SystemParameterBlock", + "FreeMemory", + "Bad Memory", + "LoadedProgram", + "FirmwareTemporary", + "FirmwarePermanent", + "FreeContigiuous" +}; +#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc] +#endif + +static struct prom_pmemblock prom_pblocks[PROM_MAX_PMEMBLOCKS]; + +struct prom_pmemblock * __init prom_getpblock_array(void) +{ + return &prom_pblocks[0]; +} + +#define MEMTYPE_DONTUSE 0 +#define MEMTYPE_PROM 1 +#define MEMTYPE_FREE 2 + +static int __init prom_memtype_classify (union linux_memtypes type) +{ + if (prom_flags & PROM_FLAG_ARCS) { + switch (type.arcs) { + case arcs_free: + case arcs_fcontig: + return MEMTYPE_FREE; + case arcs_atmp: + case arcs_aperm: + return MEMTYPE_PROM; + default: + return MEMTYPE_DONTUSE; + } + } else { + switch (type.arc) { + case arc_free: + case arc_fcontig: + return MEMTYPE_FREE; + case arc_rvpage: + case arc_atmp: + case arc_aperm: + return MEMTYPE_PROM; + default: + return MEMTYPE_DONTUSE; + } + } +} + +static void __init prom_setup_memupper(void) +{ + struct prom_pmemblock *p, *highest; + + for(p = prom_getpblock_array(), highest = 0; p->size != 0; p++) { + if(p->base == 0xdeadbeef) + prom_printf("WHEEE, bogus pmemblock\n"); + if(!highest || p->base > highest->base) + highest = p; + } + mips_memory_upper = highest->base + highest->size; +#ifdef DEBUG + prom_printf("prom_setup_memupper: mips_memory_upper = %08lx\n", + mips_memory_upper); +#endif +} + +void __init prom_meminit(void) +{ + struct linux_mdesc *p; + int totram; + int i = 0; + + p = prom_getmdesc(PROM_NULL_MDESC); +#ifdef DEBUG + prom_printf("ARCS MEMORY DESCRIPTOR dump:\n"); + while(p) { + prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n", + i, p, p->base, p->pages, mtypes(p->type)); + p = prom_getmdesc(p); + i++; + } +#endif + p = prom_getmdesc(PROM_NULL_MDESC); + totram = 0; + i = 0; + while(p) { + prom_pblocks[i].type = prom_memtype_classify (p->type); + prom_pblocks[i].base = ((p->base<<PAGE_SHIFT) + 0x80000000); + prom_pblocks[i].size = p->pages << PAGE_SHIFT; + switch (prom_pblocks[i].type) { + case MEMTYPE_FREE: + totram += prom_pblocks[i].size; +#ifdef DEBUG + prom_printf("free_chunk[%d]: base=%08lx size=%d\n", + i, prom_pblocks[i].base, + prom_pblocks[i].size); +#endif + i++; + break; + case MEMTYPE_PROM: +#ifdef DEBUG + prom_printf("prom_chunk[%d]: base=%08lx size=%d\n", + i, prom_pblocks[i].base, + prom_pblocks[i].size); +#endif + i++; + break; + default: + break; + } + p = prom_getmdesc(p); + } + prom_pblocks[i].base = 0xdeadbeef; + prom_pblocks[i].size = 0; /* indicates last elem. of array */ + printk("PROMLIB: Total free ram %d bytes (%dK,%dMB)\n", + totram, (totram/1024), (totram/1024/1024)); + + /* Setup upper physical memory bound. */ + prom_setup_memupper(); +} + +/* Called from mem_init() to fixup the mem_map page settings. */ +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ + struct prom_pmemblock *p; + int i, nents; + + /* Determine number of pblockarray entries. */ + p = prom_getpblock_array(); + for(i = 0; p[i].size; i++) + ; + nents = i; +restart: + while(start < end) { + for(i = 0; i < nents; i++) { + if((p[i].type == MEMTYPE_FREE) && + (start >= (p[i].base)) && + (start < (p[i].base + p[i].size))) { + start = p[i].base + p[i].size; + start &= PAGE_MASK; + goto restart; + } + } + set_bit(PG_reserved, &mem_map[MAP_NR(start)].flags); + start += PAGE_SIZE; + } +} + +void prom_free_prom_memory (void) +{ + struct prom_pmemblock *p; + unsigned long addr; + unsigned long num_pages = 0; + + for(p = prom_getpblock_array(); p->size != 0; p++) { + if (p->type == MEMTYPE_PROM) { + for (addr = p->base; addr < p->base + p->size; addr += PAGE_SIZE) { + mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved); + atomic_set(&mem_map[MAP_NR(addr)].count, 1); + free_page(addr); + num_pages++; + } + } + } + printk ("Freeing prom memory: %ldk freed\n", num_pages * PAGE_SIZE); +} diff --git a/arch/mips64/arc/misc.c b/arch/mips64/arc/misc.c new file mode 100644 index 000000000..56945035e --- /dev/null +++ b/arch/mips64/arc/misc.c @@ -0,0 +1,93 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Miscellaneous ARCS PROM routines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> + +#include <asm/bcache.h> +#include <asm/sgialib.h> +#include <asm/bootinfo.h> +#include <asm/system.h> + +extern unsigned long mips_cputype; +extern void *sgiwd93_host; +extern void reset_wd33c93(void *instance); + +void prom_halt(void) +{ + bcops->bc_disable(); + cli(); +#if CONFIG_SCSI_SGIWD93 + reset_wd33c93(sgiwd93_host); +#endif + ARC_CALL0(halt); +never: goto never; +} + +void prom_powerdown(void) +{ + bcops->bc_disable(); + cli(); +#if CONFIG_SCSI_SGIWD93 + reset_wd33c93(sgiwd93_host); +#endif + ARC_CALL0(pdown); +never: goto never; +} + +/* XXX is this a soft reset basically? XXX */ +void prom_restart(void) +{ + bcops->bc_disable(); + cli(); +#if CONFIG_SCSI_SGIWD93 + reset_wd33c93(sgiwd93_host); +#endif + ARC_CALL0(restart); +never: goto never; +} + +void prom_reboot(void) +{ + bcops->bc_disable(); + cli(); +#if CONFIG_SCSI_SGIWD93 + reset_wd33c93(sgiwd93_host); +#endif + ARC_CALL0(reboot); +never: goto never; +} + +void prom_imode(void) +{ + bcops->bc_disable(); + cli(); +#if CONFIG_SCSI_SGIWD93 + reset_wd33c93(sgiwd93_host); +#endif + ARC_CALL0(imode); +never: goto never; +} + +long prom_cfgsave(void) +{ + return ARC_CALL0(cfg_save); +} + +struct linux_sysid *prom_getsysid(void) +{ + return (struct linux_sysid *) ARC_CALL0(get_sysid); +} + +void __init prom_cacheflush(void) +{ + ARC_CALL0(cache_flush); +} diff --git a/arch/mips64/arc/printf.c b/arch/mips64/arc/printf.c new file mode 100644 index 000000000..ccefab0c7 --- /dev/null +++ b/arch/mips64/arc/printf.c @@ -0,0 +1,37 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Putting things on the screen using SGI arcs PROM facilities. + * + * Copyright (C) 1996 David S. Miller (dm@sgi.com) + */ +#include <linux/init.h> +#include <linux/kernel.h> + +#include <asm/sgialib.h> + +static char ppbuf[1024]; + +void __init prom_printf(char *fmt, ...) +{ + va_list args; + char ch, *bptr; + int i; + + va_start(args, fmt); + i = vsprintf(ppbuf, fmt, args); + + bptr = ppbuf; + + while((ch = *(bptr++)) != 0) { + if(ch == '\n') + prom_putchar('\r'); + + prom_putchar(ch); + } + va_end(args); + return; +} diff --git a/arch/mips64/arc/salone.c b/arch/mips64/arc/salone.c new file mode 100644 index 000000000..0635c24a0 --- /dev/null +++ b/arch/mips64/arc/salone.c @@ -0,0 +1,26 @@ +/* $Id$ + * + * Routines to load into memory and execute stand-along program images using + * ARCS PROM firmware. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> +#include <asm/sgialib.h> + +long __init prom_load(char *name, unsigned long end, unsigned long *pc, + unsigned long *eaddr) +{ + return romvec->load(name, end, pc, eaddr); +} + +long __init prom_invoke(unsigned long pc, unsigned long sp, long argc, + char **argv, char **envp)) +{ + return romvec->invoke(pc, sp, argc, argv, envp); +} + +long __init prom_exec(char *name, long argc, char **argv, char **envp) +{ + return romvec->exec(name, argc, argv, envp); +} diff --git a/arch/mips64/arc/time.c b/arch/mips64/arc/time.c new file mode 100644 index 000000000..378db5331 --- /dev/null +++ b/arch/mips64/arc/time.c @@ -0,0 +1,22 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Extracting time information from ARCS prom. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> +#include <asm/sgialib.h> + +struct __init linux_tinfo *prom_gettinfo(void) +{ + return romvec->get_tinfo(); +} + +unsigned __init long prom_getrtime(void) +{ + return romvec->get_rtime(); +} diff --git a/arch/mips64/arc/tree.c b/arch/mips64/arc/tree.c new file mode 100644 index 000000000..12a88230b --- /dev/null +++ b/arch/mips64/arc/tree.c @@ -0,0 +1,113 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * PROM component device tree code. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> +#include <asm/sgialib.h> + +#define DEBUG_PROM_TREE + +pcomponent * __init prom_getsibling(pcomponent *this) +{ + if(this == PROM_NULL_COMPONENT) + return PROM_NULL_COMPONENT; + return romvec->next_component(this); +} + +pcomponent * __init prom_getchild(pcomponent *this) +{ + return romvec->child_component(this); +} + +pcomponent * __init prom_getparent(pcomponent *child) +{ + if(child == PROM_NULL_COMPONENT) + return PROM_NULL_COMPONENT; + return romvec->parent_component(child); +} + +long __init prom_getcdata(void *buffer, pcomponent *this) +{ + return romvec->component_data(buffer, this); +} + +pcomponent * __init prom_childadd(pcomponent *this, pcomponent *tmp, + void *data) +{ + return romvec->child_add(this, tmp, data); +} + +long __init prom_delcomponent(pcomponent *this) +{ + return romvec->comp_del(this); +} + +pcomponent * __init prom_componentbypath(char *path) +{ + return romvec->component_by_path(path); +} + +#ifdef DEBUG_PROM_TREE +static char *classes[] = { + "system", "processor", "cache", "adapter", "controller", "peripheral", + "memory" +}; + +static char *types[] = { + "arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache", "sccache", + "memdev", "eisa adapter", "tc adapter", "scsi adapter", "dti adapter", + "multi-func adapter", "disk controller", "tp controller", + "cdrom controller", "worm controller", "serial controller", + "net controller", "display controller", "parallel controller", + "pointer controller", "keyboard controller", "audio controller", + "misc controller", "disk peripheral", "floppy peripheral", + "tp peripheral", "modem peripheral", "monitor peripheral", + "printer peripheral", "pointer peripheral", "keyboard peripheral", + "terminal peripheral", "line peripheral", "net peripheral", + "misc peripheral", "anonymous" +}; + +static char *iflags[] = { + "bogus", "read only", "removable", "console in", "console out", + "input", "output" +}; + +static void __init dump_component(pcomponent *p) +{ + prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>", + p, classes[p->class], types[p->type], + iflags[p->iflags], p->vers, p->rev); + prom_printf("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n", + p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname); +} + +static void __init traverse(pcomponent *p, int op) +{ + dump_component(p); + if(prom_getchild(p)) + traverse(prom_getchild(p), 1); + if(prom_getsibling(p) && op) + traverse(prom_getsibling(p), 1); +} + +void __init prom_testtree(void) +{ + pcomponent *p; + + p = prom_getchild(PROM_NULL_COMPONENT); + dump_component(p); + p = prom_getchild(p); + while(p) { + dump_component(p); + p = prom_getsibling(p); + } + prom_printf("press a key\n"); + prom_getchar(); +} +#endif diff --git a/arch/mips64/config.in b/arch/mips64/config.in index ed3798b04..d6e52deca 100644 --- a/arch/mips64/config.in +++ b/arch/mips64/config.in @@ -1,4 +1,4 @@ -# $Id$ +# $Id: config.in,v 1.1 1999/08/18 23:37:46 ralf Exp $ # # For a description of the syntax of this configuration file, # see the Configure script. @@ -12,18 +12,27 @@ endmenu mainmenu_option next_comment comment 'Machine selection' -bool 'Support for SGI workstations' CONFIG_SGI +bool 'Support for SGI IP22' CONFIG_SGI_IP22 endmenu +# +# Select some configuration options automatically for certain systems +# +unset CONFIG_BOOT_ELF32 + +if [ "$CONFIG_SGI_IP22" = "y" ]; then + define_bool CONFIG_BOOT_ELF32 y +fi + mainmenu_option next_comment comment 'CPU selection' -choice 'CPU type' \ - " R4300 CONFIG_CPU_R4300 \ - R4x00 CONFIG_CPU_R4X00 \ - R5000 CONFIG_CPU_R5000 \ - R56x0 CONFIG_CPU_NEVADA \ - R8000 CONFIG_CPU_R8000 \ +choice 'CPU type' \ + "R4300 CONFIG_CPU_R4300 \ + R4x00 CONFIG_CPU_R4X00 \ + R5000 CONFIG_CPU_R5000 \ + R56x0 CONFIG_CPU_NEVADA \ + R8000 CONFIG_CPU_R8000 \ R10000 CONFIG_CPU_R10000" R4x00 endmenu @@ -32,13 +41,6 @@ comment 'General setup' bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN -# -# XXX Binary compatibility stuff. Not for now ... -# -#if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then -# define_bool CONFIG_BINFMT_IRIX y -# define_bool CONFIG_FORWARD_KEYBOARD y -#fi define_bool CONFIG_BINFMT_AOUT n define_bool CONFIG_BINFMT_ELF y tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC @@ -123,7 +125,7 @@ if [ "$CONFIG_VT" = "y" ]; then mainmenu_option next_comment comment 'Console drivers' # XXX cleanup - if [ "$CONFIG_SGI" = "y" ]; then + if [ "$CONFIG_SGI_IP22" = "y" ]; then tristate 'SGI Newport Console support' CONFIG_SGI_NEWPORT_CONSOLE if [ "$CONFIG_SGI_NEWPORT_CONSOLE" != "y" ]; then define_bool CONFIG_DUMMY_CONSOLE y @@ -141,7 +143,7 @@ source drivers/sound/Config.in fi endmenu -if [ "$CONFIG_SGI" = "y" ]; then +if [ "$CONFIG_SGI_IP22" = "y" ]; then source drivers/sgi/Config.in fi diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig index 9b97a19f8..ab202c680 100644 --- a/arch/mips64/defconfig +++ b/arch/mips64/defconfig @@ -10,7 +10,7 @@ # # Machine selection # -CONFIG_SGI=y +CONFIG_SGI_IP22=y # # CPU selection diff --git a/arch/mips64/kernel/mips64_ksyms.c b/arch/mips64/kernel/mips64_ksyms.c new file mode 100644 index 000000000..c76978a32 --- /dev/null +++ b/arch/mips64/kernel/mips64_ksyms.c @@ -0,0 +1,125 @@ +/* $Id$ + * + * Export MIPS64-specific functions needed for loadable modules. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/interrupt.h> +#include <asm/irq.h> +#include <linux/in6.h> +#include <linux/pci.h> + +#include <asm/checksum.h> +#include <asm/dma.h> +#include <asm/floppy.h> +#include <asm/io.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/sgihpc.h> +#include <asm/softirq.h> +#include <asm/uaccess.h> + +extern void *__bzero(void *__s, size_t __count); +extern long __strncpy_from_user_nocheck_asm(char *__to, + const char *__from, long __len); +extern long __strncpy_from_user_asm(char *__to, const char *__from, + long __len); +extern long __strlen_user_nocheck_asm(const char *s); +extern long __strlen_user_asm(const char *s); + +EXPORT_SYMBOL(EISA_bus); + +/* + * String functions + */ +EXPORT_SYMBOL_NOVERS(memcmp); +EXPORT_SYMBOL_NOVERS(memset); +EXPORT_SYMBOL_NOVERS(memcpy); +EXPORT_SYMBOL_NOVERS(memmove); +EXPORT_SYMBOL_NOVERS(strcat); +EXPORT_SYMBOL_NOVERS(strchr); +EXPORT_SYMBOL_NOVERS(strlen); +EXPORT_SYMBOL_NOVERS(strncat); +EXPORT_SYMBOL_NOVERS(strnlen); +EXPORT_SYMBOL_NOVERS(strrchr); +EXPORT_SYMBOL_NOVERS(strtok); +EXPORT_SYMBOL_NOVERS(strpbrk); + +EXPORT_SYMBOL(clear_page); +EXPORT_SYMBOL(__mips_bh_counter); +EXPORT_SYMBOL(local_bh_count); +EXPORT_SYMBOL(local_irq_count); +EXPORT_SYMBOL(enable_irq); +EXPORT_SYMBOL(disable_irq); +EXPORT_SYMBOL(kernel_thread); + +/* + * Userspace access stuff. + */ +EXPORT_SYMBOL_NOVERS(__copy_user); +EXPORT_SYMBOL_NOVERS(__bzero); +EXPORT_SYMBOL_NOVERS(__strncpy_from_user_nocheck_asm); +EXPORT_SYMBOL_NOVERS(__strncpy_from_user_asm); +EXPORT_SYMBOL_NOVERS(__strlen_user_nocheck_asm); +EXPORT_SYMBOL_NOVERS(__strlen_user_asm); + + +/* Networking helper routines. */ +EXPORT_SYMBOL(csum_partial_copy); + +/* + * Functions to control caches. + */ +EXPORT_SYMBOL(flush_page_to_ram); +EXPORT_SYMBOL(flush_cache_all); +EXPORT_SYMBOL(dma_cache_wback_inv); +EXPORT_SYMBOL(dma_cache_inv); + +EXPORT_SYMBOL(invalid_pte_table); + +/* + * Base address of ports for Intel style I/O. + */ +EXPORT_SYMBOL(mips_io_port_base); + +/* + * Architecture specific stuff. + */ +#ifdef CONFIG_MIPS_JAZZ +EXPORT_SYMBOL(vdma_alloc); +EXPORT_SYMBOL(vdma_free); +EXPORT_SYMBOL(vdma_log2phys); +#endif + +#ifdef CONFIG_SGI_IP22 +EXPORT_SYMBOL(hpc3c0); +#endif + +/* + * Kernel hacking ... + */ +#include <asm/branch.h> +#include <linux/sched.h> + +int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31)); +int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31)); + +#ifdef CONFIG_MIPS_FPE_MODULE +EXPORT_SYMBOL(__compute_return_epc); +EXPORT_SYMBOL(register_fpe); +EXPORT_SYMBOL(unregister_fpe); +#endif + +#ifdef CONFIG_VT +EXPORT_SYMBOL(screen_info); +#endif + diff --git a/arch/mips64/ld.script.elf32 b/arch/mips64/ld.script.elf32 new file mode 100644 index 000000000..f5878cb35 --- /dev/null +++ b/arch/mips64/ld.script.elf32 @@ -0,0 +1,114 @@ +OUTPUT_ARCH(mips) +ENTRY(kernel_entry) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x80000000; + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0 + .text : + { + _ftext = . ; + *(.text) + *(.rodata) + *(.rodata1) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + _etext = .; + PROVIDE (etext = .); + + /* Startup code */ + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); /* Align double page for init_task_union */ + __init_end = .; + + .fini : { *(.fini) } =0 + .reginfo : { *(.reginfo) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. It would + be more correct to do this: + . = .; + The current expression does not correctly handle the case of a + text segment ending precisely at the end of a page; it causes the + data segment to skip a page. The above expression does not have + this problem, but it will currently (2/95) cause BFD to allocate + a single segment, combining both text and data, for this case. + This will prevent the text segment from being shared among + multiple executions of the program; I think that is more + important than losing a page of the virtual address space (note + that no actual memory is lost; the page which is skipped can not + be referenced). */ + . = .; + .data : + { + _fdata = . ; + *(.data) + CONSTRUCTORS + } + .data1 : { *(.data1) } + _gp = . + 0x8000; + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + + __bss_start = .; + _fbss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + _end = . ; + PROVIDE (end = .); + } + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the .debug DWARF section are relative to the beginning of the + section so we begin .debug at 0. It's not clear yet what needs to happen + for the others. */ + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /* These must appear regardless of . */ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +} diff --git a/arch/mips64/mm/Makefile b/arch/mips64/mm/Makefile index a5da59936..dc9459a41 100644 --- a/arch/mips64/mm/Makefile +++ b/arch/mips64/mm/Makefile @@ -1,4 +1,4 @@ -# $Id$ +# $Id: Makefile,v 1.1 1999/08/18 23:37:47 ralf Exp $ # # Makefile for the Linux/MIPS-specific parts of the memory manager. # @@ -6,7 +6,7 @@ O_TARGET := mm.o O_OBJS := extable.o init.o fault.o r4xx0.o tfp.o andes.o loadmmu.o -ifdef CONFIG_SGI +ifdef CONFIG_SGI_IP22 O_OBJS += umap.o endif diff --git a/arch/mips64/mm/init.c b/arch/mips64/mm/init.c index b94fa636b..903c2541c 100644 --- a/arch/mips64/mm/init.c +++ b/arch/mips64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.1 1999/08/18 23:37:47 ralf Exp $ +/* $Id: init.c,v 1.2 1999/08/19 22:56:32 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -31,7 +31,7 @@ #include <asm/jazzdma.h> #include <asm/system.h> #include <asm/pgtable.h> -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 #include <asm/sgialib.h> #endif #include <asm/mmu_context.h> diff --git a/arch/mips64/sgi-ip22/.cvsignore b/arch/mips64/sgi-ip22/.cvsignore new file mode 100644 index 000000000..857dd22e9 --- /dev/null +++ b/arch/mips64/sgi-ip22/.cvsignore @@ -0,0 +1,2 @@ +.depend +.*.flags diff --git a/arch/mips64/sgi-ip22/Makefile b/arch/mips64/sgi-ip22/Makefile new file mode 100644 index 000000000..476432a99 --- /dev/null +++ b/arch/mips64/sgi-ip22/Makefile @@ -0,0 +1,24 @@ +# $Id$ +# +# Makefile for the SGI specific kernel interface routines +# under Linux. +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +OBJS = ip22-mc.o ip22-sc.o ip22-hpc.o ip22-int.o ip22-rtc.o \ + ip22-setup.o system.o ip22-timer.o ip22-irq.o ip22-reset.o time.o + +all: sgikern.a + +sgikern.a: $(OBJS) + $(AR) rcs sgikern.a $(OBJS) + sync + +dep: + $(CPP) -M *.c > .depend + +include $(TOPDIR)/Rules.make diff --git a/arch/mips64/sgi-ip22/ip22-hpc.c b/arch/mips64/sgi-ip22/ip22-hpc.c new file mode 100644 index 000000000..c3019e8bf --- /dev/null +++ b/arch/mips64/sgi-ip22/ip22-hpc.c @@ -0,0 +1,102 @@ +/* $Id$ + * + * ip22-hpc.c: Routines for generic manipulation of the HPC controllers. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1998, 1999 Ralf Baechle + */ +#include <linux/init.h> + +#include <asm/addrspace.h> +#include <asm/sgi/sgihpc.h> +#include <asm/sgi/sgint23.h> +#include <asm/sgialib.h> + +#undef DEBUG_SGIHPC + +struct hpc3_regs *hpc3c0, *hpc3c1; +struct hpc3_miscregs *hpc3mregs; + +/* We need software copies of these because they are write only. */ +unsigned long sgi_hpc_write1, sgi_hpc_write2; + +/* Machine specific identifier knobs. */ +int sgi_has_ioc2 = 0; +int sgi_guiness = 0; +int sgi_boardid; + +void __init sgihpc_init(void) +{ + unsigned long sid, crev, brev; + + hpc3c0 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP0_PBASE); + hpc3c1 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP1_PBASE); + hpc3mregs = (struct hpc3_miscregs *) (KSEG1 + HPC3_MREGS_PBASE); + sid = hpc3mregs->sysid; + + sid &= 0xff; + crev = (sid & 0xe0) >> 5; + brev = (sid & 0x1e) >> 1; + +#ifdef DEBUG_SGIHPC + prom_printf("sgihpc_init: crev<%2x> brev<%2x>\n", crev, brev); + prom_printf("sgihpc_init: "); +#endif + + /* This test works now thanks to William J. Earl */ + if ((sid & 1) == 0 ) { +#ifdef DEBUG_SGIHPC + prom_printf("GUINESS "); +#endif + sgi_guiness = 1; + } else { +#ifdef DEBUG_SGIHPC + prom_printf("FULLHOUSE "); +#endif + sgi_guiness = 0; + } + sgi_boardid = brev; + +#ifdef DEBUG_SGIHPC + prom_printf("sgi_boardid<%d> ", sgi_boardid); +#endif + + if(crev == 1) { + if((sid & 1) || (brev >= 2)) { +#ifdef DEBUG_SGIHPC + prom_printf("IOC2 "); +#endif + sgi_has_ioc2 = 1; + } else { +#ifdef DEBUG_SGIHPC + prom_printf("IOC1 revision 1 "); +#endif + } + } else { +#ifdef DEBUG_SGIHPC + prom_printf("IOC1 revision 0 "); +#endif + } +#ifdef DEBUG_SGIHPC + prom_printf("\n"); +#endif + + sgi_hpc_write1 = (HPC3_WRITE1_PRESET | + HPC3_WRITE1_KMRESET | + HPC3_WRITE1_ERESET | + HPC3_WRITE1_LC0OFF); + + sgi_hpc_write2 = (HPC3_WRITE2_EASEL | + HPC3_WRITE2_NTHRESH | + HPC3_WRITE2_TPSPEED | + HPC3_WRITE2_EPSEL | + HPC3_WRITE2_U0AMODE | + HPC3_WRITE2_U1AMODE); + + if(!sgi_guiness) + sgi_hpc_write1 |= HPC3_WRITE1_GRESET; + hpc3mregs->write1 = sgi_hpc_write1; + hpc3mregs->write2 = sgi_hpc_write2; + + hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW; +} diff --git a/arch/mips64/sgi-ip22/ip22-int.c b/arch/mips64/sgi-ip22/ip22-int.c new file mode 100644 index 000000000..c6aa35747 --- /dev/null +++ b/arch/mips64/sgi-ip22/ip22-int.c @@ -0,0 +1,608 @@ +/* $Id$ + * + * indy_int.c: Routines for generic manipulation of the INT[23] ASIC + * found on INDY workstations.. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <linux/errno.h> +#include <linux/kernel_stat.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/malloc.h> +#include <linux/random.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> + +#include <asm/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/system.h> + +#include <asm/ptrace.h> +#include <asm/processor.h> +#include <asm/sgi/sgi.h> +#include <asm/sgi/sgihpc.h> +#include <asm/sgi/sgint23.h> +#include <asm/sgialib.h> + +struct sgi_int2_regs *sgi_i2regs; +struct sgi_int3_regs *sgi_i3regs; +struct sgi_ioc_ints *ioc_icontrol; +struct sgi_ioc_timers *ioc_timers; +volatile unsigned char *ioc_tclear; + +static char lc0msk_to_irqnr[256]; +static char lc1msk_to_irqnr[256]; +static char lc2msk_to_irqnr[256]; +static char lc3msk_to_irqnr[256]; + +extern asmlinkage void indyIRQ(void); + +#ifdef CONFIG_REMOTE_DEBUG +extern void rs_kgdb_hook(int); +#endif + +unsigned int local_bh_count[NR_CPUS]; +unsigned int local_irq_count[NR_CPUS]; +unsigned long spurious_count = 0; + +/* Local IRQ's are layed out logically like this: + * + * 0 --> 7 == local 0 interrupts + * 8 --> 15 == local 1 interrupts + * 16 --> 23 == vectored level 2 interrupts + * 24 --> 31 == vectored level 3 interrupts (not used) + */ +void disable_local_irq(unsigned int irq_nr) +{ + unsigned long flags; + + save_and_cli(flags); + switch(irq_nr) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + ioc_icontrol->imask0 &= ~(1 << irq_nr); + break; + + case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: + ioc_icontrol->imask1 &= ~(1 << (irq_nr - 8)); + break; + + case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: + ioc_icontrol->cmeimask0 &= ~(1 << (irq_nr - 16)); + break; + + default: + /* This way we'll see if anyone would ever want vectored + * level 3 interrupts. Highly unlikely. + */ + printk("Yeeee, got passed irq_nr %d at disable_irq\n", irq_nr); + panic("INVALID IRQ level!"); + }; + restore_flags(flags); +} + +void enable_local_irq(unsigned int irq_nr) +{ + unsigned long flags; + save_and_cli(flags); + switch(irq_nr) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + ioc_icontrol->imask0 |= (1 << irq_nr); + break; + + case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: + ioc_icontrol->imask1 |= (1 << (irq_nr - 8)); + break; + + case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: + enable_local_irq(7); + ioc_icontrol->cmeimask0 |= (1 << (irq_nr - 16)); + break; + + default: + printk("Yeeee, got passed irq_nr %d at disable_irq\n", irq_nr); + panic("INVALID IRQ level!"); + }; + restore_flags(flags); +} + +void disable_gio_irq(unsigned int irq_nr) +{ + /* XXX TODO XXX */ +} + +void enable_gio_irq(unsigned int irq_nr) +{ + /* XXX TODO XXX */ +} + +void disable_hpcdma_irq(unsigned int irq_nr) +{ + /* XXX TODO XXX */ +} + +void enable_hpcdma_irq(unsigned int irq_nr) +{ + /* XXX TODO XXX */ +} + +void disable_irq(unsigned int irq_nr) +{ + unsigned int n = irq_nr; + if(n >= SGINT_END) { + printk("whee, invalid irq_nr %d\n", irq_nr); + panic("IRQ, you lose..."); + } + if(n >= SGINT_LOCAL0 && n < SGINT_GIO) { + disable_local_irq(n - SGINT_LOCAL0); + } else if(n >= SGINT_GIO && n < SGINT_HPCDMA) { + disable_gio_irq(n - SGINT_GIO); + } else if(n >= SGINT_HPCDMA && n < SGINT_END) { + disable_hpcdma_irq(n - SGINT_HPCDMA); + } else { + panic("how did I get here?"); + } +} + +void enable_irq(unsigned int irq_nr) +{ + unsigned int n = irq_nr; + if(n >= SGINT_END) { + printk("whee, invalid irq_nr %d\n", irq_nr); + panic("IRQ, you lose..."); + } + if(n >= SGINT_LOCAL0 && n < SGINT_GIO) { + enable_local_irq(n - SGINT_LOCAL0); + } else if(n >= SGINT_GIO && n < SGINT_HPCDMA) { + enable_gio_irq(n - SGINT_GIO); + } else if(n >= SGINT_HPCDMA && n < SGINT_END) { + enable_hpcdma_irq(n - SGINT_HPCDMA); + } else { + panic("how did I get here?"); + } +} + +#if 0 +/* + * Currently unused. + */ +static void local_unex(int irq, void *data, struct pt_regs *regs) +{ + printk("Whee: unexpected local IRQ at %08lx\n", + (unsigned long) regs->cp0_epc); + printk("DUMP: stat0<%x> stat1<%x> vmeistat<%x>\n", + ioc_icontrol->istat0, ioc_icontrol->istat1, + ioc_icontrol->vmeistat); +} +#endif + +static struct irqaction *local_irq_action[24] = { + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL +}; + +int setup_indy_irq(int irq, struct irqaction * new) +{ + printk("setup_indy_irq: Yeee, don't know how to setup irq<%d> for %s %p\n", + irq, new->name, new->handler); + return 0; +} + +static struct irqaction r4ktimer_action = { + NULL, 0, 0, "R4000 timer/counter", NULL, NULL, +}; + +static struct irqaction indy_berr_action = { + NULL, 0, 0, "IP22 Bus Error", NULL, NULL, +}; + +static struct irqaction *irq_action[16] = { + NULL, NULL, NULL, NULL, + NULL, NULL, &indy_berr_action, &r4ktimer_action, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL +}; + +int get_irq_list(char *buf) +{ + int i, len = 0; + int num = 0; + struct irqaction * action; + + for (i = 0 ; i < 16 ; i++, num++) { + action = irq_action[i]; + if (!action) + continue; + len += sprintf(buf+len, "%2d: %8d %c %s", + num, kstat.irqs[0][num], + (action->flags & SA_INTERRUPT) ? '+' : ' ', + action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + len += sprintf(buf+len, " [on-chip]\n"); + } + for (i = 0 ; i < 24 ; i++, num++) { + action = local_irq_action[i]; + if (!action) + continue; + len += sprintf(buf+len, "%2d: %8d %c %s", + num, kstat.irqs[0][num], + (action->flags & SA_INTERRUPT) ? '+' : ' ', + action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + len += sprintf(buf+len, " [local]\n"); + } + return len; +} + +atomic_t __mips_bh_counter; + +/* + * do_IRQ handles IRQ's that have been installed without the + * SA_INTERRUPT flag: it uses the full signal-handling return + * and runs with other interrupts enabled. All relatively slow + * IRQ's should use this format: notably the keyboard/timer + * routines. + */ +asmlinkage void do_IRQ(int irq, struct pt_regs * regs) +{ + struct irqaction *action; + int do_random, cpu; + + cpu = smp_processor_id(); + hardirq_enter(cpu); + kstat.irqs[0][irq]++; + + printk("Got irq %d, press a key.", irq); + prom_getchar(); + romvec->imode(); + + /* + * mask and ack quickly, we don't want the irq controller + * thinking we're snobs just because some other CPU has + * disabled global interrupts (we have already done the + * INT_ACK cycles, it's too late to try to pretend to the + * controller that we aren't taking the interrupt). + * + * Commented out because we've already done this in the + * machinespecific part of the handler. It's reasonable to + * do this here in a highlevel language though because that way + * we could get rid of a good part of duplicated code ... + */ + /* mask_and_ack_irq(irq); */ + + action = *(irq + irq_action); + if (action) { + if (!(action->flags & SA_INTERRUPT)) + __sti(); + action = *(irq + irq_action); + do_random = 0; + do { + do_random |= action->flags; + action->handler(irq, action->dev_id, regs); + action = action->next; + } while (action); + if (do_random & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + __cli(); + } + hardirq_exit(cpu); + + /* unmasking and bottom half handling is done magically for us. */ +} + +int request_local_irq(unsigned int lirq, void (*func)(int, void *, struct pt_regs *), + unsigned long iflags, const char *dname, void *devid) +{ + struct irqaction *action; + + lirq -= SGINT_LOCAL0; + if(lirq >= 24 || !func) + return -EINVAL; + + action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + if(!action) + return -ENOMEM; + + action->handler = func; + action->flags = iflags; + action->mask = 0; + action->name = dname; + action->dev_id = devid; + action->next = 0; + local_irq_action[lirq] = action; + enable_irq(lirq + SGINT_LOCAL0); + return 0; +} + +void free_local_irq(unsigned int lirq, void *dev_id) +{ + struct irqaction *action; + + lirq -= SGINT_LOCAL0; + if(lirq >= 24) { + printk("Aieee: trying to free bogus local irq %d\n", + lirq + SGINT_LOCAL0); + return; + } + action = local_irq_action[lirq]; + local_irq_action[lirq] = NULL; + disable_irq(lirq + SGINT_LOCAL0); + kfree(action); +} + +int request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char * devname, + void *dev_id) +{ + int retval; + struct irqaction * action; + + if (irq >= SGINT_END) + return -EINVAL; + if (!handler) + return -EINVAL; + + if((irq >= SGINT_LOCAL0) && (irq < SGINT_GIO)) + return request_local_irq(irq, handler, irqflags, devname, dev_id); + + action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + if (!action) + return -ENOMEM; + + action->handler = handler; + action->flags = irqflags; + action->mask = 0; + action->name = devname; + action->next = NULL; + action->dev_id = dev_id; + + retval = setup_indy_irq(irq, action); + + if (retval) + kfree(action); + return retval; +} + +void free_irq(unsigned int irq, void *dev_id) +{ + struct irqaction * action, **p; + unsigned long flags; + + if (irq >= SGINT_END) { + printk("Trying to free IRQ%d\n",irq); + return; + } + if((irq >= SGINT_LOCAL0) && (irq < SGINT_GIO)) { + free_local_irq(irq, dev_id); + return; + } + for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { + if (action->dev_id != dev_id) + continue; + + /* Found it - now free it */ + save_and_cli(flags); + *p = action->next; + restore_flags(flags); + kfree(action); + return; + } + printk("Trying to free free IRQ%d\n",irq); +} + +int (*irq_cannonicalize)(int irq); + +static int indy_irq_cannonicalize(int irq) +{ + return irq; /* Sane hardware, sane code ... */ +} + +void __init init_IRQ(void) +{ + irq_cannonicalize = indy_irq_cannonicalize; + irq_setup(); +} + +void indy_local0_irqdispatch(struct pt_regs *regs) +{ + struct irqaction *action; + unsigned char mask = ioc_icontrol->istat0; + unsigned char mask2 = 0; + int irq, cpu = smp_processor_id();; + + mask &= ioc_icontrol->imask0; + if(mask & ISTAT0_LIO2) { + mask2 = ioc_icontrol->vmeistat; + mask2 &= ioc_icontrol->cmeimask0; + irq = lc2msk_to_irqnr[mask2]; + action = local_irq_action[irq]; + } else { + irq = lc0msk_to_irqnr[mask]; + action = local_irq_action[irq]; + } + + hardirq_enter(cpu); + kstat.irqs[0][irq + 16]++; + action->handler(irq, action->dev_id, regs); + hardirq_exit(cpu); +} + +void indy_local1_irqdispatch(struct pt_regs *regs) +{ + struct irqaction *action; + unsigned char mask = ioc_icontrol->istat1; + unsigned char mask2 = 0; + int irq, cpu = smp_processor_id();; + + mask &= ioc_icontrol->imask1; + if(mask & ISTAT1_LIO3) { + printk("WHee: Got an LIO3 irq, winging it...\n"); + mask2 = ioc_icontrol->vmeistat; + mask2 &= ioc_icontrol->cmeimask1; + irq = lc3msk_to_irqnr[ioc_icontrol->vmeistat]; + action = local_irq_action[irq]; + } else { + irq = lc1msk_to_irqnr[mask]; + action = local_irq_action[irq]; + } + hardirq_enter(cpu); + kstat.irqs[0][irq + 24]++; + action->handler(irq, action->dev_id, regs); + hardirq_exit(cpu); +} + +void indy_buserror_irq(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + int irq = 6; + + hardirq_enter(cpu); + kstat.irqs[0][irq]++; + printk("Got a bus error IRQ, shouldn't happen yet\n"); + show_regs(regs); + printk("Spinning...\n"); + while(1); + hardirq_exit(cpu); +} + +/* Misc. crap just to keep the kernel linking... */ +unsigned long probe_irq_on (void) +{ + return 0; +} + +int probe_irq_off (unsigned long irqs) +{ + return 0; +} + +void __init sgint_init(void) +{ + int i; +#ifdef CONFIG_REMOTE_DEBUG + char *ctype; +#endif + + sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE); + sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE); + + /* Init local mask --> irq tables. */ + for(i = 0; i < 256; i++) { + if(i & 0x80) { + lc0msk_to_irqnr[i] = 7; + lc1msk_to_irqnr[i] = 15; + lc2msk_to_irqnr[i] = 23; + lc3msk_to_irqnr[i] = 31; + } else if(i & 0x40) { + lc0msk_to_irqnr[i] = 6; + lc1msk_to_irqnr[i] = 14; + lc2msk_to_irqnr[i] = 22; + lc3msk_to_irqnr[i] = 30; + } else if(i & 0x20) { + lc0msk_to_irqnr[i] = 5; + lc1msk_to_irqnr[i] = 13; + lc2msk_to_irqnr[i] = 21; + lc3msk_to_irqnr[i] = 29; + } else if(i & 0x10) { + lc0msk_to_irqnr[i] = 4; + lc1msk_to_irqnr[i] = 12; + lc2msk_to_irqnr[i] = 20; + lc3msk_to_irqnr[i] = 28; + } else if(i & 0x08) { + lc0msk_to_irqnr[i] = 3; + lc1msk_to_irqnr[i] = 11; + lc2msk_to_irqnr[i] = 19; + lc3msk_to_irqnr[i] = 27; + } else if(i & 0x04) { + lc0msk_to_irqnr[i] = 2; + lc1msk_to_irqnr[i] = 10; + lc2msk_to_irqnr[i] = 18; + lc3msk_to_irqnr[i] = 26; + } else if(i & 0x02) { + lc0msk_to_irqnr[i] = 1; + lc1msk_to_irqnr[i] = 9; + lc2msk_to_irqnr[i] = 17; + lc3msk_to_irqnr[i] = 25; + } else if(i & 0x01) { + lc0msk_to_irqnr[i] = 0; + lc1msk_to_irqnr[i] = 8; + lc2msk_to_irqnr[i] = 16; + lc3msk_to_irqnr[i] = 24; + } else { + lc0msk_to_irqnr[i] = 0; + lc1msk_to_irqnr[i] = 0; + lc2msk_to_irqnr[i] = 0; + lc3msk_to_irqnr[i] = 0; + } + } + + /* Indy uses an INT3, Indigo2 uses an INT2 */ + if (sgi_guiness) { + ioc_icontrol = &sgi_i3regs->ints; + ioc_timers = &sgi_i3regs->timers; + ioc_tclear = &sgi_i3regs->tclear; + } else { + ioc_icontrol = &sgi_i2regs->ints; + ioc_timers = &sgi_i2regs->timers; + ioc_tclear = &sgi_i2regs->tclear; + } + + /* Mask out all interrupts. */ + ioc_icontrol->imask0 = 0; + ioc_icontrol->imask1 = 0; + ioc_icontrol->cmeimask0 = 0; + ioc_icontrol->cmeimask1 = 0; + + /* Now safe to set the exception vector. */ + set_except_vector(0, indyIRQ); + +#ifdef CONFIG_REMOTE_DEBUG + ctype = prom_getcmdline(); + for(i = 0; i < strlen(ctype); i++) { + if(ctype[i]=='k' && ctype[i+1]=='g' && + ctype[i+2]=='d' && ctype[i+3]=='b' && + ctype[i+4]=='=' && ctype[i+5]=='t' && + ctype[i+6]=='t' && ctype[i+7]=='y' && + ctype[i+8]=='d' && + (ctype[i+9] == '1' || ctype[i+9] == '2')) { + printk("KGDB: Using serial line /dev/ttyd%d for " + "session\n", (ctype[i+9] - '0')); + if(ctype[i+9]=='1') + rs_kgdb_hook(1); + else if(ctype[i+9]=='2') + rs_kgdb_hook(0); + else { + printk("KGDB: whoops bogon tty line " + "requested, disabling session\n"); + } + + } + } +#endif +} diff --git a/arch/mips64/sgi-ip22/ip22-irq.S b/arch/mips64/sgi-ip22/ip22-irq.S new file mode 100644 index 000000000..9f4234598 --- /dev/null +++ b/arch/mips64/sgi-ip22/ip22-irq.S @@ -0,0 +1,129 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * indyIRQ.S: Interrupt exception dispatch code for FullHouse and + * Guiness. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + +/* A lot of complication here is taken away because: + * + * 1) We handle one interrupt and return, sitting in a loop and moving across + * all the pending IRQ bits in the cause register is _NOT_ the answer, the + * common case is one pending IRQ so optimize in that direction. + * + * 2) We need not check against bits in the status register IRQ mask, that + * would make this routine slow as hell. + * + * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in + * between like BSD spl() brain-damage. + * + * Furthermore, the IRQs on the INDY look basically (barring software IRQs + * which we don't use at all) like: + * + * MIPS IRQ Source + * -------- ------ + * 0 Software (ignored) + * 1 Software (ignored) + * 2 Local IRQ level zero + * 3 Local IRQ level one + * 4 8254 Timer zero + * 5 8254 Timer one + * 6 Bus Error + * 7 R4k timer (what we use) + * + * We handle the IRQ according to _our_ priority which is: + * + * Highest ---- R4k Timer + * Local IRQ zero + * Local IRQ one + * Bus Error + * 8254 Timer zero + * Lowest ---- 8254 Timer one + * + * then we just return, if multiple IRQs are pending then we will just take + * another exception, big deal. + */ + + .text + .set noreorder + .set noat + .align 5 + NESTED(indyIRQ, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 s0, CP0_CAUSE # get irq mask + + /* First we check for r4k counter/timer IRQ. */ + andi a0, s0, CAUSEF_IP7 + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero + + /* Wheee, a timer interrupt. */ + move a0, sp + jal indy_timer_interrupt + nop # delay slot + + j ret_from_irq + nop # delay slot + +1: + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP3 # delay slot, check local level one + + /* Wheee, local level zero interrupt. */ + jal indy_local0_irqdispatch + move a0, sp # delay slot + + j ret_from_irq + nop # delay slot + +1: + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP6 # delay slot, check bus error + + /* Wheee, local level one interrupt. */ + move a0, sp + jal indy_local1_irqdispatch + nop + + j ret_from_irq + nop + +1: + beq a0, zero, 1f + nop + + /* Wheee, an asynchronous bus error... */ + move a0, sp + jal indy_buserror_irq + nop + + j ret_from_irq + nop + +1: + /* Here by mistake? This is possible, what can happen + * is that by the time we take the exception the IRQ + * pin goes low, so just leave if this is the case. + */ + andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) + beq a0, zero, 1f + + /* Must be one of the 8254 timers... */ + move a0, sp + jal indy_8254timer_irq + nop +1: + j ret_from_irq + nop + END(indyIRQ) diff --git a/arch/mips64/sgi-ip22/ip22-mc.c b/arch/mips64/sgi-ip22/ip22-mc.c new file mode 100644 index 000000000..aa43afe28 --- /dev/null +++ b/arch/mips64/sgi-ip22/ip22-mc.c @@ -0,0 +1,161 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * indy_mc.c: Routines for manipulating the INDY memory controller. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> +#include <linux/kernel.h> + +#include <asm/addrspace.h> +#include <asm/ptrace.h> +#include <asm/sgi/sgimc.h> +#include <asm/sgi/sgihpc.h> +#include <asm/sgialib.h> + +/* #define DEBUG_SGIMC */ + +struct sgimc_misc_ctrl *mcmisc_regs; +unsigned long *rpsscounter; +struct sgimc_dma_ctrl *dmactrlregs; + +static inline char *mconfig_string(unsigned long val) +{ + switch(val & SGIMC_MCONFIG_RMASK) { + case SGIMC_MCONFIG_FOURMB: + return "4MB"; + + case SGIMC_MCONFIG_EIGHTMB: + return "8MB"; + + case SGIMC_MCONFIG_SXTEENMB: + return "16MB"; + + case SGIMC_MCONFIG_TTWOMB: + return "32MB"; + + case SGIMC_MCONFIG_SFOURMB: + return "64MB"; + + case SGIMC_MCONFIG_OTEIGHTMB: + return "128MB"; + + default: + return "wheee, unknown"; + }; +} + +void __init sgimc_init(void) +{ + unsigned long tmpreg; + + mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000); + rpsscounter = (unsigned long *) (KSEG1 + 0x1fa01004); + dmactrlregs = (struct sgimc_dma_ctrl *) (KSEG1+0x1fa02000); + + printk("MC: SGI memory controller Revision %d\n", + (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV); + +#if 0 /* XXX Until I figure out what this bit really indicates XXX */ + /* XXX Is this systemid bit reliable? */ + if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) { + EISA_bus = 1; + printk("with EISA\n"); + } else { + EISA_bus = 0; + printk("no EISA\n"); + } +#endif + +#ifdef DEBUG_SGIMC + prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n", + mconfig_string(mcmisc_regs->mconfig0), + mconfig_string(mcmisc_regs->mconfig1)); + + prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n", + mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1); + prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n", + mcmisc_regs->divider, mcmisc_regs->gioparm); +#endif + + /* Place the MC into a known state. This must be done before + * interrupts are first enabled etc. + */ + + /* Step 1: The CPU/GIO error status registers will not latch + * up a new error status until the register has been + * cleared by the cpu. These status registers are + * cleared by writing any value to them. + */ + mcmisc_regs->cstat = mcmisc_regs->gstat = 0; + + /* Step 2: Enable all parity checking in cpu control register + * zero. + */ + tmpreg = mcmisc_regs->cpuctrl0; + tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | + SGIMC_CCTRL0_R4KNOCHKPARR); + mcmisc_regs->cpuctrl0 = tmpreg; + + /* Step 3: Setup the MC write buffer depth, this is controlled + * in cpu control register 1 in the lower 4 bits. + */ + tmpreg = mcmisc_regs->cpuctrl1; + tmpreg &= ~0xf; + tmpreg |= 0xd; + mcmisc_regs->cpuctrl1 = tmpreg; + + /* Step 4: Initialize the RPSS divider register to run as fast + * as it can correctly operate. The register is laid + * out as follows: + * + * ---------------------------------------- + * | RESERVED | INCREMENT | DIVIDER | + * ---------------------------------------- + * 31 16 15 8 7 0 + * + * DIVIDER determines how often a 'tick' happens, + * INCREMENT determines by how the RPSS increment + * registers value increases at each 'tick'. Thus, + * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101 + */ + mcmisc_regs->divider = 0x101; + + /* Step 5: Initialize GIO64 arbitrator configuration register. + * + * NOTE: If you dork with startup code the HPC init code in + * sgihpc_init() must run before us because of how we + * need to know Guiness vs. FullHouse and the board + * revision on this machine. You have been warned. + */ + + /* First the basic invariants across all gio64 implementations. */ + tmpreg = SGIMC_GIOPARM_HPC64; /* All 1st HPC's interface at 64bits. */ + tmpreg |= SGIMC_GIOPARM_ONEBUS; /* Only one physical GIO bus exists. */ + + if(sgi_guiness) { + /* Guiness specific settings. */ + tmpreg |= SGIMC_GIOPARM_EISA64; /* MC talks to EISA at 64bits */ + tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */ + } else { + /* Fullhouse specific settings. */ + if(sgi_boardid < 2) { + tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */ + tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */ + tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */ + tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */ + } else { + tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */ + tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */ + tmpreg |= SGIMC_GIOPARM_PLINEEXP1; + tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */ + /* someone forgot this poor little guy... */ + tmpreg |= SGIMC_GIOPARM_GFX64; /* GFX at 64 bits */ + } + } + mcmisc_regs->gioparm = tmpreg; /* poof */ +} diff --git a/arch/mips64/sgi-ip22/ip22-reset.c b/arch/mips64/sgi-ip22/ip22-reset.c new file mode 100644 index 000000000..dc4fd0936 --- /dev/null +++ b/arch/mips64/sgi-ip22/ip22-reset.c @@ -0,0 +1,246 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Reset an IP22. + * + * Copyright (C) 1997, 1998, 1999 by Ralf Baechle + */ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/notifier.h> +#include <linux/timer.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/reboot.h> +#include <asm/sgialib.h> +#include <asm/sgi/sgihpc.h> +#include <asm/sgi/sgint23.h> + +/* + * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds. + * I'm not shure if this feature is a good idea, for now it's here just to + * make the power button make behave just like under IRIX. + */ +#define POWERDOWN_TIMEOUT 120 + +/* + * Blink frequency during reboot grace period and when paniced. + */ +#define POWERDOWN_FREQ (HZ / 4) +#define PANIC_FREQ (HZ / 8) + +static unsigned char sgi_volume; + +static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer; +static int shuting_down, has_paniced; + +static void sgi_machine_restart(char *command) __attribute__((noreturn)); +static void sgi_machine_halt(void) __attribute__((noreturn)); +static void sgi_machine_power_off(void) __attribute__((noreturn)); + +/* XXX How to pass the reboot command to the firmware??? */ +static void sgi_machine_restart(char *command) +{ + if (shuting_down) + sgi_machine_power_off(); + prom_reboot(); +} + +static void sgi_machine_halt(void) +{ + if (shuting_down) + sgi_machine_power_off(); + prom_imode(); +} + +static void sgi_machine_power_off(void) +{ + struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; + + cli(); + + clock->cmd |= 0x08; /* Disable watchdog */ + clock->whsec = 0; + clock->wsec = 0; + + while(1) { + hpc3mregs->panel=0xfe; + /* Good bye cruel world ... */ + + /* If we're still running, we probably got sent an alarm + interrupt. Read the flag to clear it. */ + clock->halarm; + } +} + +static void power_timeout(unsigned long data) +{ + sgi_machine_power_off(); +} + +static void blink_timeout(unsigned long data) +{ + /* XXX Fix this for Fullhouse */ + sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF); + hpc3mregs->write1 = sgi_hpc_write1; + + del_timer(&blink_timer); + blink_timer.expires = jiffies + data; + add_timer(&blink_timer); +} + +static void debounce(unsigned long data) +{ + del_timer(&debounce_timer); + if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent. */ + debounce_timer.expires = jiffies + 5; /* 0.05s */ + add_timer(&debounce_timer); + + hpc3mregs->panel = 0xf3; + + return; + } + + if (has_paniced) + prom_reboot(); + + enable_irq(9); +} + +static inline void power_button(void) +{ + if (has_paniced) + return; + + if (shuting_down || kill_proc(1, SIGINT, 1)) { + /* No init process or button pressed twice. */ + sgi_machine_power_off(); + } + + shuting_down = 1; + blink_timer.data = POWERDOWN_FREQ; + blink_timeout(POWERDOWN_FREQ); + + init_timer(&power_timer); + power_timer.function = power_timeout; + power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ; + add_timer(&power_timer); +} + +void inline sgi_volume_set(unsigned char volume) +{ + sgi_volume = volume; + + hpc3c0->pbus_extregs[2][0] = sgi_volume; + hpc3c0->pbus_extregs[2][1] = sgi_volume; +} + +void inline sgi_volume_get(unsigned char *volume) +{ + *volume = sgi_volume; +} + +static inline void volume_up_button(unsigned long data) +{ + del_timer(&volume_timer); + + if (sgi_volume < 0xff) + sgi_volume++; + + hpc3c0->pbus_extregs[2][0] = sgi_volume; + hpc3c0->pbus_extregs[2][1] = sgi_volume; + + if (ioc_icontrol->istat1 & 2) { + volume_timer.expires = jiffies + 1; + add_timer(&volume_timer); + } + +} + +static inline void volume_down_button(unsigned long data) +{ + del_timer(&volume_timer); + + if (sgi_volume > 0) + sgi_volume--; + + hpc3c0->pbus_extregs[2][0] = sgi_volume; + hpc3c0->pbus_extregs[2][1] = sgi_volume; + + if (ioc_icontrol->istat1 & 2) { + volume_timer.expires = jiffies + 1; + add_timer(&volume_timer); + } +} + +static void panel_int(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int buttons; + + buttons = hpc3mregs->panel; + hpc3mregs->panel = 3; /* power_interrupt | power_supply_on */ + + if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */ + disable_irq(9); + init_timer(&debounce_timer); + debounce_timer.function = debounce; + debounce_timer.expires = jiffies + 5; + add_timer(&debounce_timer); + } + + if (!(buttons & 2)) /* Power button was pressed */ + power_button(); + if (!(buttons & 0x40)) { /* Volume up button was pressed */ + init_timer(&volume_timer); + volume_timer.function = volume_up_button; + volume_timer.expires = jiffies + 1; + add_timer(&volume_timer); + } + if (!(buttons & 0x10)) { /* Volume down button was pressed */ + init_timer(&volume_timer); + volume_timer.function = volume_down_button; + volume_timer.expires = jiffies + 1; + add_timer(&volume_timer); + } +} + +static int panic_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + if (has_paniced) + return NOTIFY_DONE; + has_paniced = 1; + + blink_timer.data = PANIC_FREQ; + blink_timeout(PANIC_FREQ); + + return NOTIFY_DONE; +} + +static struct notifier_block panic_block = { + panic_event, + NULL, + 0 +}; + +void ip22_reboot_setup(void) +{ + static int setup_done; + + if (setup_done) + return; + setup_done = 1; + + _machine_restart = sgi_machine_restart; + _machine_halt = sgi_machine_halt; + _machine_power_off = sgi_machine_power_off; + + request_irq(9, panel_int, 0, "Front Panel", NULL); + init_timer(&blink_timer); + blink_timer.function = blink_timeout; + notifier_chain_register(&panic_notifier_list, &panic_block); +} diff --git a/arch/mips64/sgi-ip22/ip22-rtc.c b/arch/mips64/sgi-ip22/ip22-rtc.c new file mode 100644 index 000000000..f138ff27f --- /dev/null +++ b/arch/mips64/sgi-ip22/ip22-rtc.c @@ -0,0 +1,37 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * RTC routines for Indy style attached Dallas chip. + * + * Copyright (C) 1998 by Ralf Baechle + */ +#include <linux/mc146818rtc.h> +#include <asm/sgi/sgihpc.h> + +static unsigned char indy_rtc_read_data(unsigned long addr) +{ + volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; + + return rtcregs[addr]; +} + +static void indy_rtc_write_data(unsigned char data, unsigned long addr) +{ + volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; + + rtcregs[addr] = data; +} + +static int indy_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops indy_rtc_ops = { + &indy_rtc_read_data, + &indy_rtc_write_data, + &indy_rtc_bcd_mode +}; diff --git a/arch/mips64/sgi-ip22/ip22-sc.c b/arch/mips64/sgi-ip22/ip22-sc.c new file mode 100644 index 000000000..6c48e5611 --- /dev/null +++ b/arch/mips64/sgi-ip22/ip22-sc.c @@ -0,0 +1,227 @@ +/* $Id$ + * + * indy_sc.c: Indy cache managment functions. + * + * Copyright (C) 1997 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/autoconf.h> + +#include <asm/bcache.h> +#include <asm/sgi/sgimc.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/bootinfo.h> +#include <asm/sgialib.h> +#include <asm/mmu_context.h> + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#undef DEBUG_CACHE + +#define SC_SIZE 0x00080000 +#define SC_LINE 32 +#define CI_MASK (SC_SIZE - SC_LINE) +#define SC_ROUND(n) ((n) + SC_LINE - 1) +#define SC_INDEX(n) ((n) & CI_MASK) + +static inline void indy_sc_wipe(unsigned long first, unsigned long last) +{ + unsigned long tmp; + + __asm__ __volatile__(" + .set noreorder + .set mips3 + .set noat + mfc0 %2, $12 + li $1, 0x80 # Go 64 bit + mtc0 $1, $12 + + dli $1, 0x9000000080000000 + or %0, $1 # first line to flush + or %1, $1 # last line to flush + .set at + +1: sw $0, 0(%0) + bne %0, %1, 1b + daddu %0, 32 + + mtc0 %2, $12 # Back to 32 bit + nop; nop; nop; nop; + .set mips0 + .set reorder" + : "=r" (first), "=r" (last), "=&r" (tmp) + : "0" (first), "1" (last) + : "$1"); +} + +static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) +{ + unsigned long first_line, last_line; + unsigned int flags; + +#ifdef DEBUG_CACHE + printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); +#endif + /* Which lines to flush? */ + first_line = SC_INDEX(addr); + last_line = SC_INDEX(SC_ROUND(addr + size)); + + __save_and_cli(flags); + if (first_line <= last_line) { + indy_sc_wipe(first_line, last_line); + goto out; + } + + /* Cache index wrap around. Due to the way the buddy system works + this case should not happen. We're prepared to handle it, + though. */ + indy_sc_wipe(last_line, SC_SIZE); + indy_sc_wipe(0, first_line); +out: + __restore_flags(flags); +} + +static void indy_sc_enable(void) +{ + unsigned long tmp1, tmp2, tmp3; + + /* This is really cool... */ +#ifdef DEBUG_CACHE + printk("Enabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__(" + .set push + .set noreorder + .set mips3 + mfc0 %2, $12 + nop; nop; nop; nop; + li %1, 0x80 + mtc0 %1, $12 + nop; nop; nop; nop; + li %0, 0x1 + dsll %0, 31 + lui %1, 0x9000 + dsll32 %1, 0 + or %0, %1, %0 + sb $0, 0(%0) + mtc0 $0, $12 + nop; nop; nop; nop; + mtc0 %2, $12 + nop; nop; nop; nop; + .set pop" + : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); +} + +static void indy_sc_disable(void) +{ + unsigned long tmp1, tmp2, tmp3; + +#ifdef DEBUG_CACHE + printk("Disabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__(" + .set push + .set noreorder + .set mips3 + li %0, 0x1 + dsll %0, 31 + lui %1, 0x9000 + dsll32 %1, 0 + or %0, %1, %0 + mfc0 %2, $12 + nop; nop; nop; nop; + li %1, 0x80 + mtc0 %1, $12 + nop; nop; nop; nop; + sh $0, 0(%0) + mtc0 $0, $12 + nop; nop; nop; nop; + mtc0 %2, $12 + nop; nop; nop; nop; + .set pop" + : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); +} + +static inline __init int indy_sc_probe(void) +{ + volatile unsigned int *cpu_control; + unsigned short cmd = 0xc220; + unsigned long data = 0; + int i, n; + +#ifdef __MIPSEB__ + cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00034); +#else + cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00030); +#endif +#define DEASSERT(bit) (*(cpu_control) &= (~(bit))) +#define ASSERT(bit) (*(cpu_control) |= (bit)) +#define DELAY for(n = 0; n < 100000; n++) __asm__ __volatile__("") + DEASSERT(SGIMC_EEPROM_PRE); + DEASSERT(SGIMC_EEPROM_SDATAO); + DEASSERT(SGIMC_EEPROM_SECLOCK); + DEASSERT(SGIMC_EEPROM_PRE); + DELAY; + ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK); + for(i = 0; i < 11; i++) { + if(cmd & (1<<15)) + ASSERT(SGIMC_EEPROM_SDATAO); + else + DEASSERT(SGIMC_EEPROM_SDATAO); + DEASSERT(SGIMC_EEPROM_SECLOCK); + ASSERT(SGIMC_EEPROM_SECLOCK); + cmd <<= 1; + } + DEASSERT(SGIMC_EEPROM_SDATAO); + for(i = 0; i < (sizeof(unsigned short) * 8); i++) { + unsigned int tmp; + + DEASSERT(SGIMC_EEPROM_SECLOCK); + DELAY; + ASSERT(SGIMC_EEPROM_SECLOCK); + DELAY; + data <<= 1; + tmp = *cpu_control; + if(tmp & SGIMC_EEPROM_SDATAI) + data |= 1; + } + DEASSERT(SGIMC_EEPROM_SECLOCK); + DEASSERT(SGIMC_EEPROM_CSEL); + ASSERT(SGIMC_EEPROM_PRE); + ASSERT(SGIMC_EEPROM_SECLOCK); + + data <<= PAGE_SHIFT; + if (data == 0) + return 0; + + scache_size = data; + + printk("R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n", + scache_size >> 10); + + return 1; +} + +/* XXX Check with wje if the Indy caches can differenciate between + writeback + invalidate and just invalidate. */ +struct bcache_ops indy_sc_ops = { + indy_sc_enable, + indy_sc_disable, + indy_sc_wback_invalidate, + indy_sc_wback_invalidate +}; + +void __init indy_sc_init(void) +{ + if (indy_sc_probe()) { + indy_sc_enable(); + bcops = &indy_sc_ops; + } +} diff --git a/arch/mips64/sgi-ip22/ip22-setup.c b/arch/mips64/sgi-ip22/ip22-setup.c new file mode 100644 index 000000000..d6051f166 --- /dev/null +++ b/arch/mips64/sgi-ip22/ip22-setup.c @@ -0,0 +1,173 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * SGI IP22 specific setup. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silcon Graphics, Inc. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kbd_ll.h> +#include <linux/kernel.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/console.h> +#include <linux/sched.h> +#include <linux/mc146818rtc.h> +#include <linux/pc_keyb.h> + +#include <asm/addrspace.h> +#include <asm/bcache.h> +#include <asm/keyboard.h> +#include <asm/irq.h> +#include <asm/reboot.h> +#include <asm/sgialib.h> +#include <asm/sgi/sgi.h> +#include <asm/sgi/sgimc.h> +#include <asm/sgi/sgihpc.h> +#include <asm/sgi/sgint23.h> + +extern struct rtc_ops indy_rtc_ops; +void indy_reboot_setup(void); +void sgi_volume_set(unsigned char); + +#define sgi_kh ((struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64)) + +#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ + +static void sgi_request_region(void) +{ + /* No I/O ports are being used on the Indy. */ +} + +static int sgi_request_irq(void (*handler)(int, void *, struct pt_regs *)) +{ + /* Dirty hack, this get's called as a callback from the keyboard + driver. We piggyback the initialization of the front panel + button handling on it even though they're technically not + related with the keyboard driver in any way. Doing it from + indy_setup wouldn't work since kmalloc isn't initialized yet. */ + indy_reboot_setup(); + + return request_irq(SGI_KEYBOARD_IRQ, handler, 0, "keyboard", NULL); +} + +static int sgi_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) +{ + /* Nothing to do, interrupt is shared with the keyboard hw */ + return 0; +} + +static void sgi_aux_free_irq(void) +{ + /* Nothing to do, interrupt is shared with the keyboard hw */ +} + +static unsigned char sgi_read_input(void) +{ + return sgi_kh->data; +} + +static void sgi_write_output(unsigned char val) +{ + int status; + + do { + status = sgi_kh->command; + } while (status & KBD_STAT_IBF); + sgi_kh->data = val; +} + +static void sgi_write_command(unsigned char val) +{ + int status; + + do { + status = sgi_kh->command; + } while (status & KBD_STAT_IBF); + sgi_kh->command = val; +} + +static unsigned char sgi_read_status(void) +{ + return sgi_kh->command; +} + +struct kbd_ops sgi_kbd_ops = { + sgi_request_region, + sgi_request_irq, + + sgi_aux_request_irq, + sgi_aux_free_irq, + + sgi_read_input, + sgi_write_output, + sgi_write_command, + sgi_read_status +}; + +static void __init sgi_irq_setup(void) +{ + sgint_init(); +} + +void __init sgi_setup(void) +{ +#ifdef CONFIG_SERIAL_CONSOLE + char *ctype; +#endif + + irq_setup = sgi_irq_setup; + + /* Init the INDY HPC I/O controller. Need to call this before + * fucking with the memory controller because it needs to know the + * boardID and whether this is a Guiness or a FullHouse machine. + */ + sgihpc_init(); + + /* Init INDY memory controller. */ + sgimc_init(); + + /* Now enable boardcaches, if any. */ + indy_sc_init(); + +#ifdef CONFIG_SERIAL_CONSOLE + /* ARCS console environment variable is set to "g?" for + * graphics console, it is set to "d" for the first serial + * line and "d2" for the second serial line. + */ + ctype = prom_getenv("console"); + if(*ctype == 'd') { + if(*(ctype+1)=='2') + console_setup ("ttyS1"); + else + console_setup ("ttyS0"); + } +#endif +#ifdef CONFIG_SGI_PROM_CONSOLE + console_setup("ttyS0"); +#endif + + sgi_volume_set(simple_strtoul(prom_getenv("volume"), NULL, 10)); + +#ifdef CONFIG_VT +#ifdef CONFIG_SGI_NEWPORT_CONSOLE + conswitchp = &newport_con; +#else + conswitchp = &dummy_con; +#endif +#endif + rtc_ops = &indy_rtc_ops; + kbd_ops = &sgi_kbd_ops; +#ifdef CONFIG_PSMOUSE + aux_device_present = 0xaa; +#endif +#ifdef CONFIG_VIDEO_VINO + init_vino(); +#endif +} diff --git a/arch/mips64/sgi-ip22/ip22-timer.c b/arch/mips64/sgi-ip22/ip22-timer.c new file mode 100644 index 000000000..c22651b86 --- /dev/null +++ b/arch/mips64/sgi-ip22/ip22-timer.c @@ -0,0 +1,292 @@ +/* $Id$ + * + * indy_timer.c: Setting up the clock on the INDY 8254 controller. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copytight (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/interrupt.h> +#include <linux/timex.h> +#include <linux/kernel_stat.h> + +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/ptrace.h> +#include <asm/system.h> +#include <asm/sgi/sgi.h> +#include <asm/sgi/sgihpc.h> +#include <asm/sgi/sgint23.h> +#include <asm/sgialib.h> + + +/* Because of a bug in the i8254 timer we need to use the onchip r4k + * counter as our system wide timer interrupt running at 100HZ. + */ +static unsigned long r4k_offset; /* Amount to increment compare reg each time */ +static unsigned long r4k_cur; /* What counter should be at next timer irq */ + +static inline void ack_r4ktimer(unsigned long newval) +{ + write_32bit_cp0_register(CP0_COMPARE, newval); +} + +static int set_rtc_mmss(unsigned long nowtime) +{ + struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; + int retval = 0; + int real_seconds, real_minutes, clock_minutes; + +#define FROB_FROM_CLOCK(x) (((x) & 0xf) | ((((x) & 0xf0) >> 4) * 10)); +#define FROB_TO_CLOCK(x) ((((((x) & 0xff) / 10)<<4) | (((x) & 0xff) % 10)) & 0xff) + + clock->cmd &= ~(0x80); + clock_minutes = clock->min; + clock->cmd |= (0x80); + + clock_minutes = FROB_FROM_CLOCK(clock_minutes); + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + + if(((abs(real_minutes - clock_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + + real_minutes %= 60; + if(abs(real_minutes - clock_minutes) < 30) { + /* Force clock oscillator to be on. */ + clock->month &= ~(0x80); + + /* Write real_seconds and real_minutes into the Dallas. */ + clock->cmd &= ~(0x80); + clock->sec = real_seconds; + clock->min = real_minutes; + clock->cmd |= (0x80); + } else + return -1; + +#undef FROB_FROM_CLOCK +#undef FROB_TO_CLOCK + + return retval; +} + +static long last_rtc_update = 0; +unsigned long missed_heart_beats = 0; + +void indy_timer_interrupt(struct pt_regs *regs) +{ + unsigned long count; + int irq = 7; + + /* Ack timer and compute new compare. */ + count = read_32bit_cp0_register(CP0_COUNT); + /* This has races. */ + if ((count - r4k_cur) >= r4k_offset) { + /* If this happens to often we'll need to compensate. */ + missed_heart_beats++; + r4k_cur = count + r4k_offset; + } + else + r4k_cur += r4k_offset; + ack_r4ktimer(r4k_cur); + kstat.irqs[0][irq]++; + do_timer(regs); + + /* We update the Dallas time of day approx. every 11 minutes, + * because of how the numbers work out we need to make + * absolutely sure we do this update within 500ms before the + * next second starts, thus the following code. + */ + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660 && + xtime.tv_usec >= 500000 - (tick >> 1) && + xtime.tv_usec <= 500000 + (tick >> 1)) { + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + /* do it again in 60s */ + last_rtc_update = xtime.tv_sec - 600; + } +} + +static unsigned long dosample(volatile unsigned char *tcwp, + volatile unsigned char *tc2p) +{ + unsigned long ct0, ct1; + unsigned char msb, lsb; + + /* Start the counter. */ + *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN); + *tc2p = (SGINT_TCSAMP_COUNTER & 0xff); + *tc2p = (SGINT_TCSAMP_COUNTER >> 8); + + /* Get initial counter invariant */ + ct0 = read_32bit_cp0_register(CP0_COUNT); + + /* Latch and spin until top byte of counter2 is zero */ + do { + *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT); + lsb = *tc2p; + msb = *tc2p; + ct1 = read_32bit_cp0_register(CP0_COUNT); + } while(msb); + + /* Stop the counter. */ + *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST); + + /* Return the difference, this is how far the r4k counter increments + * for every one HZ. + */ + return ct1 - ct0; +} + +/* Converts Gregorian date to seconds since 1970-01-01 00:00:00. + * Assumes input in normal date format, i.e. 1980-12-31 23:59:59 + * => year=1980, mon=12, day=31, hour=23, min=59, sec=59. + * + * [For the Julian calendar (which was used in Russia before 1917, + * Britain & colonies before 1752, anywhere else before 1582, + * and is still in use by some communities) leave out the + * -year/100+year/400 terms, and add 10.] + * + * This algorithm was first published by Gauss (I think). + * + * WARNING: this function will overflow on 2106-02-07 06:28:16 on + * machines were long is 32-bit! (However, as time_t is signed, we + * will already get problems at other places on 2038-01-19 03:14:08) + */ +static inline unsigned long mktime(unsigned int year, unsigned int mon, + unsigned int day, unsigned int hour, + unsigned int min, unsigned int sec) +{ + if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ + mon += 12; /* Puts Feb last since it has leap day */ + year -= 1; + } + return ((( + (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) + + year*365 - 719499 + )*24 + hour /* now have hours */ + )*60 + min /* now have minutes */ + )*60 + sec; /* finally seconds */ +} + +static unsigned long __init get_indy_time(void) +{ + struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; + unsigned int year, mon, day, hour, min, sec; + + /* Freeze it. */ + clock->cmd &= ~(0x80); + + /* Read regs. */ + sec = clock->sec; + min = clock->min; + hour = (clock->hr & 0x3f); + day = (clock->date & 0x3f); + mon = (clock->month & 0x1f); + year = clock->year; + + /* Unfreeze clock. */ + clock->cmd |= 0x80; + + /* Frob the bits. */ +#define FROB1(x) (((x) & 0xf) + ((((x) & 0xf0) >> 4) * 10)); +#define FROB2(x) (((x) & 0xf) + (((((x) & 0xf0) >> 4) & 0x3) * 10)); + + /* XXX Should really check that secs register is the same + * XXX as when we first read it and if not go back and + * XXX read the regs above again. + */ + sec = FROB1(sec); min = FROB1(min); day = FROB1(day); + mon = FROB1(mon); year = FROB1(year); + hour = FROB2(hour); + +#undef FROB1 +#undef FROB2 + + /* Wheee... */ + if(year < 45) + year += 30; + if ((year += 1940) < 1970) + year += 100; + + return mktime(year, mon, day, hour, min, sec); +} + +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) + +void __init indy_timer_init(void) +{ + struct sgi_ioc_timers *p; + volatile unsigned char *tcwp, *tc2p; + + /* Figure out the r4k offset, the algorithm is very simple + * and works in _all_ cases as long as the 8254 counter + * register itself works ok (as an interrupt driving timer + * it does not because of bug, this is why we are using + * the onchip r4k counter/compare register to serve this + * purpose, but for r4k_offset calculation it will work + * ok for us). There are other very complicated ways + * of performing this calculation but this one works just + * fine so I am not going to futz around. ;-) + */ + p = ioc_timers; + tcwp = &p->tcword; + tc2p = &p->tcnt2; + + printk("calculating r4koff... "); + dosample(tcwp, tc2p); /* First sample. */ + dosample(tcwp, tc2p); /* Eat one. */ + r4k_offset = dosample(tcwp, tc2p); /* Second sample. */ + + printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); + + r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); + write_32bit_cp0_register(CP0_COMPARE, r4k_cur); + set_cp0_status(ST0_IM, ALLINTS); + sti(); + + /* Read time from the dallas chipset. */ + xtime.tv_sec = get_indy_time(); + xtime.tv_usec = 0; +} + +void indy_8254timer_irq(void) +{ + int cpu = smp_processor_id(); + int irq = 4; + + hardirq_enter(cpu); + kstat.irqs[0][irq]++; + printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n"); + prom_getchar(); + prom_imode(); + hardirq_exit(cpu); +} + +void do_gettimeofday(struct timeval *tv) +{ + unsigned long flags; + + save_and_cli(flags); + *tv = xtime; + restore_flags(flags); +} + +void do_settimeofday(struct timeval *tv) +{ + cli(); + xtime = *tv; + time_state = TIME_BAD; + time_maxerror = MAXPHASE; + time_esterror = MAXPHASE; + sti(); +} diff --git a/arch/mips64/sgi-ip22/system.c b/arch/mips64/sgi-ip22/system.c new file mode 100644 index 000000000..69237a9f5 --- /dev/null +++ b/arch/mips64/sgi-ip22/system.c @@ -0,0 +1,135 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * system.c: Probe the system type using ARCS prom interface library. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/string.h> + +#include <asm/sgi/sgi.h> +#include <asm/sgialib.h> +#include <asm/bootinfo.h> + +enum sgi_mach sgimach; + +struct smatch { + char *name; + int type; +}; + +static struct smatch sgi_cputable[] = { + { "MIPS-R2000", CPU_R2000 }, + { "MIPS-R3000", CPU_R3000 }, + { "MIPS-R3000A", CPU_R3000A }, + { "MIPS-R4000", CPU_R4000SC }, + { "MIPS-R4400", CPU_R4400SC }, + { "MIPS-R4600", CPU_R4600 }, + { "MIPS-R8000", CPU_R8000 }, + { "MIPS-R5000", CPU_R5000 }, + { "MIPS-R5000A", CPU_R5000A } +}; + +#define NUM_CPUS 9 /* for now */ + +static int __init string_to_cpu(char *s) +{ + int i; + + for(i = 0; i < NUM_CPUS; i++) { + if(!strcmp(s, sgi_cputable[i].name)) + return sgi_cputable[i].type; + } + prom_printf("\nYeee, could not determine MIPS cpu type <%s>\n", s); + prom_printf("press a key to reboot\n"); + prom_getchar(); + romvec->imode(); + return 0; +} + +/* + * We' call this early before loadmmu(). If we do the other way around + * the firmware will crash and burn. + */ +void __init sgi_sysinit(void) +{ + pcomponent *p, *toplev, *cpup = 0; + int cputype = -1; + + + /* The root component tells us what machine architecture we + * have here. + */ + p = prom_getchild(PROM_NULL_COMPONENT); + + /* Now scan for cpu(s). */ + toplev = p = prom_getchild(p); + while(p) { + int ncpus = 0; + + if(p->type == Cpu) { + if(++ncpus > 1) { + prom_printf("\nYeee, SGI MP not ready yet\n"); + prom_printf("press a key to reboot\n"); + prom_getchar(); + romvec->imode(); + } + printk("CPU: %s ", p->iname); + cpup = p; + cputype = string_to_cpu(cpup->iname); + } + p = prom_getsibling(p); + } + if(cputype == -1) { + prom_printf("\nYeee, could not find cpu ARCS component\n"); + prom_printf("press a key to reboot\n"); + prom_getchar(); + romvec->imode(); + } + p = prom_getchild(cpup); + while(p) { + switch(p->class) { + case processor: + switch(p->type) { + case Fpu: + printk("FPU<%s> ", p->iname); + break; + + default: + break; + }; + break; + + case cache: + switch(p->type) { + case picache: + printk("ICACHE "); + break; + + case pdcache: + printk("DCACHE "); + break; + + case sccache: + printk("SCACHE "); + break; + + default: + break; + + }; + break; + + default: + break; + }; + p = prom_getsibling(p); + } + printk("\n"); +} diff --git a/arch/mips64/sgi-ip22/time.c b/arch/mips64/sgi-ip22/time.c new file mode 100644 index 000000000..5d1d907de --- /dev/null +++ b/arch/mips64/sgi-ip22/time.c @@ -0,0 +1,20 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * time.c: Generic SGI time_init() code, this will dispatch to the + * appropriate per-architecture time/counter init code. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#include <linux/init.h> + +extern void indy_timer_init(void); + +void __init time_init(void) +{ + /* XXX assume INDY for now XXX */ + indy_timer_init(); +} diff --git a/drivers/Makefile b/drivers/Makefile index 58af28821..51ad67441 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -57,7 +57,7 @@ else endif endif -ifdef CONFIG_SGI +ifdef CONFIG_SGI_IP22 SUB_DIRS += sgi MOD_SUB_DIRS += sgi endif diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 02df81f77..baab892ef 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -787,8 +787,8 @@ __initfunc(int blk_dev_init(void)) #ifdef CONFIG_BLK_DEV_FD floppy_init(); #else -#if !defined(CONFIG_SGI) && !defined (__mc68000__) && !defined(CONFIG_PMAC) \ - && !defined(__sparc__) && !defined(CONFIG_APUS) \ +#if !defined(CONFIG_SGI_IP22) && !defined (__mc68000__) && \ + !defined(CONFIG_PMAC) && !defined(__sparc__) && !defined(CONFIG_APUS) \ && !defined(CONFIG_DECSTATION) && !defined(CONFIG_BAGET_MIPS) outb_p(0xc, 0x3f2); #endif diff --git a/drivers/char/Config.in b/drivers/char/Config.in index 6c9f0a651..250802a51 100644 --- a/drivers/char/Config.in +++ b/drivers/char/Config.in @@ -137,7 +137,7 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then dep_tristate 'Colour QuickCam Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_CQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_SGI" = "y" ]; then + if [ "$CONFIG_SGI_IP22" = "y" ]; then dep_tristate 'SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV fi fi diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 9b5b5fc20..024706dc6 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -281,7 +281,7 @@ int __init misc_init(void) #ifdef CONFIG_SGI_NEWPORT_GFX gfx_register (); #endif -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 streamable_init (); #endif if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { diff --git a/drivers/char/vt.c b/drivers/char/vt.c index b7f51e2f3..1bb5120cd 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -89,7 +89,7 @@ unsigned int video_scan_lines; */ #if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \ - || (defined(__mips__) && !defined(CONFIG_SGI)) + || (defined(__mips__) && !defined(CONFIG_SGI_IP22)) static void kd_nosound(unsigned long ignored) diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index 2f75c1bf3..3cb968060 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -1359,7 +1359,7 @@ uchar sr; hostdata = (struct WD33C93_hostdata *)instance->hostdata; regp = hostdata->regp; -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 { int busycount = 0; extern void sgiwd93_reset(uchar*); diff --git a/drivers/scsi/wd33c93.h b/drivers/scsi/wd33c93.h index 0a49ce982..a6b094701 100644 --- a/drivers/scsi/wd33c93.h +++ b/drivers/scsi/wd33c93.h @@ -190,7 +190,7 @@ typedef struct { volatile unsigned char SASR; char pad; -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 char pad2,pad3; #endif volatile unsigned char SCMD; diff --git a/include/asm-mips/bcache.h b/include/asm-mips/bcache.h index 0296a0b77..e3507bb04 100644 --- a/include/asm-mips/bcache.h +++ b/include/asm-mips/bcache.h @@ -1,14 +1,14 @@ -/* - * include/asm-mips/bcache.h +/* $Id$ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1997 by Ralf Baechle - * - * $Id: bcache.h,v 1.3 1998/01/04 00:59:35 ralf Exp $ + * Copyright (c) 1997, 1999 by Ralf Baechle */ +#ifndef _ASM_BCACHE_H +#define _ASM_BCACHE_H + struct bcache_ops { void (*bc_enable)(void); void (*bc_disable)(void); @@ -20,3 +20,5 @@ extern void indy_sc_init(void); extern void sni_pcimt_sc_init(void); extern struct bcache_ops *bcops; + +#endif /* _ASM_BCACHE_H */ diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 454b68991..d576ca8ce 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -1,4 +1,4 @@ -/* $Id: bootinfo.h,v 1.6 1999/01/04 16:09:20 ralf Exp $ +/* $Id: bootinfo.h,v 1.7 1999/04/12 18:59:14 harald Exp $ * * bootinfo.h -- Definition of the Linux/MIPS boot information structure * @@ -161,7 +161,7 @@ typedef struct mips_arc_DisplayInfo { /* video adapter information */ unsigned short lines; } mips_arc_DisplayInfo; -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 /* screen info will dissapear... soon */ //#define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 158, 0, 0, 0, 62, 0, 16} #define DEFAULT_SCREEN_INFO {0, 0, 0, 0, 0, 160, 0, 0, 0, 64, 0, 16} diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h index 1432efa8e..81868496a 100644 --- a/include/asm-mips/dma.h +++ b/include/asm-mips/dma.h @@ -1,4 +1,4 @@ -/* $Id: dma.h,v 1.4 1998/11/15 03:25:44 ralf Exp $ +/* $Id: dma.h,v 1.2 1999/01/04 16:09:21 ralf Exp $ * linux/include/asm/dma.h: Defines for using and allocating dma channels. * Written by Hennus Bergman, 1992. * High DMA channel support & info by Hannu Savolainen @@ -83,7 +83,7 @@ * Deskstations or Acer PICA but not the much more versatile DMA logic used * for the local devices on Acer PICA or Magnums. */ -#ifndef CONFIG_SGI +#ifndef CONFIG_SGI_IP22 #define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000) #else #define MAX_DMA_ADDRESS (~0UL) diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h index af1a8f171..eb89b6317 100644 --- a/include/asm-mips/elf.h +++ b/include/asm-mips/elf.h @@ -1,5 +1,5 @@ /* - * $Id: elf.h,v 1.5 1998/03/17 22:16:13 ralf Exp $ + * $Id: elf.h,v 1.6 1999/02/15 02:22:10 ralf Exp $ */ #ifndef __ASM_MIPS_ELF_H #define __ASM_MIPS_ELF_H @@ -21,7 +21,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; /* * These are used to set parameters in the core dumps. - * FIXME(eric) I don't know what the correct endianness to use is. */ #define ELF_CLASS ELFCLASS32 #ifdef __MIPSEB__ diff --git a/include/asm-mips/reboot.h b/include/asm-mips/reboot.h index 930b49831..217c4a828 100644 --- a/include/asm-mips/reboot.h +++ b/include/asm-mips/reboot.h @@ -3,15 +3,15 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1997 by Ralf Baechle + * Copyright (C) 1997, 1999 by Ralf Baechle * * Declare variables for rebooting. */ -#ifndef __ASM_MIPS_REBOOT_H -#define __ASM_MIPS_REBOOT_H +#ifndef _ASM_REBOOT_H +#define _ASM_REBOOT_H void (*_machine_restart)(char *command); void (*_machine_halt)(void); void (*_machine_power_off)(void); -#endif /* __ASM_MIPS_REBOOT_H */ +#endif /* _ASM_REBOOT_H */ diff --git a/include/asm-mips64/bcache.h b/include/asm-mips64/bcache.h new file mode 100644 index 000000000..e3507bb04 --- /dev/null +++ b/include/asm-mips64/bcache.h @@ -0,0 +1,24 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 1997, 1999 by Ralf Baechle + */ +#ifndef _ASM_BCACHE_H +#define _ASM_BCACHE_H + +struct bcache_ops { + void (*bc_enable)(void); + void (*bc_disable)(void); + void (*bc_wback_inv)(unsigned long page, unsigned long size); + void (*bc_inv)(unsigned long page, unsigned long size); +}; + +extern void indy_sc_init(void); +extern void sni_pcimt_sc_init(void); + +extern struct bcache_ops *bcops; + +#endif /* _ASM_BCACHE_H */ diff --git a/include/asm-mips64/bitops.h b/include/asm-mips64/bitops.h index a9edabe72..e6e675a5c 100644 --- a/include/asm-mips64/bitops.h +++ b/include/asm-mips64/bitops.h @@ -1,4 +1,4 @@ -/* $Id$ +/* $Id: bitops.h,v 1.2 1999/08/19 22:56:34 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -19,8 +19,9 @@ #include <asm/mipsregs.h> #endif -/* This gets exported to userland, so we need to have a MIPS I versions - * as well ... +/* + * This gets exported to userland, so we need to have a MIPS I versions + * as well. Userland always get the non-thread / signal safe variants. */ #ifndef __KERNEL__ diff --git a/include/asm-mips64/checksum.h b/include/asm-mips64/checksum.h new file mode 100644 index 000000000..d8f8bee72 --- /dev/null +++ b/include/asm-mips64/checksum.h @@ -0,0 +1,257 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#ifndef _ASM_CHECKSUM_H +#define _ASM_CHECKSUM_H + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); + +/* + * this is a new version of the above that records errors it finds in *errp, + * but continues and zeros the rest of the buffer. + */ +#define csum_partial_copy_nocheck csum_partial_copy + +/* + * this is a new version of the above that records errors it finds in *errp, + * but continues and zeros the rest of the buffer. + */ +unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, + unsigned int sum, int *errp); + +#define HAVE_CSUM_COPY_USER +unsigned int csum_and_copy_to_user (const char *src, char *dst, + int len, int sum, int *err_ptr); + +/* + * the same as csum_partial, but copies from user space (but on MIPS + * we have just one address space, so this is identical to the above) + * + * this is obsolete and will go away. + */ +#define csum_partial_copy_fromuser csum_partial_copy +unsigned int csum_partial_copy(const char *src, char *dst, int len, unsigned int sum); + +/* + * Fold a partial checksum without adding pseudo headers + */ +static inline unsigned short int csum_fold(unsigned int sum) +{ + __asm__(" + .set noat + sll $1,%0,16 + addu %0,$1 + sltu $1,%0,$1 + srl %0,%0,16 + addu %0,$1 + xori %0,0xffff + .set at" + : "=r" (sum) + : "0" (sum) + : "$1"); + + return sum; +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + * + * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by + * Arnt Gulbrandsen. + */ +static inline unsigned short ip_fast_csum(unsigned char * iph, + unsigned int ihl) +{ + unsigned int sum; + unsigned long dummy; + + /* + * This is for 32-bit processors ... but works just fine for 64-bit + * processors for now ... XXX + */ + __asm__ __volatile__(" + .set noreorder + .set noat + lw %0,(%1) + subu %2,4 + #blez %2,2f + sll %2,2 # delay slot + + lw %3,4(%1) + addu %2,%1 # delay slot + addu %0,%3 + sltu $1,%0,%3 + lw %3,8(%1) + addu %0,$1 + addu %0,%3 + sltu $1,%0,%3 + lw %3,12(%1) + addu %0,$1 + addu %0,%3 + sltu $1,%0,%3 + addu %0,$1 + +1: lw %3,16(%1) + addiu %1,4 + addu %0,%3 + sltu $1,%0,%3 + bne %2,%1,1b + addu %0,$1 # delay slot + +2: .set at + .set reorder" + : "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy) + : "1" (iph), "2" (ihl) + : "$1"); + + return csum_fold(sum); +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum) +{ + __asm__(" + .set noat + addu %0,%2 + sltu $1,%0,%2 + addu %0,$1 + + addu %0,%3 + sltu $1,%0,%3 + addu %0,$1 + + addu %0,%4 + sltu $1,%0,%4 + addu %0,$1 + .set at" + : "=r" (sum) + : "0" (daddr), "r"(saddr), +#ifdef __MIPSEL__ + "r" ((ntohs(len)<<16)+proto*256), +#else + "r" (((proto)<<16)+len), +#endif + "r"(sum) + : "$1"); + + return sum; +} + +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, + unsigned long daddr, + unsigned short len, + unsigned short proto, + unsigned int sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +static inline unsigned short ip_compute_csum(unsigned char * buff, int len) +{ + return csum_fold(csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u16 len, + unsigned short proto, + unsigned int sum) +{ + __asm__(" + .set noreorder + .set noat + addu %0,%5 # proto (long in network byte order) + sltu $1,%0,%5 + addu %0,$1 + + addu %0,%6 # csum + sltu $1,%0,%6 + lw %1,0(%2) # four words source address + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,4(%2) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,8(%2) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,12(%2) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,0(%3) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,4(%3) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,8(%3) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + + lw %1,12(%3) + addu %0,$1 + addu %0,%1 + sltu $1,%0,$1 + .set noat + .set noreorder" + : "=r" (sum), + "=r" (proto) + : "r" (saddr), + "r" (daddr), + "0" (htonl((__u32) (len))), + "1" (htonl(proto)), + "r"(sum) + : "$1"); + + return csum_fold(sum); +} + +#endif /* _ASM_CHECKSUM_H */ diff --git a/include/asm-mips64/dma.h b/include/asm-mips64/dma.h index 3a3c1ec2b..169698ba5 100644 --- a/include/asm-mips64/dma.h +++ b/include/asm-mips64/dma.h @@ -84,7 +84,7 @@ * Deskstations or Acer PICA but not the much more versatile DMA logic used * for the local devices on Acer PICA or Magnums. */ -#ifndef CONFIG_SGI +#ifndef CONFIG_SGI_IP22 #define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000) #else #define MAX_DMA_ADDRESS (~0UL) diff --git a/include/asm-mips64/elf.h b/include/asm-mips64/elf.h new file mode 100644 index 000000000..e9b755277 --- /dev/null +++ b/include/asm-mips64/elf.h @@ -0,0 +1,85 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#ifndef _ASM_ELF_H +#define _ASM_ELF_H + +/* ELF register definitions */ +#define ELF_NGREG 45 +#define ELF_NFPREG 33 + +typedef unsigned long elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_MIPS_RS4_BE) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS64 +#ifdef __MIPSEB__ +#define ELF_DATA ELFDATA2MSB +#elif __MIPSEL__ +#define ELF_DATA ELFDATA2LSB +#endif +#define ELF_ARCH EM_MIPS + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +#define ELF_CORE_COPY_REGS(_dest,_regs) \ + memcpy((char *) &_dest, (char *) _regs, \ + sizeof(struct pt_regs)); + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. This could be done in userspace, + but it's not easy, and we've already done it here. */ + +#define ELF_HWCAP (0) + +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. + + For the moment, we have only optimizations for the Intel generations, + but that could change... */ + +#define ELF_PLATFORM (NULL) + +/* + * See comments in asm-alpha/elf.h, this is the same thing + * on the MIPS. + */ +#define ELF_PLAT_INIT(_r) do { \ + _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0; \ + _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0; \ + _r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0; \ + _r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0; \ + _r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0; \ + _r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0; \ + _r->regs[25] = _r->regs[26] = _r->regs[27] = _r->regs[28] = 0; \ + _r->regs[30] = _r->regs[31] = 0; \ +} while (0) + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) + +#ifdef __KERNEL__ +#define SET_PERSONALITY(ex,ibcs2) \ + current->personality = (ibcs2 ? PER_SVR4 : PER_LINUX) +#endif + +#endif /* _ASM_ELF_H */ diff --git a/include/asm-mips64/floppy.h b/include/asm-mips64/floppy.h new file mode 100644 index 000000000..d8f9b5005 --- /dev/null +++ b/include/asm-mips64/floppy.h @@ -0,0 +1,104 @@ +/* $Id$ + * + * Architecture specific parts of the Floppy driver + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996, 1997, 1998, 1999 Ralf Baechle + */ +#ifndef _ASM_FLOPPY_H +#define _ASM_FLOPPY_H + +#include <asm/bootinfo.h> +#include <asm/jazz.h> +#include <asm/jazzdma.h> + +struct fd_ops { + unsigned char (*fd_inb)(unsigned int port); + void (*fd_outb)(unsigned char value, unsigned int port); + + /* + * How to access the floppy DMA functions. + */ + void (*fd_enable_dma)(int channel); + void (*fd_disable_dma)(int channel); + int (*fd_request_dma)(int channel); + void (*fd_free_dma)(int channel); + void (*fd_clear_dma_ff)(int channel); + void (*fd_set_dma_mode)(int channel, char mode); + void (*fd_set_dma_addr)(int channel, unsigned int a); + void (*fd_set_dma_count)(int channel, unsigned int count); + int (*fd_get_dma_residue)(int channel); + void (*fd_enable_irq)(int irq); + void (*fd_disable_irq)(int irq); + unsigned long (*fd_getfdaddr1)(void); + unsigned long (*fd_dma_mem_alloc)(unsigned long size); + void (*fd_dma_mem_free)(unsigned long addr, unsigned long size); + unsigned long (*fd_drive_type)(unsigned long); +}; + +extern struct fd_ops *fd_ops; + +#define fd_inb(port) fd_ops->fd_inb(port) +#define fd_outb(value,port) fd_ops->fd_outb(value,port) + +#define fd_enable_dma(channel) fd_ops->fd_enable_dma(channel) +#define fd_disable_dma(channel) fd_ops->fd_disable_dma(channel) +#define fd_request_dma(channel) fd_ops->fd_request_dma(channel) +#define fd_free_dma(channel) fd_ops->fd_free_dma(channel) +#define fd_clear_dma_ff(channel) fd_ops->fd_clear_dma_ff(channel) +#define fd_set_dma_mode(channel, mode) fd_ops->fd_set_dma_mode(channel, mode) +#define fd_set_dma_addr(channel, addr) fd_ops->fd_set_dma_addr(channel, \ + virt_to_bus(addr)) +#define fd_set_dma_count(channel,count) fd_ops->fd_set_dma_count(channel,count) +#define fd_get_dma_residue(channel) fd_ops->fd_get_dma_residue(channel) + +#define fd_enable_irq(irq) fd_ops->fd_enable_irq(irq) +#define fd_disable_irq(irq) fd_ops->fd_disable_irq(irq) +#define fd_request_irq(irq) request_irq(irq, floppy_interrupt, \ + SA_INTERRUPT \ + | SA_SAMPLE_RANDOM, \ + "floppy", NULL) +#define fd_free_irq(irq) free_irq(irq, NULL); +#define fd_dma_mem_alloc(size) fd_ops->fd_dma_mem_alloc(size) +#define fd_dma_mem_free(mem,size) fd_ops->fd_dma_mem_free(mem,size) +#define fd_drive_type(n) fd_ops->fd_drive_type(n) + +#define MAX_BUFFER_SECTORS 24 + + +/* + * And on Mips's the CMOS info fails also ... + * + * FIXME: This information should come from the ARC configuration tree + * or whereever a particular machine has stored this ... + */ +#define FLOPPY0_TYPE fd_drive_type(0) +#define FLOPPY1_TYPE fd_drive_type(1) + +#define FDC1 fd_ops->fd_getfdaddr1(); +static int FDC2=-1; + +#define N_FDC 1 /* do you *really* want a second controller? */ +#define N_DRIVE 8 + +#define FLOPPY_MOTOR_MASK 0xf0 + +/* + * The DMA channel used by the floppy controller cannot access data at + * addresses >= 16MB + * + * Went back to the 1MB limit, as some people had problems with the floppy + * driver otherwise. It doesn't matter much for performance anyway, as most + * floppy accesses go through the track buffer. + * + * On MIPSes using vdma, this actually means that *all* transfers go thru + * the * track buffer since 0x1000000 is always smaller than KSEG0/1. + * Actually this needs to be a bit more complicated since the so much different + * hardware available with MIPS CPUs ... + */ +#define CROSS_64KB(a,s) ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64) + +#endif /* _ASM_FLOPPY_H */ diff --git a/include/asm-mips64/namei.h b/include/asm-mips64/namei.h new file mode 100644 index 000000000..3152a3836 --- /dev/null +++ b/include/asm-mips64/namei.h @@ -0,0 +1,19 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#ifndef _ASM_NAMEI_H +#define _ASM_NAMEI_H + +/* + * This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ + +#define __prefix_lookup_dentry(name, lookup_flags) \ + do {} while (0) + +#endif /* _ASM_NAMEI_H */ diff --git a/include/asm-mips64/reboot.h b/include/asm-mips64/reboot.h new file mode 100644 index 000000000..217c4a828 --- /dev/null +++ b/include/asm-mips64/reboot.h @@ -0,0 +1,17 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1997, 1999 by Ralf Baechle + * + * Declare variables for rebooting. + */ +#ifndef _ASM_REBOOT_H +#define _ASM_REBOOT_H + +void (*_machine_restart)(char *command); +void (*_machine_halt)(void); +void (*_machine_power_off)(void); + +#endif /* _ASM_REBOOT_H */ diff --git a/include/asm-mips64/regdef.h b/include/asm-mips64/regdef.h new file mode 100644 index 000000000..a6853fb69 --- /dev/null +++ b/include/asm-mips64/regdef.h @@ -0,0 +1,53 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1985 MIPS Computer Systems, Inc. + * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc. + * Copyright (C) 1999 Ralf Baechle + */ +#ifndef _ASM_REGDEF_H +#define _ASM_REGDEF_H + +#define zero $0 /* wired zero */ +#define AT $at /* assembler temp - uppercase because of ".set at" */ +#define v0 $2 /* return value - caller saved */ +#define v1 $3 +#define a0 $4 /* argument registers */ +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define a4 $8 /* arg reg 64 bit; caller saved in 32 bit */ +#define ta0 $8 +#define a5 $9 +#define ta1 $9 +#define a6 $10 +#define ta2 $10 +#define a7 $11 +#define ta3 $11 +#define t0 $12 /* caller saved */ +#define t1 $13 +#define t2 $14 +#define t3 $15 +#define s0 $16 /* callee saved */ +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 /* caller saved */ +#define t9 $25 /* callee address for PIC/temp */ +#define jp $25 /* PIC jump register */ +#define k0 $26 /* kernel temporary */ +#define k1 $27 +#define gp $28 /* global pointer - caller saved for PIC */ +#define sp $29 /* stack pointer */ +#define fp $30 /* frame pointer */ +#define s8 $30 /* callee saved */ +#define ra $31 /* return address */ + +#endif /* _ASM_REGDEF_H */ diff --git a/include/asm-mips64/sgi/sgi.h b/include/asm-mips64/sgi/sgi.h new file mode 100644 index 000000000..1606e8d5a --- /dev/null +++ b/include/asm-mips64/sgi/sgi.h @@ -0,0 +1,48 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * sgi.h: Definitions specific to SGI machines. + * + * Copyright (C) 1996 David S. Miller (dm@sgi.com) + */ +#ifndef _ASM_SGI_SGI_H +#define _ASM_SGI_SGI_H + +/* UP=UniProcessor MP=MultiProcessor(capable) */ +enum sgi_mach { + ip4, /* R2k UP */ + ip5, /* R2k MP */ + ip6, /* R3k UP */ + ip7, /* R3k MP */ + ip9, /* R3k UP */ + ip12, /* R3kA UP, Indigo */ + ip15, /* R3kA MP */ + ip17, /* R4K UP */ + ip19, /* R4K MP */ + ip20, /* R4K UP, Indigo */ + ip21, /* TFP MP */ + ip22, /* R4x00 UP, Indigo2 */ + ip25, /* R10k MP */ + ip26, /* TFP UP, Indigo2 */ + ip27, /* R10k MP, R12k MP, Origin */ + ip28, /* R10k UP, Indigo2 */ + ip30, + ip32, +}; + +extern enum sgi_mach sgimach; +extern void sgi_sysinit(void); + +/* Many I/O space registers are byte sized and are contained within + * one byte per word, specifically the MSB, this macro helps out. + */ +#ifdef __MIPSEL__ +#define SGI_MSB(regaddr) (regaddr) +#else +#define SGI_MSB(regaddr) ((regaddr) | 0x3) +#endif + +#endif /* _ASM_SGI_SGI_H */ diff --git a/include/asm-mips64/sgi/sgihpc.h b/include/asm-mips64/sgi/sgihpc.h new file mode 100644 index 000000000..d862d9dc9 --- /dev/null +++ b/include/asm-mips64/sgi/sgihpc.h @@ -0,0 +1,378 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * sgihpc.h: Various HPC I/O controller defines. The HPC is basically + * the approximate functional equivalent of the Sun SYSIO + * on SGI INDY machines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1998 Ralf Baechle (ralf@gnu.org) + */ +#ifndef _ASM_SGI_SGIHPC_H +#define _ASM_SGI_SGIHPC_H + +#include <asm/page.h> + +extern int sgi_has_ioc2; /* to know if we have older ioc1 or ioc2. */ +extern int sgi_guiness; /* GUINESS or FULLHOUSE machine. */ +extern int sgi_boardid; /* Board revision. */ + +/* An HPC dma descriptor. */ +struct hpc_dma_desc { + unsigned long pbuf; /* physical address of data buffer */ + unsigned long cntinfo; /* counter and info bits */ +#define HPCDMA_EOX 0x80000000 /* last desc in chain for tx */ +#define HPCDMA_EOR 0x80000000 /* last desc in chain for rx */ +#define HPCDMA_EOXP 0x40000000 /* end of packet for tx */ +#define HPCDMA_EORP 0x40000000 /* end of packet for rx */ +#define HPCDMA_XIE 0x20000000 /* irq generated when at end of this desc */ +#define HPCDMA_XIU 0x01000000 /* Tx buffer in use by CPU. */ +#define HPCDMA_EIPC 0x00ff0000 /* SEEQ ethernet special xternal bytecount */ +#define HPCDMA_ETXD 0x00008000 /* set to one by HPC when packet tx'd */ +#define HPCDMA_OWN 0x00004000 /* Denotes ring buffer ownership on rx */ +#define HPCDMA_BCNT 0x00003fff /* size in bytes of this dma buffer */ + + unsigned long pnext; /* paddr of next hpc_dma_desc if any */ +}; + +typedef volatile unsigned long hpcreg; + +/* HPC1 stuff. */ + +/* HPC3 stuff. */ + +/* The set of regs for each HPC3 pbus dma channel. */ +struct hpc3_pbus_dmacregs { + hpcreg pbdma_bptr; /* pbus dma channel buffer ptr */ + hpcreg pbdma_dptr; /* pbus dma channel desc ptr */ + char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ + hpcreg pbdma_ctrl; /* pbus dma channel control reg */ +#define HPC3_PDMACTRL_SEL 0x00000002 /* little endian transfer */ +#define HPC3_PDMACTRL_RCV 0x00000004 /* direction is receive */ +#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */ +#define HPC3_PDMACTRL_ACT 0x00000010 /* start dma transfer */ +#define HPC3_PDMACTRL_LD 0x00000020 /* load enable for ACT */ +#define HPC3_PDMACTRL_RT 0x00000040 /* Use realtime GIO bus servicing */ +#define HPC3_PDMACTRL_HW 0x0000ff00 /* DMA High-water mark */ +#define HPC3_PDMACTRL_FB 0x003f0000 /* Ptr to beginning of fifo */ +#define HPC3_PDMACTRL_FE 0x3f000000 /* Ptr to end of fifo */ + + char _unused2[PAGE_SIZE - (sizeof(hpcreg))]; /* padding */ +}; + +/* The HPC3 scsi registers, this does not include external ones. */ +struct hpc3_scsiregs { + hpcreg cbptr; /* current dma buffer ptr, diagnostic use only */ + hpcreg ndptr; /* next dma descriptor ptr */ + char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ + hpcreg bcd; /* byte count info */ +#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */ +#define HPC3_SBCD_XIE 0x00004000 /* Send IRQ when done with cur buf */ +#define HPC3_SBCD_EOX 0x00008000 /* Indicates this is last buf in chain */ + + hpcreg ctrl; /* control register */ +#define HPC3_SCTRL_IRQ 0x01 /* IRQ asserted, either dma done or parity */ +#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */ +#define HPC3_SCTRL_DIR 0x04 /* DMA direction, 1=dev2mem 0=mem2dev */ +#define HPC3_SCTRL_FLUSH 0x08 /* Tells HPC3 to flush scsi fifos */ +#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */ +#define HPC3_SCTRL_AMASK 0x20 /* DMA active inhibits PIO */ +#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */ +#define HPC3_SCTRL_PERR 0x80 /* Bad parity on HPC3 iface to scsi controller */ + + hpcreg gfptr; /* current GIO fifo ptr */ + hpcreg dfptr; /* current device fifo ptr */ + hpcreg dconfig; /* DMA configuration register */ +#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */ +#define HPC3_SDCFG_D1 0x00006 /* Cycles to spend in D1 state */ +#define HPC3_SDCFG_D2 0x00038 /* Cycles to spend in D2 state */ +#define HPC3_SDCFG_D3 0x001c0 /* Cycles to spend in D3 state */ +#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */ +#define HPC3_SDCFG_HW 0x01000 /* Enable 16-bit halfword DMA accesses to scsi */ +#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */ +#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */ +#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */ +#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */ + + hpcreg pconfig; /* PIO configuration register */ +#define HPC3_SPCFG_P3 0x0003 /* Cycles to spend in P3 state */ +#define HPC3_SPCFG_P2W 0x001c /* Cycles to spend in P2 state for writes */ +#define HPC3_SPCFG_P2R 0x01e0 /* Cycles to spend in P2 state for reads */ +#define HPC3_SPCFG_P1 0x0e00 /* Cycles to spend in P1 state */ +#define HPC3_SPCFG_HW 0x1000 /* Enable 16-bit halfword PIO accesses to scsi */ +#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */ +#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */ +#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */ + + char _unused2[PAGE_SIZE - (6 * sizeof(hpcreg))]; /* padding */ +}; + +/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */ +struct hpc3_ethregs { + /* Receiver registers. */ + hpcreg rx_cbptr; /* current dma buffer ptr, diagnostic use only */ + hpcreg rx_ndptr; /* next dma descriptor ptr */ + char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ + hpcreg rx_bcd; /* byte count info */ +#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */ +#define HPC3_ERXBCD_XIE 0x20000000 /* HPC3 interrupts cpu at end of this buf */ +#define HPC3_ERXBCD_EOX 0x80000000 /* flags this as end of descriptor chain */ + + hpcreg rx_ctrl; /* control register */ +#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */ +#define HPC3_ERXCTRL_STAT6 0x00000040 /* Rdonly irq status */ +#define HPC3_ERXCTRL_STAT7 0x00000080 /* Rdonlt old/new status bit from Seeq */ +#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */ +#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */ +#define HPC3_ERXCTRL_AMASK 0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */ +#define HPC3_ERXCTRL_RBO 0x00000800 /* Receive buffer overflow if set to 1 */ + + hpcreg rx_gfptr; /* current GIO fifo ptr */ + hpcreg rx_dfptr; /* current device fifo ptr */ + hpcreg _unused2; /* padding */ + hpcreg rx_reset; /* reset register */ +#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */ +#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */ +#define HPC3_ERXRST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */ + + hpcreg rx_dconfig; /* DMA configuration register */ +#define HPC3_ERXDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */ +#define HPC3_ERXDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */ +#define HPC3_ERXDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */ +#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */ +#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */ +#define HPC3_ERXDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */ +#define HPC3_ERXDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */ +#define HPC3_ERXDCFG_PTO 0x30000 /* Programmed timeout value for above two */ + + hpcreg rx_pconfig; /* PIO configuration register */ +#define HPC3_ERXPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */ +#define HPC3_ERXPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */ +#define HPC3_ERXPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */ +#define HPC3_ERXPCFG_TST 0x1000 /* Diagnistic ram test feature bit */ + + char _unused3[PAGE_SIZE - (8 * sizeof(hpcreg))]; /* padding */ + + /* Transmitter registers. */ + hpcreg tx_cbptr; /* current dma buffer ptr, diagnostic use only */ + hpcreg tx_ndptr; /* next dma descriptor ptr */ + char _unused4[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ + hpcreg tx_bcd; /* byte count info */ +#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */ +#define HPC3_ETXBCD_ESAMP 0x10000000 /* if set, too late to add descriptor */ +#define HPC3_ETXBCD_XIE 0x20000000 /* Interrupt cpu at end of cur desc */ +#define HPC3_ETXBCD_EOP 0x40000000 /* Last byte of cur buf is end of packet */ +#define HPC3_ETXBCD_EOX 0x80000000 /* This buf is the end of desc chain */ + + hpcreg tx_ctrl; /* control register */ +#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */ +#define HPC3_ETXCTRL_STAT4 0x00000010 /* Indicate late collision occurred */ +#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */ +#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* Dma channel endian mode, 1=little 0=big */ +#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */ +#define HPC3_ETXCTRL_AMASK 0x00000400 /* Indicates ACTIVE inhibits PIO's */ + + hpcreg tx_gfptr; /* current GIO fifo ptr */ + hpcreg tx_dfptr; /* current device fifo ptr */ + char _unused5[PAGE_SIZE - (4 * sizeof(hpcreg))]; /* padding */ +}; + +struct hpc3_regs { + /* First regs for the PBUS 8 dma channels. */ + struct hpc3_pbus_dmacregs pbdma[8]; + + /* Now the HPC scsi registers, we get two scsi reg sets. */ + struct hpc3_scsiregs scsi_chan0, scsi_chan1; + + /* The SEEQ hpc3 ethernet dma/control registers. */ + struct hpc3_ethregs ethregs; + + /* Here are where the hpc3 fifo's can be directly accessed + * via PIO accesses. Under normal operation we never stick + * our grubby paws in here so it's just padding. + */ + char _unused1[PAGE_SIZE * 24]; + + /* HPC3 irq status regs. Due to a peculiar bug you need to + * look at two different register addresses to get at all of + * the status bits. The first reg can only reliably report + * bits 4:0 of the status, and the second reg can only + * reliably report bits 9:5 of the hpc3 irq status. I told + * you it was a peculiar bug. ;-) + */ + hpcreg istat0; /* Irq status, only bits <4:0> reliable. */ +#define HPC3_ISTAT_PBIMASK 0x0ff /* irq bits for pbus devs 0 --> 7 */ +#define HPC3_ISTAT_SC0MASK 0x100 /* irq bit for scsi channel 0 */ +#define HPC3_ISTAT_SC1MASK 0x200 /* irq bit for scsi channel 1 */ + + hpcreg gio64_misc; /* GIO64 misc control bits. */ +#define HPC3_GIOMISC_ERTIME 0x1 /* Enable external timer real time. */ +#define HPC3_GIOMISC_DENDIAN 0x2 /* dma descriptor endian, 1=lit 0=big */ + + hpcreg eeprom_data; /* EEPROM data reg. */ +#define HPC3_EEPROM_EPROT 0x01 /* Protect register enable */ +#define HPC3_EEPROM_CSEL 0x02 /* Chip select */ +#define HPC3_EEPROM_ECLK 0x04 /* EEPROM clock */ +#define HPC3_EEPROM_DATO 0x08 /* Data out */ +#define HPC3_EEPROM_DATI 0x10 /* Data in */ + + hpcreg istat1; /* Irq status, only bits <9:5> reliable. */ + hpcreg gio64_estat; /* GIO64 error interrupt status reg. */ +#define HPC3_GIOESTAT_BLMASK 0x000ff /* Bus lane where bad parity occurred */ +#define HPC3_GIOESTAT_CTYPE 0x00100 /* Bus cycle type, 0=PIO 1=DMA */ +#define HPC3_GIOESTAT_PIDMSK 0x3f700 /* DMA channel parity identifier */ + + /* Now direct PIO per-HPC3 peripheral access to external regs. */ + char _unused2[0x13fec]; /* Trust me... */ + hpcreg scsi0_ext[256]; /* SCSI channel 0 external regs */ + char _unused3[0x07c00]; /* Trust me... */ + hpcreg scsi1_ext[256]; /* SCSI channel 1 external regs */ + char _unused4[0x07c00]; /* It'll only hurt a little... */ + + /* Did DaveM forget the ethernet external regs? + * Anyhow, they're not here and we need some padding instead. + */ + char _unused5[0x04000]; /* It'll hurt a lot if you leave this out */ + + /* Per-peripheral device external registers and dma/pio control. */ + hpcreg pbus_extregs[16][256]; /* 2nd indice indexes controller */ + hpcreg pbus_dmacfgs[8][128]; /* 2nd indice indexes controller */ +#define HPC3_PIODCFG_D3R 0x00000001 /* Cycles to spend in D3 for reads */ +#define HPC3_PIODCFG_D4R 0x0000001e /* Cycles to spend in D4 for reads */ +#define HPC3_PIODCFG_D5R 0x000001e0 /* Cycles to spend in D5 for reads */ +#define HPC3_PIODCFG_D3W 0x00000200 /* Cycles to spend in D3 for writes */ +#define HPC3_PIODCFG_D4W 0x00003c00 /* Cycles to spend in D4 for writes */ +#define HPC3_PIODCFG_D5W 0x0003c000 /* Cycles to spend in D5 for writes */ +#define HPC3_PIODCFG_HWORD 0x00040000 /* Enable 16-bit dma access mode */ +#define HPC3_PIODCFG_EHI 0x00080000 /* Places halfwords on high 16 bits of bus */ +#define HPC3_PIODCFG_RTIME 0x00200000 /* Make this device real time on GIO bus */ +#define HPC3_PIODCFG_BURST 0x07c00000 /* 5 bit burst count for DMA device */ +#define HPC3_PIODCFG_DRQLV 0x08000000 /* Use live pbus_dreq unsynchronized signal */ + + hpcreg pbus_piocfgs[64][10]; /* 2nd indice indexes controller */ +#define HPC3_PIOPCFG_RP2 0x00001 /* Cycles to spend in P2 state for reads */ +#define HPC3_PIOPCFG_RP3 0x0001e /* Cycles to spend in P3 state for reads */ +#define HPC3_PIOPCFG_RP4 0x001e0 /* Cycles to spend in P4 state for reads */ +#define HPC3_PIOPCFG_WP2 0x00200 /* Cycles to spend in P2 state for writes */ +#define HPC3_PIOPCFG_WP3 0x03c00 /* Cycles to spend in P3 state for writes */ +#define HPC3_PIOPCFG_WP4 0x3c000 /* Cycles to spend in P4 state for writes */ +#define HPC3_PIOPCFG_HW 0x40000 /* Enable 16-bit PIO accesses */ +#define HPC3_PIOPCFG_EHI 0x80000 /* Place even address bits in bits <15:8> */ + + /* PBUS PROM control regs. */ + hpcreg pbus_promwe; /* PROM write enable register */ +#define HPC3_PROM_WENAB 0x1 /* Enable writes to the PROM */ + + char _unused6[0x800 - sizeof(hpcreg)]; + hpcreg pbus_promswap; /* Chip select swap reg */ +#define HPC3_PROM_SWAP 0x1 /* invert GIO addr bit to select prom0 or prom1 */ + + char _unused7[0x800 - sizeof(hpcreg)]; + hpcreg pbus_gout; /* PROM general purpose output reg */ +#define HPC3_PROM_STAT 0x1 /* General purpose status bit in gout */ + + char _unused8[0x1000 - sizeof(hpcreg)]; + hpcreg pbus_promram[16384]; /* 64k of PROM battery backed ram */ +}; + +/* It is possible to have two HPC3's within the address space on + * one machine, though only having one is more likely on an INDY. + * Controller 0 lives at physical address 0x1fb80000 and the controller + * 1 if present lives at address 0x1fb00000. + */ +extern struct hpc3_regs *hpc3c0, *hpc3c1; +#define HPC3_CHIP0_PBASE 0x1fb80000 /* physical */ +#define HPC3_CHIP1_PBASE 0x1fb00000 /* physical */ + +/* Control and misc status information, these live in pbus channel 6. */ +struct hpc3_miscregs { + hpcreg pdata, pctrl, pstat, pdmactrl, pistat, pimask; + hpcreg ptimer1, ptimer2, ptimer3, ptimer4; + hpcreg _unused1[2]; + hpcreg ser1cmd, ser1data; + hpcreg ser0cmd, ser0data; + hpcreg kbdmouse0, kbdmouse1; + hpcreg gcsel, genctrl, panel; + hpcreg _unused2; + hpcreg sysid; + hpcreg _unused3; + hpcreg read, _unused4; + hpcreg dselect; +#define HPC3_DSELECT_SCLK10MHZ 0x00 /* use 10MHZ serial clock */ +#define HPC3_DSELECT_ISDNB 0x01 /* enable isdn B */ +#define HPC3_DSELECT_ISDNA 0x02 /* enable isdn A */ +#define HPC3_DSELECT_LPR 0x04 /* use parallel DMA */ +#define HPC3_DSELECT_SCLK667MHZ 0x10 /* use 6.67MHZ serial clock */ +#define HPC3_DSELECT_SCLKEXT 0x20 /* use external serial clock */ + + hpcreg _unused5; + hpcreg write1; +#define HPC3_WRITE1_PRESET 0x01 /* 0=LPR_RESET, 1=NORMAL */ +#define HPC3_WRITE1_KMRESET 0x02 /* 0=KBDMOUSE_RESET, 1=NORMAL */ +#define HPC3_WRITE1_ERESET 0x04 /* 0=EISA_RESET, 1=NORMAL */ +#define HPC3_WRITE1_GRESET 0x08 /* 0=MAGIC_GIO_RESET, 1=NORMAL */ +#define HPC3_WRITE1_LC0OFF 0x10 /* turn led off (guiness=red, else green) */ +#define HPC3_WRITE1_LC1OFF 0x20 /* turn led off (guiness=green, else amber) */ + + hpcreg _unused6; + hpcreg write2; +#define HPC3_WRITE2_NTHRESH 0x01 /* use 4.5db threshhold */ +#define HPC3_WRITE2_TPSPEED 0x02 /* use 100ohm TP speed */ +#define HPC3_WRITE2_EPSEL 0x04 /* force cable mode: 1=AUI 0=TP */ +#define HPC3_WRITE2_EASEL 0x08 /* 1=autoselect 0=manual cable selection */ +#define HPC3_WRITE2_U1AMODE 0x10 /* 1=PC 0=MAC UART mode */ +#define HPC3_WRITE2_U0AMODE 0x20 /* 1=PC 0=MAC UART mode */ +#define HPC3_WRITE2_MLO 0x40 /* 1=4.75V 0=+5V */ +#define HPC3_WRITE2_MHI 0x80 /* 1=5.25V 0=+5V */ +}; +extern struct hpc3_miscregs *hpc3mregs; +#define HPC3_MREGS_PBASE 0x1fbd9800 /* physical */ + +/* We need software copies of these because they are write only. */ +extern unsigned long sgi_hpc_write1, sgi_hpc_write2; + +#define SGI_KEYBOARD_IRQ 20 + +struct hpc_keyb { +#ifdef __MIPSEB__ + unsigned char _unused0[3]; + volatile unsigned char data; + unsigned char _unused1[3]; + volatile unsigned char command; +#else + volatile unsigned char data; + unsigned char _unused0[3]; + volatile unsigned char command; + unsigned char _unused1[3]; +#endif +}; + +/* Indy RTC */ + +/* The layout of registers for the INDY Dallas 1286 clock chipset. */ +struct indy_clock { + volatile unsigned int hsec; + volatile unsigned int sec; + volatile unsigned int min; + volatile unsigned int malarm; + volatile unsigned int hr; + volatile unsigned int halarm; + volatile unsigned int day; + volatile unsigned int dalarm; + volatile unsigned int date; + volatile unsigned int month; + volatile unsigned int year; + volatile unsigned int cmd; + volatile unsigned int whsec; + volatile unsigned int wsec; + volatile unsigned int _unused0[50]; +}; + +#define INDY_CLOCK_REGS (KSEG1ADDR(0x1fbe0000)) + +extern void sgihpc_init(void); + +#endif /* _ASM_SGI_SGIHPC_H */ diff --git a/include/asm-mips64/sgi/sgimc.h b/include/asm-mips64/sgi/sgimc.h new file mode 100644 index 000000000..9e236a564 --- /dev/null +++ b/include/asm-mips64/sgi/sgimc.h @@ -0,0 +1,227 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * sgimc.h: Definitions for memory controller hardware found on + * SGI IP20, IP22, IP26, and IP28 machines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ +#ifndef _ASM_SGI_SGIMC_H +#define _ASM_SGI_SGIMC_H + +struct sgimc_misc_ctrl { + unsigned long _unused1; + volatile unsigned long cpuctrl0; /* CPU control register 0, readwrite */ +#define SGIMC_CCTRL0_REFS 0x0000000f /* REFS mask */ +#define SGIMC_CCTRL0_EREFRESH 0x00000010 /* Memory refresh enable */ +#define SGIMC_CCTRL0_EPERRGIO 0x00000020 /* GIO parity error enable */ +#define SGIMC_CCTRL0_EPERRMEM 0x00000040 /* Main mem parity error enable */ +#define SGIMC_CCTRL0_EPERRCPU 0x00000080 /* CPU bus parity error enable */ +#define SGIMC_CCTRL0_WDOG 0x00000100 /* Watchdog timer enable */ +#define SGIMC_CCTRL0_SYSINIT 0x00000200 /* System init bit */ +#define SGIMC_CCTRL0_GFXRESET 0x00000400 /* Graphics interface reset */ +#define SGIMC_CCTRL0_EISALOCK 0x00000800 /* Lock CPU from memory for EISA */ +#define SGIMC_CCTRL0_EPERRSCMD 0x00001000 /* SysCMD bus parity error enable */ +#define SGIMC_CCTRL0_IENAB 0x00002000 /* Allow interrupts from MC */ +#define SGIMC_CCTRL0_ESNOOP 0x00004000 /* Snooping I/O enable */ +#define SGIMC_CCTRL0_EPROMWR 0x00008000 /* Prom writes from cpu enable */ +#define SGIMC_CCTRL0_WRESETPMEM 0x00010000 /* Perform warm reset, preserves mem */ +#define SGIMC_CCTRL0_LENDIAN 0x00020000 /* Put MC in little-endian mode */ +#define SGIMC_CCTRL0_WRESETDMEM 0x00040000 /* Warm reset, destroys mem contents */ +#define SGIMC_CCTRL0_CMEMBADPAR 0x02000000 /* Generate bad perr from cpu to mem */ +#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */ +#define SGIMC_CCTRL0_GIOBTOB 0x08000000 /* Allow GIO back to back writes */ + + unsigned long _unused2; + volatile unsigned long cpuctrl1; /* CPU control register 1, readwrite */ +#define SGIMC_CCTRL1_EGIOTIMEO 0x00000010 /* GIO bus timeout enable */ +#define SGIMC_CCTRL1_FIXEDEHPC 0x00001000 /* Fixed HPC endianness */ +#define SGIMC_CCTRL1_LITTLEHPC 0x00002000 /* Little endian HPC */ +#define SGIMC_CCTRL1_FIXEDEEXP0 0x00004000 /* Fixed EXP0 endianness */ +#define SGIMC_CCTRL1_LITTLEEXP0 0x00008000 /* Little endian EXP0 */ +#define SGIMC_CCTRL1_FIXEDEEXP1 0x00010000 /* Fixed EXP1 endianness */ +#define SGIMC_CCTRL1_LITTLEEXP1 0x00020000 /* Little endian EXP1 */ + + unsigned long _unused3; + volatile unsigned long watchdogt; /* Watchdog reg rdonly, write clears */ + + unsigned long _unused4; + volatile unsigned long systemid; /* MC system ID register, readonly */ +#define SGIMC_SYSID_MASKREV 0x0000000f /* Revision of MC controller */ +#define SGIMC_SYSID_EPRESENT 0x00000010 /* Indicates presence of EISA bus */ + + unsigned long _unused5[3]; + volatile unsigned long divider; /* Divider reg for RPSS */ + + unsigned long _unused6; + volatile unsigned char eeprom; /* EEPROM byte reg for r4k */ +#define SGIMC_EEPROM_PRE 0x00000001 /* eeprom chip PRE pin assertion */ +#define SGIMC_EEPROM_CSEL 0x00000002 /* Active high, eeprom chip select */ +#define SGIMC_EEPROM_SECLOCK 0x00000004 /* EEPROM serial clock */ +#define SGIMC_EEPROM_SDATAO 0x00000008 /* Serial EEPROM data-out */ +#define SGIMC_EEPROM_SDATAI 0x00000010 /* Serial EEPROM data-in */ + + unsigned char _unused7[3]; + unsigned long _unused8[3]; + volatile unsigned short rcntpre; /* Preload refresh counter */ + + unsigned short _unused9; + unsigned long _unused9a; + volatile unsigned short rcounter; /* Readonly refresh counter */ + + unsigned short _unused10; + unsigned long _unused11[13]; + volatile unsigned long gioparm; /* Parameter word for GIO64 */ +#define SGIMC_GIOPARM_HPC64 0x00000001 /* HPC talks to GIO using 64-bits */ +#define SGIMC_GIOPARM_GFX64 0x00000002 /* GFX talks to GIO using 64-bits */ +#define SGIMC_GIOPARM_EXP064 0x00000004 /* EXP(slot0) talks using 64-bits */ +#define SGIMC_GIOPARM_EXP164 0x00000008 /* EXP(slot1) talks using 64-bits */ +#define SGIMC_GIOPARM_EISA64 0x00000010 /* EISA bus talks 64-bits to GIO */ +#define SGIMC_GIOPARM_HPC264 0x00000020 /* 2nd HPX talks 64-bits to GIO */ +#define SGIMC_GIOPARM_RTIMEGFX 0x00000040 /* GFX device has realtime attr */ +#define SGIMC_GIOPARM_RTIMEEXP0 0x00000080 /* EXP(slot0) has realtime attr */ +#define SGIMC_GIOPARM_RTIMEEXP1 0x00000100 /* EXP(slot1) has realtime attr */ +#define SGIMC_GIOPARM_MASTEREISA 0x00000200 /* EISA bus can act as bus master */ +#define SGIMC_GIOPARM_ONEBUS 0x00000400 /* Exists one GIO64 pipelined bus */ +#define SGIMC_GIOPARM_MASTERGFX 0x00000800 /* GFX can act as a bus master */ +#define SGIMC_GIOPARM_MASTEREXP0 0x00001000 /* EXP(slot0) can bus master */ +#define SGIMC_GIOPARM_MASTEREXP1 0x00002000 /* EXP(slot1) can bus master */ +#define SGIMC_GIOPARM_PLINEEXP0 0x00004000 /* EXP(slot0) has pipeline attr */ +#define SGIMC_GIOPARM_PLINEEXP1 0x00008000 /* EXP(slot1) has pipeline attr */ + + unsigned long _unused13; + volatile unsigned short cputp; /* CPU bus arb time period */ + + unsigned short _unused14; + unsigned long _unused15[3]; + volatile unsigned short lbursttp; /* Time period for long bursts */ + + unsigned short _unused16; + unsigned long _unused17[9]; + volatile unsigned long mconfig0; /* Memory config register zero */ + unsigned long _unused18; + volatile unsigned long mconfig1; /* Memory config register one */ + + /* These defines apply to both mconfig registers above. */ +#define SGIMC_MCONFIG_FOURMB 0x00000000 /* Physical ram = 4megs */ +#define SGIMC_MCONFIG_EIGHTMB 0x00000100 /* Physical ram = 8megs */ +#define SGIMC_MCONFIG_SXTEENMB 0x00000300 /* Physical ram = 16megs */ +#define SGIMC_MCONFIG_TTWOMB 0x00000700 /* Physical ram = 32megs */ +#define SGIMC_MCONFIG_SFOURMB 0x00000f00 /* Physical ram = 64megs */ +#define SGIMC_MCONFIG_OTEIGHTMB 0x00001f00 /* Physical ram = 128megs */ +#define SGIMC_MCONFIG_RMASK 0x00001f00 /* Ram config bitmask */ + + unsigned long _unused19; + volatile unsigned long cmacc; /* Mem access config for CPU */ + unsigned long _unused20; + volatile unsigned long gmacc; /* Mem access config for GIO */ + + /* This define applies to both cmacc and gmacc registers above. */ +#define SGIMC_MACC_ALIASBIG 0x20000000 /* 512MB home for alias */ + + /* Error address/status regs from GIO and CPU perspectives. */ + unsigned long _unused21; + volatile unsigned long cerr; /* Error address reg for CPU */ + unsigned long _unused22; + volatile unsigned long cstat; /* Status reg for CPU */ + unsigned long _unused23; + volatile unsigned long gerr; /* Error address reg for GIO */ + unsigned long _unused24; + volatile unsigned long gstat; /* Status reg for GIO */ + + /* Special hard bus locking registers. */ + unsigned long _unused25; + volatile unsigned char syssembit; /* Uni-bit system semaphore */ + unsigned char _unused26[3]; + unsigned long _unused27; + volatile unsigned char mlock; /* Global GIO memory access lock */ + unsigned char _unused28[3]; + unsigned long _unused29; + volatile unsigned char elock; /* Locks EISA from GIO accesses */ + + /* GIO dma control registers. */ + unsigned char _unused30[3]; + unsigned long _unused31[14]; + volatile unsigned long gio_dma_trans;/* DMA mask to translation GIO addrs */ + unsigned long _unused32; + volatile unsigned long gio_dma_sbits;/* DMA GIO addr substitution bits */ + unsigned long _unused33; + volatile unsigned long dma_intr_cause; /* DMA IRQ cause indicator bits */ + unsigned long _unused34; + volatile unsigned long dma_ctrl; /* Main DMA control reg */ + + /* DMA TLB entry 0 */ + unsigned long _unused35; + volatile unsigned long dtlb_hi0; + unsigned long _unused36; + volatile unsigned long dtlb_lo0; + + /* DMA TLB entry 1 */ + unsigned long _unused37; + volatile unsigned long dtlb_hi1; + unsigned long _unused38; + volatile unsigned long dtlb_lo1; + + /* DMA TLB entry 2 */ + unsigned long _unused39; + volatile unsigned long dtlb_hi2; + unsigned long _unused40; + volatile unsigned long dtlb_lo2; + + /* DMA TLB entry 3 */ + unsigned long _unused41; + volatile unsigned long dtlb_hi3; + unsigned long _unused42; + volatile unsigned long dtlb_lo3; +}; + +/* MC misc control registers live at physical 0x1fa00000. */ +extern struct sgimc_misc_ctrl *mcmisc_regs; +extern unsigned long *rpsscounter; /* Chirps at 100ns */ + +struct sgimc_dma_ctrl { + unsigned long _unused1; + volatile unsigned long maddronly; /* Address DMA goes at */ + unsigned long _unused2; + volatile unsigned long maddrpdeflts; /* Same as above, plus set defaults */ + unsigned long _unused3; + volatile unsigned long dmasz; /* DMA count */ + unsigned long _unused4; + volatile unsigned long ssize; /* DMA stride size */ + unsigned long _unused5; + volatile unsigned long gmaddronly; /* Set GIO DMA but do not start trans */ + unsigned long _unused6; + volatile unsigned long dmaddnpgo; /* Set GIO DMA addr + start transfer */ + unsigned long _unused7; + volatile unsigned long dmamode; /* DMA mode config bit settings */ + unsigned long _unused8; + volatile unsigned long dmacount; /* Zoom and byte count for DMA */ + unsigned long _unused9; + volatile unsigned long dmastart; /* Pedal to the metal. */ + unsigned long _unused10; + volatile unsigned long dmarunning; /* DMA op is in progress */ + unsigned long _unused11; + + /* Set dma addr, defaults, and kick it */ + volatile unsigned long maddr_defl_go; /* go go go! -lm */ +}; + +/* MC controller dma regs live at physical 0x1fa02000. */ +extern struct sgimc_dma_ctrl *dmactrlregs; + +/* Base location of the two ram banks found in IP2[0268] machines. */ +#define SGIMC_SEG0_BADDR 0x08000000 +#define SGIMC_SEG1_BADDR 0x20000000 + +/* Maximum size of the above banks are per machine. */ +extern unsigned long sgimc_seg0_size, sgimc_seg1_size; +#define SGIMC_SEG0_SIZE_ALL 0x10000000 /* 256MB */ +#define SGIMC_SEG1_SIZE_IP20_IP22 0x08000000 /* 128MB */ +#define SGIMC_SEG1_SIZE_IP26_IP28 0x20000000 /* 512MB */ + +extern void sgimc_init(void); + +#endif /* _ASM_SGI_SGIMC_H */ diff --git a/include/asm-mips64/sgi/sgint23.h b/include/asm-mips64/sgi/sgint23.h new file mode 100644 index 000000000..1633345ef --- /dev/null +++ b/include/asm-mips64/sgi/sgint23.h @@ -0,0 +1,192 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * sgint23.h: Defines for the SGI INT2 and INT3 chipsets. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - INT2 corrections + */ +#ifndef _ASM_SGI_SGINT23_H +#define _ASM_SGI_SGINT23_H + +/* These are the virtual IRQ numbers, we divide all IRQ's into + * 'spaces', the 'space' determines where and how to enable/disable + * that particular IRQ on an SGI machine. Add new 'spaces' as new + * IRQ hardware is supported. + */ +#define SGINT_LOCAL0 0 /* INDY has 8 local0 irq levels */ +#define SGINT_LOCAL1 8 /* INDY has 8 local1 irq levels */ +#define SGINT_LOCAL2 16 /* INDY has 8 local2 vectored irq levels */ +#define SGINT_LOCAL3 24 /* INDY has 8 local3 vectored irq levels */ +#define SGINT_GIO 32 /* INDY has 9 GIO irq levels */ +#define SGINT_HPCDMA 41 /* INDY has 11 HPCDMA irq _sources_ */ +#define SGINT_END 52 /* End of 'spaces' */ + +/* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */ +#define SGI_INT2_BASE 0x1fbd9000 /* physical */ +#define SGI_INT3_BASE 0x1fbd9880 /* physical */ + +struct sgi_ioc_ints { +#ifdef __MIPSEB__ + unsigned char _unused0[3]; + volatile unsigned char istat0; /* Interrupt status zero */ +#else + volatile unsigned char istat0; /* Interrupt status zero */ + unsigned char _unused0[3]; +#endif +#define ISTAT0_FFULL 0x01 +#define ISTAT0_SCSI0 0x02 +#define ISTAT0_SCSI1 0x04 +#define ISTAT0_ENET 0x08 +#define ISTAT0_GFXDMA 0x10 +#define ISTAT0_LPR 0x20 +#define ISTAT0_HPC2 0x40 +#define ISTAT0_LIO2 0x80 + +#ifdef __MIPSEB__ + unsigned char _unused1[3]; + volatile unsigned char imask0; /* Interrupt mask zero */ + unsigned char _unused2[3]; + volatile unsigned char istat1; /* Interrupt status one */ +#else + volatile unsigned char imask0; /* Interrupt mask zero */ + unsigned char _unused1[3]; + volatile unsigned char istat1; /* Interrupt status one */ + unsigned char _unused2[3]; +#endif +#define ISTAT1_ISDNI 0x01 +#define ISTAT1_PWR 0x02 +#define ISTAT1_ISDNH 0x04 +#define ISTAT1_LIO3 0x08 +#define ISTAT1_HPC3 0x10 +#define ISTAT1_AFAIL 0x20 +#define ISTAT1_VIDEO 0x40 +#define ISTAT1_GIO2 0x80 + +#ifdef __MIPSEB__ + unsigned char _unused3[3]; + volatile unsigned char imask1; /* Interrupt mask one */ + unsigned char _unused4[3]; + volatile unsigned char vmeistat; /* VME interrupt status */ + unsigned char _unused5[3]; + volatile unsigned char cmeimask0; /* VME interrupt mask zero */ + unsigned char _unused6[3]; + volatile unsigned char cmeimask1; /* VME interrupt mask one */ + unsigned char _unused7[3]; + volatile unsigned char cmepol; /* VME polarity */ +#else + volatile unsigned char imask1; /* Interrupt mask one */ + unsigned char _unused3[3]; + volatile unsigned char vmeistat; /* VME interrupt status */ + unsigned char _unused4[3]; + volatile unsigned char cmeimask0; /* VME interrupt mask zero */ + unsigned char _unused5[3]; + volatile unsigned char cmeimask1; /* VME interrupt mask one */ + unsigned char _unused6[3]; + volatile unsigned char cmepol; /* VME polarity */ + unsigned char _unused7[3]; +#endif +}; + +struct sgi_ioc_timers { +#ifdef __MIPSEB__ + unsigned char _unused0[3]; + volatile unsigned char tcnt0; /* counter 0 */ + unsigned char _unused1[3]; + volatile unsigned char tcnt1; /* counter 1 */ + unsigned char _unused2[3]; + volatile unsigned char tcnt2; /* counter 2 */ + unsigned char _unused3[3]; + volatile unsigned char tcword; /* control word */ +#else + volatile unsigned char tcnt0; /* counter 0 */ + unsigned char _unused0[3]; + volatile unsigned char tcnt1; /* counter 1 */ + unsigned char _unused1[3]; + volatile unsigned char tcnt2; /* counter 2 */ + unsigned char _unused2[3]; + volatile unsigned char tcword; /* control word */ + unsigned char _unused3[3]; +#endif +}; + +/* Timer control word bits. */ +#define SGINT_TCWORD_BCD 0x01 /* Use BCD mode for counters */ +#define SGINT_TCWORD_MMASK 0x0e /* Mode bitmask. */ +#define SGINT_TCWORD_MITC 0x00 /* IRQ on terminal count (doesn't work) */ +#define SGINT_TCWORD_MOS 0x02 /* One-shot IRQ mode. */ +#define SGINT_TCWORD_MRGEN 0x04 /* Normal rate generation */ +#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */ +#define SGINT_TCWORD_MSWST 0x08 /* Software strobe */ +#define SGINT_TCWORD_MHWST 0x0a /* Hardware strobe */ +#define SGINT_TCWORD_CMASK 0x30 /* Command mask */ +#define SGINT_TCWORD_CLAT 0x00 /* Latch command */ +#define SGINT_TCWORD_CLSB 0x10 /* LSB read/write */ +#define SGINT_TCWORD_CMSB 0x20 /* MSB read/write */ +#define SGINT_TCWORD_CALL 0x30 /* Full counter read/write */ +#define SGINT_TCWORD_CNT0 0x00 /* Select counter zero */ +#define SGINT_TCWORD_CNT1 0x40 /* Select counter one */ +#define SGINT_TCWORD_CNT2 0x80 /* Select counter two */ +#define SGINT_TCWORD_CRBCK 0xc0 /* Readback command */ + +#define SGINT_TCSAMP_COUNTER 10255 + +/* FIXME: What does this really look like? It was written to have + * 17 registers, but there are only 16 in my Indigo2. + * I guessed at which one to remove... - andrewb + */ +struct sgi_int2_regs { + struct sgi_ioc_ints ints; + + volatile unsigned long ledbits; /* LED control bits */ +#define INT2_LED_TXCLK 0x01 /* GPI to TXCLK enable */ +#define INT2_LED_SERSLCT0 0x02 /* serial port0: 0=apple 1=pc */ +#define INT2_LED_SERSLCT1 0x04 /* serial port1: 0=apple 1=pc */ +#define INT2_LED_CHEAPER 0x08 /* 0=cheapernet 1=ethernet */ +#define INT2_LED_POWEROFF 0x10 /* Power-off request, active high */ + +#ifdef __MIPSEB__ + unsigned char _unused0[3]; + volatile unsigned char tclear; /* Timer clear strobe address */ +#else + volatile unsigned char tclear; /* Timer clear strobe address */ + unsigned char _unused0[3]; +#endif +#define INT2_TCLEAR_T0CLR 0x1 /* Clear timer0 IRQ */ +#define INT2_TCLEAR_T1CLR 0x2 /* Clear timer1 IRQ */ +/* I am guesing there are only two unused registers here + * but I could be wrong... - andrewb + */ +/* unsigned long _unused[3]; */ + unsigned long _unused[2]; + struct sgi_ioc_timers timers; +}; + +struct sgi_int3_regs { + struct sgi_ioc_ints ints; + +#ifdef __MIPSEB__ + unsigned char _unused0[3]; + volatile unsigned char tclear; /* Timer clear strobe address */ +#else + volatile unsigned char tclear; /* Timer clear strobe address */ + unsigned char _unused0[3]; +#endif + volatile unsigned long estatus; /* Error status reg */ + unsigned long _unused1[2]; + struct sgi_ioc_timers timers; +}; + +extern struct sgi_int2_regs *sgi_i2regs; +extern struct sgi_int3_regs *sgi_i3regs; +extern struct sgi_ioc_ints *ioc_icontrol; +extern struct sgi_ioc_timers *ioc_timers; +extern volatile unsigned char *ioc_tclear; + +extern void sgint_init(void); +extern void indy_timer_init(void); + +#endif /* _ASM_SGI_SGINT23_H */ diff --git a/include/asm-mips64/sgialib.h b/include/asm-mips64/sgialib.h index 6f7b29019..0aa83307a 100644 --- a/include/asm-mips64/sgialib.h +++ b/include/asm-mips64/sgialib.h @@ -1,9 +1,13 @@ /* $Id$ - * sgialib.h: SGI ARCS firmware interface library for the Linux kernel. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * SGI ARCS firmware interface library for the Linux kernel. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ - #ifndef _ASM_SGIALIB_H #define _ASM_SGIALIB_H diff --git a/include/asm-mips64/sgiarcs.h b/include/asm-mips64/sgiarcs.h index 23c88859f..eb736d2bb 100644 --- a/include/asm-mips64/sgiarcs.h +++ b/include/asm-mips64/sgiarcs.h @@ -1,8 +1,14 @@ -/* $Id$ +/* $Id: sgiarcs.h,v 1.1 1999/08/18 23:37:52 ralf Exp $ * - * SGI ARCS firmware interface defines. + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * ARC firmware interface defines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_SGIARCS_H #define _ASM_SGIARCS_H @@ -365,4 +371,111 @@ struct linux_smonblock { int smax; /* Max # of symbols. */ }; +#define __arc_clobbers \ + "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ + "$12","$13","$14","$15","$16","$24","25","$31" + +#define ARC_CALL0(dest) \ +({ long __res; \ + unsigned long __vec = (unsigned long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec) \ + : __arc_clobbers); \ + (unsigned long) __res; \ +}) + +#define ARC_CALL1(dest,a1) \ +({ long __res; \ + register signed int __a1 __asm__("$4") = (int) (long) (a1); \ + unsigned long __vec = (unsigned long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec), "r" (__a1) \ + : __arc_clobbers); \ + (unsigned long) __res; \ +}) + +#define ARC_CALL2(dest,a1,a2) \ +({ long __res; \ + register signed int __a1 __asm__("$4") = (int) (long) (a1); \ + register signed int __a2 __asm__("$5") = (int) (long) (a2); \ + unsigned long __vec = (unsigned long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec), "r" (__a1), "r" (__a2) \ + : __arc_clobbers); \ + __res; \ +}) + +#define ARC_CALL3(dest,a1,a2,a3) \ +({ long __res; \ + register signed int __a1 __asm__("$4") = (int) (long) (a1); \ + register signed int __a2 __asm__("$5") = (int) (long) (a2); \ + register signed int __a3 __asm__("$6") = (int) (long) (a3); \ + unsigned long __vec = (unsigned long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3) \ + : __arc_clobbers); \ + __res; \ +}) + +#define ARC_CALL4(dest,a1,a2,a3,a4) \ +({ long __res; \ + register signed int __a1 __asm__("$4") = (int) (long) (a1); \ + register signed int __a2 __asm__("$5") = (int) (long) (a2); \ + register signed int __a3 __asm__("$6") = (int) (long) (a3); \ + register signed int __a4 __asm__("$7") = (int) (long) (a4); \ + unsigned long __vec = (unsigned long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3), \ + "r" (__a4) \ + : __arc_clobbers); \ + __res; \ +}) + +#define ARC_CALL5(dest,a1,a2,a3,a4,a5) \ +({ long __res; \ + register signed int __a1 __asm__("$4") = (int) (long) (a1); \ + register signed int __a2 __asm__("$5") = (int) (long) (a2); \ + register signed int __a3 __asm__("$6") = (int) (long) (a3); \ + register signed int __a4 __asm__("$7") = (int) (long) (a4); \ + register signed int __a5 = (a5); \ + unsigned long __vec = (unsigned long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "sw\t%6, 16($29)\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec), \ + "r" (__a1), "r" (__a2), "r" (__a3), "r" (__a4), \ + "r" (__a5) \ + : __arc_clobbers); \ + __res; \ +}) + #endif /* _ASM_SGIARCS_H */ diff --git a/include/asm-mips64/sgidefs.h b/include/asm-mips64/sgidefs.h index c92927845..195ab5e47 100644 --- a/include/asm-mips64/sgidefs.h +++ b/include/asm-mips64/sgidefs.h @@ -1,11 +1,11 @@ -/* $Id$ +/* $Id: sgidefs.h,v 1.1 1999/08/18 23:37:52 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1996, 1999 by Ralf Baechle - * Copyright (C) 1996, 1999 Silicon Graphics, Inc. + * Copyright (C) 1999 Silicon Graphics, Inc. * * Definitions commonly used in SGI style code. */ @@ -23,11 +23,6 @@ /* * Subprogram calling convention - * - * At the moment only _MIPS_SIM_ABI32 is in use. This will change rsn. - * Until GCC 2.8.0 is released don't rely on this definitions because the - * 64bit code is essentially using the 32bit interface model just with - * 64bit registers. */ #define _MIPS_SIM_ABI32 1 #define _MIPS_SIM_NABI32 2 diff --git a/include/asm-mips64/stackframe.h b/include/asm-mips64/stackframe.h new file mode 100644 index 000000000..35605e3f4 --- /dev/null +++ b/include/asm-mips64/stackframe.h @@ -0,0 +1,201 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle, Paul M. Antoine. + */ +#ifndef _ASM_STACKFRAME_H +#define _ASM_STACKFRAME_H + +#include <asm/asm.h> +#include <asm/offset.h> + +#define SAVE_AT \ + sw $1, PT_R1(sp) + +#define SAVE_TEMP \ + mfhi v1; \ + sw $8, PT_R8(sp); \ + sw $9, PT_R9(sp); \ + sw v1, PT_HI(sp); \ + mflo v1; \ + sw $10,PT_R10(sp); \ + sw $11, PT_R11(sp); \ + sw v1, PT_LO(sp); \ + sw $12, PT_R12(sp); \ + sw $13, PT_R13(sp); \ + sw $14, PT_R14(sp); \ + sw $15, PT_R15(sp); \ + sw $24, PT_R24(sp) + +#define SAVE_STATIC \ + sw $16, PT_R16(sp); \ + sw $17, PT_R17(sp); \ + sw $18, PT_R18(sp); \ + sw $19, PT_R19(sp); \ + sw $20, PT_R20(sp); \ + sw $21, PT_R21(sp); \ + sw $22, PT_R22(sp); \ + sw $23, PT_R23(sp); \ + sw $30, PT_R30(sp) + +#define __str2(x) #x +#define __str(x) __str2(x) + +#define save_static(frame) \ + __asm__ __volatile__( \ + "sw\t$16,"__str(PT_R16)"(%0)\n\t" \ + "sw\t$17,"__str(PT_R17)"(%0)\n\t" \ + "sw\t$18,"__str(PT_R18)"(%0)\n\t" \ + "sw\t$19,"__str(PT_R19)"(%0)\n\t" \ + "sw\t$20,"__str(PT_R20)"(%0)\n\t" \ + "sw\t$21,"__str(PT_R21)"(%0)\n\t" \ + "sw\t$22,"__str(PT_R22)"(%0)\n\t" \ + "sw\t$23,"__str(PT_R23)"(%0)\n\t" \ + "sw\t$30,"__str(PT_R30)"(%0)\n\t" \ + : /* No outputs */ \ + : "r" (frame)) + +#define SAVE_SOME \ + .set push; \ + .set reorder; \ + mfc0 k0, CP0_STATUS; \ + sll k0, 3; /* extract cu0 bit */ \ + .set noreorder; \ + bltz k0, 8f; \ + move k1, sp; \ + .set reorder; \ + /* Called from user mode, new stack. */ \ + lui k1, %hi(kernelsp); \ + lw k1, %lo(kernelsp)(k1); \ +8: \ + move k0, sp; \ + subu sp, k1, PT_SIZE; \ + sw k0, PT_R29(sp); \ + sw $3, PT_R3(sp); \ + sw $0, PT_R0(sp); \ + mfc0 v1, CP0_STATUS; \ + sw $2, PT_R2(sp); \ + sw v1, PT_STATUS(sp); \ + sw $4, PT_R4(sp); \ + mfc0 v1, CP0_CAUSE; \ + sw $5, PT_R5(sp); \ + sw v1, PT_CAUSE(sp); \ + sw $6, PT_R6(sp); \ + mfc0 v1, CP0_EPC; \ + sw $7, PT_R7(sp); \ + sw v1, PT_EPC(sp); \ + sw $25, PT_R25(sp); \ + sw $28, PT_R28(sp); \ + sw $31, PT_R31(sp); \ + ori $28, sp, 0x1fff; \ + xori $28, 0x1fff; \ + .set pop + +#define SAVE_ALL \ + SAVE_SOME; \ + SAVE_AT; \ + SAVE_TEMP; \ + SAVE_STATIC + +#define RESTORE_AT \ + lw $1, PT_R1(sp); \ + +#define RESTORE_SP \ + lw sp, PT_R29(sp) + +#define RESTORE_TEMP \ + lw $24, PT_LO(sp); \ + lw $8, PT_R8(sp); \ + lw $9, PT_R9(sp); \ + mtlo $24; \ + lw $24, PT_HI(sp); \ + lw $10,PT_R10(sp); \ + lw $11, PT_R11(sp); \ + mthi $24; \ + lw $12, PT_R12(sp); \ + lw $13, PT_R13(sp); \ + lw $14, PT_R14(sp); \ + lw $15, PT_R15(sp); \ + lw $24, PT_R24(sp) + +#define RESTORE_STATIC \ + lw $16, PT_R16(sp); \ + lw $17, PT_R17(sp); \ + lw $18, PT_R18(sp); \ + lw $19, PT_R19(sp); \ + lw $20, PT_R20(sp); \ + lw $21, PT_R21(sp); \ + lw $22, PT_R22(sp); \ + lw $23, PT_R23(sp); \ + lw $30, PT_R30(sp) + +#define RESTORE_SOME \ + .set push; \ + .set reorder; \ + mfc0 t0, CP0_STATUS; \ + .set pop; \ + ori t0, 0x1f; \ + xori t0, 0x1f; \ + mtc0 t0, CP0_STATUS; \ + li v1, 0xff00; \ + and t0, v1; \ + lw v0, PT_STATUS(sp); \ + nor v1, $0, v1; \ + and v0, v1; \ + or v0, t0; \ + mtc0 v0, CP0_STATUS; \ + lw v1, PT_EPC(sp); \ + mtc0 v1, CP0_EPC; \ + lw $31, PT_R31(sp); \ + lw $28, PT_R28(sp); \ + lw $25, PT_R25(sp); \ + lw $7, PT_R7(sp); \ + lw $6, PT_R6(sp); \ + lw $5, PT_R5(sp); \ + lw $4, PT_R4(sp); \ + lw $3, PT_R3(sp); \ + lw $2, PT_R2(sp) + +#define RESTORE_ALL \ + RESTORE_SOME; \ + RESTORE_AT; \ + RESTORE_TEMP; \ + RESTORE_STATIC; \ + RESTORE_SP + +/* + * Move to kernel mode and disable interrupts. + * Set cp0 enable bit as sign that we're running on the kernel stack + */ +#define CLI \ + mfc0 t0,CP0_STATUS; \ + li t1,ST0_CU0|0x1f; \ + or t0,t1; \ + xori t0,0x1f; \ + mtc0 t0,CP0_STATUS + +/* + * Move to kernel mode and enable interrupts. + * Set cp0 enable bit as sign that we're running on the kernel stack + */ +#define STI \ + mfc0 t0,CP0_STATUS; \ + li t1,ST0_CU0|0x1f; \ + or t0,t1; \ + xori t0,0x1e; \ + mtc0 t0,CP0_STATUS + +/* + * Just move to kernel mode and leave interrupts as they are. + * Set cp0 enable bit as sign that we're running on the kernel stack + */ +#define KMODE \ + mfc0 t0,CP0_STATUS; \ + li t1,ST0_CU0|0x1e; \ + or t0,t1; \ + xori t0,0x1e; \ + mtc0 t0,CP0_STATUS + +#endif /* _ASM_STACKFRAME_H */ diff --git a/include/asm-mips64/user.h b/include/asm-mips64/user.h new file mode 100644 index 000000000..88322ae2d --- /dev/null +++ b/include/asm-mips64/user.h @@ -0,0 +1,60 @@ +/* $Id$ + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle + */ +#ifndef _ASM_USER_H +#define _ASM_USER_H + +#include <linux/ptrace.h> + +#include <asm/page.h> +#include <asm/reg.h> + +/* + * Core file format: The core file is written in such a way that gdb + * can understand it and provide useful information to the user (under + * linux we use the `trad-core' bfd, NOT the irix-core). The file + * contents are as follows: + * + * upage: 1 page consisting of a user struct that tells gdb + * what is present in the file. Directly after this is a + * copy of the task_struct, which is currently not used by gdb, + * but it may come in handy at some point. All of the registers + * are stored as part of the upage. The upage should always be + * only one page long. + * data: The data segment follows next. We use current->end_text to + * current->brk to pick up all of the user variables, plus any memory + * that may have been sbrk'ed. No attempt is made to determine if a + * page is demand-zero or if a page is totally unused, we just cover + * the entire range. All of the addresses are rounded in such a way + * that an integral number of pages is written. + * stack: We need the stack information in order to get a meaningful + * backtrace. We need to write the data from usp to + * current->start_stack, so we round each of these in order to be able + * to write an integer number of pages. + */ +struct user { + unsigned long regs[EF_SIZE/4+64]; /* integer and fp regs */ + size_t u_tsize; /* text size (pages) */ + size_t u_dsize; /* data size (pages) */ + size_t u_ssize; /* stack size (pages) */ + unsigned long start_code; /* text starting address */ + unsigned long start_data; /* data starting address */ + unsigned long start_stack; /* stack starting address */ + long int signal; /* signal causing core dump */ + struct regs * u_ar0; /* help gdb find registers */ + unsigned long magic; /* identifies a core file */ + char u_comm[32]; /* user command name */ +}; + +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_DATA_START_ADDR (u.start_data) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#endif /* _ASM_USER_H */ diff --git a/init/main.c b/init/main.c index 4bc8c7727..8dd6fc91a 100644 --- a/init/main.c +++ b/init/main.c @@ -27,7 +27,7 @@ #include <asm/io.h> #include <asm/bugs.h> -#ifdef CONFIG_SGI +#ifdef CONFIG_SGI_IP22 #include <asm/sgialib.h> #endif diff --git a/net/core/dst.c b/net/core/dst.c index f1695ca84..92dd0941a 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -5,7 +5,6 @@ * */ -#include <asm/segment.h> #include <asm/system.h> #include <asm/bitops.h> #include <linux/types.h> diff --git a/net/netsyms.c b/net/netsyms.c index ff92b23f1..9fee8a822 100644 --- a/net/netsyms.c +++ b/net/netsyms.c @@ -490,8 +490,10 @@ EXPORT_SYMBOL(init_hippi_dev); EXPORT_SYMBOL(unregister_hipdev); #endif +#ifdef CONFIG_INET EXPORT_SYMBOL(sysctl_wmem_max); EXPORT_SYMBOL(sysctl_rmem_max); +#endif #if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) #include<linux/if_ltalk.h> |