summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.cvsignore2
-rw-r--r--Documentation/Configure.help24
-rw-r--r--arch/mips/arc/memory.c4
-rw-r--r--arch/mips/sgi/kernel/indy_timer.c17
-rw-r--r--arch/mips64/Makefile34
-rw-r--r--arch/mips64/arc/Makefile23
-rw-r--r--arch/mips64/arc/identify.c16
-rw-r--r--arch/mips64/arc/memory.c32
-rw-r--r--arch/mips64/arc/misc.c10
-rw-r--r--arch/mips64/config.in29
-rw-r--r--arch/mips64/defconfig52
-rw-r--r--arch/mips64/defconfig-ip22283
-rw-r--r--arch/mips64/defconfig-ip27285
-rw-r--r--arch/mips64/kernel/Makefile15
-rw-r--r--arch/mips64/kernel/binfmt_elf32.c1
-rw-r--r--arch/mips64/kernel/entry.S14
-rw-r--r--arch/mips64/kernel/head.S13
-rw-r--r--arch/mips64/kernel/mips64_ksyms.c5
-rw-r--r--arch/mips64/kernel/r4k_tlb_debug.c35
-rw-r--r--arch/mips64/kernel/r4k_tlb_glue.S1
-rw-r--r--arch/mips64/kernel/scall_64.S8
-rw-r--r--arch/mips64/kernel/scall_o32.S30
-rw-r--r--arch/mips64/kernel/setup.c16
-rw-r--r--arch/mips64/kernel/signal.c7
-rw-r--r--arch/mips64/kernel/unaligned.c10
-rw-r--r--arch/mips64/ld.script.elf64119
-rw-r--r--arch/mips64/lib/memcpy.S2
-rw-r--r--arch/mips64/lib/strlen_user.S2
-rw-r--r--arch/mips64/lib/strncpy_user.S2
-rw-r--r--arch/mips64/mm/Makefile23
-rw-r--r--arch/mips64/mm/andes.c405
-rw-r--r--arch/mips64/mm/loadmmu.c16
-rw-r--r--arch/mips64/mm/r4xx0.c14
-rw-r--r--arch/mips64/mm/tfp.c8
-rw-r--r--arch/mips64/sgi-ip22/Makefile12
-rw-r--r--arch/mips64/sgi-ip22/ip22-timer.c15
-rw-r--r--arch/mips64/sgi-ip27/.cvsignore2
-rw-r--r--arch/mips64/sgi-ip27/Makefile15
-rw-r--r--arch/mips64/sgi-ip27/ip27-irq-glue.S65
-rw-r--r--arch/mips64/sgi-ip27/ip27-irq.c321
-rw-r--r--arch/mips64/sgi-ip27/ip27-klconfig.c33
-rw-r--r--arch/mips64/sgi-ip27/ip27-memory.c65
-rw-r--r--arch/mips64/sgi-ip27/ip27-reset.c45
-rw-r--r--arch/mips64/sgi-ip27/ip27-setup.c88
-rw-r--r--arch/mips64/sgi-ip27/ip27-timer.c115
-rw-r--r--drivers/net/ioc3-eth.c45
-rw-r--r--include/asm-mips64/addrspace.h61
-rw-r--r--include/asm-mips64/arc/hinv.h175
-rw-r--r--include/asm-mips64/arc/types.h6
-rw-r--r--include/asm-mips64/asm.h12
-rw-r--r--include/asm-mips64/bcache.h38
-rw-r--r--include/asm-mips64/bootinfo.h5
-rw-r--r--include/asm-mips64/cacheops.h48
-rw-r--r--include/asm-mips64/current.h4
-rw-r--r--include/asm-mips64/elf.h12
-rw-r--r--include/asm-mips64/io.h25
-rw-r--r--include/asm-mips64/mipsregs.h5
-rw-r--r--include/asm-mips64/page.h13
-rw-r--r--include/asm-mips64/pgtable.h6
-rw-r--r--include/asm-mips64/processor.h9
-rw-r--r--include/asm-mips64/r10kcache.h152
-rw-r--r--include/asm-mips64/r4kcache.h2
-rw-r--r--include/asm-mips64/r4kcacheops.h48
-rw-r--r--include/asm-mips64/serial.h6
-rw-r--r--include/asm-mips64/sgialib.h18
-rw-r--r--include/asm-mips64/sgiarcs.h72
-rw-r--r--include/linux/serial.h1
-rw-r--r--include/linux/serialP.h6
68 files changed, 2744 insertions, 358 deletions
diff --git a/.cvsignore b/.cvsignore
index c0faf905d..55f38e0b1 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -8,6 +8,6 @@
.version
System.map
vmlinux
+vmlinux.64
modules
nohup.out
-
diff --git a/Documentation/Configure.help b/Documentation/Configure.help
index abdf723a2..dc9782ea8 100644
--- a/Documentation/Configure.help
+++ b/Documentation/Configure.help
@@ -1384,10 +1384,23 @@ CONFIG_OLIVETTI_M700
a machine on the Internet that has a program like lynx or netscape).
Support for SGI IP22
+CONFIG_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.
+Support for SGI IP27
+ This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
+ workstations. To compile a Linux kernel that runs on these, say Y
+ here.
+
+IP27 N-Mode
+CONFIG_SGI_SN0_N_MODE
+ The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be
+ configured in either N-Modes which allows for more nodes or M-Mode
+ which allows for more more memory. Your system is most probly
+ running in M-Mode, so you should say N here.
+
MIPS JAZZ onboard SONIC Ethernet support
CONFIG_MIPS_JAZZ_SONIC
This is the driver for the onboard card of of MIPS Magnum 4000,
@@ -1398,11 +1411,6 @@ CONFIG_JAZZ_ESP
This is the driver for the onboard SCSI hostadapter of MIPS Magnum 4000,
Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
-Support for SGI IP27
- This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
- workstations. To compile a Linux kernel that runs on these, say Y
- here.
-
CPU type
CONFIG_CPU_R3000
Please make shure to pick the right CPU type. Linux/MIPS is not
@@ -10832,6 +10840,12 @@ CONFIG_CROSSCOMPILE
Say Y here if you are compiling the kernel on a different
architecture than the one it is intended to run on.
+Kernel support for Linux/MIPS 32-bit binary compatibility
+CONFIG_MIPS32_COMPAT
+ Select this option this option if you want Linux/MIPS 32-bit binary
+ compatibility. Since all software available available for Linux/MIPS
+ is currently 32-bit you should say Y here.
+
Build fp exception handler module
CONFIG_MIPS_FPE_MODULE
Build the floating point exception handler module. This option is
diff --git a/arch/mips/arc/memory.c b/arch/mips/arc/memory.c
index b2540bf0c..851a16e9d 100644
--- a/arch/mips/arc/memory.c
+++ b/arch/mips/arc/memory.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: memory.c,v 1.6 1999/10/09 00:00:57 ralf Exp $
+ * $Id: memory.c,v 1.7 1999/12/04 03:58:59 ralf Exp $
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -189,7 +189,7 @@ restart:
}
}
-void prom_free_prom_memory (void)
+void __init prom_free_prom_memory (void)
{
struct prom_pmemblock *p;
unsigned long addr;
diff --git a/arch/mips/sgi/kernel/indy_timer.c b/arch/mips/sgi/kernel/indy_timer.c
index 162d0e32d..0b388bf32 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.14 1999/10/09 00:00:59 ralf Exp $
+/* $Id: indy_timer.c,v 1.15 1999/10/21 00:23:05 ralf Exp $
*
* indy_timer.c: Setting up the clock on the INDY 8254 controller.
*
@@ -85,6 +85,7 @@ void indy_timer_interrupt(struct pt_regs *regs)
unsigned long count;
int irq = 7;
+ write_lock(&xtime_lock);
/* Ack timer and compute new compare. */
count = read_32bit_cp0_register(CP0_COUNT);
/* This has races. */
@@ -114,6 +115,7 @@ void indy_timer_interrupt(struct pt_regs *regs)
/* do it again in 60 s */
last_rtc_update = xtime.tv_sec - 600;
}
+ write_unlock(&xtime_lock);
}
static unsigned long dosample(volatile unsigned char *tcwp,
@@ -254,9 +256,10 @@ void __init indy_timer_init(void)
set_cp0_status(ST0_IM, ALLINTS);
sti();
- /* Read time from the dallas chipset. */
- xtime.tv_sec = get_indy_time();
+ write_lock_irq(&xtime_lock);
+ xtime.tv_sec = get_indy_time(); /* Read time from RTC. */
xtime.tv_usec = 0;
+ write_unlock_irq(&xtime_lock);
}
void indy_8254timer_irq(void)
@@ -276,17 +279,17 @@ void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
- save_and_cli(flags);
+ read_lock_irqsave(&xtime_lock, flags);
*tv = xtime;
- restore_flags(flags);
+ read_unlock_irqrestore(&xtime_lock, flags);
}
void do_settimeofday(struct timeval *tv)
{
- cli();
+ write_lock_irq(&xtime_lock);
xtime = *tv;
time_state = TIME_BAD;
time_maxerror = MAXPHASE;
time_esterror = MAXPHASE;
- sti();
+ write_unlock_irq(&xtime_lock);
}
diff --git a/arch/mips64/Makefile b/arch/mips64/Makefile
index 20685e5e3..6879aca98 100644
--- a/arch/mips64/Makefile
+++ b/arch/mips64/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.3 1999/10/19 20:51:44 ralf Exp $
+# $Id: Makefile,v 1.3 1999/12/04 03:59:00 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
@@ -77,6 +77,18 @@ SUBDIRS += arch/mips64/sgi-ip22 arch/mips64/arc
LOADADDR += 0x88004000
endif
+ifdef CONFIG_SGI_IP27
+LIBS += arch/mips64/sgi-ip27/ip27.a arch/mips64/arc/arclib.a
+SUBDIRS += arch/mips64/sgi-ip27 arch/mips64/arc
+#
+# Set LOADADDR to >= 0xc000000000300000 if you want to leave space for
+# symmon, 0xc00000000001c000 for production kernels. Note that the value
+# must be 16kb aligned or the handling of the current variable will break.
+#
+#LOADADDR += 0xa80000000001c000
+LOADADDR += 0x8001c000
+endif
+
#
# 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
@@ -86,6 +98,17 @@ ifdef CONFIG_BOOT_ELF32
CFLAGS += -Wa,-32
LINKFLAGS += -T arch/mips64/ld.script.elf32
endif
+#
+# The 64-bit ELF tools are pretty broken so at this time we generate 64-bit
+# ELF files from 32-bit files by conversion.
+#
+ifdef CONFIG_BOOT_ELF64
+CFLAGS += -Wa,-32
+LINKFLAGS += -T arch/mips64/ld.script.elf32
+#AS += -64
+#LD += -m elf64bmip
+#LINKFLAGS += -T arch/mips64/ld.script.elf64
+endif
LINKFLAGS += -Ttext $(LOADADDR)
@@ -97,6 +120,15 @@ LIBS := arch/mips64/lib/lib.a $(LIBS)
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+ifdef CONFIG_CPU_LITTLE_ENDIAN
+64bit-bfd = elf64-littlemips
+else
+64bit-bfd = elf64-bigmips
+endif
+
+vmlinux.64: vmlinux
+ $(OBJCOPY) -O $(64bit-bfd) --change-addresses=0xa7ffffff80000000 $< $@
+
zImage: vmlinux
@$(MAKEBOOT) zImage
diff --git a/arch/mips64/arc/Makefile b/arch/mips64/arc/Makefile
index 471ff92a1..039caf88d 100644
--- a/arch/mips64/arc/Makefile
+++ b/arch/mips64/arc/Makefile
@@ -1,23 +1,14 @@
# $Id: Makefile,v 1.1 1999/08/20 21:13:32 ralf Exp $
-# 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).
+# Makefile for the ARC prom monitor library routines under Linux.
#
-# 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
+L_TARGET = arclib.a
+L_OBJS = console.o init.o printf.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
+ifdef CONFIG_ARC_MEMORY
+L_OBJS += memory.o
+endif
include $(TOPDIR)/Rules.make
diff --git a/arch/mips64/arc/identify.c b/arch/mips64/arc/identify.c
index 2103dd427..ab2d553ad 100644
--- a/arch/mips64/arc/identify.c
+++ b/arch/mips64/arc/identify.c
@@ -13,6 +13,7 @@
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*/
#include <linux/init.h>
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -29,6 +30,7 @@ struct smatch {
static struct smatch mach_table[] = {
{ "SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, PROM_FLAG_ARCS },
+ { "SGI-IP27", MACH_GROUP_SGI, MACH_SGI_IP27, 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 }
@@ -58,12 +60,22 @@ prom_identify_arch(void)
{
pcomponent *p;
struct smatch *mach;
+ const char *iname;
/* The root component tells us what machine architecture we
have here. */
p = ArcGetChild(PROM_NULL_COMPONENT);
- printk("ARCH: %s\n", (char *) (long) p->iname);
- mach = string_to_mach((char *) (long) p->iname);
+ if (p == NULL) {
+#ifdef CONFIG_SGI_IP27
+ /* IP27 PROM bisbehaves, seems to not implement ARC
+ GetChild(). So we just assume it's an IP27. */
+ iname = "SGI-IP27";
+#endif
+ } else
+ iname = (char *) (long) p->iname;
+
+ printk("ARCH: %s\n", iname);
+ mach = string_to_mach(iname);
mips_machgroup = mach->group;
mips_machtype = mach->type;
diff --git a/arch/mips64/arc/memory.c b/arch/mips64/arc/memory.c
index 85129ee99..a63d8d631 100644
--- a/arch/mips64/arc/memory.c
+++ b/arch/mips64/arc/memory.c
@@ -4,12 +4,14 @@
* 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 by David S. Miller
+ * Copyright (C) 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
*
- * Copyright (C) 1996 by David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1999 by Ralf Baechle
- * Copyright (C) 1999 by Silicon Graphics, Inc.
+ * PROM library functions for acquiring/using memory descriptors given to us
+ * from the ARCS firmware. This is only used when CONFIG_ARC_MEMORY is set
+ * because on some machines like SGI IP27 the ARC memory configuration data
+ * completly bogus and alternate easier to use mechanisms are available.
*/
#include <linux/config.h>
#include <linux/init.h>
@@ -133,11 +135,12 @@ void __init
prom_meminit(void)
{
struct linux_mdesc *p;
- int totram;
- int i = 0;
+ unsigned long totram;
+ int i;
- p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
#ifdef DEBUG
+ i = 0;
+ p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
prom_printf("ARCS MEMORY DESCRIPTOR dump:\n");
while(p) {
prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
@@ -151,21 +154,22 @@ prom_meminit(void)
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].base = PAGE_OFFSET + (p->base << PAGE_SHIFT);
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",
+ prom_printf("free_chunk[%d]: base=%08lx size=%x"
+ " total=%x\n",
i, prom_pblocks[i].base,
- prom_pblocks[i].size);
+ prom_pblocks[i].size, totram);
#endif
i++;
break;
case MEMTYPE_PROM:
#ifdef DEBUG
- prom_printf("prom_chunk[%d]: base=%08lx size=%d\n",
+ prom_printf("prom_chunk[%d]: base=%08lx size=%x\n",
i, prom_pblocks[i].base,
prom_pblocks[i].size);
#endif
@@ -178,7 +182,7 @@ prom_meminit(void)
}
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",
+ printk("PROMLIB: Total free ram %ld bytes (%ldK,%ldMB)\n",
totram, (totram/1024), (totram/1024/1024));
/* Setup upper physical memory bound. */
@@ -217,7 +221,7 @@ restart:
}
}
-void
+void __init
prom_free_prom_memory (void)
{
struct prom_pmemblock *p;
diff --git a/arch/mips64/arc/misc.c b/arch/mips64/arc/misc.c
index 220c3cc71..703305c20 100644
--- a/arch/mips64/arc/misc.c
+++ b/arch/mips64/arc/misc.c
@@ -28,7 +28,7 @@ extern void reset_wd33c93(void *instance);
VOID
ArcHalt(VOID)
{
- bcops->bc_disable();
+ bc_disable();
cli();
#if CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
@@ -40,7 +40,7 @@ never: goto never;
VOID
ArcPowerDown(VOID)
{
- bcops->bc_disable();
+ bc_disable();
cli();
#if CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
@@ -53,7 +53,7 @@ never: goto never;
VOID
ArcRestart(VOID)
{
- bcops->bc_disable();
+ bc_disable();
cli();
#if CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
@@ -65,7 +65,7 @@ never: goto never;
VOID
ArcReboot(VOID)
{
- bcops->bc_disable();
+ bc_disable();
cli();
#if CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
@@ -77,7 +77,7 @@ never: goto never;
VOID
ArcEnterInteractiveMode(VOID)
{
- bcops->bc_disable();
+ bc_disable();
cli();
#if CONFIG_SCSI_SGIWD93
reset_wd33c93(sgiwd93_host);
diff --git a/arch/mips64/config.in b/arch/mips64/config.in
index 7ee2b2a42..85f28ad6e 100644
--- a/arch/mips64/config.in
+++ b/arch/mips64/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.8 1999/11/23 17:12:49 ralf Exp $
+# $Id: config.in,v 1.5 1999/12/04 03:59:00 ralf Exp $
#
# For a description of the syntax of this configuration file,
# see the Configure script.
@@ -13,18 +13,35 @@ endmenu
mainmenu_option next_comment
comment 'Machine selection'
bool 'Support for SGI IP22' CONFIG_SGI_IP22
+bool 'Support for SGI IP27' CONFIG_SGI_IP27
+if [ "$CONFIG_SGI_IP27" = "y" ]; then
+ bool ' IP27 N-Mode' CONFIG_SGI_SN0_N_MODE
+ #bool ' IP27 XXL' CONFIG_SGI_SN0_XXL
+fi
endmenu
#
# Select some configuration options automatically based on user selections
#
unset CONFIG_BOOT_ELF32
+unset CONFIG_BOOT_ELF64
unset CONFIG_ARC32
unset CONFIG_ARC64
+unset CONFIG_BOARD_SCACHE
+unset CONFIG_COHERENT_IO
+unset CONFIG_BINFMT_ELF32
if [ "$CONFIG_SGI_IP22" = "y" ]; then
define_bool CONFIG_BOOT_ELF32 y
define_bool CONFIG_ARC32 y
+ define_bool CONFIG_BOARD_SCACHE y
+ define_bool CONFIG_ARC_MEMORY y
+fi
+
+if [ "$CONFIG_SGI_IP27" = "y" ]; then
+ define_bool CONFIG_BOOT_ELF64 y
+ define_bool CONFIG_ARC64 y
+ define_bool CONFIG_COHERENT_IO y
fi
mainmenu_option next_comment
@@ -47,14 +64,16 @@ if [ "$CONFIG_CPU_R10000" = "y" ]; then
fi
bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
-define_bool CONFIG_BINFMT_AOUT n
-define_bool CONFIG_BINFMT_ELF y
-tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
-
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
bool 'Sysctl support' CONFIG_SYSCTL
+tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF
+bool 'Kernel support for Linux/MIPS 32-bit binary compatibility' CONFIG_MIPS32_COMPAT
+if [ "$CONFIG_MIPS32_COMPAT" = "y" ]; then
+ define_bool CONFIG_BINFMT_ELF32 y
+fi
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
mainmenu_option next_comment
comment 'Loadable module support'
diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig
index 71fac0fc9..22060ed89 100644
--- a/arch/mips64/defconfig
+++ b/arch/mips64/defconfig
@@ -10,31 +10,36 @@
#
# Machine selection
#
-CONFIG_SGI_IP22=y
-CONFIG_BOOT_ELF32=y
-CONFIG_ARC32=y
+# CONFIG_SGI_IP22 is not set
+CONFIG_SGI_IP27=y
+# CONFIG_SGI_SN0_N_MODE is not set
+CONFIG_BOOT_ELF64=y
+CONFIG_ARC64=y
+CONFIG_COHERENT_IO=y
#
# CPU selection
#
# CONFIG_CPU_R4300 is not set
# CONFIG_CPU_R4X00 is not set
-CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
+CONFIG_CPU_R10000=y
#
# General setup
#
+# CONFIG_MIPS_INSANE_LARGE is not set
# CONFIG_CPU_LITTLE_ENDIAN is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_SYSCTL is not set
+# CONFIG_BINFMT_ELF is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=y
+# CONFIG_BINFMT_MISC is not set
#
# Loadable module support
@@ -116,7 +121,16 @@ CONFIG_NETDEVICES=y
#
# Ethernet (10 or 100Mbit)
#
-# CONFIG_NET_ETHERNET is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_SGI_IOC3_ETH=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET is not set
# CONFIG_FDDI is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
@@ -144,7 +158,6 @@ CONFIG_NETDEVICES=y
# CONFIG_PCMCIA_PCNET is not set
# CONFIG_PCMCIA_3C589 is not set
# CONFIG_PCMCIA_RAYCS is not set
-CONFIG_SGISEEQ=y
#
# Amateur Radio support
@@ -169,9 +182,9 @@ CONFIG_SGISEEQ=y
#
# Character devices
#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-# CONFIG_SERIAL is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_UNIX98_PTYS is not set
@@ -260,24 +273,13 @@ CONFIG_SGI_PARTITION=y
# CONFIG_NLS is not set
#
-# Console drivers
-#
-CONFIG_SGI_NEWPORT_CONSOLE=y
-
-#
# Sound
#
# CONFIG_SOUND is not set
#
-# SGI devices
-#
-# CONFIG_SGI_SERIAL is not set
-CONFIG_SGI_DS1286=y
-
-#
# Kernel hacking
#
CONFIG_CROSSCOMPILE=y
# CONFIG_REMOTE_DEBUG is not set
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22
new file mode 100644
index 000000000..71fac0fc9
--- /dev/null
+++ b/arch/mips64/defconfig-ip22
@@ -0,0 +1,283 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Machine selection
+#
+CONFIG_SGI_IP22=y
+CONFIG_BOOT_ELF32=y
+CONFIG_ARC32=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=m
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_SKB_LARGE=y
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network devices
+#
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_RAYCS is not set
+CONFIG_SGISEEQ=y
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# USB drivers - not for the faint of heart
+#
+# CONFIG_USB is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+CONFIG_SGI_NEWPORT_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# SGI devices
+#
+# CONFIG_SGI_SERIAL is not set
+CONFIG_SGI_DS1286=y
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27
new file mode 100644
index 000000000..22060ed89
--- /dev/null
+++ b/arch/mips64/defconfig-ip27
@@ -0,0 +1,285 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
+# Machine selection
+#
+# CONFIG_SGI_IP22 is not set
+CONFIG_SGI_IP27=y
+# CONFIG_SGI_SN0_N_MODE is not set
+CONFIG_BOOT_ELF64=y
+CONFIG_ARC64=y
+CONFIG_COHERENT_IO=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+CONFIG_CPU_R10000=y
+
+#
+# General setup
+#
+# CONFIG_MIPS_INSANE_LARGE is not set
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_BINFMT_ELF is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_BINFMT_ELF32=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=m
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_SKB_LARGE=y
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_SGI_IOC3_ETH=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network devices
+#
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# USB drivers - not for the faint of heart
+#
+# CONFIG_USB is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_REMOTE_DEBUG is not set
+CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/mips64/kernel/Makefile b/arch/mips64/kernel/Makefile
index 9856524c3..0f70cba13 100644
--- a/arch/mips64/kernel/Makefile
+++ b/arch/mips64/kernel/Makefile
@@ -12,12 +12,19 @@
all: kernel.o head.o init_task.o
O_TARGET := kernel.o
-O_OBJS := binfmt_elf32.o branch.o entry.o proc.o process.o ptrace.o \
- r4k_cache.o r4k_fpu.o r4k_genex.o r4k_switch.o r4k_tlb_debug.o \
- r4k_tlb_glue.o scall_64.o scall_o32.o semaphore.o setup.o signal.o \
- softfp.o syscall.o traps.o unaligned.o
+O_OBJS := branch.o entry.o proc.o process.o ptrace.o r4k_cache.o r4k_fpu.o \
+ r4k_genex.o r4k_switch.o r4k_tlb_debug.o r4k_tlb_glue.o scall_64.o \
+ semaphore.o setup.o signal.o softfp.o syscall.o traps.o unaligned.o
OX_OBJS := mips64_ksyms.o
+ifdef CONFIG_MIPS32_COMPAT
+O_OBJS += linux32.o scall_o32.o signal32.o
+endif
+
+ifdef CONFIG_BINFMT_ELF32
+O_OBJS += binfmt_elf32.o
+endif
+
clean:
include $(TOPDIR)/Rules.make
diff --git a/arch/mips64/kernel/binfmt_elf32.c b/arch/mips64/kernel/binfmt_elf32.c
index 3494f4cf0..a199839a6 100644
--- a/arch/mips64/kernel/binfmt_elf32.c
+++ b/arch/mips64/kernel/binfmt_elf32.c
@@ -90,7 +90,6 @@ struct elf_prpsinfo32
#ifdef CONFIG_BINFMT_ELF32_MODULE
#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE
#endif
-#define ELF_FLAGS_INIT current->thread.flags |= SPARC_FLAG_32BIT
MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux/MIPS binaries");
MODULE_AUTHOR("Ralf Baechle (ralf@oss.sgi.com)");
diff --git a/arch/mips64/kernel/entry.S b/arch/mips64/kernel/entry.S
index 05bbee928..1206a68c3 100644
--- a/arch/mips64/kernel/entry.S
+++ b/arch/mips64/kernel/entry.S
@@ -21,13 +21,12 @@
.text
.set noreorder
.align 4
-EXPORT(ret_from_fork)
+FEXPORT(ret_from_fork)
jal schedule_tail
move a0, v0 # prev
j ret_from_sys_call
nop
-EXPORT(handle_bottom_half)
- .type handle_bottom_half,@function
+FEXPORT(handle_bottom_half)
jal do_bottom_half
nop
b 9f
@@ -36,10 +35,8 @@ EXPORT(handle_bottom_half)
reschedule: jal schedule
nop
-EXPORT(ret_from_sys_call)
- .type ret_from_sys_call,@function
-EXPORT(ret_from_irq)
- .type ret_from_irq,@function
+FEXPORT(ret_from_sys_call)
+FEXPORT(ret_from_irq)
ld t0, bh_mask
ld t1, bh_active # unused delay slot
and t0, t1
@@ -57,8 +54,7 @@ EXPORT(ret_from_irq)
jal do_signal
move a1, sp
-EXPORT(return) .set noat
- .type return,@function
+FEXPORT(return) .set noat
RESTORE_ALL
eret
.set at
diff --git a/arch/mips64/kernel/head.S b/arch/mips64/kernel/head.S
index daa0e3ad1..98718e93c 100644
--- a/arch/mips64/kernel/head.S
+++ b/arch/mips64/kernel/head.S
@@ -12,6 +12,7 @@
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
#define __ASSEMBLY__
+#include <linux/config.h>
#include <linux/init.h>
#include <asm/asm.h>
#include <asm/regdef.h>
@@ -28,6 +29,14 @@ EXPORT(_stext)
NESTED(kernel_entry, 16, sp) # kernel entry point
+#ifdef CONFIG_ARC64
+ /* We get launched at a XKPHYS address but the kernel is linked to
+ run at a KSEG0 address, so jump there. */
+ la t0, 1f
+ jr t0
+1:
+#endif
+
ori sp, 0xf # align stack on 16 byte.
xori sp, 0xf
@@ -38,9 +47,9 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
CLI # disable interrupts
mfc0 t0, CP0_STATUS
- li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX)
+ li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3)
and t0, t1
- or t0, ST0_CU0
+ or t0, (ST0_CU0|ST0_KX|ST0_SX)
mtc0 t0, CP0_STATUS
la $28, init_task_union # init current pointer
diff --git a/arch/mips64/kernel/mips64_ksyms.c b/arch/mips64/kernel/mips64_ksyms.c
index d6fa01d8a..cc077a486 100644
--- a/arch/mips64/kernel/mips64_ksyms.c
+++ b/arch/mips64/kernel/mips64_ksyms.c
@@ -89,6 +89,11 @@ 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);
+
+/*
* Kernel hacking ...
*/
#include <asm/branch.h>
diff --git a/arch/mips64/kernel/r4k_tlb_debug.c b/arch/mips64/kernel/r4k_tlb_debug.c
index f14725189..a9d41cb46 100644
--- a/arch/mips64/kernel/r4k_tlb_debug.c
+++ b/arch/mips64/kernel/r4k_tlb_debug.c
@@ -6,6 +6,9 @@
*
* Copyright (C) 1999 Ralf Baechle
* Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * TLB debugging routines. These perform horribly slow but can easily be
+ * modified for debugging purposes.
*/
#include <linux/linkage.h>
#include <linux/kernel.h>
@@ -43,8 +46,10 @@ asmlinkage void xtlb_refill_debug(struct pt_regs *regs)
asmlinkage void xtlb_mod_debug(struct pt_regs *regs)
{
- show_regs(regs);
- panic(__FUNCTION__ " called.");
+ unsigned long addr;
+
+ addr = regs->cp0_badvaddr;
+ do_page_fault(regs, 1, addr);
}
asmlinkage void xtlb_tlbl_debug(struct pt_regs *regs)
@@ -52,20 +57,7 @@ asmlinkage void xtlb_tlbl_debug(struct pt_regs *regs)
unsigned long addr;
addr = regs->cp0_badvaddr;
-#if 0
- printk(__FUNCTION__ " called.\n");
- show_regs(regs);
- printk("TLB Dump:\n");
- dump_tlb_all();
- printk("c0_badvaddr = %08lx\n", addr);
-#endif
do_page_fault(regs, 0, addr);
-
-#if 0
- printk("TLB Dump:\n");
- dump_tlb_all();
- printk("\n");
-#endif
}
asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs)
@@ -73,18 +65,5 @@ asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs)
unsigned long addr;
addr = regs->cp0_badvaddr;
-#if 0
- printk(__FUNCTION__ " called.\n");
- show_regs(regs);
- printk("TLB Dump:\n");
- dump_tlb_all();
- printk("c0_badvaddr = %08lx\n", addr);
-#endif
do_page_fault(regs, 1, addr);
-
-#if 0
- printk("TLB Dump:\n");
- dump_tlb_all();
- printk("\n");
-#endif
}
diff --git a/arch/mips64/kernel/r4k_tlb_glue.S b/arch/mips64/kernel/r4k_tlb_glue.S
index 767ecb76f..81d457fda 100644
--- a/arch/mips64/kernel/r4k_tlb_glue.S
+++ b/arch/mips64/kernel/r4k_tlb_glue.S
@@ -26,6 +26,7 @@ NESTED(__tlb_refill_debug_tramp, PT_SIZE, sp)
.macro tlb_handler name
NESTED(__\name, PT_SIZE, sp)
SAVE_ALL
+ CLI
dmfc0 t0, CP0_BADVADDR
sd t0, PT_BVADDR(sp)
move a0, sp
diff --git a/arch/mips64/kernel/scall_64.S b/arch/mips64/kernel/scall_64.S
index 27ce842e9..3d49cbe07 100644
--- a/arch/mips64/kernel/scall_64.S
+++ b/arch/mips64/kernel/scall_64.S
@@ -7,6 +7,7 @@
* Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
+#include <linux/config.h>
#include <asm/asm.h>
#include <linux/errno.h>
#include <asm/current.h>
@@ -24,6 +25,10 @@
/* Highest syscall handled here. */
#define MAX_SYSCALL_NO __NR_Linux + __NR_Linux_syscalls
+#ifndef CONFIG_MIPS32_COMPAT
+#define handle_sys64 handle_sys
+#endif
+
.align 5
NESTED(handle_sys64, PT_SIZE, sp)
@@ -55,8 +60,7 @@ NESTED(handle_sys64, PT_SIZE, sp)
sd v0, PT_R0(sp) # set flag for syscall restarting
1: sd v0, PT_R2(sp) # result
-EXPORT(ret_from_sys_call_64)
- .type ret_from_sys_call_64,@function
+FEXPORT(ret_from_sys_call_64)
ld t0, bh_mask
ld t1, bh_active # unused delay slot
and t0, t1
diff --git a/arch/mips64/kernel/scall_o32.S b/arch/mips64/kernel/scall_o32.S
index 2899405f0..56b087a7b 100644
--- a/arch/mips64/kernel/scall_o32.S
+++ b/arch/mips64/kernel/scall_o32.S
@@ -258,13 +258,13 @@ illegal_syscall:
sys sys_getppid 0
sys sys_getpgrp 0 /* 4065 */
sys sys_setsid 0
- sys sys_sigaction 3
+ sys sys32_sigaction 3
sys sys_sgetmask 0
sys sys_ssetmask 1
sys sys_setreuid 2 /* 4070 */
sys sys_setregid 2
- sys sys_sigsuspend 0
- sys sys_sigpending 1
+ sys sys32_sigsuspend 0
+ sys sys32_sigpending 1
sys sys_sethostname 2
sys sys_setrlimit 2 /* 4075 */
sys sys_getrlimit 2
@@ -297,9 +297,9 @@ illegal_syscall:
sys sys_syslog 3
sys sys_setitimer 3
sys sys_getitimer 2 /* 4105 */
- sys sys_newstat 2
- sys sys_newlstat 2
- sys sys_newfstat 2
+ sys sys32_newstat 2
+ sys sys32_newlstat 2
+ sys sys32_newfstat 2
sys sys_uname 1
sys sys_ni_syscall 0 /* sys_ioperm *//* 4110 */
sys sys_vhangup 0
@@ -310,7 +310,7 @@ illegal_syscall:
sys sys_sysinfo 1
sys sys_ipc 6
sys sys_fsync 1
- sys sys_sigreturn 0
+ sys sys32_sigreturn 0
sys sys_clone 0 /* 4120 */
sys sys_setdomainname 2
sys sys_newuname 1
@@ -384,20 +384,20 @@ illegal_syscall:
sys sys_setresgid 3 /* 4190 */
sys sys_getresgid 3
sys sys_prctl 5
- sys sys_rt_sigreturn 0
- sys sys_rt_sigaction 4
- sys sys_rt_sigprocmask 4 /* 4195 */
- sys sys_rt_sigpending 2
- sys sys_rt_sigtimedwait 4
- sys sys_rt_sigqueueinfo 3
- sys sys_rt_sigsuspend 0
+ sys sys32_rt_sigreturn 0
+ sys sys32_rt_sigaction 4
+ sys sys32_rt_sigprocmask 4 /* 4195 */
+ sys sys32_rt_sigpending 2
+ sys sys32_rt_sigtimedwait 4
+ sys sys32_rt_sigqueueinfo 3
+ sys sys32_rt_sigsuspend 0
sys sys_pread 4 /* 4200 */
sys sys_pwrite 4
sys sys_chown 3
sys sys_getcwd 2
sys sys_capget 2
sys sys_capset 2 /* 4205 */
- sys sys_sigaltstack 0
+ sys sys32_sigaltstack 0
sys sys_sendfile 3
sys sys_ni_syscall 0
sys sys_ni_syscall 0
diff --git a/arch/mips64/kernel/setup.c b/arch/mips64/kernel/setup.c
index 347266fd2..37b4f33e9 100644
--- a/arch/mips64/kernel/setup.c
+++ b/arch/mips64/kernel/setup.c
@@ -95,7 +95,14 @@ static char command_line[CL_SIZE] = { 0, };
char saved_command_line[CL_SIZE];
extern char arcs_cmdline[CL_SIZE];
+/*
+ * mips_io_port_base is the begin of the address space to which x86 style
+ * I/O ports are mapped.
+ */
+unsigned long mips_io_port_base;
+
extern void ip22_setup(void);
+extern void ip27_setup(void);
static inline void cpu_probe(void)
{
@@ -146,6 +153,9 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p,
#ifdef CONFIG_SGI_IP22
ip22_setup();
#endif
+#ifdef CONFIG_SGI_IP27
+ ip27_setup();
+#endif
memory_end = mips_memory_upper;
@@ -164,6 +174,12 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p,
*cmdline_p = command_line;
*memory_start_p = (unsigned long) &_end;
+#ifdef CONFIG_BOOT_ELF64
+ /* memory_end is a XKPHYS address but memory_start is in CKSEG.
+ All memory handling is done using XKPHYS addresses, so convert. */
+ *memory_start_p = (*memory_start_p & 0x1ffffffUL)
+ | 0xa800000000000000UL;
+#endif
*memory_end_p = memory_end;
#ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/mips64/kernel/signal.c b/arch/mips64/kernel/signal.c
index 712459430..bc21e4d4c 100644
--- a/arch/mips64/kernel/signal.c
+++ b/arch/mips64/kernel/signal.c
@@ -519,12 +519,19 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
}
extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
+extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
struct k_sigaction *ka;
siginfo_t info;
+#ifdef CONFIG_BINFMT_ELF32
+ if (current->thread.mflags & MF_32BIT) {
+ return do_signal32(oldset, regs);
+ }
+#endif
+
#ifdef CONFIG_BINFMT_IRIX
if (current->personality != PER_LINUX)
return do_irix_signal(oldset, regs);
diff --git a/arch/mips64/kernel/unaligned.c b/arch/mips64/kernel/unaligned.c
index 22c1819eb..5381642f1 100644
--- a/arch/mips64/kernel/unaligned.c
+++ b/arch/mips64/kernel/unaligned.c
@@ -377,7 +377,7 @@ sigill:
unsigned long unaligned_instructions;
-asmlinkage void do_ade(abi64_no_regargs, struct pt_regs regs)
+asmlinkage void do_ade(struct pt_regs *regs)
{
unsigned long pc;
@@ -386,16 +386,16 @@ asmlinkage void do_ade(abi64_no_regargs, struct pt_regs regs)
* This also catches attempts to activate MIPS16 code on
* CPUs which don't support it.
*/
- if (regs.cp0_badvaddr == regs.cp0_epc)
+ if (regs->cp0_badvaddr == regs->cp0_epc)
goto sigbus;
- pc = regs.cp0_epc + ((regs.cp0_cause & CAUSEF_BD) ? 4 : 0);
- if (compute_return_epc(&regs))
+ pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0);
+ if (compute_return_epc(regs))
return;
if ((current->thread.mflags & MF_FIXADE) == 0)
goto sigbus;
- emulate_load_store_insn(&regs, regs.cp0_badvaddr, pc);
+ emulate_load_store_insn(regs, regs->cp0_badvaddr, pc);
unaligned_instructions++;
return;
diff --git a/arch/mips64/ld.script.elf64 b/arch/mips64/ld.script.elf64
new file mode 100644
index 000000000..abfdf5422
--- /dev/null
+++ b/arch/mips64/ld.script.elf64
@@ -0,0 +1,119 @@
+OUTPUT_ARCH(mips)
+ENTRY(kernel_entry)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ /* . = 0xc000000000000000; */
+
+ /* This is the value for an Origin kernel, taken from an IRIX kernel. */
+ /* . = 0xc00000000001c000; */
+
+ /* Set the vaddr for the text segment to a value
+ >= 0xa800 0000 0001 9000 if no symmon is going to configured
+ >= 0xa800 0000 0030 0000 otherwise */
+
+ /* . = 0xa800000000300000; */
+ /* . = 0xa800000000300000; */
+ . = 0xffffffff80300000;
+ .text : {
+ _ftext = . ;
+ *(.text)
+ *(.rodata)
+ *(.rodata1)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } = 0
+ _etext = .;
+ PROVIDE (etext = .);
+
+ . = ALIGN(16384);
+ .data.init_task : { *(.data.init_task) }
+
+ /* Startup code */
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(16);
+ __setup_start = .;
+ .setup.init : { *(.setup.init) }
+ __setup_end = .;
+ __initcall_start = .;
+ .initcall.init : { *(.initcall.init) }
+ __initcall_end = .;
+ . = ALIGN(4096); /* Align double page for init_task_union */
+ __init_end = .;
+
+ . = ALIGN(4096);
+ .data.page_aligned : { *(.data.idt) }
+
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+ .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/lib/memcpy.S b/arch/mips64/lib/memcpy.S
index 9f44b4b8b..d78327f11 100644
--- a/arch/mips64/lib/memcpy.S
+++ b/arch/mips64/lib/memcpy.S
@@ -96,7 +96,7 @@
LEAF(xxmemcpy) /* a0=dst a1=src a2=len */
move v0, a0 /* return value */
__memcpy:
-EXPORT(__copy_user)
+FEXPORT(__copy_user)
xor ta0, a0, a1
andi ta0, ta0, 0x3
move t3, a0
diff --git a/arch/mips64/lib/strlen_user.S b/arch/mips64/lib/strlen_user.S
index bb4347c02..38b7082d9 100644
--- a/arch/mips64/lib/strlen_user.S
+++ b/arch/mips64/lib/strlen_user.S
@@ -28,7 +28,7 @@ LEAF(__strlen_user_asm)
and v0, a0
bltz v0, fault
-EXPORT(__strlen_user_nocheck_asm)
+FEXPORT(__strlen_user_nocheck_asm)
move v0, a0
1: EX(lb, ta0, (v0), fault)
daddiu v0, 1
diff --git a/arch/mips64/lib/strncpy_user.S b/arch/mips64/lib/strncpy_user.S
index d30046cae..49ba07b05 100644
--- a/arch/mips64/lib/strncpy_user.S
+++ b/arch/mips64/lib/strncpy_user.S
@@ -33,7 +33,7 @@ LEAF(__strncpy_from_user_asm)
and v0, a1
bltz v0, fault
-EXPORT(__strncpy_from_user_nocheck_asm)
+FEXPORT(__strncpy_from_user_nocheck_asm)
move v0, zero
move v1, a1
.set noreorder
diff --git a/arch/mips64/mm/Makefile b/arch/mips64/mm/Makefile
index 17100d9f6..db898cad4 100644
--- a/arch/mips64/mm/Makefile
+++ b/arch/mips64/mm/Makefile
@@ -1,10 +1,29 @@
-# $Id: Makefile,v 1.2 1999/08/20 21:13:33 ralf Exp $
+# $Id: Makefile,v 1.3 1999/12/04 03:59:00 ralf Exp $
#
# Makefile for the Linux/MIPS-specific parts of the memory manager.
#
O_TARGET := mm.o
-O_OBJS := extable.o init.o fault.o r4xx0.o tfp.o andes.o loadmmu.o
+O_OBJS := extable.o init.o fault.o loadmmu.o
+
+ifdef CONFIG_CPU_R4300
+O_OBJS += r4xx0.o
+endif
+ifdef CONFIG_CPU_R4X00
+O_OBJS += r4xx0.o
+endif
+ifdef CONFIG_CPU_R5000
+O_OBJS += r4xx0.o
+endif
+ifdef CONFIG_CPU_NEVADA
+O_OBJS += r4xx0.o
+endif
+ifdef CONFIG_CPU_R8000
+O_OBJS += tfp.o
+endif
+ifdef CONFIG_CPU_R10000
+O_OBJS += andes.o
+endif
ifdef CONFIG_SGI_IP22
O_OBJS += umap.o
diff --git a/arch/mips64/mm/andes.c b/arch/mips64/mm/andes.c
index dec5940c8..0c80e0377 100644
--- a/arch/mips64/mm/andes.c
+++ b/arch/mips64/mm/andes.c
@@ -1,10 +1,9 @@
-/* $Id: andes.c,v 1.3 1999/11/23 17:12:50 ralf Exp $
+/* $Id: andes.c,v 1.3 1999/12/04 03:59:00 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 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
@@ -14,79 +13,380 @@
#include <linux/mm.h>
#include <asm/page.h>
#include <asm/pgtable.h>
+#include <asm/r10kcache.h>
#include <asm/system.h>
#include <asm/sgialib.h>
#include <asm/mmu_context.h>
-extern unsigned long mips_tlb_entries;
+/* CP0 hazard avoidance. I think we can drop this for the R10000. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+ "nop; nop; nop; nop; nop; nop;\n\t" \
+ ".set reorder\n\t")
-/* Cache operations. XXX Write these dave... */
+/* R10000 has no Create_Dirty type cacheops. */
+static void andes_clear_page(unsigned long page)
+{
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "daddiu\t$1,%0,%2\n"
+ "1:\tsd\t$0,(%0)\n\t"
+ "sd\t$0,8(%0)\n\t"
+ "sd\t$0,16(%0)\n\t"
+ "sd\t$0,24(%0)\n\t"
+ "daddiu\t%0,64\n\t"
+ "sd\t$0,-32(%0)\n\t"
+ "sd\t$0,-24(%0)\n\t"
+ "sd\t$0,-16(%0)\n\t"
+ "bne\t$1,%0,1b\n\t"
+ "sd\t$0,-8(%0)\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (page)
+ :"0" (page), "I" (PAGE_SIZE)
+ :"$1", "memory");
+}
+
+static void andes_copy_page(unsigned long to, unsigned long from)
+{
+ unsigned long dummy1, dummy2, reg1, reg2;
+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "daddiu\t$1,%0,%6\n"
+ "1:\tld\t%2,(%1)\n\t"
+ "ld\t%3,8(%1)\n\t"
+ "sd\t%2,(%0)\n\t"
+ "sd\t%3,8(%0)\n\t"
+ "ld\t%2,16(%1)\n\t"
+ "ld\t%3,24(%1)\n\t"
+ "sd\t%2,16(%0)\n\t"
+ "sd\t%3,24(%0)\n\t"
+ "daddiu\t%0,64\n\t"
+ "daddiu\t%1,64\n\t"
+ "ld\t%2,-32(%1)\n\t"
+ "ld\t%3,-24(%1)\n\t"
+ "sd\t%2,-32(%0)\n\t"
+ "sd\t%3,-24(%0)\n\t"
+ "ld\t%2,-16(%1)\n\t"
+ "ld\t%3,-8(%1)\n\t"
+ "sd\t%2,-16(%0)\n\t"
+ "bne\t$1,%0,1b\n\t"
+ " sd\t%3,-8(%0)\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
+ :"0" (to), "1" (from), "I" (PAGE_SIZE));
+}
+
+/* Cache operations. These are only used with the virtual memory system,
+ not for non-coherent I/O so it's ok to ignore the secondary caches. */
static void
andes_flush_cache_all(void)
{
- /* XXX */
+ blast_dcache32(); blast_icache64();
}
static void
andes_flush_cache_mm(struct mm_struct *mm)
{
- /* XXX */
+ if (mm->context != 0) {
+#ifdef DEBUG_CACHE
+ printk("cmm[%d]", (int)mm->context);
+#endif
+ andes_flush_cache_all();
+ }
}
static void
andes_flush_cache_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
- /* XXX */
+ if (mm->context != 0) {
+ unsigned long flags;
+
+#ifdef DEBUG_CACHE
+ printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end);
+#endif
+ save_and_cli(flags);
+ blast_dcache32(); blast_icache64();
+ restore_flags(flags);
+ }
}
static void
andes_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
{
- /* XXX */
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long flags;
+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+ int text;
+
+ /*
+ * If ownes no valid ASID yet, cannot possibly have gotten
+ * this page into the cache.
+ */
+ if (mm->context == 0)
+ return;
+
+#ifdef DEBUG_CACHE
+ printk("cpage[%d,%08lx]", (int)mm->context, page);
+#endif
+ save_and_cli(flags);
+ page &= PAGE_MASK;
+ pgdp = pgd_offset(mm, page);
+ pmdp = pmd_offset(pgdp, page);
+ ptep = pte_offset(pmdp, page);
+
+ /*
+ * If the page isn't marked valid, the page cannot possibly be
+ * in the cache.
+ */
+ if(!(pte_val(*ptep) & _PAGE_PRESENT))
+ goto out;
+
+ text = (vma->vm_flags & VM_EXEC);
+ /*
+ * Doing flushes for another ASID than the current one is
+ * too difficult since stupid R4k caches do a TLB translation
+ * for every cache flush operation. So we do indexed flushes
+ * in that case, which doesn't overly flush the cache too much.
+ */
+ if ((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+ blast_dcache32_page(page);
+ if(text)
+ blast_icache64_page(page);
+ } else {
+ /*
+ * Do indexed flush, too much work to get the (possible)
+ * tlb refills to work correctly.
+ */
+ page = (CKSEG0 + (page & (dcache_size - 1)));
+ blast_dcache32_page_indexed(page);
+ if(text)
+ blast_icache64_page_indexed(page);
+ }
+out:
+ restore_flags(flags);
}
+/* Hoo hum... will this ever be called for an address that is not in CKSEG0
+ and not cacheable? */
static void
andes_flush_page_to_ram(unsigned long page)
{
- /* XXX */
+ page &= PAGE_MASK;
+ if ((page >= K0BASE_NONCOH && page < (0xb0UL << 56))
+ || (page >= KSEG0 && page < KSEG1)
+ || (page >= KSEG2)) {
+#ifdef DEBUG_CACHE
+ printk("cram[%08lx]", page);
+#endif
+ blast_dcache32_page(page);
+ }
}
static void
-andes_flush_cache_sigtramp(unsigned long page)
+andes_flush_cache_sigtramp(unsigned long addr)
{
- /* XXX */
+ unsigned long daddr, iaddr;
+
+ daddr = addr & ~(dc_lsize - 1);
+ protected_writeback_dcache_line(daddr);
+ protected_writeback_dcache_line(daddr + dc_lsize);
+ iaddr = addr & ~(ic_lsize - 1);
+ protected_flush_icache_line(iaddr);
+ protected_flush_icache_line(iaddr + ic_lsize);
}
-/* TLB operations. XXX Write these dave... */
-static void
+#define NTLB_ENTRIES 64
+#define NTLB_ENTRIES_HALF 32
+
+/* TLB operations.
+ XXX These should work fine on R10k without the BARRIERs. */
+static inline void
andes_flush_tlb_all(void)
{
- /* XXX */
+ unsigned long flags;
+ unsigned long old_ctx;
+ unsigned long entry;
+
+#ifdef DEBUG_TLB
+ printk("[tlball]");
+#endif
+
+ __save_and_cli(flags);
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = get_entryhi() & 0xff;
+ set_entryhi(CKSEG0);
+ set_entrylo0(0);
+ set_entrylo1(0);
+ BARRIER;
+
+ entry = get_wired();
+
+ /* Blast 'em all away. */
+ while(entry < NTLB_ENTRIES) {
+ set_index(entry);
+ BARRIER;
+ tlb_write_indexed();
+ BARRIER;
+ entry++;
+ }
+ BARRIER;
+ set_entryhi(old_ctx);
+ __restore_flags(flags);
}
-static void
-andes_flush_tlb_mm(struct mm_struct *mm)
+static void andes_flush_tlb_mm(struct mm_struct *mm)
{
- /* XXX */
+ if(mm->context != 0) {
+ unsigned long flags;
+
+#ifdef DEBUG_TLB
+ printk("[tlbmm<%d>]", mm->context);
+#endif
+ save_and_cli(flags);
+ get_new_mmu_context(mm, asid_cache);
+ if(mm == current->mm)
+ set_entryhi(mm->context & 0xff);
+ restore_flags(flags);
+ }
}
static void
andes_flush_tlb_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
- /* XXX */
+ if(mm->context != 0) {
+ unsigned long flags;
+ int size;
+
+#ifdef DEBUG_TLB
+ printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff),
+ start, end);
+#endif
+ save_and_cli(flags);
+ size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ size = (size + 1) >> 1;
+ if(size <= NTLB_ENTRIES_HALF) {
+ int oldpid = (get_entryhi() & 0xff);
+ int newpid = (mm->context & 0xff);
+
+ start &= (PAGE_MASK << 1);
+ end += ((PAGE_SIZE << 1) - 1);
+ end &= (PAGE_MASK << 1);
+ while(start < end) {
+ int idx;
+
+ set_entryhi(start | newpid);
+ start += (PAGE_SIZE << 1);
+ BARRIER;
+ tlb_probe();
+ BARRIER;
+ idx = get_index();
+ set_entrylo0(0);
+ set_entrylo1(0);
+ set_entryhi(KSEG0);
+ BARRIER;
+ if(idx < 0)
+ continue;
+ tlb_write_indexed();
+ BARRIER;
+ }
+ set_entryhi(oldpid);
+ } else {
+ get_new_mmu_context(mm, asid_cache);
+ if(mm == current->mm)
+ set_entryhi(mm->context & 0xff);
+ }
+ __restore_flags(flags);
+ }
}
static void
andes_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
- /* XXX */
+ if(vma->vm_mm->context != 0) {
+ unsigned long flags;
+ int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+ printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page);
+#endif
+ newpid = (vma->vm_mm->context & 0xff);
+ page &= (PAGE_MASK << 1);
+ save_and_cli(flags);
+ oldpid = (get_entryhi() & 0xff);
+ set_entryhi(page | newpid);
+ BARRIER;
+ tlb_probe();
+ BARRIER;
+ idx = get_index();
+ set_entrylo0(0);
+ set_entrylo1(0);
+ set_entryhi(KSEG0);
+ if(idx < 0)
+ goto finish;
+ BARRIER;
+ tlb_write_indexed();
+
+ finish:
+ BARRIER;
+ set_entryhi(oldpid);
+ restore_flags(flags);
+ }
}
-static void
-andes_load_pgd(unsigned long pg_dir)
+/* XXX Simplify this. On the R10000 writing a TLB entry for an virtual
+ address that already exists will overwrite the old entry and not result
+ in TLB malfunction or TLB shutdown. */
+static void andes_update_mmu_cache(struct vm_area_struct * vma,
+ unsigned long address, pte_t pte)
{
+ unsigned long flags;
+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+ int idx, pid;
+
+ pid = get_entryhi() & 0xff;
+
+#ifdef DEBUG_TLB
+ if((pid != (vma->vm_mm->context & 0xff)) ||
+ (vma->vm_mm->context == 0)) {
+ printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n",
+ (int) (vma->vm_mm->context & 0xff), pid);
+ }
+#endif
+
+ __save_and_cli(flags);
+ address &= (PAGE_MASK << 1);
+ set_entryhi(address | (pid));
+ pgdp = pgd_offset(vma->vm_mm, address);
+ BARRIER;
+ tlb_probe();
+ BARRIER;
+ pmdp = pmd_offset(pgdp, address);
+ idx = get_index();
+ ptep = pte_offset(pmdp, address);
+ BARRIER;
+ set_entrylo0(pte_val(*ptep++) >> 6);
+ set_entrylo1(pte_val(*ptep) >> 6);
+ set_entryhi(address | (pid));
+ BARRIER;
+ if(idx < 0) {
+ tlb_write_random();
+ } else {
+ tlb_write_indexed();
+ }
+ BARRIER;
+ set_entryhi(pid);
+ BARRIER;
+ __restore_flags(flags);
}
static int
@@ -95,8 +395,49 @@ andes_user_mode(struct pt_regs *regs)
return (regs->cp0_status & ST0_KSU) == KSU_USER;
}
+static void andes_show_regs(struct pt_regs *regs)
+{
+ /* Saved main processor registers. */
+ printk("$0 : %016lx %016lx %016lx %016lx\n",
+ 0UL, regs->regs[1], regs->regs[2], regs->regs[3]);
+ printk("$4 : %016lx %016lx %016lx %016lx\n",
+ regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+ printk("$8 : %016lx %016lx %016lx %016lx\n",
+ regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+ printk("$12 : %016lx %016lx %016lx %016lx\n",
+ regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+ printk("$16 : %016lx %016lx %016lx %016lx\n",
+ regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
+ printk("$20 : %016lx %016lx %016lx %016lx\n",
+ regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+ printk("$24 : %016lx %016lx\n",
+ regs->regs[24], regs->regs[25]);
+ printk("$28 : %016lx %016lx %016lx %016lx\n",
+ regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+ printk("Hi : %016lx\n", regs->hi);
+ printk("Lo : %016lx\n", regs->lo);
+
+ /* Saved cp0 registers. */
+ printk("epc : %016lx\nbadvaddr: %016lx\n",
+ regs->cp0_epc, regs->cp0_badvaddr);
+ printk("Status : %08x\nCause : %08x\n",
+ (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause);
+}
+
void __init ld_mmu_andes(void)
{
+ printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
+
+ printk("Primary instruction cache %dkb, linesize %d bytes\n",
+ icache_size >> 10, ic_lsize);
+ printk("Primary data cache %dkb, linesize %d bytes\n",
+ dcache_size >> 10, dc_lsize);
+ printk("Secondary cache sized at %ldK, linesize %ld\n",
+ scache_size() >> 10, sc_lsize());
+
+ clear_page = andes_clear_page;
+ copy_page = andes_copy_page;
+
flush_cache_all = andes_flush_cache_all;
flush_cache_mm = andes_flush_cache_mm;
flush_cache_range = andes_flush_cache_range;
@@ -109,10 +450,26 @@ void __init ld_mmu_andes(void)
flush_tlb_range = andes_flush_tlb_range;
flush_tlb_page = andes_flush_tlb_page;
+ update_mmu_cache = andes_update_mmu_cache;
+ show_regs = andes_show_regs;
+
user_mode = andes_user_mode;
- load_pgd = andes_load_pgd;
+ flush_cache_all();
+ write_32bit_cp0_register(CP0_WIRED, 0);
+
+ /*
+ * You should never change this register:
+ * - On R4600 1.7 the tlbp never hits for pages smaller than
+ * the value in the c0_pagemask register.
+ * - The entire mm handling assumes the c0_pagemask register to
+ * be set for 4kb pages.
+ */
+ write_32bit_cp0_register(CP0_PAGEMASK, PM_4K);
+
+ /* We can't flush the TLB at this time since the IP27 ARC firmware
+ depends on it. ARC go home. */
+ /* flush_tlb_all(); */
- flush_cache_all();
- flush_tlb_all();
+ /* Did I tell you that ARC SUCKS? */
}
diff --git a/arch/mips64/mm/loadmmu.c b/arch/mips64/mm/loadmmu.c
index 3053b9dbd..0359f92a1 100644
--- a/arch/mips64/mm/loadmmu.c
+++ b/arch/mips64/mm/loadmmu.c
@@ -1,4 +1,4 @@
-/* $Id: loadmmu.c,v 1.6 1999/11/23 17:12:50 ralf Exp $
+/* $Id: loadmmu.c,v 1.3 1999/12/04 03:59:00 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
@@ -8,6 +8,7 @@
* Copyright (C) 1997, 1999 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -45,7 +46,6 @@ void (*flush_tlb_range)(struct mm_struct *mm, unsigned long start,
void (*flush_tlb_page)(struct vm_area_struct *vma, unsigned long page);
/* Miscellaneous. */
-void (*load_pgd)(unsigned long pg_dir);
void (*update_mmu_cache)(struct vm_area_struct * vma,
unsigned long address, pte_t pte);
@@ -60,6 +60,10 @@ extern void ld_mmu_andes(void);
void __init load_mmu(void)
{
switch(mips_cputype) {
+#if defined (CONFIG_CPU_R4300) \
+ || defined (CONFIG_CPU_R4X00) \
+ || defined (CONFIG_CPU_R5000) \
+ || defined (CONFIG_CPU_NEVADA)
case CPU_R4000PC:
case CPU_R4000SC:
case CPU_R4000MC:
@@ -78,16 +82,21 @@ void __init load_mmu(void)
printk("Loading R4000 MMU routines.\n");
ld_mmu_r4xx0();
break;
+#endif
+#if defined (CONFIG_CPU_R8000)
case CPU_R8000:
printk("Loading TFP MMU routines.\n");
ld_mmu_tfp();
break;
+#endif
+#if defined (CONFIG_CPU_R10000)
case CPU_R10000:
printk("Loading R10000 MMU routines.\n");
ld_mmu_andes();
break;
+#endif
default:
/* XXX We need an generic routine in the MIPS port
@@ -96,6 +105,7 @@ void __init load_mmu(void)
* XXX routines look good for this, but only the SGI
* XXX code has a full library for that at this time.
*/
- panic("Yeee, unsupported mmu/cache architecture.");
+ panic("Yeee, unsupported mmu/cache architecture or "
+ "wrong compiletime kernel configuration.");
}
}
diff --git a/arch/mips64/mm/r4xx0.c b/arch/mips64/mm/r4xx0.c
index 4cd61e19b..ff239b38e 100644
--- a/arch/mips64/mm/r4xx0.c
+++ b/arch/mips64/mm/r4xx0.c
@@ -1,4 +1,4 @@
-/* $Id: r4xx0.c,v 1.6 1999/11/23 17:12:50 ralf Exp $
+/* $Id: r4xx0.c,v 1.5 1999/12/04 03:59:00 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
@@ -36,7 +36,7 @@ static int ic_lsize, dc_lsize; /* LineSize in bytes */
/* Secondary cache (if present) parameters. */
static unsigned int scache_size, sc_lsize; /* Again, in bytes */
-#include <asm/cacheops.h>
+#include <asm/r4kcacheops.h>
#include <asm/r4kcache.h>
#undef DEBUG_CACHE
@@ -1876,7 +1876,7 @@ r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size)
}
__restore_flags(flags);
}
- bcops->bc_wback_inv(addr, size);
+ bc_wback_inv(addr, size);
}
static void
@@ -1921,7 +1921,7 @@ r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size)
__restore_flags(flags);
}
- bcops->bc_inv(addr, size);
+ bc_inv(addr, size);
}
static void
@@ -2124,11 +2124,6 @@ static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
}
}
-/* Load a new root pointer into the TLB. */
-static void r4k_load_pgd(unsigned long pg_dir)
-{
-}
-
#ifdef DEBUG_TLBUPDATE
static unsigned long ehi_debug[NTLB_ENTRIES];
static unsigned long el0_debug[NTLB_ENTRIES];
@@ -2520,7 +2515,6 @@ void __init ld_mmu_r4xx0(void)
flush_tlb_range = r4k_flush_tlb_range;
flush_tlb_page = r4k_flush_tlb_page;
- load_pgd = r4k_load_pgd;
update_mmu_cache = r4k_update_mmu_cache;
show_regs = r4k_show_regs;
diff --git a/arch/mips64/mm/tfp.c b/arch/mips64/mm/tfp.c
index 517a617b0..aca942a66 100644
--- a/arch/mips64/mm/tfp.c
+++ b/arch/mips64/mm/tfp.c
@@ -1,4 +1,4 @@
-/* $Id: tfp.c,v 1.4 1999/11/23 17:12:50 ralf Exp $
+/* $Id: tfp.c,v 1.4 1999/12/04 03:59:01 ralf Exp $
*
* tfp.c: MMU and cache routines specific to the r8000 (TFP).
*
@@ -74,10 +74,6 @@ static void tfp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
/* XXX */
}
-static void tfp_load_pgd(unsigned long pg_dir)
-{
-}
-
static int tfp_user_mode(struct pt_regs *regs)
{
return (regs->cp0_status & ST0_KSU) == KSU_USER;
@@ -99,8 +95,6 @@ void __init ld_mmu_tfp(void)
user_mode = tfp_user_mode;
- load_pgd = tfp_load_pgd;
-
flush_cache_all();
flush_tlb_all();
}
diff --git a/arch/mips64/sgi-ip22/Makefile b/arch/mips64/sgi-ip22/Makefile
index 8e03f3d9a..3265aab41 100644
--- a/arch/mips64/sgi-ip22/Makefile
+++ b/arch/mips64/sgi-ip22/Makefile
@@ -9,16 +9,8 @@
.S.o:
$(CC) $(CFLAGS) -c $< -o $*.o
-OBJS = ip22-mc.o ip22-sc.o ip22-hpc.o ip22-int.o ip22-rtc.o \
+L_TARGET = ip22.a
+L_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-timer.c b/arch/mips64/sgi-ip22/ip22-timer.c
index 633bf0ef8..ff8ece37a 100644
--- a/arch/mips64/sgi-ip22/ip22-timer.c
+++ b/arch/mips64/sgi-ip22/ip22-timer.c
@@ -85,6 +85,7 @@ void indy_timer_interrupt(struct pt_regs *regs)
unsigned long count;
int irq = 7;
+ write_lock(&xtime_lock);
/* Ack timer and compute new compare. */
count = read_32bit_cp0_register(CP0_COUNT);
/* This has races. */
@@ -114,6 +115,7 @@ void indy_timer_interrupt(struct pt_regs *regs)
/* do it again in 60s */
last_rtc_update = xtime.tv_sec - 600;
}
+ write_unlock(&xtime_lock);
}
static unsigned long dosample(volatile unsigned char *tcwp,
@@ -252,9 +254,10 @@ void __init indy_timer_init(void)
set_cp0_status(ST0_IM, ALLINTS);
sti();
- /* Read time from the dallas chipset. */
- xtime.tv_sec = get_indy_time();
+ write_lock_irq(&xtime_lock);
+ xtime.tv_sec = get_indy_time(); /* Read time from RTC. */
xtime.tv_usec = 0;
+ write_unlock_irq(&xtime_lock);
}
void indy_8254timer_irq(void)
@@ -274,17 +277,17 @@ void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
- save_and_cli(flags);
+ read_lock_irqsave(&xtime_lock, flags);
*tv = xtime;
- restore_flags(flags);
+ read_unlock_irqrestore(&xtime_lock, flags);
}
void do_settimeofday(struct timeval *tv)
{
- cli();
+ write_lock_irq(&xtime_lock);
xtime = *tv;
time_state = TIME_BAD;
time_maxerror = MAXPHASE;
time_esterror = MAXPHASE;
- sti();
+ write_unlock_irq(&xtime_lock);
}
diff --git a/arch/mips64/sgi-ip27/.cvsignore b/arch/mips64/sgi-ip27/.cvsignore
new file mode 100644
index 000000000..857dd22e9
--- /dev/null
+++ b/arch/mips64/sgi-ip27/.cvsignore
@@ -0,0 +1,2 @@
+.depend
+.*.flags
diff --git a/arch/mips64/sgi-ip27/Makefile b/arch/mips64/sgi-ip27/Makefile
new file mode 100644
index 000000000..46fbe0b5c
--- /dev/null
+++ b/arch/mips64/sgi-ip27/Makefile
@@ -0,0 +1,15 @@
+# $Id$
+#
+# Makefile for the IP27 specific kernel interface routines under Linux.
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+L_TARGET = ip27.a
+L_OBJS = ip27-irq.o ip27-irq-glue.o ip27-klconfig.o ip27-memory.o \
+ ip27-reset.o ip27-setup.o ip27-timer.o
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips64/sgi-ip27/ip27-irq-glue.S b/arch/mips64/sgi-ip27/ip27-irq-glue.S
new file mode 100644
index 000000000..40517c2d4
--- /dev/null
+++ b/arch/mips64/sgi-ip27/ip27-irq-glue.S
@@ -0,0 +1,65 @@
+/* $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) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+ .text
+ .set noat
+ .align 5
+NESTED(ip27_irq, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+
+ /* IP27 may signal interrupt which we're not interested in.
+ Mask them out. */
+ mfc0 s0, CP0_CAUSE
+ mfc0 t0, CP0_STATUS
+ and s0, t0
+
+ /* First check for RT interrupt. */
+ andi a0, s0, CAUSEF_IP4
+ beqz a0, 1f
+
+ /* Ok, a timer interrupt. */
+ move a0, sp
+ jal rt_timer_interrupt
+
+ j ret_from_irq
+
+1: andi a0, s0, (CAUSEF_IP2 | CAUSEF_IP3)
+ beqz a0, 1f
+
+ /* ... a device interrupt ... */
+ move a0, sp
+ jal ip27_do_irq
+
+ j ret_from_irq
+
+1:
+#if 1
+ mfc0 a1, CP0_STATUS
+ srl a1, a1, 8
+ andi a1, 0xff
+
+ mfc0 a2, CP0_CAUSE
+ srl a2, a2, 8
+ andi a2, 0xff
+
+ move a3, s0
+ PRINT("Spurious interrupt, c0_status = %02x, c0_cause = %02x, pending %02x.\n")
+ ld a1, PT_EPC(sp)
+0: b 0b
+#endif
+
+ j ret_from_irq
+ END(ip27_irq)
diff --git a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
new file mode 100644
index 000000000..8749652b6
--- /dev/null
+++ b/arch/mips64/sgi-ip27/ip27-irq.c
@@ -0,0 +1,321 @@
+/* $Id$
+ *
+ * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
+ *
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#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/pci/bridge.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/arch.h>
+
+extern asmlinkage void ip27_irq(void);
+int (*irq_cannonicalize)(int irq);
+
+unsigned int local_bh_count[NR_CPUS];
+unsigned int local_irq_count[NR_CPUS];
+unsigned long spurious_count = 0;
+
+void disable_irq(unsigned int irq_nr)
+{
+ panic("disable_irq() called ...");
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+ panic("enable_irq() called ...");
+}
+
+/* This is stupid for an Origin which can have thousands of IRQs ... */
+static struct irqaction *irq_action[NR_IRQS];
+
+int get_irq_list(char *buf)
+{
+ int i, len = 0;
+ struct irqaction * action;
+
+ for (i = 0 ; i < 32 ; i++) {
+ action = irq_action[i];
+ if (!action)
+ continue;
+ len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.irqs[0][i],
+ (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, "\n");
+ }
+ return len;
+}
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special SMP cross-CPU interrupts
+ * have their own specific handlers).
+ */
+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[cpu][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. */
+}
+
+/* For now ... */
+void ip27_do_irq(struct pt_regs *regs)
+{
+ hubreg_t pend0, mask0;
+
+ pend0 = LOCAL_HUB_L(PI_INT_PEND0);
+ mask0 = LOCAL_HUB_L(PI_INT_MASK0_A);
+
+ if (pend0 & mask0 & (1 << 9)) {
+ LOCAL_HUB_S(PI_INT_MASK0_A, mask0 & ~(1 << 9));
+ LOCAL_HUB_S(PI_INT_PEND_MOD, 9);
+ LOCAL_HUB_L(PI_INT_MASK0_A); /* Flush */
+ do_IRQ(9, regs);
+ LOCAL_HUB_S(PI_INT_MASK0_A, mask0);
+ }
+}
+
+
+/* Startup one of the (PCI ...) IRQs routes over a bridge. */
+static unsigned int bridge_startup(unsigned int irq)
+{
+ bridge_t *bridge = (bridge_t *) 0x9200000008000000;
+ bridgereg_t br;
+ int pin;
+
+ /* FIIIIIXME ... Temporary kludge. This knows how interrupts are
+ setup in _my_ Origin. */
+ switch (irq) {
+ case IOC3_SERIAL_INT: pin = 3; break;
+ case IOC3_ETH_INT: pin = 2; break;
+ default: panic("bridge_startup: whoops?");
+ }
+
+ br = LOCAL_HUB_L(PI_INT_MASK0_A);
+ LOCAL_HUB_S(PI_INT_MASK0_A, br | (1 << irq));
+ LOCAL_HUB_L(PI_INT_MASK0_A); /* Flush */
+
+ bridge->b_int_addr[pin].addr = 0x20000 | irq;
+ bridge->b_int_enable |= (1 << pin);
+ bridge->b_widget.w_tflush; /* Flush */
+
+ return 0; /* Never anything pending. */
+}
+
+/* Startup one of the (PCI ...) IRQs routes over a bridge. */
+static unsigned int bridge_shutdown(unsigned int irq)
+{
+ bridge_t *bridge = (bridge_t *) 0x9200000008000000;
+ bridgereg_t br;
+ int pin;
+
+ /* FIIIIIXME ... Temporary kludge. This knows how interrupts are
+ setup in _my_ Origin. */
+ switch (irq) {
+ case IOC3_SERIAL_INT: pin = 3; break;
+ case IOC3_ETH_INT: pin = 2; break;
+ default: panic("bridge_startup: whoops?");
+ }
+
+ br = LOCAL_HUB_L(PI_INT_MASK0_A);
+ LOCAL_HUB_S(PI_INT_MASK0_A, br & ~(1 << irq));
+ LOCAL_HUB_L(PI_INT_MASK0_A); /* Flush */
+
+ bridge->b_int_enable &= ~(1 << pin);
+ bridge->b_widget.w_tflush; /* Flush */
+
+ return 0; /* Never anything pending. */
+}
+
+static void bridge_init(void)
+{
+ bridge_t *bridge = (bridge_t *) 0x9200000008000000;
+
+ /* Hmm... IRIX sets additional bits in the address which are
+ documented as reserved in the bridge docs ... */
+ bridge->b_int_mode = 0x0; /* Don't clear ints */
+ bridge->b_wid_int_upper = 0x000a8000; /* Ints to node 0 */
+ bridge->b_wid_int_lower = 0x01000090;
+ bridge->b_dir_map = 0xa00000; /* DMA */
+ bridge->b_int_enable = 0;
+ bridge->b_widget.w_tflush; /* Flush */
+ set_cp0_status(SRB_DEV0 | SRB_DEV1, SRB_DEV0 | SRB_DEV1);
+}
+
+void irq_debug(void)
+{
+ bridge_t *bridge = (bridge_t *) 0x9200000008000000;
+
+ printk("bridge->b_int_status = 0x%x\n", bridge->b_int_status);
+ printk("bridge->b_int_enable = 0x%x\n", bridge->b_int_enable);
+ printk("PI_INT_PEND0 = 0x%x\n", LOCAL_HUB_L(PI_INT_PEND0));
+ printk("PI_INT_MASK0_A = 0x%x\n", LOCAL_HUB_L(PI_INT_MASK0_A));
+}
+
+int setup_irq(int irq, struct irqaction *new)
+{
+ int shared = 0;
+ struct irqaction *old, **p;
+ unsigned long flags;
+
+ if (new->flags & SA_SAMPLE_RANDOM)
+ rand_initialize_irq(irq);
+
+ save_and_cli(flags);
+ p = irq_action + irq;
+ if ((old = *p) != NULL) {
+ /* Can't share interrupts unless both agree to */
+ if (!(old->flags & new->flags & SA_SHIRQ)) {
+ restore_flags(flags);
+ return -EBUSY;
+ }
+
+ /* Add new interrupt at end of irq queue */
+ do {
+ p = &old->next;
+ old = *p;
+ } while (old);
+ shared = 1;
+ }
+
+ *p = new;
+
+ if (!shared) {
+ bridge_startup(irq);
+ }
+ restore_flags(flags);
+
+ return 0;
+}
+
+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 < 8 > irq > 9)
+ return -EINVAL;
+ if (!handler)
+ return -EINVAL;
+
+ action = (struct irqaction *)kmalloc(sizeof(*action), 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_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 < 8 > irq > 9) {
+ printk("Trying to free IRQ%d\n", irq);
+ 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;
+ if (!irq[irq_action])
+ bridge_shutdown(irq);
+ restore_flags(flags);
+ kfree(action);
+ return;
+ }
+ printk("Trying to free free IRQ%d\n",irq);
+}
+
+/* Useless ISA nonsense. */
+unsigned long probe_irq_on (void)
+{
+ return 0;
+}
+
+int probe_irq_off (unsigned long irqs)
+{
+ return 0;
+}
+
+static int indy_irq_cannonicalize(int irq)
+{
+ return irq; /* Sane hardware, sane code ... */
+}
+
+void __init init_IRQ(void)
+{
+ irq_cannonicalize = indy_irq_cannonicalize;
+
+ bridge_init();
+ set_except_vector(0, ip27_irq);
+}
diff --git a/arch/mips64/sgi-ip27/ip27-klconfig.c b/arch/mips64/sgi-ip27/ip27-klconfig.c
new file mode 100644
index 000000000..54073abfd
--- /dev/null
+++ b/arch/mips64/sgi-ip27/ip27-klconfig.c
@@ -0,0 +1,33 @@
+/* $Id$
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/timex.h>
+#include <linux/mm.h>
+
+#include <asm/sn/klconfig.h>
+
+lboard_t *find_lboard(unsigned int type)
+{
+ lboard_t *b;
+
+ for (
+b = KL_CONFIG_INFO(get_nasid());
+b;
+b = KLCF_NEXT(b)) {
+ if (KLCF_REMOTE(b))
+ continue; /* Skip remote boards. */
+
+ if (b->brd_type == type)
+ return (lboard_t *) b;
+ }
+
+ return NULL;
+}
diff --git a/arch/mips64/sgi-ip27/ip27-memory.c b/arch/mips64/sgi-ip27/ip27-memory.c
new file mode 100644
index 000000000..a3110cc31
--- /dev/null
+++ b/arch/mips64/sgi-ip27/ip27-memory.c
@@ -0,0 +1,65 @@
+/* $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) 2000 by Ralf Baechle
+ * Copyright (C) 2000 by Silicon Graphics, Inc.
+ *
+ * On SGI IP27 the ARC memory configuration data is completly bogus but
+ * alternate easier to use mechanisms are available.
+ */
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/sn/klconfig.h>
+
+void __init
+prom_meminit(void)
+{
+ unsigned long mb;
+ int bank, size;
+ lboard_t *board;
+ klmembnk_t *mem;
+
+ board = find_lboard(KLTYPE_IP27);
+ if (!board)
+ panic("Can't find memory info for myself.");
+
+ mem = (klmembnk_t *) KLCF_COMP(board, IP27_MEM_INDEX);
+ if (!mem)
+ panic("I'm running but don't exist?");
+
+ mb = 0;
+ for (bank = 0; bank < MD_MEM_BANKS; bank++) {
+ size = KLCONFIG_MEMBNK_SIZE(mem, bank);
+ mb += size;
+ if (size != 512) {
+ break;
+ }
+ }
+
+ if (bank != MD_MEM_BANKS && size != 0)
+ printk("Warning: noncontiguous memory configuration, "
+ "not using entire available memory.");
+
+ printk("Found %ldmb of memory.\n", mb);
+ mips_memory_upper = PAGE_OFFSET + (mb << 20);
+}
+
+/* Called from mem_init() to fixup the mem_map page settings. */
+void __init
+prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+ /* mem_map is already completly setup. */
+}
+
+void __init
+prom_free_prom_memory (void)
+{
+ /* We got nothing to free here ... */
+}
diff --git a/arch/mips64/sgi-ip27/ip27-reset.c b/arch/mips64/sgi-ip27/ip27-reset.c
new file mode 100644
index 000000000..fade7ed76
--- /dev/null
+++ b/arch/mips64/sgi-ip27/ip27-reset.c
@@ -0,0 +1,45 @@
+/* $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 IP27.
+ *
+ * Copyright (C) 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
+
+void machine_restart(char *command) __attribute__((noreturn));
+void machine_halt(void) __attribute__((noreturn));
+void machine_power_off(void) __attribute__((noreturn));
+
+/* XXX How to pass the reboot command to the firmware??? */
+void machine_restart(char *command)
+{
+ ArcReboot();
+}
+
+void machine_halt(void)
+{
+ ArcEnterInteractiveMode();
+}
+
+void machine_power_off(void)
+{
+ /* To do ... */
+}
+
+void ip27_reboot_setup(void)
+{
+ /* Nothing to do on IP27. */
+}
diff --git a/arch/mips64/sgi-ip27/ip27-setup.c b/arch/mips64/sgi-ip27/ip27-setup.c
new file mode 100644
index 000000000..52e3782dd
--- /dev/null
+++ b/arch/mips64/sgi-ip27/ip27-setup.c
@@ -0,0 +1,88 @@
+/* $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 IP27 specific setup.
+ *
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silcon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/ioc3.h>
+#include <asm/mipsregs.h>
+#include <asm/sn/klconfig.h>
+
+/*
+ * get_nasid() returns the physical node id number of the caller.
+ */
+nasid_t
+get_nasid(void)
+{
+ return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
+ >> NSRI_NODEID_SHFT);
+}
+
+/* Extracted from the IOC3 meta driver. FIXME. */
+static inline void ioc3_sio_init(void)
+{
+ struct ioc3 *ioc3;
+ nasid_t nid;
+ long loops;
+
+ nid = get_nasid();
+ ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+ ioc3->sscr_a = 0; /* PIO mode for uarta. */
+ ioc3->sscr_b = 0; /* PIO mode for uartb. */
+ ioc3->sio_iec = ~0;
+ ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT);
+
+ loops=1000000; while(loops--);
+ ioc3->sregs.uarta.iu_fcr = 0;
+ ioc3->sregs.uartb.iu_fcr = 0;
+ loops=1000000; while(loops--);
+}
+
+static inline void ioc3_eth_init(void)
+{
+ struct ioc3 *ioc3;
+ nasid_t nid;
+
+ nid = get_nasid();
+ ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+ ioc3->eier = 0;
+}
+
+void __init ip27_setup(void)
+{
+ nasid_t nid;
+ hubreg_t p, e;
+
+ set_cp0_status(ST0_IM, 0);
+ nid = get_nasid();
+ printk("IP27: Running on node %d.\n", nid);
+
+ p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
+ e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
+ printk("Node %d has %s primary CPU%s.\n", nid,
+ p ? "a" : "no",
+ e ? ", CPU is running" : "");
+
+ p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
+ e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
+ printk("Node %d has %s secondary CPU%s.\n", nid,
+ p ? "a" : "no",
+ e ? ", CPU is running" : "");
+
+ ioc3_sio_init();
+ ioc3_eth_init();
+}
diff --git a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c
new file mode 100644
index 000000000..e5fd6c377
--- /dev/null
+++ b/arch/mips64/sgi-ip27/ip27-timer.c
@@ -0,0 +1,115 @@
+/* $Id$
+ *
+ * Copytight (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copytight (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/timex.h>
+#include <linux/mm.h>
+
+#include <asm/pgtable.h>
+#include <asm/sgialib.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+/* This is a hack; we really need to figure these values out dynamically
+ *
+ * Since 800 ns works very well with various HUB frequencies, such as
+ * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
+ *
+ * Ralf: which clock rate is used to feed the counter?
+ */
+#define NSEC_PER_CYCLE 800
+#define NSEC_PER_SEC 1000000000
+#define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE)
+#define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ)
+
+static unsigned long ct_cur; /* What counter should be at next timer irq */
+
+extern rwlock_t xtime_lock;
+
+void rt_timer_interrupt(struct pt_regs *regs)
+{
+ int irq = 7; /* XXX Assign number */
+
+ write_lock(&xtime_lock);
+
+again:
+ LOCAL_HUB_S(PI_RT_PEND_A, 0); /* Ack */
+ ct_cur += CYCLES_PER_JIFFY;
+ LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur);
+
+ if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur)
+ goto again;
+
+ kstat.irqs[0][irq]++;
+ do_timer(regs);
+
+ write_unlock(&xtime_lock);
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+ unsigned long flags;
+
+ read_lock_irqsave(&xtime_lock, flags);
+ *tv = xtime;
+ read_unlock_irqrestore(&xtime_lock, flags);
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+ write_lock_irq(&xtime_lock);
+ xtime = *tv;
+ time_state = TIME_BAD;
+ time_maxerror = MAXPHASE;
+ time_esterror = MAXPHASE;
+ write_unlock_irq(&xtime_lock);
+}
+
+/* Includes for ioc3_init(). */
+#include <linux/init.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/ioc3.h>
+#include <asm/pci/bridge.h>
+
+extern void ioc3_eth_init(void);
+
+void __init time_init(void)
+{
+ unsigned int cpufreq;
+ char *cpufreqstr;
+
+ /* Is this timesource good enough? Ok to assume that all CPUs have
+ this clockrate? Are they 100% synchronously clocked? */
+ cpufreqstr = ArcGetEnvironmentVariable("cpufreq");
+ if (cpufreqstr == NULL)
+ panic("Cannot detect CPU clock rate");
+ cpufreq = simple_strtoul(cpufreqstr, NULL, 10);
+ printk("PROM says CPU clock is %dMHz\n", cpufreq);
+
+ /* We didn't flush the TLB earlier since the ARC firmware depends on
+ it. So do it now. */
+ flush_tlb_all();
+
+ /* Don't worry about second CPU, it's disabled. */
+ LOCAL_HUB_S(PI_RT_EN_A, 1);
+ LOCAL_HUB_S(PI_PROF_EN_A, 0);
+ ct_cur = CYCLES_PER_JIFFY;
+ LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur);
+ LOCAL_HUB_S(PI_RT_COUNT, 0);
+ LOCAL_HUB_S(PI_RT_PEND_A, 0);
+
+ set_cp0_status(SRB_TIMOCLK, SRB_TIMOCLK);
+}
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 126ef69f1..e6c0b6aef 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -37,6 +37,7 @@
* gracefully.
* - Free rings and buffers when closing or before re-initializing rings.
* - Handle allocation failures in ioc3_alloc_skb() more gracefully.
+ * - Handle allocation failures in ioc3_init_rings().
* - Maybe implement private_ioctl().
* - Use prefetching for large packets. What is a good lower limit for
* prefetching?
@@ -300,7 +301,7 @@ static struct net_device_stats *ioc3_get_stats(struct net_device *dev)
return &ip->stats;
}
-static void
+static inline void
ioc3_rx(struct net_device *dev, struct ioc3_private *ip, struct ioc3 *ioc3)
{
struct sk_buff *skb, *new_skb;
@@ -328,8 +329,7 @@ ioc3_rx(struct net_device *dev, struct ioc3_private *ip, struct ioc3 *ioc3)
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- new_skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE,
- GFP_DMA|GFP_ATOMIC);
+ new_skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
if (!new_skb) {
/* Ouch, drop packet and just recycle packet
to keep the ring filled. */
@@ -383,7 +383,7 @@ next:
return;
}
-static void
+static inline void
ioc3_tx(struct ioc3_private *ip, struct ioc3 *ioc3)
{
int tx_entry, o_entry;
@@ -412,6 +412,25 @@ ioc3_tx(struct ioc3_private *ip, struct ioc3 *ioc3)
ip->tx_ci = o_entry;
}
+/*
+ * Deal with fatal IOC3 errors. For now let's panic. This condition might
+ * be caused by a hard or software problems, so we should try to recover
+ * more gracefully if this ever happens.
+ */
+static void
+ioc3_error(struct net_device *dev, struct ioc3_private *ip,
+ struct ioc3 *ioc3, u32 eisr)
+{
+ if (eisr & (EISR_RXMEMERR | EISR_TXMEMERR)) {
+ if (eisr & EISR_RXMEMERR) {
+ panic("%s: RX PCI error.\n", dev->name);
+ }
+ if (eisr & EISR_TXMEMERR) {
+ panic("%s: TX PCI error.\n", dev->name);
+ }
+ }
+}
+
/* The interrupt handler does all of the Rx thread work and cleans up
after the Tx thread. */
static void ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs)
@@ -435,6 +454,9 @@ static void ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs)
if (eisr & EISR_TXEXPLICIT) {
ioc3_tx(ip, ioc3);
}
+ if (eisr & (EISR_RXMEMERR | EISR_TXMEMERR)) {
+ ioc3_error(dev, ip, ioc3, eisr);
+ }
if (dev->tbusy && (TX_BUFFS_AVAIL(ip) >= 0)) {
dev->tbusy = 0;
@@ -501,6 +523,7 @@ static void
ioc3_init_rings(struct net_device *dev, struct ioc3_private *p,
struct ioc3 *ioc3)
{
+ struct ioc3_erxbuf *rxb;
unsigned long *rxr;
unsigned long ring;
int i;
@@ -515,17 +538,20 @@ ioc3_init_rings(struct net_device *dev, struct ioc3_private *p,
for (i = 0; i < RX_BUFFS; i++) {
struct sk_buff *skb;
- skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_DMA);
- if (!skb)
+ skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, 0);
+ if (!skb) {
+ show_free_areas();
continue;
+ }
p->rx_skbs[i] = skb;
skb->dev = dev;
/* Because we reserve afterwards. */
skb_put(skb, (1664 + RX_OFFSET));
- rxr[i] = (0xa5UL << 56) |
- ((unsigned long) skb->data & TO_PHYS_MASK);
+ rxb = (struct ioc3_erxbuf *) skb->data;
+ rxb->w0 = 0; /* Clear valid bit */
+ rxr[i] = (0xa5UL << 56) | ((unsigned long) rxb & TO_PHYS_MASK);
skb_reserve(skb, RX_OFFSET);
}
@@ -652,7 +678,8 @@ ioc3_open(struct net_device *dev)
ioc3->emcr = ((RX_OFFSET / 2) << EMCR_RXOFF_SHIFT) | EMCR_TXDMAEN |
EMCR_TXEN | EMCR_RXDMAEN | EMCR_RXEN;
- ioc3->eier = EISR_RXTIMERINT | EISR_TXEXPLICIT; /* Interrupts ... */
+ ioc3->eier = EISR_RXTIMERINT | EISR_TXEXPLICIT | /* Interrupts ... */
+ EISR_RXMEMERR | EISR_TXMEMERR;
dev->tbusy = 0;
dev->interrupt = 0;
diff --git a/include/asm-mips64/addrspace.h b/include/asm-mips64/addrspace.h
index d8d5a90a5..fee19b6d3 100644
--- a/include/asm-mips64/addrspace.h
+++ b/include/asm-mips64/addrspace.h
@@ -1,15 +1,17 @@
-/* $Id: addrspace.h,v 1.2 1999/10/19 20:51:53 ralf Exp $
+/* $Id: addrspace.h,v 1.2 1999/12/04 03:59:12 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) 1999 by Silicon Graphics, Inc.
+ * Copyright (C) 1990, 1999 by Silicon Graphics, Inc.
*/
#ifndef _ASM_ADDRSPACE_H
#define _ASM_ADDRSPACE_H
+#include <linux/config.h>
+
/*
* Memory segments (32bit kernel mode addresses)
*/
@@ -27,7 +29,8 @@
/*
* Returns the physical address of a KSEG0/KSEG1 address
*/
-#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff)
+#define CPHYSADDR(a) (((unsigned long)(a)) & 0x1fffffffUL)
+#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffffUL)
/*
* Map an address to a certain kernel segment
@@ -49,4 +52,56 @@
#define CKSSEG 0xffffffffc0000000
#define CKSEG3 0xffffffffe0000000
+#if defined (CONFIG_CPU_R4300) \
+ || defined (CONFIG_CPU_R4X00) \
+ || defined (CONFIG_CPU_R5000) \
+ || defined (CONFIG_CPU_NEVADA)
+#define KUSIZE 0x0000010000000000 /* 2^^40 */
+#define KUSIZE_64 0x0000010000000000 /* 2^^40 */
+#define K0SIZE 0x0000001000000000 /* 2^^36 */
+#define K1SIZE 0x0000001000000000 /* 2^^36 */
+#define K2SIZE 0x000000ff80000000
+#define KSEGSIZE 0x000000ff80000000 /* max syssegsz */
+#define TO_PHYS_MASK 0x0000000fffffffff /* 2^^36 - 1 */
+#endif
+
+#if defined (CONFIG_CPU_R8000)
+/* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */
+#define KUSIZE 0x0000010000000000 /* 2^^40 */
+#define KUSIZE_64 0x0000010000000000 /* 2^^40 */
+#define K0SIZE 0x0000010000000000 /* 2^^40 */
+#define K1SIZE 0x0000010000000000 /* 2^^40 */
+#define K2SIZE 0x0001000000000000
+#define KSEGSIZE 0x0000010000000000 /* max syssegsz */
+#define TO_PHYS_MASK 0x000000ffffffffff /* 2^^40 - 1 */
+#endif
+
+#if defined (CONFIG_CPU_R10000)
+#define KUSIZE 0x0000010000000000 /* 2^^40 */
+#define KUSIZE_64 0x0000010000000000 /* 2^^40 */
+#define K0SIZE 0x0000010000000000 /* 2^^40 */
+#define K1SIZE 0x0000010000000000 /* 2^^40 */
+#define K2SIZE 0x00000fff80000000
+#define KSEGSIZE 0x00000fff80000000 /* max syssegsz */
+#define TO_PHYS_MASK 0x000000ffffffffff /* 2^^40 - 1 */
+#endif
+
+/*
+ * Further names for SGI source compatibility. These are stolen from
+ * IRIX's <sys/mips_addrspace.h>.
+ */
+#define KUBASE 0
+#define KUSIZE_32 0x0000000080000000 /* KUSIZE for a 32 bit proc */
+#define K0BASE 0xa800000000000000
+#define K0BASE_EXL_WR K0BASE /* exclusive on write */
+#define K0BASE_NONCOH 0x9800000000000000 /* noncoherent */
+#define K0BASE_EXL 0xa000000000000000 /* exclusive */
+
+#ifdef CONFIG_SGI_IP27
+#define K1BASE 0x9600000000000000 /* Uncached attr 3, uncac */
+#else
+#define K1BASE 0x9000000000000000
+#endif
+#define K2BASE 0xc000000000000000
+
#endif /* _ASM_ADDRSPACE_H */
diff --git a/include/asm-mips64/arc/hinv.h b/include/asm-mips64/arc/hinv.h
new file mode 100644
index 000000000..698891f87
--- /dev/null
+++ b/include/asm-mips64/arc/hinv.h
@@ -0,0 +1,175 @@
+/* $Id$
+ *
+ * ARCS hardware/memory inventory/configuration and system ID definitions.
+ */
+#ifndef _ASM_ARC_HINV_H
+#define _ASM_ARC_HINV_H
+
+#include <asm/arc/types.h>
+
+/* configuration query defines */
+typedef enum configclass {
+ SystemClass,
+ ProcessorClass,
+ CacheClass,
+#ifndef _NT_PROM
+ MemoryClass,
+ AdapterClass,
+ ControllerClass,
+ PeripheralClass
+#else /* _NT_PROM */
+ AdapterClass,
+ ControllerClass,
+ PeripheralClass,
+ MemoryClass
+#endif /* _NT_PROM */
+} CONFIGCLASS;
+
+typedef enum configtype {
+ ARC,
+ CPU,
+ FPU,
+ PrimaryICache,
+ PrimaryDCache,
+ SecondaryICache,
+ SecondaryDCache,
+ SecondaryCache,
+#ifndef _NT_PROM
+ Memory,
+#endif
+ EISAAdapter,
+ TCAdapter,
+ SCSIAdapter,
+ DTIAdapter,
+ MultiFunctionAdapter,
+ DiskController,
+ TapeController,
+ CDROMController,
+ WORMController,
+ SerialController,
+ NetworkController,
+ DisplayController,
+ ParallelController,
+ PointerController,
+ KeyboardController,
+ AudioController,
+ OtherController,
+ DiskPeripheral,
+ FloppyDiskPeripheral,
+ TapePeripheral,
+ ModemPeripheral,
+ MonitorPeripheral,
+ PrinterPeripheral,
+ PointerPeripheral,
+ KeyboardPeripheral,
+ TerminalPeripheral,
+ LinePeripheral,
+ NetworkPeripheral,
+#ifdef _NT_PROM
+ Memory,
+#endif
+ OtherPeripheral,
+
+ /* new stuff for IP30 */
+ /* added without moving anything */
+ /* except ANONYMOUS. */
+
+ XTalkAdapter,
+ PCIAdapter,
+ GIOAdapter,
+ TPUAdapter,
+
+ Anonymous
+} CONFIGTYPE;
+
+typedef enum {
+ Failed = 1,
+ ReadOnly = 2,
+ Removable = 4,
+ ConsoleIn = 8,
+ ConsoleOut = 16,
+ Input = 32,
+ Output = 64
+} IDENTIFIERFLAG;
+
+#ifndef NULL /* for GetChild(NULL); */
+#define NULL 0
+#endif
+
+union key_u {
+ struct {
+#ifdef _MIPSEB
+ unsigned char c_bsize; /* block size in lines */
+ unsigned char c_lsize; /* line size in bytes/tag */
+ unsigned short c_size; /* cache size in 4K pages */
+#else /* _MIPSEL */
+ unsigned short c_size; /* cache size in 4K pages */
+ unsigned char c_lsize; /* line size in bytes/tag */
+ unsigned char c_bsize; /* block size in lines */
+#endif /* _MIPSEL */
+ } cache;
+ ULONG FullKey;
+};
+
+#if _MIPS_SIM == _ABI64
+#define SGI_ARCS_VERS 64 /* sgi 64-bit version */
+#define SGI_ARCS_REV 0 /* rev .00 */
+#else
+#define SGI_ARCS_VERS 1 /* first version */
+#define SGI_ARCS_REV 10 /* rev .10, 3/04/92 */
+#endif
+
+typedef struct component {
+ CONFIGCLASS Class;
+ CONFIGTYPE Type;
+ IDENTIFIERFLAG Flags;
+ USHORT Version;
+ USHORT Revision;
+ ULONG Key;
+ ULONG AffinityMask;
+ ULONG ConfigurationDataSize;
+ ULONG IdentifierLength;
+ char *Identifier;
+} COMPONENT;
+
+/* internal structure that holds pathname parsing data */
+struct cfgdata {
+ char *name; /* full name */
+ int minlen; /* minimum length to match */
+ CONFIGTYPE type; /* type of token */
+};
+
+/* System ID */
+typedef struct systemid {
+ CHAR VendorId[8];
+ CHAR ProductId[8];
+} SYSTEMID;
+
+/* memory query functions */
+typedef enum memorytype {
+ ExceptionBlock,
+ SPBPage, /* ARCS == SystemParameterBlock */
+#ifndef _NT_PROM
+ FreeContiguous,
+ FreeMemory,
+ BadMemory,
+ LoadedProgram,
+ FirmwareTemporary,
+ FirmwarePermanent
+#else /* _NT_PROM */
+ FreeMemory,
+ BadMemory,
+ LoadedProgram,
+ FirmwareTemporary,
+ FirmwarePermanent,
+ FreeContiguous
+#endif /* _NT_PROM */
+} MEMORYTYPE;
+
+typedef struct memorydescriptor {
+ MEMORYTYPE Type;
+ LONG BasePage;
+ LONG PageCount;
+} MEMORYDESCRIPTOR;
+
+#endif /* _ASM_ARC_HINV_H */
diff --git a/include/asm-mips64/arc/types.h b/include/asm-mips64/arc/types.h
index 685580411..79ca5d9da 100644
--- a/include/asm-mips64/arc/types.h
+++ b/include/asm-mips64/arc/types.h
@@ -40,11 +40,11 @@ typedef LONG _PVOID;
typedef char CHAR;
typedef short SHORT;
-typedef long LARGE_INTEGER __attribute__ (__mode__ (__DI__));
-typedef long LONG __attribute__ (__mode__ (__DI__));
+typedef long LARGE_INTEGER __attribute__ ((__mode__ (__DI__)));
+typedef long LONG __attribute__ ((__mode__ (__DI__)));
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
-typedef unsigned long ULONG __attribute__ (__mode__ (__DI__));
+typedef unsigned long ULONG __attribute__ ((__mode__ (__DI__)));
typedef void VOID;
/* The pointer types. We're 64-bit and the firmware is also 64-bit, so
diff --git a/include/asm-mips64/asm.h b/include/asm-mips64/asm.h
index fe616eb08..48f6bfbec 100644
--- a/include/asm-mips64/asm.h
+++ b/include/asm-mips64/asm.h
@@ -1,4 +1,4 @@
-/* $Id: asm.h,v 1.1 1999/08/18 23:37:50 ralf Exp $
+/* $Id: asm.h,v 1.2 1999/12/04 03:59:12 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
@@ -65,11 +65,19 @@ symbol: .frame sp, framesize, rpc
/*
* EXPORT - export definition of symbol
*/
-#define EXPORT(symbol) \
+#define EXPORT(symbol) \
.globl symbol; \
symbol:
/*
+ * FEXPORT - export definition of a function symbol
+ */
+#define FEXPORT(symbol) \
+ .globl symbol; \
+ .type symbol,@function; \
+symbol:
+
+/*
* ABS - export absolute symbol
*/
#define ABS(symbol,value) \
diff --git a/include/asm-mips64/bcache.h b/include/asm-mips64/bcache.h
index e3507bb04..0df4edb7d 100644
--- a/include/asm-mips64/bcache.h
+++ b/include/asm-mips64/bcache.h
@@ -5,10 +5,17 @@
* for more details.
*
* Copyright (c) 1997, 1999 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
*/
#ifndef _ASM_BCACHE_H
#define _ASM_BCACHE_H
+#include <linux/config.h>
+
+#ifdef CONFIG_BOARD_SCACHE
+
+/* Some R4000 / R4400 / R4600 / R5000 machines may have chipset implemented
+ caches. On machines with other CPUs the CPU does the cache thing itself. */
struct bcache_ops {
void (*bc_enable)(void);
void (*bc_disable)(void);
@@ -21,4 +28,35 @@ extern void sni_pcimt_sc_init(void);
extern struct bcache_ops *bcops;
+void inline bc_enable(void)
+{
+ bcops->bc_enable();
+}
+
+void inline bc_disable(void)
+{
+ bcops->bc_disble();
+}
+
+void bc_wback_inv(unsigned long page, unsigned long size)
+{
+ bcops->bc_wback_inv(page, size);
+}
+
+void bc_inv(unsigned long page, unsigned long size)
+{
+ bcops->bc_inv(page, size);
+}
+
+#else /* !defined(CONFIG_BOARD_SCACHE) */
+
+/* Not R4000 / R4400 / R4600 / R5000. */
+
+#define bc_enable() do { } while (0)
+#define bc_disable() do { } while (0)
+#define bc_wback_inv(page, size) do { } while (0)
+#define bc_inv(page, size) do { } while (0)
+
+#endif /* !defined(CONFIG_BOARD_SCACHE) */
+
#endif /* _ASM_BCACHE_H */
diff --git a/include/asm-mips64/bootinfo.h b/include/asm-mips64/bootinfo.h
index 10c209c51..f62ec0e2f 100644
--- a/include/asm-mips64/bootinfo.h
+++ b/include/asm-mips64/bootinfo.h
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: bootinfo.h,v 1.1 1999/08/18 23:37:50 ralf Exp $
*
* bootinfo.h -- Definition of the Linux/MIPS boot information structure
*
@@ -89,8 +89,9 @@
* Valid machtype for group SGI
*/
#define MACH_SGI_INDY 0 /* R4?K and R5K Indy workstaions */
+#define MACH_SGI_IP27 1 /* Origin 200, Origin 2000, Onyx 2 */
-#define GROUP_SGI_NAMES { "Indy" }
+#define GROUP_SGI_NAMES { "Indy", "IP27" }
/*
* Valid machtype for group COBALT
diff --git a/include/asm-mips64/cacheops.h b/include/asm-mips64/cacheops.h
index 438aa1b94..e69de29bb 100644
--- a/include/asm-mips64/cacheops.h
+++ b/include/asm-mips64/cacheops.h
@@ -1,48 +0,0 @@
-/* $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.
- *
- * Cache operations for the cache instruction.
- *
- * (C) Copyright 1996, 1997, 1999 by Ralf Baechle
- */
-#ifndef _ASM_CACHEOPS_H
-#define _ASM_CACHEOPS_H
-
-/*
- * Cache Operations
- */
-#define Index_Invalidate_I 0x00
-#define Index_Writeback_Inv_D 0x01
-#define Index_Invalidate_SI 0x02
-#define Index_Writeback_Inv_SD 0x03
-#define Index_Load_Tag_I 0x04
-#define Index_Load_Tag_D 0x05
-#define Index_Load_Tag_SI 0x06
-#define Index_Load_Tag_SD 0x07
-#define Index_Store_Tag_I 0x08
-#define Index_Store_Tag_D 0x09
-#define Index_Store_Tag_SI 0x0A
-#define Index_Store_Tag_SD 0x0B
-#define Create_Dirty_Excl_D 0x0d
-#define Create_Dirty_Excl_SD 0x0f
-#define Hit_Invalidate_I 0x10
-#define Hit_Invalidate_D 0x11
-#define Hit_Invalidate_SI 0x12
-#define Hit_Invalidate_SD 0x13
-#define Fill 0x14
-#define Hit_Writeback_Inv_D 0x15
- /* 0x16 is unused */
-#define Hit_Writeback_Inv_SD 0x17
-#define Hit_Writeback_I 0x18
-#define Hit_Writeback_D 0x19
- /* 0x1a is unused */
-#define Hit_Writeback_SD 0x1b
- /* 0x1c is unused */
- /* 0x1e is unused */
-#define Hit_Set_Virtual_SI 0x1e
-#define Hit_Set_Virtual_SD 0x1f
-
-#endif /* _ASM_CACHEOPS_H */
diff --git a/include/asm-mips64/current.h b/include/asm-mips64/current.h
index 0afc8cad4..abaab72af 100644
--- a/include/asm-mips64/current.h
+++ b/include/asm-mips64/current.h
@@ -1,4 +1,4 @@
-/* $Id: current.h,v 1.2 1999/09/28 22:27:19 ralf Exp $
+/* $Id: current.h,v 1.3 1999/12/04 03:59:12 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
@@ -25,7 +25,7 @@ register struct task_struct *current asm("$28");
lui reg, %hi(kernelsp); \
.set push; \
.set noreorder; \
- lw reg, %lo(kernelsp)(reg); \
+ ld reg, %lo(kernelsp)(reg); \
.set pop; \
ori reg, 0x3fff; \
xori reg, 0x3fff
diff --git a/include/asm-mips64/elf.h b/include/asm-mips64/elf.h
index f6f8785d4..f7724d9c8 100644
--- a/include/asm-mips64/elf.h
+++ b/include/asm-mips64/elf.h
@@ -82,8 +82,16 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#endif
#ifdef __KERNEL__
-#define SET_PERSONALITY(ex,ibcs2) \
- current->personality = (ibcs2 ? PER_SVR4 : PER_LINUX)
+#define SET_PERSONALITY(ex, ibcs2) \
+do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+ current->thread.mflags |= MF_32BIT; \
+ else \
+ current->thread.mflags &= ~MF_32BIT; \
+ if (ibcs2) \
+ current->personality = PER_SVR4; \
+ else if (current->personality != PER_LINUX32) \
+ current->personality = PER_LINUX; \
+} while (0)
#endif
#endif /* _ASM_ELF_H */
diff --git a/include/asm-mips64/io.h b/include/asm-mips64/io.h
index edcd71b0e..e9df13a60 100644
--- a/include/asm-mips64/io.h
+++ b/include/asm-mips64/io.h
@@ -1,4 +1,4 @@
-/* $Id: io.h,v 1.1 1999/08/18 23:37:51 ralf Exp $
+/* $Id: io.h,v 1.2 1999/10/09 00:01:43 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
@@ -11,13 +11,13 @@
#ifndef _ASM_IO_H
#define _ASM_IO_H
+#include <linux/config.h>
+
/*
* Slowdown I/O port space accesses for antique hardware.
*/
#undef CONF_SLOWDOWN_IO
-#include <linux/config.h>
-
#include <asm/addrspace.h>
/*
@@ -394,8 +394,27 @@ __OUTS(w,l,4)
* be discarded. This operation is necessary before dma operations
* to the memory.
*/
+#ifdef CONFIG_COHERENT_IO
+
+/* This is for example for IP27. */
+extern inline void dma_cache_wback_inv(unsigned long start, unsigned long size)
+{
+}
+
+extern inline void dma_cache_wback(unsigned long start, unsigned long size)
+{
+}
+
+extern inline void dma_cache_inv(unsigned long start, unsigned long size)
+{
+}
+
+#else
+
extern void (*dma_cache_wback_inv)(unsigned long start, unsigned long size);
extern void (*dma_cache_wback)(unsigned long start, unsigned long size);
extern void (*dma_cache_inv)(unsigned long start, unsigned long size);
+#endif
+
#endif /* _ASM_IO_H */
diff --git a/include/asm-mips64/mipsregs.h b/include/asm-mips64/mipsregs.h
index 2a4063ec9..3dba0bba0 100644
--- a/include/asm-mips64/mipsregs.h
+++ b/include/asm-mips64/mipsregs.h
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: mipsregs.h,v 1.1 1999/08/18 23:37:51 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
@@ -153,8 +153,7 @@ set_cp0_##name(unsigned int change, unsigned int new) \
res = read_32bit_cp0_register(register); \
res &= ~change; \
res |= (new & change); \
- if(change) \
- write_32bit_cp0_register(register, res); \
+ write_32bit_cp0_register(register, res); \
\
return res; \
}
diff --git a/include/asm-mips64/page.h b/include/asm-mips64/page.h
index 4471bb273..607da8bb4 100644
--- a/include/asm-mips64/page.h
+++ b/include/asm-mips64/page.h
@@ -1,4 +1,4 @@
-/* $Id: page.h,v 1.1 1999/08/18 23:37:51 ralf Exp $
+/* $Id: page.h,v 1.2 1999/12/04 03:59:12 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
@@ -10,6 +10,8 @@
#ifndef _ASM_PAGE_H
#define _ASM_PAGE_H
+#include <linux/config.h>
+
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
@@ -74,9 +76,16 @@ typedef unsigned long pgprot_t;
/*
* This handles the memory map.
- * We handle pages at KSEG0 for kernels with 32 bit address space.
+ * We handle pages at KSEG0 for kernels with upto 512mb of memory,
+ * at XKPHYS for kernels with more than that.
*/
+#ifdef CONFIG_SGI_IP22
#define PAGE_OFFSET 0xffffffff80000000UL
+#endif
+#ifdef CONFIG_SGI_IP27
+#define PAGE_OFFSET 0xa800000000000000UL
+#endif
+
#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)
diff --git a/include/asm-mips64/pgtable.h b/include/asm-mips64/pgtable.h
index 02ca0e208..0f1fe41b3 100644
--- a/include/asm-mips64/pgtable.h
+++ b/include/asm-mips64/pgtable.h
@@ -198,8 +198,6 @@ extern unsigned long zero_page_mask;
#define PAGE_PTR(address) \
((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
-extern void (*load_pgd)(unsigned long pg_dir);
-
extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
extern pmd_t invalid_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)];
@@ -777,7 +775,7 @@ extern inline void set_entryhi(unsigned long val)
}
/* CP0_INDEX register */
-extern inline unsigned long get_index(void)
+extern inline unsigned int get_index(void)
{
unsigned long val;
@@ -789,7 +787,7 @@ extern inline unsigned long get_index(void)
return val;
}
-extern inline void set_index(unsigned long val)
+extern inline void set_index(unsigned int val)
{
__asm__ __volatile__(
".set noreorder\n\t"
diff --git a/include/asm-mips64/processor.h b/include/asm-mips64/processor.h
index e17b9b2c3..1bb9240e8 100644
--- a/include/asm-mips64/processor.h
+++ b/include/asm-mips64/processor.h
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.4 1999/12/04 03:59:12 ralf Exp $
+/* $Id: processor.h,v 1.5 2000/01/16 01:40:43 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
@@ -76,16 +76,17 @@ extern struct task_struct *last_task_used_math;
/*
* User space process size: 1TB. This is hardcoded into a few places,
* so don't change it unless you know what you are doing. TASK_SIZE
- * is limited to 1TB by the R4000 architecture; R10000 and better do
+ * is limited to 1TB by the R4000 architecture; R10000 and better can
* support 16TB.
-#define TASK_SIZE 0x80000000UL
*/
+#define TASK_SIZE32 0x80000000UL
#define TASK_SIZE 0x10000000000UL
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
-#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+#define TASK_UNMAPPED_BASE ((current->thread.mflags & MF_32BIT) ? \
+ (TASK_SIZE32 / 3) : (TASK_SIZE / 3))
/*
* Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
diff --git a/include/asm-mips64/r10kcache.h b/include/asm-mips64/r10kcache.h
index cd6ec974d..77d14e9a7 100644
--- a/include/asm-mips64/r10kcache.h
+++ b/include/asm-mips64/r10kcache.h
@@ -1,4 +1,4 @@
-/* $Id: r10kcache.h,v 1.1 2000/01/12 23:18:32 ralf Exp $
+/* $Id: r10kcache.h,v 1.1 2000/01/16 01:27:14 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
@@ -21,6 +21,8 @@
/* These are fixed for the current R10000. */
#define icache_size 0x8000
#define dcache_size 0x8000
+#define icache_way_size 0x4000
+#define dcache_way_size 0x4000
#define ic_lsize 64
#define dc_lsize 32
@@ -148,6 +150,22 @@ extern inline void protected_writeback_dcache_line(unsigned long addr)
: "r" (addr), "i" (Hit_Writeback_Inv_D));
}
+#define cache32_unroll16(base,op) \
+ __asm__ __volatile__(" \
+ .set noreorder; \
+ cache %1, 0x000(%0); cache %1, 0x020(%0); \
+ cache %1, 0x040(%0); cache %1, 0x060(%0); \
+ cache %1, 0x080(%0); cache %1, 0x0a0(%0); \
+ cache %1, 0x0c0(%0); cache %1, 0x0e0(%0); \
+ cache %1, 0x100(%0); cache %1, 0x120(%0); \
+ cache %1, 0x140(%0); cache %1, 0x160(%0); \
+ cache %1, 0x180(%0); cache %1, 0x1a0(%0); \
+ cache %1, 0x1c0(%0); cache %1, 0x1e0(%0); \
+ .set reorder" \
+ : \
+ : "r" (base), \
+ "i" (op));
+
#define cache32_unroll32(base,op) \
__asm__ __volatile__(" \
.set noreorder; \
@@ -174,12 +192,15 @@ extern inline void protected_writeback_dcache_line(unsigned long addr)
extern inline void blast_dcache32(void)
{
- unsigned long start = KSEG0;
- unsigned long end = (start + dcache_size);
-
- while (start < end) {
- cache32_unroll32(start,Index_Writeback_Inv_D);
- start += 0x400;
+ unsigned long way0 = KSEG0;
+ unsigned long way1 = way0 ^ 1;
+ unsigned long end = (way0 + dcache_way_size);
+
+ while (way0 < end) {
+ cache32_unroll16(way0, Index_Writeback_Inv_D);
+ cache32_unroll16(way1, Index_Writeback_Inv_D);
+ way0 += 0x200;
+ way1 += 0x200;
}
}
@@ -189,22 +210,41 @@ extern inline void blast_dcache32_page(unsigned long page)
unsigned long end = page + PAGE_SIZE;
while (start < end) {
- cache32_unroll32(start,Hit_Writeback_Inv_D);
- start += 0x800;
+ cache32_unroll32(start, Hit_Writeback_Inv_D);
+ start += 0x400;
}
}
extern inline void blast_dcache32_page_indexed(unsigned long page)
{
- unsigned long start = page;
- unsigned long end = (start + PAGE_SIZE);
+ unsigned long way0 = page;
+ unsigned long way1 = page ^ 1;
+ unsigned long end = page + PAGE_SIZE;
- while (start < end) {
- cache32_unroll32(start,Index_Writeback_Inv_D);
- start += 0x400;
+ while (way0 < end) {
+ cache32_unroll16(way0, Index_Writeback_Inv_D);
+ cache32_unroll16(way1, Index_Writeback_Inv_D);
+ way0 += 0x200;
+ way1 += 0x200;
}
}
+#define cache64_unroll16(base,op) \
+ __asm__ __volatile__(" \
+ .set noreorder; \
+ cache %1, 0x000(%0); cache %1, 0x040(%0); \
+ cache %1, 0x080(%0); cache %1, 0x0c0(%0); \
+ cache %1, 0x100(%0); cache %1, 0x140(%0); \
+ cache %1, 0x180(%0); cache %1, 0x1c0(%0); \
+ cache %1, 0x200(%0); cache %1, 0x240(%0); \
+ cache %1, 0x280(%0); cache %1, 0x2c0(%0); \
+ cache %1, 0x300(%0); cache %1, 0x340(%0); \
+ cache %1, 0x380(%0); cache %1, 0x3c0(%0); \
+ .set reorder" \
+ : \
+ : "r" (base), \
+ "i" (op));
+
#define cache64_unroll32(base,op) \
__asm__ __volatile__(" \
.set noreorder; \
@@ -231,12 +271,15 @@ extern inline void blast_dcache32_page_indexed(unsigned long page)
extern inline void blast_icache64(void)
{
- unsigned long start = KSEG0;
- unsigned long end = KSEG0 + dcache_size;
-
- while (start < end) {
- cache64_unroll32(start,Index_Invalidate_I);
- start += 0x800;
+ unsigned long way0 = KSEG0;
+ unsigned long way1 = way0 ^ 1;
+ unsigned long end = way0 + icache_way_size;
+
+ while (way0 < end) {
+ cache64_unroll16(way0,Index_Invalidate_I);
+ cache64_unroll16(way1,Index_Invalidate_I);
+ way0 += 0x400;
+ way1 += 0x400;
}
}
@@ -253,23 +296,29 @@ extern inline void blast_icache64_page(unsigned long page)
extern inline void blast_icache64_page_indexed(unsigned long page)
{
- unsigned long start = page;
+ unsigned long way0 = page;
+ unsigned long way1 = page ^ 1;
unsigned long end = page + PAGE_SIZE;
- while (start < end) {
- cache64_unroll32(start,Index_Invalidate_I);
- start += 0x800;
+ while (way0 < end) {
+ cache64_unroll16(way0,Index_Invalidate_I);
+ cache64_unroll16(way1,Index_Invalidate_I);
+ way0 += 0x400;
+ way1 += 0x400;
}
}
extern inline void blast_scache64(void)
{
- unsigned long start = KSEG0;
+ unsigned long way0 = KSEG0;
+ unsigned long way1 = way0 ^ 1;
unsigned long end = KSEG0 + scache_size();
- while (start < end) {
- cache64_unroll32(start,Index_Writeback_Inv_S);
- start += 0x800;
+ while (way0 < end) {
+ cache64_unroll16(way0,Index_Writeback_Inv_S);
+ cache64_unroll16(way1,Index_Writeback_Inv_S);
+ way0 += 0x400;
+ way1 += 0x400;
}
}
@@ -286,15 +335,34 @@ extern inline void blast_scache64_page(unsigned long page)
extern inline void blast_scache64_page_indexed(unsigned long page)
{
- unsigned long start = page;
+ unsigned long way0 = page;
+ unsigned long way1 = page ^ 1;
unsigned long end = page + PAGE_SIZE;
- while (start < end) {
- cache64_unroll32(start,Index_Writeback_Inv_S);
- start += 0x800;
+ while (way0 < end) {
+ cache64_unroll16(way0,Index_Writeback_Inv_S);
+ cache64_unroll16(way1,Index_Writeback_Inv_S);
+ way0 += 0x400;
+ way1 += 0x400;
}
}
+#define cache128_unroll16(base,op) \
+ __asm__ __volatile__(" \
+ .set noreorder; \
+ cache %1, 0x000(%0); cache %1, 0x080(%0); \
+ cache %1, 0x100(%0); cache %1, 0x180(%0); \
+ cache %1, 0x200(%0); cache %1, 0x280(%0); \
+ cache %1, 0x300(%0); cache %1, 0x380(%0); \
+ cache %1, 0x400(%0); cache %1, 0x480(%0); \
+ cache %1, 0x500(%0); cache %1, 0x580(%0); \
+ cache %1, 0x600(%0); cache %1, 0x680(%0); \
+ cache %1, 0x700(%0); cache %1, 0x780(%0); \
+ .set reorder" \
+ : \
+ : "r" (base), \
+ "i" (op));
+
#define cache128_unroll32(base,op) \
__asm__ __volatile__(" \
.set noreorder; \
@@ -321,23 +389,27 @@ extern inline void blast_scache64_page_indexed(unsigned long page)
extern inline void blast_scache128(void)
{
- unsigned long start = KSEG0;
- unsigned long end = KSEG0 + scache_size();
-
- while (start < end) {
- cache128_unroll32(start,Index_Writeback_Inv_S);
- start += 0x1000;
+ unsigned long way0 = KSEG0;
+ unsigned long way1 = way0 ^ 1;
+ unsigned long end = way0 + scache_size();
+
+ while (way0 < end) {
+ cache128_unroll16(way0, Index_Writeback_Inv_S);
+ cache128_unroll16(way1, Index_Writeback_Inv_S);
+ way0 += 0x800;
+ way1 += 0x800;
}
}
extern inline void blast_scache128_page(unsigned long page)
{
- cache128_unroll32(page,Hit_Writeback_Inv_S);
+ cache128_unroll32(page, Hit_Writeback_Inv_S);
}
extern inline void blast_scache128_page_indexed(unsigned long page)
{
- cache128_unroll32(page,Index_Writeback_Inv_S);
+ cache128_unroll32(page , Index_Writeback_Inv_S);
+ cache128_unroll32(page ^ 1, Index_Writeback_Inv_S);
}
#endif /* _ASM_R10KCACHE_H */
diff --git a/include/asm-mips64/r4kcache.h b/include/asm-mips64/r4kcache.h
index 6801259dd..cee70ceb9 100644
--- a/include/asm-mips64/r4kcache.h
+++ b/include/asm-mips64/r4kcache.h
@@ -14,7 +14,7 @@
#define _ASM_R4KCACHE_H
#include <asm/asm.h>
-#include <asm/cacheops.h>
+#include <asm/r4kcacheops.h>
extern inline void flush_icache_line_indexed(unsigned long addr)
{
diff --git a/include/asm-mips64/r4kcacheops.h b/include/asm-mips64/r4kcacheops.h
new file mode 100644
index 000000000..bc4b924ed
--- /dev/null
+++ b/include/asm-mips64/r4kcacheops.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.
+ *
+ * Cache operations for the cache instruction.
+ *
+ * (C) Copyright 1996, 1997, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_R4kCACHEOPS_H
+#define _ASM_R4kCACHEOPS_H
+
+/*
+ * Cache Operations
+ */
+#define Index_Invalidate_I 0x00
+#define Index_Writeback_Inv_D 0x01
+#define Index_Invalidate_SI 0x02
+#define Index_Writeback_Inv_SD 0x03
+#define Index_Load_Tag_I 0x04
+#define Index_Load_Tag_D 0x05
+#define Index_Load_Tag_SI 0x06
+#define Index_Load_Tag_SD 0x07
+#define Index_Store_Tag_I 0x08
+#define Index_Store_Tag_D 0x09
+#define Index_Store_Tag_SI 0x0A
+#define Index_Store_Tag_SD 0x0B
+#define Create_Dirty_Excl_D 0x0d
+#define Create_Dirty_Excl_SD 0x0f
+#define Hit_Invalidate_I 0x10
+#define Hit_Invalidate_D 0x11
+#define Hit_Invalidate_SI 0x12
+#define Hit_Invalidate_SD 0x13
+#define Fill 0x14
+#define Hit_Writeback_Inv_D 0x15
+ /* 0x16 is unused */
+#define Hit_Writeback_Inv_SD 0x17
+#define Hit_Writeback_I 0x18
+#define Hit_Writeback_D 0x19
+ /* 0x1a is unused */
+#define Hit_Writeback_SD 0x1b
+ /* 0x1c is unused */
+ /* 0x1e is unused */
+#define Hit_Set_Virtual_SI 0x1e
+#define Hit_Set_Virtual_SD 0x1f
+
+#endif /* _ASM_R4kCACHEOPS_H */
diff --git a/include/asm-mips64/serial.h b/include/asm-mips64/serial.h
index 2b148a7d8..c6b3245d7 100644
--- a/include/asm-mips64/serial.h
+++ b/include/asm-mips64/serial.h
@@ -1,4 +1,4 @@
-/* $Id: serial.h,v 1.1 2000/01/04 10:37:18 ralf Exp $
+/* $Id: serial.h,v 1.1 2000/01/04 10:51:55 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
@@ -37,8 +37,8 @@
#ifdef CONFIG_SGI_IP27
#define ORIGIN_SERIAL_PORT_DFNS \
- { 0, IOC3_BAUD, 0x9200000008620178, IOC3_SERIAL_INT, IOC3_COM_FLAGS },\
- { 0, IOC3_BAUD, 0x9200000008620170, IOC3_SERIAL_INT, IOC3_COM_FLAGS },
+ { 0, IOC3_BAUD, 0x9200000008620178, 0, IOC3_COM_FLAGS },\
+ { 0, IOC3_BAUD, 0x9200000008620170, 0, IOC3_COM_FLAGS },
#else
#define ORIGIN_SERIAL_PORT_DFNS
#endif
diff --git a/include/asm-mips64/sgialib.h b/include/asm-mips64/sgialib.h
index cafa0aa1c..ab02c8fd9 100644
--- a/include/asm-mips64/sgialib.h
+++ b/include/asm-mips64/sgialib.h
@@ -1,4 +1,4 @@
-/* $Id: sgialib.h,v 1.2 1999/08/20 21:59:08 ralf Exp $
+/* $Id: sgialib.h,v 1.3 1999/12/04 03:59:12 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
@@ -42,7 +42,7 @@ extern void prom_printf(char *fmt, ...);
/* Memory descriptor management. */
#define PROM_MAX_PMEMBLOCKS 32
struct prom_pmemblock {
- LONG base; /* Within KSEG0. */
+ LONG base; /* Within KSEG0 or XKPHYS. */
ULONG size; /* In bytes. */
ULONG type; /* free or prom memory */
};
@@ -120,13 +120,13 @@ extern long prom_invoke(unsigned long pc, unsigned long sp, long argc, char **ar
extern long prom_exec(char *name, long argc, char **argv, char **envp);
/* Misc. routines. */
-extern void prom_halt(void) __attribute__((noreturn));
-extern void prom_powerdown(void) __attribute__((noreturn));
-extern void prom_restart(void) __attribute__((noreturn));
+extern void prom_halt(VOID) __attribute__((noreturn));
+extern void prom_powerdown(VOID) __attribute__((noreturn));
+extern void prom_restart(VOID) __attribute__((noreturn));
extern VOID ArcReboot(VOID) __attribute__((noreturn));
-extern VOID ArcEnterInteractiveMode(VOID) __attribute__((noreturn));
-extern long prom_cfgsave(void);
-extern struct linux_sysid *prom_getsysid(void);
-extern void prom_cacheflush(void);
+extern VOID ArcEnterInteractiveMode(void) __attribute__((noreturn));
+extern long prom_cfgsave(VOID);
+extern struct linux_sysid *prom_getsysid(VOID);
+extern VOID ArcFlushAllCaches(VOID);
#endif /* _ASM_SGIALIB_H */
diff --git a/include/asm-mips64/sgiarcs.h b/include/asm-mips64/sgiarcs.h
index 632920b3b..457c03af1 100644
--- a/include/asm-mips64/sgiarcs.h
+++ b/include/asm-mips64/sgiarcs.h
@@ -1,4 +1,4 @@
-/* $Id: sgiarcs.h,v 1.3 1999/08/21 22:19:17 ralf Exp $
+/* $Id: sgiarcs.h,v 1.4 1999/12/04 03:59:12 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
@@ -13,6 +13,7 @@
#ifndef _ASM_SGIARCS_H
#define _ASM_SGIARCS_H
+#include <linux/config.h>
#include <asm/arc/types.h>
/* Various ARCS error codes. */
@@ -364,6 +365,7 @@ struct linux_smonblock {
* Macros for calling a 32-bit ARC implementation from 64-bit code
*/
+#ifdef CONFIG_ARC32
#define __arc_clobbers \
"$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \
"$12","$13","$14","$15","$16","$24","25","$31"
@@ -470,5 +472,73 @@ struct linux_smonblock {
: __arc_clobbers); \
__res; \
})
+#endif /* CONFIG_ARC32 */
+
+#ifdef CONFIG_ARC64
+
+#define ARC_CALL0(dest) \
+({ long __res; \
+ long (*__vec)(void) = (void *) romvec->dest; \
+ \
+ __res = __vec(); \
+ __res; \
+})
+
+#define ARC_CALL1(dest,a1) \
+({ long __res; \
+ long __a1 = (long) (a1); \
+ long (*__vec)(long) = (void *) romvec->dest; \
+ \
+ __res = __vec(__a1); \
+ __res; \
+})
+
+#define ARC_CALL2(dest,a1,a2) \
+({ long __res; \
+ long __a1 = (long) (a1); \
+ long __a2 = (long) (a2); \
+ long (*__vec)(long, long) = (void *) romvec->dest; \
+ \
+ __res = __vec(__a1, __a2); \
+ __res; \
+})
+
+#define ARC_CALL3(dest,a1,a2,a3) \
+({ long __res; \
+ long __a1 = (long) (a1); \
+ long __a2 = (long) (a2); \
+ long __a3 = (long) (a3); \
+ long (*__vec)(long, long, long) = (void *) romvec->dest; \
+ \
+ __res = __vec(__a1, __a2, __a3); \
+ __res; \
+})
+
+#define ARC_CALL4(dest,a1,a2,a3,a4) \
+({ long __res; \
+ long __a1 = (long) (a1); \
+ long __a2 = (long) (a2); \
+ long __a3 = (long) (a3); \
+ long __a4 = (long) (a4); \
+ long (*__vec)(long, long, long, long) = (void *) romvec->dest; \
+ \
+ __res = __vec(__a1, __a2, __a3, __a4); \
+ __res; \
+})
+
+#define ARC_CALL5(dest,a1,a2,a3,a4,a5) \
+({ long __res; \
+ long __a1 = (long) (a1); \
+ long __a2 = (long) (a2); \
+ long __a3 = (long) (a3); \
+ long __a4 = (long) (a4); \
+ long __a5 = (long) (a5); \
+ long (*__vec)(long, long, long, long, long); \
+ __vec = (void *) romvec->dest; \
+ \
+ __res = __vec(__a1, __a2, __a3, __a4, __a5); \
+ __res; \
+})
+#endif /* CONFIG_ARC64 */
#endif /* _ASM_SGIARCS_H */
diff --git a/include/linux/serial.h b/include/linux/serial.h
index e1ad16ae6..3cc56b08f 100644
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -95,6 +95,7 @@ struct serial_uart_config {
#define ASYNC_FLAGS 0x3FFF /* Possible legal async flags */
#define ASYNC_USR_MASK 0x3430 /* Legal flags that non-privileged
* users can set or reset */
+#define ASYNC_IOC3 0x4000 /* SGI IOC3 serial */
/* Internal flags used only by kernel/chr_drv/serial.c */
#define ASYNC_INITIALIZED 0x80000000 /* Serial port was initialized */
diff --git a/include/linux/serialP.h b/include/linux/serialP.h
index 02fcb9363..3726d9b5d 100644
--- a/include/linux/serialP.h
+++ b/include/linux/serialP.h
@@ -39,7 +39,7 @@ struct async_icount {
struct serial_state {
int magic;
int baud_base;
- int port;
+ unsigned long port;
int irq;
int flags;
int hub6;
@@ -54,14 +54,14 @@ struct serial_state {
unsigned short close_delay;
unsigned short closing_wait; /* time to wait before closing */
struct async_icount icount;
- struct termios normal_termios;
+ struct termios normal_termios;
struct termios callout_termios;
struct async_struct *info;
};
struct async_struct {
int magic;
- int port;
+ unsigned long port;
int hub6;
int flags;
int xmit_fifo_size;