summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-09-12 01:29:55 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-09-12 01:29:55 +0000
commit545f435ebcfd94a1e7c20b46efe81b4d6ac4e698 (patch)
treee9ce4bc598d06374bda906f18365984bf22a526a /arch/mips
parent4291a610eef89d0d5c69d9a10ee6560e1aa36c74 (diff)
Merge with Linux 2.1.55. More bugfixes and goodies from my private
CVS archive.
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Makefile10
-rw-r--r--arch/mips/config.in35
-rw-r--r--arch/mips/dec/decstation.S8
-rw-r--r--arch/mips/dec/int-handler.S8
-rw-r--r--arch/mips/defconfig10
-rw-r--r--arch/mips/kernel/Makefile4
-rw-r--r--arch/mips/kernel/entry.S17
-rw-r--r--arch/mips/kernel/fpe.c55
-rw-r--r--arch/mips/kernel/irq.c34
-rw-r--r--arch/mips/kernel/mips_ksyms.c18
-rw-r--r--arch/mips/kernel/pci.c26
-rw-r--r--arch/mips/kernel/ptrace.c26
-rw-r--r--arch/mips/kernel/r4k_misc.S35
-rw-r--r--arch/mips/kernel/setup.c12
-rw-r--r--arch/mips/kernel/signal.c14
-rw-r--r--arch/mips/kernel/syscall.c38
-rw-r--r--arch/mips/kernel/syscalls.h22
-rw-r--r--arch/mips/kernel/traps.c28
-rw-r--r--arch/mips/lib/copy_user.S65
-rw-r--r--arch/mips/mm/loadmmu.c5
-rw-r--r--arch/mips/mm/r4xx0.c72
-rw-r--r--arch/mips/sgi/kernel/indy_int.c38
-rw-r--r--arch/mips/sgi/kernel/indy_timer.c13
23 files changed, 375 insertions, 218 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 516baec29..b1df65c86 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -13,21 +13,21 @@
# Copyright (C) 1994, 1995, 1996 by Ralf Baechle
# DECStation modifications by Paul M. Antoine, 1996
#
-# $Id: Makefile,v 1.5 1997/07/01 08:54:40 ralf Exp $
+# $Id: Makefile,v 1.7 1997/08/30 04:51:27 ralf Exp $
#
#
# Select the object file format to substitute into the linker script.
#
ifdef CONFIG_CPU_LITTLE_ENDIAN
-CROSS_COMPILE = mipsel-linux-
+tool-prefix = mipsel-linux-
ifdef CONFIG_MIPS_ECOFF
oformat = ecoff-littlemips
else
oformat = elf32-littlemips
endif
else
-CROSS_COMPILE = mips-linux-
+tool-prefix = mips-linux-
ifdef CONFIG_MIPS_ECOFF
oformat = ecoff-bigmips
else
@@ -35,6 +35,10 @@ oformat = elf32-bigmips
endif
endif
+ifdef CONFIG_CROSSCOMPILE
+CROSS_COMPILE = $(tool-prefix)
+endif
+
LINKFLAGS = -static -N
MODFLAGS += -mlong-calls
diff --git a/arch/mips/config.in b/arch/mips/config.in
index 35903797a..9e820f29e 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -21,10 +21,6 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
fi
bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000
bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
-if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
- "$CONFIG_OLIVETTI_M700" = "y" ]; then
- define_bool CONFIG_VIDEO_G364 y
-fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'Support for SGI workstations' CONFIG_SGI
if [ "$CONFIG_SGI" = "y" ]; then
@@ -32,6 +28,21 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
fi
fi
bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
+
+#
+# Select some configuration options automatically for certain systems.
+#
+unset CONFIG_PCI
+unset CONFIG_MIPS_JAZZ
+unset CONFIG_VIDEO_G364
+
+if [ "$CONFIG_ALGOR_P4032" = "y" ]; then
+ define_bool CONFIG_PCI y
+fi
+if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
+ "$CONFIG_OLIVETTI_M700" = "y" ]; then
+ define_bool CONFIG_VIDEO_G364 y
+fi
if [ "$CONFIG_DESKSTATION_RPC44" = "y" -o \
"$CONFIG_DESKSTATION_TYNE" = "y" ]; then
define_bool CONFIG_MIPS_ARC y
@@ -41,9 +52,7 @@ if [ "$CONFIG_ACER_PICA_61" = "y" -o \
"$CONFIG_MIPS_MAGNUM_4000" = "y" ]; then
define_bool CONFIG_MIPS_JAZZ y
fi
-unset CONFIG_PCI
-if [ "$CONFIG_SNI_RM200_PCI" = "y" -o \
- "$CONFIG_ALGOR_P4032" = "y" ]; then
+if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
define_bool CONFIG_PCI y
fi
endmenu
@@ -70,15 +79,19 @@ else
define_bool CONFIG_ELF_KERNEL y
bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
fi
+
if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
define_bool CONFIG_BINFMT_IRIX y
define_bool CONFIG_FORWARD_KEYBOARD y
fi
-define_bool CONFIG_BINFMT_ELF y
define_bool CONFIG_BINFMT_AOUT n
+define_bool CONFIG_BINFMT_ELF y
+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
+ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+ tristate 'Kernel support for JAVA binaries (obsolete)' CONFIG_BINFMT_JAVA
fi
+
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
bool 'Sysctl support' CONFIG_SYSCTL
@@ -208,6 +221,10 @@ mainmenu_option next_comment
comment 'Kernel hacking'
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
+bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Build fp execption handler module' CONFIG_MIPS_FPE_MODULE
+fi
bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
bool 'Kernel profiling support' CONFIG_PROFILE
if [ "$CONFIG_PROFILE" = "y" ]; then
diff --git a/arch/mips/dec/decstation.S b/arch/mips/dec/decstation.S
index a5a4f9b6d..612fcea0b 100644
--- a/arch/mips/dec/decstation.S
+++ b/arch/mips/dec/decstation.S
@@ -14,6 +14,8 @@
* the end hasn't been modified to suit the DECStation's interrupts.
* (Paul, you need to fix this file to comply with NAPS. Won't be
* too hard - Ralf)
+ *
+ * $Id:$
*/
#include <asm/asm.h>
#include <asm/mipsconfig.h>
@@ -223,12 +225,12 @@ loc_scsi: PANIC("Unimplemented loc_scsi handler")
* comment - Ralf)
* Andy, 6/16/95
*/
-loc_ethernet: PANIC("Unimplemented loc_ethernet\n")
+loc_ethernet: PANIC("Unimplemented loc_ethernet")
/*
* Keyboard interrupt, remapped to level 1
*/
-loc_keyboard: PANIC("Unimplemented loc_keyboard\n")
+loc_keyboard: PANIC("Unimplemented loc_keyboard")
loc_mouse: PANIC("Unimplemented loc_mouse handler")
@@ -291,7 +293,7 @@ ll_rtc: PANIC("Unimplemented RTC interrupt handler")
* Timer IRQ
* We remap the timer irq to be more similar to a IBM compatible
*/
-ll_timer: PANIC("Timer interrupt!\n");
+ll_timer: PANIC("Timer interrupt!");
/*
* CPU count/compare IRQ (unused)
*/
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
index 9191574d2..1706dc975 100644
--- a/arch/mips/dec/int-handler.S
+++ b/arch/mips/dec/int-handler.S
@@ -11,6 +11,8 @@
*
* FIXME: still plenty to do in this file, as much of the code hasn't been
* modified to suit the DECStation's interrupts.
+ *
+ * $Id:$
*/
#include <asm/asm.h>
#include <asm/regdef.h>
@@ -114,12 +116,12 @@ loc_scsi: PANIC("Unimplemented loc_scsi handler")
* Only god knows why... Tell me if you find the reason!
* Andy, 6/16/95
*/
-loc_ethernet: PANIC("Unimplemented loc_ethernet\n")
+loc_ethernet: PANIC("Unimplemented loc_ethernet")
/*
* Keyboard interrupt, remapped to level 1
*/
-loc_keyboard: PANIC("Unimplemented loc_keyboard\n")
+loc_keyboard: PANIC("Unimplemented loc_keyboard")
loc_mouse: PANIC("Unimplemented loc_mouse handler")
@@ -182,7 +184,7 @@ ll_rtc: PANIC("Unimplemented RTC interrupt handler")
* Timer IRQ
* We remap the timer irq to be more similar to a IBM compatible
*/
-ll_timer: PANIC("Timer interrupt!\n");
+ll_timer: PANIC("Timer interrupt!");
/*
* CPU count/compare IRQ (unused)
*/
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index b1892eba6..ae3ba1f9d 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -33,12 +33,13 @@ CONFIG_CPU_R4X00=y
#
CONFIG_ELF_KERNEL=y
CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
CONFIG_NET=y
CONFIG_SYSVIPC=y
CONFIG_SYSCTL=y
-# CONFIG_PARPORT is not set
+# CONFIG_PNP_PARPORT is not set
#
# Loadable module support
@@ -121,6 +122,7 @@ CONFIG_MIPS_JAZZ_SONIC=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_NET_ISA is not set
CONFIG_NET_EISA=y
CONFIG_PCNET32=y
@@ -133,7 +135,6 @@ CONFIG_PCNET32=y
# CONFIG_NET_POCKET is not set
# CONFIG_FDDI is not set
# CONFIG_DLCI is not set
-# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_NET_RADIO is not set
# CONFIG_SLIP is not set
@@ -177,6 +178,7 @@ CONFIG_ISO9660_FS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_UFS_FS is not set
+# CONFIG_MAC_PARTITION is not set
#
# Character devices
@@ -192,6 +194,7 @@ CONFIG_SERIAL=y
# CONFIG_APM is not set
# CONFIG_WATCHDOG is not set
# CONFIG_RTC is not set
+# CONFIG_NVRAM is not set
# CONFIG_JOYSTICK is not set
#
@@ -202,5 +205,6 @@ CONFIG_SERIAL=y
#
# Kernel hacking
#
+# CONFIG_CROSSCOMPILE is not set
# CONFIG_REMOTE_DEBUG is not set
# CONFIG_PROFILE is not set
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 21dd3610b..b3a550177 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -18,6 +18,10 @@ O_OBJS := branch.o process.o signal.o entry.o traps.o ptrace.o vm86.o \
r2300_misc.o r2300_scall.o r2300_fpu.o r6000_fpu.o unaligned.o
OX_OBJS := mips_ksyms.o
+ifdef CONFIG_MIPS_FPE_MODULE
+M_OBJS += fpe.o
+endif
+
#
# SGI's have very different interrupt/timer hardware.
#
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 00c321a35..c955b964e 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -6,6 +6,8 @@
* for more details.
*
* Copyright (C) 1994, 1995 by Ralf Baechle
+ *
+ * $Id: entry.S,v 1.2 1997/08/11 04:21:31 ralf Exp $
*/
/*
@@ -38,24 +40,17 @@
.set noreorder
.set mips3
.align 4
-/* XXX cli/sti ??? */
handle_bottom_half:
- mfc0 s3,CP0_STATUS # Enable IRQs
- ori t0,s3, 0x1f
- xori t0,0x1e
-
jal do_bottom_half
- mtc0 t0,CP0_STATUS
-
+ nop
b 9f
- mtc0 s3,CP0_STATUS # Restore old IRQ state
+ nop
-reschedule:
- jal schedule
+reschedule: jal schedule
nop
EXPORT(ret_from_sys_call)
- lw t0,bh_mask
+ lw t0,bh_mask
lw t1,bh_active # unused delay slot
and t0,t1
bnez t0,handle_bottom_half
diff --git a/arch/mips/kernel/fpe.c b/arch/mips/kernel/fpe.c
new file mode 100644
index 000000000..46ff43bb4
--- /dev/null
+++ b/arch/mips/kernel/fpe.c
@@ -0,0 +1,55 @@
+/*
+ * The real floating point exception handler. While it doesn't really
+ * make sense to have this in a module, it makes debugging of this code
+ * in the kernel space a lot easier. So far this handler in the released
+ * kernel source is just a dummy.
+ *
+ * Copyright (C) 1997 Ralf Baechle
+ *
+ * $Id:$
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/branch.h>
+#include <asm/ptrace.h>
+
+MODULE_AUTHOR("Ralf Baechle <ralf@gnu.ai.mit.edu>");
+MODULE_DESCRIPTION("Experimental floating point exception handler");
+MODULE_SUPPORTED_DEVICE("MIPS FPU");
+
+static void do_fpe(struct pt_regs *regs, unsigned int fcr31)
+{
+ lock_kernel();
+#ifdef CONF_DEBUG_EXCEPTIONS
+ show_regs(regs);
+#endif
+ printk("Caught floating exception at epc == %08lx, fcr31 == %08x\n",
+ regs->cp0_epc, fcr31);
+ if (compute_return_epc(regs))
+ goto out;
+ force_sig(SIGFPE, current);
+out:
+ unlock_kernel();
+}
+
+/*
+ * For easier experimentation we never increment/decrement
+ * the module useable counter.
+ */
+int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
+int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
+
+int init_module(void)
+{
+ return register_fpe(do_fpe);
+}
+
+void cleanup_module(void)
+{
+ unregister_fpe(do_fpe);
+}
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index b2d112373..89ff7a3b0 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -1,17 +1,10 @@
/*
- * linux/arch/mips/kernel/irq.c
+ * Code to handle x86 style IRQs plus some generic interrupt stuff.
*
- * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994, 1995, 1996, 1997 Ralf Baechle
*
- * This file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
- * instead of just grabbing them. Thus setups with different IRQ numbers
- * shouldn't result in any weird surprises, and installing new handlers
- * should be easier.
- *
- * Mips support by Ralf Baechle and Andreas Busse
- *
- * $Id: irq.c,v 1.2 1997/07/01 08:59:07 ralf Exp $
+ * $Id: irq.c,v 1.4 1997/09/11 20:35:50 ralf Exp $
*/
#include <linux/config.h>
#include <linux/errno.h>
@@ -30,13 +23,9 @@
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/jazz.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <asm/vector.h>
-#ifdef CONFIG_SGI
-#include <asm/sgialib.h>
-#endif
unsigned char cache_21 = 0xff;
unsigned char cache_A1 = 0xff;
@@ -51,9 +40,6 @@ unsigned long spurious_count = 0;
static inline void mask_irq(unsigned int irq_nr)
{
unsigned char mask;
-
- if (irq_nr >= 16)
- return;
mask = 1 << (irq_nr & 7);
if (irq_nr < 8) {
@@ -69,9 +55,6 @@ static inline void unmask_irq(unsigned int irq_nr)
{
unsigned char mask;
- if (irq_nr >= 16)
- return;
-
mask = ~(1 << (irq_nr & 7));
if (irq_nr < 8) {
cache_21 &= mask;
@@ -139,13 +122,6 @@ int get_irq_list(char *buf)
atomic_t __mips_bh_counter;
-#ifdef __SMP__
-#error Send superfluous SMP boxes to ralf@uni-koblenz.de
-#else
-#define irq_enter(cpu, irq) (++local_irq_count[cpu])
-#define irq_exit(cpu, irq) (--local_irq_count[cpu])
-#endif
-
/*
* do_IRQ handles IRQ's that have been installed without the
* SA_INTERRUPT flag: it uses the full signal-handling return
@@ -255,7 +231,7 @@ int request_irq(unsigned int irq,
int retval;
struct irqaction * action;
- if (irq > 31)
+ if (irq >= 32)
return -EINVAL;
if (!handler)
return -EINVAL;
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index d6657ac89..83712649c 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -7,7 +7,7 @@
*
* Copyright (C) 1996, 1997 by Ralf Baechle
*
- * $Id: mips_ksyms.c,v 1.2 1997/07/26 19:31:40 ralf Exp $
+ * $Id: mips_ksyms.c,v 1.2 1997/07/29 03:58:54 ralf Exp $
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -71,3 +71,19 @@ EXPORT_SYMBOL(port_base);
#ifdef CONFIG_SGI
EXPORT_SYMBOL(hpc3c0);
#endif
+
+/*
+ * Kernel hacking ...
+ */
+#include <asm/branch.h>
+#include <linux/sched.h>
+
+int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
+int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31));
+
+#ifdef CONFIG_MIPS_FPE_MODULE
+EXPORT_SYMBOL(force_sig);
+EXPORT_SYMBOL(__compute_return_epc);
+EXPORT_SYMBOL(register_fpe);
+EXPORT_SYMBOL(unregister_fpe);
+#endif
diff --git a/arch/mips/kernel/pci.c b/arch/mips/kernel/pci.c
index 5e71233af..25ea56fdd 100644
--- a/arch/mips/kernel/pci.c
+++ b/arch/mips/kernel/pci.c
@@ -82,32 +82,6 @@ int pcibios_find_class (unsigned int class_code, unsigned short index,
return PCIBIOS_DEVICE_NOT_FOUND;
}
-const char *pcibios_strerror (int error)
-{
- static char buf[80];
-
- switch (error) {
- case PCIBIOS_SUCCESSFUL:
- return "SUCCESSFUL";
-
- case PCIBIOS_FUNC_NOT_SUPPORTED:
- return "FUNC_NOT_SUPPORTED";
-
- case PCIBIOS_BAD_VENDOR_ID:
- return "SUCCESSFUL";
-
- case PCIBIOS_DEVICE_NOT_FOUND:
- return "DEVICE_NOT_FOUND";
-
- case PCIBIOS_BAD_REGISTER_NUMBER:
- return "BAD_REGISTER_NUMBER";
-
- default:
- sprintf (buf, "UNKNOWN RETURN 0x%x", error);
- return buf;
- }
-}
-
/*
* The functions below are machine specific and must be reimplented for
* each PCI chipset configuration. We just run the hook to the machine
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 97a11abc4..b5a5a4428 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -59,12 +59,15 @@ repeat:
goto repeat;
}
page = pte_page(*pgtable);
-/* this is a hack for non-kernel-mapped video buffers and similar */
+ /* This is a hack for non-kernel-mapped video buffers and similar */
if (MAP_NR(page) >= MAP_NR(high_memory))
return 0;
page += addr & ~PAGE_MASK;
+ /* We can't use flush_page_to_ram() since we're running in
+ * another context ...
+ */
+ flush_cache_all();
retval = *(unsigned long *) page;
- flush_page_to_ram(page);
return retval;
}
@@ -117,14 +120,17 @@ repeat:
handle_mm_fault(tsk, vma, addr, 1);
goto repeat;
}
-/* this is a hack for non-kernel-mapped video buffers and similar */
- flush_cache_page(vma, addr);
- if (MAP_NR(page) < MAP_NR(high_memory)) {
- *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
+ /* This is a hack for non-kernel-mapped video buffers and similar */
+ if (MAP_NR(page) < MAP_NR(high_memory))
+ flush_cache_page(vma, addr);
+ *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
+ if (MAP_NR(page) < MAP_NR(high_memory))
flush_page_to_ram(page);
- }
-/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
-/* this should also re-instate whatever read-only mode there was before */
+ /*
+ * We're bypassing pagetables, so we have to set the dirty bit
+ * ourselves this should also re-instate whatever read-only mode
+ * there was before
+ */
set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
flush_tlb_page(vma, addr);
}
@@ -369,7 +375,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case 5:
tmp = child->tss.fpu.hard.control;
break;
- case 6:
+ case 6: /* implementation / version register */
tmp = 0;
break;
default:
diff --git a/arch/mips/kernel/r4k_misc.S b/arch/mips/kernel/r4k_misc.S
index 0cbc2222f..090b3109f 100644
--- a/arch/mips/kernel/r4k_misc.S
+++ b/arch/mips/kernel/r4k_misc.S
@@ -1,10 +1,12 @@
-/* $Id: r4k_misc.S,v 1.8 1996/07/22 22:32:52 dm Exp $
+/*
* r4k_misc.S: Misc. exception handling code for r4k.
*
* Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
*
* Multi-cpu abstraction and reworking:
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * $Id: r4k_misc.S,v 1.2 1997/06/09 06:20:52 ralf Exp $
*/
#include <asm/asm.h>
#include <asm/current.h>
@@ -21,7 +23,7 @@
#include <asm/regdef.h>
#include <asm/stackframe.h>
-#define NOTLB_OPTIMIZE /* If you are paranoid, define this. */
+#undef NOTLB_OPTIMIZE /* If you are paranoid, define this. */
/* ABUSE of CPP macros 101. */
@@ -108,10 +110,32 @@
.set noreorder
.set mips3
- /* Note for many R4k variants tlb probes cannot be executed out
+/*
+ * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0:
+ * 2. A timing hazard exists for the TLBP instruction.
+ *
+ * stalling_instruction
+ * TLBP
+ *
+ * The JTLB is being read for the TLBP throughout the stall generated by the
+ * previous instruction. This is not really correct as the stalling instruction
+ * can modify the address used to access the JTLB. The failure symptom is that
+ * the TLBP instruction will use an address created for the stalling instruction
+ * and not the address held in C0_ENHI and thus report the wrong results.
+ *
+ * The software work-around is to not allow the instruction preceding the TLBP
+ * to stall - make it an NOP or some other instruction guaranteed not to stall.
+ *
+ * Errata 2 will not be fixed. This errata is also on the R5000.
+ *
+ * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
+ */
+#define R5K_HAZARD nop
+
+ /*
+ * Note for many R4k variants tlb probes cannot be executed out
* of the instruction cache else you get bogus results.
*/
-
.align 5
NESTED(r4k_handle_tlbl, PT_SIZE, sp)
.set noat
@@ -120,6 +144,7 @@ invalid_tlbl:
#ifndef NOTLB_OPTIMIZE
/* Test present bit in entry. */
LOAD_PTE(k0, k1)
+ R5K_HAZARD
tlbp
PTE_PRESENT(k0, k1, nopage_tlbl)
PTE_MAKEVALID(k0, k1)
@@ -141,6 +166,7 @@ nopage_tlbl:
.set noat
#ifndef NOTLB_OPTIMIZE
LOAD_PTE(k0, k1)
+ R5K_HAZARD
tlbp # find faulting entry
PTE_WRITABLE(k0, k1, nopage_tlbs)
PTE_MAKEWRITE(k0, k1)
@@ -162,6 +188,7 @@ nopage_tlbs:
.set noat
#ifndef NOTLB_OPTIMIZE
LOAD_PTE(k0, k1)
+ R5K_HAZARD
tlbp # find faulting entry
andi k0, k0, _PAGE_WRITE
beqz k0, nowrite_mod
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 1b00365a6..3ebf269f5 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -4,6 +4,8 @@
* Copyright (C) 1995 Linus Torvalds
* Copyright (C) 1995, 1996 Ralf Baechle
* Copyright (C) 1996 Stoned Elipot
+ *
+ * $Id:$
*/
#include <linux/config.h>
#include <linux/errno.h>
@@ -168,9 +170,10 @@ __initfunc(void setup_arch(char **cmdline_p,
break;
#endif
#if defined(CONFIG_MIPS_ARC)
-/* Perhaps arch/mips/deskstation should be renommed arch/mips/arc.
- * For now CONFIG_MIPS_ARC means DeskStation. -Stoned.
- */
+ /*
+ * Perhaps arch/mips/deskstation should be renamed to arch/mips/arc.
+ * For now CONFIG_MIPS_ARC means DeskStation. -Stoned.
+ */
case MACH_GROUP_ARC:
deskstation_setup();
break;
@@ -196,9 +199,6 @@ __initfunc(void setup_arch(char **cmdline_p,
atag = bi_TagFind(tag_drive_info);
memcpy(&drive_info, TAGVALPTR(atag), atag->size);
-#if 0
- aux_device_present = AUX_DEVICE_INFO;
-#endif
memory_end = mips_memory_upper;
/*
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 34ed87fb6..b2e76e8a7 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -4,7 +4,7 @@
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1994, 1995, 1996 Ralf Baechle
*
- * $Id: signal.c,v 1.3 1997/06/25 20:08:49 ralf Exp $
+ * $Id: signal.c,v 1.4 1997/08/06 19:15:07 miguel Exp $
*/
#include <linux/config.h>
#include <linux/sched.h>
@@ -42,7 +42,7 @@ asmlinkage int sys_sigsuspend(struct pt_regs *regs)
unsigned long mask;
sigset_t *uset, set;
- uset = (sigset_t *)(long) regs->regs[4];
+ uset = (sigset_t *) regs->regs[4];
if (get_user(set, uset))
return -EFAULT;
@@ -392,3 +392,13 @@ asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler)
{
return -ENOSYS;
}
+
+/*
+ * Compatibility syscall. Can be replaced in libc.
+ */
+asmlinkage int sys_pause(void)
+{
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ return -ERESTARTNOHAND;
+}
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index f1b117a63..0a190e3ab 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -21,6 +21,7 @@
#include <linux/smp_lock.h>
#include <linux/mman.h>
#include <linux/sched.h>
+#include <linux/utsname.h>
#include <linux/unistd.h>
#include <asm/branch.h>
#include <asm/ptrace.h>
@@ -149,6 +150,43 @@ out:
}
/*
+ * Compacrapability ...
+ */
+asmlinkage int sys_uname(struct old_utsname * name)
+{
+ if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+ return 0;
+ return -EFAULT;
+}
+
+/*
+ * Compacrapability ...
+ */
+asmlinkage int sys_olduname(struct oldold_utsname * name)
+{
+ int error;
+
+ if (!name)
+ return -EFAULT;
+ if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
+ return -EFAULT;
+
+ error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
+ error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
+ error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+ error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
+ error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+ error -= __put_user(0,name->release+__OLD_UTS_LEN);
+ error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+ error -= __put_user(0,name->version+__OLD_UTS_LEN);
+ error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+ error = __put_user(0,name->machine+__OLD_UTS_LEN);
+ error = error ? -EFAULT : 0;
+
+ return error;
+}
+
+/*
* Do the indirect syscall syscall.
* Don't care about kernel locking; the actual syscall will do it.
*/
diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h
index fd1b39bca..3232af01c 100644
--- a/arch/mips/kernel/syscalls.h
+++ b/arch/mips/kernel/syscalls.h
@@ -7,7 +7,7 @@
*
* Copyright (C) 1995, 1996, 1997 by Ralf Baechle
*
- * $Id: syscalls.h,v 1.5 1997/07/20 14:57:27 ralf Exp $
+ * $Id: syscalls.h,v 1.6 1997/08/06 19:15:08 miguel Exp $
*/
/*
@@ -35,7 +35,7 @@ SYS(sys_time, 1)
SYS(sys_mknod, 3)
SYS(sys_chmod, 2) /* 4015 */
SYS(sys_chown, 3)
-SYS(sys_break, 0)
+SYS(sys_ni_syscall, 0)
SYS(sys_stat, 2)
SYS(sys_lseek, 3)
SYS(sys_getpid, 0) /* 4020 */
@@ -49,11 +49,11 @@ SYS(sys_alarm, 1)
SYS(sys_fstat, 2)
SYS(sys_pause, 0)
SYS(sys_utime, 2) /* 4030 */
-SYS(sys_stty, 0)
-SYS(sys_gtty, 0)
+SYS(sys_ni_syscall, 0)
+SYS(sys_ni_syscall, 0)
SYS(sys_access, 2)
SYS(sys_nice, 1)
-SYS(sys_ftime, 0) /* 4035 */
+SYS(sys_ni_syscall, 0) /* 4035 */
SYS(sys_sync, 0)
SYS(sys_kill, 2)
SYS(sys_rename, 2)
@@ -62,7 +62,7 @@ SYS(sys_rmdir, 1) /* 4040 */
SYS(sys_dup, 1)
SYS(sys_pipe, 0)
SYS(sys_times, 1)
-SYS(sys_prof, 0)
+SYS(sys_ni_syscall, 0)
SYS(sys_brk, 1) /* 4045 */
SYS(sys_setgid, 1)
SYS(sys_getgid, 0)
@@ -70,13 +70,13 @@ SYS(sys_signal, 2)
SYS(sys_geteuid, 0)
SYS(sys_getegid, 0) /* 4050 */
SYS(sys_acct, 0)
-SYS(sys_phys, 0)
-SYS(sys_lock, 0)
+SYS(sys_ni_syscall, 0)
+SYS(sys_ni_syscall, 0)
SYS(sys_ioctl, 3)
SYS(sys_fcntl, 3) /* 4055 */
-SYS(sys_mpx, 2)
+SYS(sys_ni_syscall, 2)
SYS(sys_setpgid, 2)
-SYS(sys_ulimit, 0)
+SYS(sys_ni_syscall, 0)
SYS(sys_olduname, 1)
SYS(sys_umask, 1) /* 4060 */
SYS(sys_chroot, 1)
@@ -116,7 +116,7 @@ SYS(sys_fchmod, 2)
SYS(sys_fchown, 3) /* 4095 */
SYS(sys_getpriority, 2)
SYS(sys_setpriority, 3)
-SYS(sys_profil, 0)
+SYS(sys_ni_syscall, 0)
SYS(sys_statfs, 2)
SYS(sys_fstatfs, 2) /* 4100 */
SYS(sys_ioperm, 3)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index b7ceea080..c38fcf549 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -12,8 +12,6 @@
* to mainly kill the offending process (probably by giving it a signal,
* but possibly by killing it outright if necessary).
*
- * FIXME: This is the place for a fpu emulator.
- *
* Modified for R3000 by Paul M. Antoine, 1995, 1996
*/
#include <linux/config.h>
@@ -228,8 +226,34 @@ out:
unlock_kernel();
}
+#ifdef CONFIG_MIPS_FPE_MODULE
+static void (*fpe_handler)(struct pt_regs *regs, unsigned int fcr31);
+
+/*
+ * Register_fpe/unregister_fpe are for debugging purposes only. To make
+ * this hack work a bit better there is no error checking.
+ */
+int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31))
+{
+ fpe_handler = handler;
+ return 0;
+}
+
+int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31))
+{
+ fpe_handler = NULL;
+ return 0;
+}
+#endif
+
void do_fpe(struct pt_regs *regs, unsigned int fcr31)
{
+#ifdef CONFIG_MIPS_FPE_MODULE
+ if (fpe_handler != NULL) {
+ fpe_handler(regs, fcr31);
+ return;
+ }
+#endif
lock_kernel();
#ifdef CONF_DEBUG_EXCEPTIONS
show_regs(regs);
diff --git a/arch/mips/lib/copy_user.S b/arch/mips/lib/copy_user.S
index 30fa6d6e9..a7fdc74e5 100644
--- a/arch/mips/lib/copy_user.S
+++ b/arch/mips/lib/copy_user.S
@@ -1,13 +1,15 @@
/*
- * arch/mips/mips1/memcpy.S
+ * arch/mips/lib/copy_user.S
*
* 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 by Ralf Baechle
+ * Copyright (c) 1996, 1997 by Ralf Baechle
*
- * Less stupid memcpy/user_copy implementation for 32 bit MIPS CPUs.
+ * Less stupid user_copy implementation for 32 bit MIPS CPUs.
+ *
+ * $Id: copy_user.S,v 1.2 1997/08/11 04:26:12 ralf Exp $
*/
#include <asm/asm.h>
#include <asm/regdef.h>
@@ -37,8 +39,8 @@ not_even_the_same_alignment:
andi v1,3
sltu t0,v0,v1
MOVN(v1,v0,t0)
- beqz v1,3f # -> finished
- LONG_ADDU v1,a0 # delay slot
+ beqz v1,src_aligned
+ LONG_ADDU v1,a0
1: lb $1,(a1)
EX(1b, fault)
LONG_ADDIU a1,1
@@ -46,20 +48,22 @@ not_even_the_same_alignment:
EX(2b, fault)
LONG_ADDIU a0,1
bne a0,v1,1b
- LONG_SUBU v0,1 # delay slot
-3:
+ LONG_SUBU v0,1
+src_aligned:
+
/*
* Ok. We've fixed the alignment of the copy src for this case.
* Now let's copy in the usual BLOCK_SIZE byte blocks using unaligned
* stores.
* XXX Align the destination address. This is better if the __copy_user
* encounters an access fault because we never have to deal with an
- * only partially modified destination word.
+ * only partially modified destination word. This is required to
+ * keep the semantics of the result of copy_*_user().
*/
ori v1,v0,BLOCK_SIZE-1
xori v1,BLOCK_SIZE-1
beqz v1,copy_left_over
- nop # delay slot
+ nop
LONG_SUBU v0,v1
LONG_ADDU v1,a0
@@ -81,16 +85,16 @@ not_even_the_same_alignment:
UEX(2b, fault_plus_12)
LONG_ADDIU a0,BLOCK_SIZE
bne a0,v1,1b
- LONG_ADDIU a1,BLOCK_SIZE # delay slot
+ LONG_ADDIU a1,BLOCK_SIZE
9:
b copy_left_over # < BLOCK_SIZE bytes left
- nop # delay slot
+ nop
/* ---------------------------------------------------------------------- */
not_w_aligned:
/*
- * Ok, src or destination are not 8-byte aligned.
+ * Ok, src or destination are not 4-byte aligned.
* Try to fix that. Do at least both addresses have the same alignment?
*/
xor t0,a0,a1
@@ -107,8 +111,8 @@ not_w_aligned:
andi v1,3
sltu t0,v0,v1
MOVN(v1,v0,t0)
- beqz v1,align4 # -> finished
- LONG_ADDU v1,a0 # delay slot
+ beqz v1,__copy_user
+ LONG_ADDU v1,a0
1: lb $1,(a1)
EX(1b, fault)
LONG_ADDIU a1,1
@@ -116,23 +120,23 @@ not_w_aligned:
EX(2b, fault)
LONG_ADDIU a0,1
bne a0,v1,1b
- LONG_SUBU v0,1 # delay slot
+ LONG_SUBU v0,1
b align4
- nop # delay slot
+ nop
/* ---------------------------------------------------------------------- */
LEAF(__copy_user)
or t1,a0,a1
andi t1,3
- bnez t1,not_w_aligned
- move v0,a2 # delay slot
+ bnez t1,not_w_aligned # not word alignment
+ move v0,a2
align4:
ori v1,v0,BLOCK_SIZE-1
xori v1,BLOCK_SIZE-1
beqz v1,copy_left_over
- nop # delay slot
+ nop
LONG_SUBU v0,v1
LONG_ADDU v1,a0
@@ -154,7 +158,7 @@ align4:
EX(2b, fault_plus_12)
LONG_ADDIU a0,BLOCK_SIZE
bne a0,v1,1b
- LONG_ADDIU a1,BLOCK_SIZE # delay slot
+ LONG_ADDIU a1,BLOCK_SIZE
9:
/*
@@ -162,7 +166,7 @@ align4:
*/
copy_left_over:
beqz v0,3f
- nop # delay slot
+ nop
1: lb $1,(a1)
EX(1b, fault)
LONG_ADDIU a1,1
@@ -170,9 +174,11 @@ copy_left_over:
EX(2b, fault)
LONG_SUBU v0,1
bnez v0,1b
- LONG_ADDIU a0,1
-3: jr ra
- nop # delay slot
+ LONG_ADDIU a0,1
+3:
+
+done: jr ra
+ nop
END(__copy_user)
.set at
@@ -193,14 +199,3 @@ fault_plus_8: LONG_ADDIU v0,8
jr ra
fault_plus_12: LONG_ADDIU v0,12
jr ra
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * For now we use __copy_user for __memcpy, too. This is effizient (one
- * instruction penatly) and smaller but adds unwanted error checking we don't
- * need. This hopefully doesn't cover any bugs. The memcpy() wrapper in
- * <asm/string.h> takes care of the return value in a way GCC can optimize.
- */
- .globl __memcpy
-__memcpy = __copy_user
diff --git a/arch/mips/mm/loadmmu.c b/arch/mips/mm/loadmmu.c
index 70597201a..c4b4258b7 100644
--- a/arch/mips/mm/loadmmu.c
+++ b/arch/mips/mm/loadmmu.c
@@ -1,7 +1,9 @@
-/* $Id: loadmmu.c,v 1.1.1.1 1997/06/01 03:16:38 ralf Exp $
+/*
* loadmmu.c: Setup cpu/cache specific function ptrs at boot time.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * $Id: loadmmu.c,v 1.1.1.1 1997/06/01 03:16:38 ralf Exp $
*/
#include <linux/kernel.h>
@@ -76,6 +78,7 @@ void loadmmu(void)
case CPU_R4700:
case CPU_R5000:
case CPU_R5000A:
+ case CPU_NEVADA:
printk("Loading R4000 MMU routines.\n");
ld_mmu_r4xx0();
break;
diff --git a/arch/mips/mm/r4xx0.c b/arch/mips/mm/r4xx0.c
index 2b32ca455..2586a961c 100644
--- a/arch/mips/mm/r4xx0.c
+++ b/arch/mips/mm/r4xx0.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: r4xx0.c,v 1.5 1997/07/29 22:54:52 tsbogend Exp $
+ * $Id: r4xx0.c,v 1.6 1997/08/06 19:15:10 miguel Exp $
*/
#include <linux/config.h>
@@ -39,7 +39,16 @@ static scache_size, sc_lsize; /* Again, in bytes */
#undef DEBUG_CACHE
/*
- * Zero an entire page.
+ * On processors with QED R4600 style two set assosicative cache
+ * this is the bit which selects the way in the cache for the
+ * indexed cachops.
+ */
+#define waybit 0x2000
+
+/*
+ * Zero an entire page. We have three flavours of the routine available.
+ * One for CPU with 16byte, with 32byte cachelines plus a special version
+ * with nops which handles the buggy R4600 v1.x.
*/
static void r4k_clear_page_d16(unsigned long page)
@@ -1465,11 +1474,8 @@ static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma,
*/
page = (KSEG0 + (page & (dcache_size - 1)));
blast_dcache16_page_indexed(page);
- blast_dcache16_page_indexed(page ^ 0x2000);
- if(text) {
+ if(text)
blast_icache16_page_indexed(page);
- blast_icache16_page_indexed(page ^ 0x2000);
- }
}
out:
restore_flags(flags);
@@ -1583,10 +1589,10 @@ static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma,
*/
page = (KSEG0 + (page & (dcache_size - 1)));
blast_dcache32_page_indexed(page);
- blast_dcache32_page_indexed(page ^ 0x2000);
+ blast_dcache32_page_indexed(page ^ waybit);
if(text) {
blast_icache32_page_indexed(page);
- blast_icache32_page_indexed(page ^ 0x2000);
+ blast_icache32_page_indexed(page ^ waybit);
}
}
out:
@@ -1776,7 +1782,6 @@ static void r4k_flush_page_to_ram_d32i32_r4600(unsigned long page)
unsigned long flags;
#ifdef DEBUG_CACHE
- /* #if 1 */
printk("r4600_cram[%08lx]", page);
#endif
/*
@@ -1786,7 +1791,6 @@ static void r4k_flush_page_to_ram_d32i32_r4600(unsigned long page)
save_and_cli(flags);
blast_dcache32_page(page);
- blast_dcache32_page(page ^ 0x2000);
#ifdef CONFIG_SGI
{
unsigned long tmp1, tmp2;
@@ -1824,6 +1828,7 @@ static void r4k_flush_page_to_ram_d32i32_r4600(unsigned long page)
static void r4k_flush_cache_sigtramp(unsigned long addr)
{
+ /* XXX protect like uaccess.h loads/stores */
addr &= ~(dc_lsize - 1);
__asm__ __volatile__("nop;nop;nop;nop");
flush_dcache_line(addr);
@@ -2534,7 +2539,7 @@ void ld_mmu_r4xx0(void)
unsigned long cfg = read_32bit_cp0_register(CP0_CONFIG);
int sc_present = 0;
- printk("CPU REVISION IS: %08x\n", read_32bit_cp0_register(CP0_PRID));
+ printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID));
probe_icache(cfg);
probe_dcache(cfg);
@@ -2546,7 +2551,6 @@ void ld_mmu_r4xx0(void)
case CPU_R4400PC:
case CPU_R4400SC:
case CPU_R4400MC:
-try_again:
probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
sc_present = probe_scache_kseg1(cfg);
break;
@@ -2554,38 +2558,40 @@ try_again:
case CPU_R4600:
case CPU_R4640:
case CPU_R4700:
- case CPU_R5000:
+ case CPU_R5000: /* XXX: We don't handle the true R5000 SCACHE */
+ case CPU_NEVADA:
probe_scache_kseg1 = (probe_func_t)
(KSEG1ADDR(&probe_scache_eeprom));
sc_present = probe_scache_eeprom(cfg);
- /* Try using tags if eeprom give us bogus data. */
- if(sc_present == -1)
- goto try_again;
+ /* Try using tags if eeprom gives us bogus data. */
+ if(sc_present == -1) {
+ probe_scache_kseg1 =
+ (probe_func_t) (KSEG1ADDR(&probe_scache));
+ sc_present = probe_scache_kseg1(cfg);
+ }
break;
};
- if(!sc_present) {
- /* Lacks secondary cache. */
- setup_noscache_funcs();
+ if(sc_present == 1
+ && (mips_cputype == CPU_R4000SC
+ || mips_cputype == CPU_R4000MC
+ || mips_cputype == CPU_R4400SC
+ || mips_cputype == CPU_R4400MC)) {
+ /* Has a true secondary cache. */
+ setup_scache_funcs();
} else {
- /* Has a secondary cache. */
- if(mips_cputype != CPU_R4600 &&
- mips_cputype != CPU_R4640 &&
- mips_cputype != CPU_R4700 &&
- mips_cputype != CPU_R5000) {
- setup_scache_funcs();
- } else {
- setup_noscache_funcs();
- if((mips_cputype != CPU_R5000)) {
- flush_cache_page =
- r4k_flush_cache_page_d32i32_r4600;
- flush_page_to_ram =
- r4k_flush_page_to_ram_d32i32_r4600;
- }
+ /* Lacks true secondary cache. */
+ setup_noscache_funcs();
+ if((mips_cputype != CPU_R5000)) { /* XXX */
+ flush_cache_page =
+ r4k_flush_cache_page_d32i32_r4600;
+ flush_page_to_ram =
+ r4k_flush_page_to_ram_d32i32_r4600;
}
}
+ /* XXX Handle true second level cache w/ split I/D */
flush_cache_sigtramp = r4k_flush_cache_sigtramp;
flush_tlb_all = r4k_flush_tlb_all;
diff --git a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c
index 2d23372ae..343a71f9e 100644
--- a/arch/mips/sgi/kernel/indy_int.c
+++ b/arch/mips/sgi/kernel/indy_int.c
@@ -4,7 +4,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: indy_int.c,v 1.2 1997/07/01 09:00:58 ralf Exp $
+ * $Id: indy_int.c,v 1.3 1997/08/26 04:34:55 miguel Exp $
*/
#include <linux/config.h>
@@ -260,13 +260,6 @@ int get_irq_list(char *buf)
atomic_t __mips_bh_counter;
-#ifdef __SMP__
-#error Send superfluous SMP boxes to ralf@uni-koblenz.de
-#else
-#define irq_enter(cpu, irq) (++local_irq_count[cpu])
-#define irq_exit(cpu, irq) (--local_irq_count[cpu])
-#endif
-
/*
* do_IRQ handles IRQ's that have been installed without the
* SA_INTERRUPT flag: it uses the full signal-handling return
@@ -434,7 +427,7 @@ void indy_local0_irqdispatch(struct pt_regs *regs)
struct irqaction *action;
unsigned char mask = ioc_icontrol->istat0;
unsigned char mask2 = 0;
- int irq;
+ int irq, cpu = smp_processor_id();;
mask &= ioc_icontrol->imask0;
if(mask & ISTAT0_LIO2) {
@@ -446,13 +439,11 @@ void indy_local0_irqdispatch(struct pt_regs *regs)
irq = lc0msk_to_irqnr[mask];
action = local_irq_action[irq];
}
-#if 0
- printk("local0_dispatch: got irq %d mask %2x mask2 %2x\n",
- irq, mask, mask2);
- prom_getchar();
-#endif
+
+ irq_enter(cpu, irq);
kstat.interrupts[irq + 16]++;
action->handler(irq, action->dev_id, regs);
+ irq_exit(cpu, irq);
}
void indy_local1_irqdispatch(struct pt_regs *regs)
@@ -460,7 +451,7 @@ void indy_local1_irqdispatch(struct pt_regs *regs)
struct irqaction *action;
unsigned char mask = ioc_icontrol->istat1;
unsigned char mask2 = 0;
- int irq;
+ int irq, cpu = smp_processor_id();;
mask &= ioc_icontrol->imask1;
if(mask & ISTAT1_LIO3) {
@@ -473,23 +464,24 @@ void indy_local1_irqdispatch(struct pt_regs *regs)
irq = lc1msk_to_irqnr[mask];
action = local_irq_action[irq];
}
-#if 0
- printk("local1_dispatch: got irq %d mask %2x mask2 %2x\n",
- irq, mask, mask2);
- prom_getchar();
-#endif
+ irq_enter(cpu, irq);
kstat.interrupts[irq + 24]++;
action->handler(irq, action->dev_id, regs);
+ irq_exit(cpu, irq);
}
void indy_buserror_irq(struct pt_regs *regs)
{
- kstat.interrupts[6]++;
+ int cpu = smp_processor_id();
+ int irq = 6;
+
+ irq_enter(cpu, irq);
+ kstat.interrupts[irq]++;
printk("Got a bus error IRQ, shouldn't happen yet\n");
show_regs(regs);
printk("Spinning...\n");
- while(1)
- ;
+ while(1);
+ irq_exit(cpu, irq);
}
/* Misc. crap just to keep the kernel linking... */
diff --git a/arch/mips/sgi/kernel/indy_timer.c b/arch/mips/sgi/kernel/indy_timer.c
index 43c1c76c6..d0ba84929 100644
--- a/arch/mips/sgi/kernel/indy_timer.c
+++ b/arch/mips/sgi/kernel/indy_timer.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: indy_timer.c,v 1.2 1997/06/28 23:27:29 ralf Exp $
+ * $Id: indy_timer.c,v 1.2 1997/07/01 09:00:59 ralf Exp $
*/
#include <linux/errno.h>
@@ -101,10 +101,12 @@ static long last_rtc_update = 0;
void indy_timer_interrupt(struct pt_regs *regs)
{
+ int irq = 7;
+
/* Ack timer and compute new compare. */
r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
ack_r4ktimer(r4k_cur);
- kstat.interrupts[7]++;
+ kstat.interrupts[irq]++;
do_timer(regs);
/* We update the Dallas time of day approx. every 11 minutes,
@@ -272,10 +274,15 @@ void indy_timer_init(void)
void indy_8254timer_irq(void)
{
- kstat.interrupts[4]++;
+ int cpu = smp_processor_id();
+ int irq = 4;
+
+ irq_enter(cpu, irq);
+ kstat.interrupts[irq]++;
printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
prom_getchar();
prom_imode();
+ irq_exit(cpu, irq);
}
void do_gettimeofday(struct timeval *tv)