diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-09-12 01:29:55 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-09-12 01:29:55 +0000 |
commit | 545f435ebcfd94a1e7c20b46efe81b4d6ac4e698 (patch) | |
tree | e9ce4bc598d06374bda906f18365984bf22a526a /arch/mips | |
parent | 4291a610eef89d0d5c69d9a10ee6560e1aa36c74 (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/Makefile | 10 | ||||
-rw-r--r-- | arch/mips/config.in | 35 | ||||
-rw-r--r-- | arch/mips/dec/decstation.S | 8 | ||||
-rw-r--r-- | arch/mips/dec/int-handler.S | 8 | ||||
-rw-r--r-- | arch/mips/defconfig | 10 | ||||
-rw-r--r-- | arch/mips/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/mips/kernel/entry.S | 17 | ||||
-rw-r--r-- | arch/mips/kernel/fpe.c | 55 | ||||
-rw-r--r-- | arch/mips/kernel/irq.c | 34 | ||||
-rw-r--r-- | arch/mips/kernel/mips_ksyms.c | 18 | ||||
-rw-r--r-- | arch/mips/kernel/pci.c | 26 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace.c | 26 | ||||
-rw-r--r-- | arch/mips/kernel/r4k_misc.S | 35 | ||||
-rw-r--r-- | arch/mips/kernel/setup.c | 12 | ||||
-rw-r--r-- | arch/mips/kernel/signal.c | 14 | ||||
-rw-r--r-- | arch/mips/kernel/syscall.c | 38 | ||||
-rw-r--r-- | arch/mips/kernel/syscalls.h | 22 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 28 | ||||
-rw-r--r-- | arch/mips/lib/copy_user.S | 65 | ||||
-rw-r--r-- | arch/mips/mm/loadmmu.c | 5 | ||||
-rw-r--r-- | arch/mips/mm/r4xx0.c | 72 | ||||
-rw-r--r-- | arch/mips/sgi/kernel/indy_int.c | 38 | ||||
-rw-r--r-- | arch/mips/sgi/kernel/indy_timer.c | 13 |
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) |