diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-12-01 17:57:09 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-12-01 17:57:09 +0000 |
commit | a62a0f262e0179df8c632f529c95abf54ef78332 (patch) | |
tree | 80e6a7a7d407d08e218332bb3fcccdaf9f28fcc1 /arch/mips | |
parent | fd095d09f2d475dc2e8599b1b8bae1cd65e91685 (diff) |
Part #2 merging back my changes ...
Diffstat (limited to 'arch/mips')
52 files changed, 932 insertions, 737 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index b1df65c86..2624d2d0c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -13,7 +13,7 @@ # Copyright (C) 1994, 1995, 1996 by Ralf Baechle # DECStation modifications by Paul M. Antoine, 1996 # -# $Id: Makefile,v 1.7 1997/08/30 04:51:27 ralf Exp $ +# $Id: Makefile,v 1.9 1997/09/19 08:34:54 ralf Exp $ # # @@ -82,6 +82,9 @@ endif ifdef CONFIG_CPU_R5000 CFLAGS := $(CFLAGS) -mcpu=r8000 -mips2 endif +ifdef CONFIG_CPU_NEVADA +CFLAGS := $(CFLAGS) -mcpu=r8000 -mips2 -mmad +endif ifdef CONFIG_CPU_R8000 CFLAGS := $(CFLAGS) -mcpu=r8000 -mips2 endif diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index f632508f0..dd834efd9 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -41,6 +41,7 @@ zdisk: zImage fi dep: + $(CPP) -M *.[cS] > .depend clean: rm -f zImage zImage.tmp mkboot diff --git a/arch/mips/config.in b/arch/mips/config.in index 9e820f29e..e942e1ba1 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -66,6 +66,7 @@ choice 'CPU type' \ R4300 CONFIG_CPU_R4300 \ R4x00 CONFIG_CPU_R4X00 \ R5000 CONFIG_CPU_R5000 \ + R56x0 CONFIG_CPU_NEVADA \ R8000 CONFIG_CPU_R8000 \ R10000 CONFIG_CPU_R10000" R4x00 endmenu @@ -97,7 +98,7 @@ bool 'System V IPC' CONFIG_SYSVIPC bool 'Sysctl support' CONFIG_SYSCTL if [ "$CONFIG_SGI" != "y" ]; then - tristate 'Parallel port support' CONFIG_PNP_PARPORT + tristate 'Parallel port support' CONFIG_PARPORT fi endmenu diff --git a/arch/mips/dec/decstation.S b/arch/mips/dec/decstation.S index 612fcea0b..ebc618a4c 100644 --- a/arch/mips/dec/decstation.S +++ b/arch/mips/dec/decstation.S @@ -15,7 +15,7 @@ * (Paul, you need to fix this file to comply with NAPS. Won't be * too hard - Ralf) * - * $Id:$ + * $Id: decstation.S,v 1.3 1997/09/20 19:20:06 root Exp $ */ #include <asm/asm.h> #include <asm/mipsconfig.h> @@ -257,19 +257,16 @@ loc_floppy: PANIC("Unimplemented loc_floppy handler") /* * Now call the real handler */ -loc_call: la t0,IRQ_vectors # delay slot - - /* +loc_call: /* * Temporarily disable interrupt source */ /* lhu t2,JAZZ_IO_IRQ_ENABLE */ - addu t0,t3 # make ptr to IRQ handler - LOAD_L t0,(t0) and t2,s1 # delay slot /* sh t2,JAZZ_IO_IRQ_ENABLE */ - jalr t0 # call IRQ handler - nor s1,zero,s1 # delay slot + nor s1,zero,s1 + jal do_IRQ # call IRQ handler + move a1,sp /* * Reenable interrupt @@ -278,7 +275,7 @@ loc_call: la t0,IRQ_vectors # delay slot or t2,s1 /* sh t2,JAZZ_IO_IRQ_ENABLE */ - jr v0 + j ret_from_irq nop # delay slot ll_tc3: PANIC("Unimplemented tc3 interrupt handler") @@ -304,19 +301,15 @@ ll_reset: li a0,0 /* * Now call the real handler */ -call_real: la t0,IRQ_vectors # delay slot - - /* +call_real: /* * temporarily disable interrupt */ mfc0 t2,CP0_STATUS and t2,s1 - - addu t0,t3 - LOAD_L t0,(t0) - mtc0 t2,CP0_STATUS # delay slot - jalr t0 - nor s1,zero,s1 # delay slot + mtc0 t2,CP0_STATUS + nor s1,zero,s1 + jal do_IRQ + move a1,sp /* * reenable interrupt @@ -325,8 +318,8 @@ call_real: la t0,IRQ_vectors # delay slot or t2,s1 mtc0 t2,CP0_STATUS - jr v0 - nop # delay slot + j ret_from_irq + nop # delay slot /* * Just for debugging... load a0 with address of the point inside the diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S index 1706dc975..87348b5b1 100644 --- a/arch/mips/dec/int-handler.S +++ b/arch/mips/dec/int-handler.S @@ -12,7 +12,7 @@ * FIXME: still plenty to do in this file, as much of the code hasn't been * modified to suit the DECStation's interrupts. * - * $Id:$ + * $Id: int-handler.S,v 1.3 1997/09/20 19:20:07 root Exp $ */ #include <asm/asm.h> #include <asm/regdef.h> @@ -98,7 +98,7 @@ ll_sw0: li s1,~IE_SW0 PRINT("sw0 received...\n") li t1,1 b call_real - li t3,PTRSIZE # delay slot, re-map to irq level 1 + nop ll_sw1: li s1,~IE_SW1 PANIC("Unimplemented sw1 handler") @@ -108,14 +108,6 @@ loc_sound: PANIC("Unimplemented loc_sound handler") loc_video: PANIC("Unimplemented loc_video handler") loc_scsi: PANIC("Unimplemented loc_scsi handler") -/* - * Ethernet interrupt, remapped to level 15 - * NOTE: Due to a bug somewhere in the kernel I was not able - * to figure out, the PRINT() is necessary. Without this, - * I get a "gfp called nonatomically from interrupt 00000000". - * Only god knows why... Tell me if you find the reason! - * Andy, 6/16/95 - */ loc_ethernet: PANIC("Unimplemented loc_ethernet") /* @@ -148,19 +140,15 @@ loc_floppy: PANIC("Unimplemented loc_floppy handler") /* * Now call the real handler */ -loc_call: la t0,IRQ_vectors # delay slot - - /* +loc_call: /* * Temporarily disable interrupt source */ /* lhu t2,JAZZ_IO_IRQ_ENABLE */ - addu t0,t3 # make ptr to IRQ handler - lw t0,(t0) - and t2,s1 # delay slot + and t2,s1 /* sh t2,JAZZ_IO_IRQ_ENABLE */ - jalr t0 # call IRQ handler - nor s1,zero,s1 # delay slot + jal do_IRQ # call IRQ handler + nor s1,zero,s1 /* * Reenable interrupt @@ -169,7 +157,7 @@ loc_call: la t0,IRQ_vectors # delay slot or t2,s1 /* sh t2,JAZZ_IO_IRQ_ENABLE */ - jr v0 + j ret_from_irq nop # delay slot ll_tc3: PANIC("Unimplemented tc3 interrupt handler") @@ -195,19 +183,15 @@ ll_reset: li a0,0 /* * Now call the real handler */ -call_real: la t0,IRQ_vectors # delay slot - - /* +call_real: /* * temporarily disable interrupt */ mfc0 t2,CP0_STATUS and t2,s1 - addu t0,t3 - lw t0,(t0) - mtc0 t2,CP0_STATUS # delay slot - jalr t0 - nor s1,zero,s1 # delay slot + mtc0 t2,CP0_STATUS + jal do_IRQ + nor s1,zero,s1 /* * reenable interrupt @@ -216,7 +200,7 @@ call_real: la t0,IRQ_vectors # delay slot or t2,s1 mtc0 t2,CP0_STATUS - jr v0 + j ret_from_irq nop # delay slot /* diff --git a/arch/mips/defconfig b/arch/mips/defconfig index ae3ba1f9d..5c94da263 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -25,6 +25,7 @@ CONFIG_PCI=y # CONFIG_CPU_R4300 is not set CONFIG_CPU_R4X00=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 @@ -39,7 +40,7 @@ CONFIG_BINFMT_ELF=y CONFIG_NET=y CONFIG_SYSVIPC=y CONFIG_SYSCTL=y -# CONFIG_PNP_PARPORT is not set +# CONFIG_PARPORT is not set # # Loadable module support @@ -130,6 +131,7 @@ CONFIG_PCNET32=y # CONFIG_CS89x0 is not set # CONFIG_DE4X5 is not set # CONFIG_DEC_ELCP is not set +# CONFIG_DEC_ELCP is not set # CONFIG_DGRS is not set # CONFIG_EEXPRESS_PRO100 is not set # CONFIG_NET_POCKET is not set @@ -139,6 +141,7 @@ CONFIG_PCNET32=y # CONFIG_NET_RADIO is not set # CONFIG_SLIP is not set # CONFIG_TR is not set +# CONFIG_WAN_DRIVERS is not set # CONFIG_LAPBETHER is not set # CONFIG_X25_ASY is not set @@ -205,6 +208,6 @@ CONFIG_SERIAL=y # # Kernel hacking # -# CONFIG_CROSSCOMPILE is not set +CONFIG_CROSSCOMPILE=y # CONFIG_REMOTE_DEBUG is not set # CONFIG_PROFILE is not set diff --git a/arch/mips/deskstation/hw-access.c b/arch/mips/deskstation/hw-access.c index 8b1bd0e3b..64659ba76 100644 --- a/arch/mips/deskstation/hw-access.c +++ b/arch/mips/deskstation/hw-access.c @@ -7,7 +7,7 @@ * * Copyright (C) 1996, 1997 by Ralf Baechle * - * $Id: hw-access.c,v 1.2 1997/07/23 17:40:54 ralf Exp $ + * $Id: hw-access.c,v 1.3 1997/07/29 17:46:42 ralf Exp $ */ #include <linux/config.h> #include <linux/delay.h> @@ -46,69 +46,69 @@ fd_outb(unsigned char value, unsigned int port) * How to access the floppy DMA functions. */ static void -fd_enable_dma(void) +fd_enable_dma(int channel) { - enable_dma(FLOPPY_DMA); + enable_dma(channel); } static void -fd_disable_dma(void) +fd_disable_dma(int channel) { - disable_dma(FLOPPY_DMA); + disable_dma(int channel); } static int -fd_request_dma(void) +fd_request_dma(int channel) { - return request_dma(FLOPPY_DMA, "floppy"); + return request_dma(channel, "floppy"); } static void -fd_free_dma(void) +fd_free_dma(int channel) { - free_dma(FLOPPY_DMA); + free_dma(channel); } static void -fd_clear_dma_ff(void) +fd_clear_dma_ff(int channel) { - clear_dma_ff(FLOPPY_DMA); + clear_dma_ff(channel); } static void -fd_set_dma_mode(char mode) +fd_set_dma_mode(int channel, char mode) { - set_dma_mode(FLOPPY_DMA, mode); + set_dma_mode(channel, mode); } static void -fd_set_dma_addr(unsigned int addr) +fd_set_dma_addr(int channel, unsigned int addr) { - set_dma_addr(FLOPPY_DMA, addr); + set_dma_addr(channel, addr); } static void -fd_set_dma_count(unsigned int count) +fd_set_dma_count(int channel, unsigned int count) { - set_dma_count(FLOPPY_DMA, count); + set_dma_count(channel, count); } static int -fd_get_dma_residue(void) +fd_get_dma_residue(int channel) { - return get_dma_residue(FLOPPY_DMA); + return get_dma_residue(channel); } static void -fd_enable_irq(void) +fd_enable_irq(int irq) { - enable_irq(FLOPPY_IRQ); + enable_irq(irq); } static void -fd_disable_irq(void) +fd_disable_irq(int irq) { - disable_irq(FLOPPY_IRQ); + disable_irq(irq); } void diff --git a/arch/mips/deskstation/int-handler.S b/arch/mips/deskstation/int-handler.S index b7fd32d71..508110fef 100644 --- a/arch/mips/deskstation/int-handler.S +++ b/arch/mips/deskstation/int-handler.S @@ -1,7 +1,9 @@ /* * Deskstation rPC44/Tyne specific interrupt handler code * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle + * Copyright (C) 1994, 1995, 1996, 1997 by Ralf Baechle + * + * $Id: int-handler.S,v 1.3 1997/09/20 19:20:09 root Exp $ */ #include <asm/asm.h> #include <asm/mipsconfig.h> @@ -9,7 +11,7 @@ #include <asm/regdef.h> #include <asm/stackframe.h> -#error "FIXME - PORT_BASE is defined to port_base which breaks this file" +#error "FIXME - PORT_BASE is defined to mips_io_port_base which breaks this file" .text .set noreorder @@ -43,12 +45,8 @@ /* * Now call the real handler */ - la t3,IRQ_vectors - sll t2,a0,PTRLOG - addu t3,t2 - LONG_L t3,(t3) - jalr t3 - nop # delay slot + jal do_IRQ + move a1,sp /* * Unblock first pic */ @@ -57,7 +55,7 @@ nor s1,zero,s1 and t1,s1 sb t1,%lo(cache_21)(s4) - jr v0 + j ret_from_irq sb t1,%lo(PORT_BASE+0x21)(s0) # delay slot /* @@ -85,13 +83,8 @@ poll_second: li a0,0x0f /* * Now call the real handler */ - la t3,IRQ_vectors - addiu a0,8 - sll t2,a0,PTRLOG - addu t3,t2 - LONG_L t3,(t3) - jalr t3 - nop # delay slot + jal do_IRQ + nop /* * Unblock second pic */ @@ -100,12 +93,12 @@ poll_second: li a0,0x0f nor s1,zero,s1 and t1,t1,s1 sb t1,%lo(cache_A1)(s4) - jr v0 - sb t1,%lo(PORT_BASE+0xa1)(s0) # delay slot + j ret_from_irq + sb t1,%lo(PORT_BASE+0xa1)(s0) /* * "Jump extender" to reach spurious_interrupt */ 3: j spurious_interrupt - nop # delay slot + nop END(deskstation_handle_int) diff --git a/arch/mips/jazz/hw-access.c b/arch/mips/jazz/hw-access.c index 4cb45ea89..2ed460ee1 100644 --- a/arch/mips/jazz/hw-access.c +++ b/arch/mips/jazz/hw-access.c @@ -6,6 +6,8 @@ * for more details. * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle + * + * $Id: hw-access.c,v 1.4 1997/07/29 17:46:45 ralf Exp $ */ #include <linux/delay.h> #include <linux/linkage.h> @@ -40,64 +42,64 @@ fd_outb(unsigned char value, unsigned int port) * How to access the floppy DMA functions. */ static void -fd_enable_dma(void) +fd_enable_dma(int channel) { vdma_enable(JAZZ_FLOPPY_DMA); } static void -fd_disable_dma(void) +fd_disable_dma(int channel) { vdma_disable(JAZZ_FLOPPY_DMA); } static int -fd_request_dma(void) +fd_request_dma(int channel) { return 0; } static void -fd_free_dma(void) +fd_free_dma(int channel) { } static void -fd_clear_dma_ff(void) +fd_clear_dma_ff(int channel) { } static void -fd_set_dma_mode(char mode) +fd_set_dma_mode(int channel, char mode) { vdma_set_mode(JAZZ_FLOPPY_DMA, mode); } static void -fd_set_dma_addr(unsigned int a) +fd_set_dma_addr(int channel, unsigned int a) { vdma_set_addr(JAZZ_FLOPPY_DMA, vdma_phys2log(PHYSADDR(a))); } static void -fd_set_dma_count(unsigned int count) +fd_set_dma_count(int channel, unsigned int count) { vdma_set_count(JAZZ_FLOPPY_DMA, count); } static int -fd_get_dma_residue(void) +fd_get_dma_residue(int channel) { return vdma_get_residue(JAZZ_FLOPPY_DMA); } static void -fd_enable_irq(void) +fd_enable_irq(int irq) { } static void -fd_disable_irq(void) +fd_disable_irq(int irq) { } @@ -148,7 +150,8 @@ struct feature jazz_feature = { rtc_write_data }; -static volatile keyboard_hardware *jazz_kh = (keyboard_hardware *)JAZZ_KEYBOARD_ADDRESS; +static volatile keyboard_hardware *jazz_kh = + (keyboard_hardware *) JAZZ_KEYBOARD_ADDRESS; static unsigned char jazz_read_input(void) { @@ -177,5 +180,4 @@ void jazz_keyboard_setup(void) kbd_write_command = jazz_write_command; kbd_read_status = jazz_read_status; request_region(0x60, 16, "keyboard"); - r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | JAZZ_IE_KEYBOARD); } diff --git a/arch/mips/jazz/int-handler.S b/arch/mips/jazz/int-handler.S index 7d8fc5659..4c233ef54 100644 --- a/arch/mips/jazz/int-handler.S +++ b/arch/mips/jazz/int-handler.S @@ -9,6 +9,8 @@ * interrupts. These interrupts should use their own vectors. * Squeeze the last cycles out of the handlers. Only a dead * cycle is a good cycle. + * + * $Id: int-handler.S,v 1.3 1997/09/20 19:20:11 root Exp $ */ #include <asm/asm.h> #include <asm/mipsconfig.h> @@ -110,12 +112,8 @@ ll_isa_irq: lw a0,JAZZ_EISA_IRQ_ACK /* * Now call the real handler */ - la t3,IRQ_vectors - sll t2,a0,PTRLOG - addu t3,t2 - LONG_L t3,(t3) - jalr t3 - nop # delay slot + jal do_IRQ + move a1,sp /* * Unblock first pic */ @@ -124,8 +122,8 @@ ll_isa_irq: lw a0,JAZZ_EISA_IRQ_ACK nor s1,zero,s1 and a0,s1 sb a0,%lo(cache_21)(s4) - jr v0 - sb a0,%lo(JAZZ_PORT_BASE)+0x21(s0) # delay slot + j ret_from_irq + sb a0,%lo(JAZZ_PORT_BASE)+0x21(s0) .align 5 ack_second: /* @@ -144,13 +142,8 @@ ack_second: /* /* * Now call the real handler */ - la t3,IRQ_vectors - addiu a0,8 - sll t2,a0,PTRLOG - addu t3,t2 - LONG_L t3,(t3) - jalr t3 - nop # delay slot + jal do_IRQ + move a1,sp /* * Unblock second pic @@ -160,8 +153,8 @@ ack_second: /* nor s1,zero,s1 and a0,s1 sb a0,%lo(cache_A1)(s4) - jr v0 - sb a0,%lo(JAZZ_PORT_BASE)+0xa1(s0) # delay slot + j ret_from_irq + sb a0,%lo(JAZZ_PORT_BASE)+0xa1(s0) /* * Hmm... This is not just a plain PC clone so the question is @@ -187,40 +180,35 @@ ll_timer: lw zero,JAZZ_TIMER_REGISTER # timer irq cleared on read li a0,0 jal do_IRQ - move a1,sp # delay slot + move a1,sp mfc0 t0,CP0_STATUS # disable interrupts again ori t0,1 xori t0,1 mtc0 t0,CP0_STATUS - j ret_from_sys_call - nop # delay slot + j ret_from_irq + nop /* * CPU count/compare IRQ (unused) */ ll_count: j return - mtc0 zero,CP0_COMPARE + mtc0 zero,CP0_COMPARE #if 0 /* * Call the handler for the interrupt * (Currently unused) */ -call_real: la t0,IRQ_vectors - - /* +call_real: /* * temporarily disable interrupt */ mfc0 t2,CP0_STATUS and t2,s1 - - addu t0,t3 - lw t0,(t0) - mtc0 t2,CP0_STATUS # delay slot - jalr t0 - nor s1,zero,s1 # delay slot + mtc0 t2,CP0_STATUS + nor s1,zero,s1 + jal do_IRQ /* * reenable interrupt @@ -228,9 +216,7 @@ call_real: la t0,IRQ_vectors mfc0 t2,CP0_STATUS or t2,s1 mtc0 t2,CP0_STATUS - - jr v0 - nop # delay slot + j ret_from_irq #endif .data @@ -247,14 +233,14 @@ ll_vectors: PTR ll_count # Count/Compare IRQ * Interrupt handlers for local devices. */ .text + .set reorder loc_no_irq: PANIC("Unimplemented loc_no_irq handler") /* - * Parallel port IRQ + * Parallel port IRQ, remapped to level 5 */ loc_parallel: li s1,~JAZZ_IE_PARALLEL li a0,JAZZ_PARALLEL_IRQ b loc_call - li t3,PTRSIZE*JAZZ_PARALLEL_IRQ # delay slot /* * Floppy IRQ, remapped to level 6 @@ -262,7 +248,6 @@ loc_parallel: li s1,~JAZZ_IE_PARALLEL loc_floppy: li s1,~JAZZ_IE_FLOPPY li a0,JAZZ_FLOPPY_IRQ b loc_call - li t3,PTRSIZE*JAZZ_FLOPPY_IRQ # delay slot /* * Sound? What sound hardware (whistle) ??? @@ -271,20 +256,15 @@ loc_sound: PANIC("Unimplemented loc_sound handler") loc_video: PANIC("Unimplemented loc_video handler") /* - * Ethernet interrupt handler + * Ethernet interrupt handler, remapped to level 13 */ loc_ethernet: li s1,~JAZZ_IE_ETHERNET li a0,JAZZ_ETHERNET_IRQ b loc_call - li t3,PTRSIZE*JAZZ_ETHERNET_IRQ # delay slot -/* - * SCSI interrupt handler - */ loc_scsi: li s1,~JAZZ_IE_SCSI - li a0,JAZZ_SCSI_IRQ + li a0,12 # JAZZ_SCSI_IRQ b loc_call - li t3,PTRSIZE*JAZZ_SCSI_IRQ # delay slot /* * Keyboard interrupt handler @@ -292,42 +272,36 @@ loc_scsi: li s1,~JAZZ_IE_SCSI loc_keyboard: li s1,~JAZZ_IE_KEYBOARD li a0,JAZZ_KEYBOARD_IRQ b loc_call - li t3,PTRSIZE*JAZZ_KEYBOARD_IRQ # re-map to irq level 1 loc_mouse: PANIC("Unimplemented loc_mouse handler") /* - * Serial port 1 IRQ + * Serial port 1 IRQ, remapped to level 3 */ loc_serial1: li s1,~JAZZ_IE_SERIAL1 li a0,JAZZ_SERIAL1_IRQ b loc_call - li t3,PTRSIZE*JAZZ_SERIAL1_IRQ # delay slot /* - * Serial port 2 IRQ + * Serial port 2 IRQ, remapped to level 4 */ loc_serial2: li s1,~JAZZ_IE_SERIAL2 li a0,JAZZ_SERIAL2_IRQ b loc_call - li t3,PTRSIZE*JAZZ_SERIAL2_IRQ # delay slot /* * Call the interrupt handler for an interrupt generated by a * local device. */ -loc_call: la t0,IRQ_vectors # delay slot - - /* +loc_call: /* * Temporarily disable interrupt source */ lhu t2,JAZZ_IO_IRQ_ENABLE - addu t0,t3 # make ptr to IRQ handler - lw t0,(t0) - and t2,s1 # delay slot + and t2,s1 sh t2,JAZZ_IO_IRQ_ENABLE - jalr t0 # call IRQ handler - nor s1,zero,s1 # delay slot + + nor s1,zero,s1 + jal do_IRQ /* * Reenable interrupt @@ -336,14 +310,12 @@ loc_call: la t0,IRQ_vectors # delay slot or t2,s1 sh t2,JAZZ_IO_IRQ_ENABLE - jr v0 - nop # delay slot + j ret_from_irq /* * "Jump extender" to reach spurious_interrupt */ 3: j spurious_interrupt - nop # delay slot /* * Vectors for interrupts generated by local devices diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c index 988499c79..7d4f3b3e3 100644 --- a/arch/mips/jazz/jazzdma.c +++ b/arch/mips/jazz/jazzdma.c @@ -514,18 +514,3 @@ int vdma_get_residue(int channel) return residual; } - -/* - * Get DMA channel enable register - */ -int vdma_get_enable(int channel) -{ - int enable; - - enable = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE+(channel<<5)); - - if (vdma_debug) - printk("vdma_get_enable: channel %d: enable=%d\n",channel,enable); - - return enable; -} diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index 3bbf84947..3bbe3714e 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c @@ -6,12 +6,13 @@ * for more details. * * Copyright (C) 1996, 1997 by Ralf Baechle + * + * $Id: setup.c,v 1.4 1997/07/29 17:57:06 ralf Exp $ */ #include <linux/init.h> #include <linux/ioport.h> #include <linux/sched.h> #include <linux/interrupt.h> -#include <linux/mm.h> #include <asm/bootinfo.h> #include <asm/keyboard.h> #include <asm/irq.h> @@ -20,7 +21,6 @@ #include <asm/reboot.h> #include <asm/vector.h> #include <asm/io.h> -#include <asm/pgtable.h> /* * Initial irq handlers. diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 69cd54975..2b398d00b 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -16,7 +16,6 @@ O_OBJS := branch.o process.o signal.o entry.o traps.o ptrace.o vm86.o \ ioport.o pci.o reset.o setup.o syscall.o sysmips.o ipc.o \ r4k_switch.o r4k_misc.o r4k_scall.o r4k_fpu.o r2300_switch.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 diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index b9d138a32..4ca20214d 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -16,8 +16,7 @@ #include <asm/uaccess.h> /* - * Compute the return address and do emulate branch and instruction - * simulation, if required. + * Compute the return address and do emulate branch simulation, if required. */ int __compute_return_epc(struct pt_regs *regs) { @@ -162,14 +161,12 @@ int __compute_return_epc(struct pt_regs *regs) /* * And now the FPA/cp1 branch instructions. - * - * FIXME: This will silently fail for MIPS IV cop1 branches with - * the cc field != 0. */ case cop1_op: asm ("cfc1\t%0,$31":"=r" (fcr31)); bit = (insn.i_format.rt >> 2); - bit += bit ? 24 : 23; + bit += (bit != 0); + bit += 23; switch (insn.i_format.rt) { case 0: /* bc1f */ case 2: /* bc1fl */ diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index c955b964e..2e286da80 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -7,7 +7,7 @@ * * Copyright (C) 1994, 1995 by Ralf Baechle * - * $Id: entry.S,v 1.2 1997/08/11 04:21:31 ralf Exp $ + * $Id: entry.S,v 1.4 1997/09/20 19:20:13 root Exp $ */ /* @@ -50,6 +50,7 @@ reschedule: jal schedule nop EXPORT(ret_from_sys_call) +EXPORT(ret_from_irq) lw t0,bh_mask lw t1,bh_active # unused delay slot and t0,t1 @@ -75,64 +76,15 @@ EXPORT(ret_from_sys_call) jal do_signal move a1,sp - .set noat -EXPORT(return) +EXPORT(return) .set noat RESTORE_ALL eret .set at /* - * Beware: interrupt, fast_interrupt and bad_interrupt have unusual - * calling conventions to speedup the mess. - * - * a0 - interrupt number - * s2 - destroyed - * return values: - * v0 - return routine + * Common spurious interrupt handler. */ .text - .set at - .align 5 -NESTED(interrupt, PT_SIZE, sp) - move s2,ra - mfc0 t0,CP0_STATUS # enable IRQs - ori t0,0x1f - xori t0,0x1e - mtc0 t0,CP0_STATUS - - jal do_IRQ - move a1,sp - - mfc0 t0,CP0_STATUS # disable IRQs - ori t0,1 - xori t0,1 - mtc0 t0,CP0_STATUS - .set reorder - la v0,ret_from_sys_call - jr s2 - .set noreorder - END(interrupt) - - .align 5 -NESTED(fast_interrupt, PT_SIZE, sp) - move s2,ra - jal do_fast_IRQ - nop - - .set reorder - la v0,return - jr s2 - .set noreorder - END(fast_interrupt) - - /* - * Don't return & unblock the pic - */ -LEAF(bad_interrupt) - j return - END(bad_interrupt) - - .text .align 5 LEAF(spurious_interrupt) /* @@ -141,10 +93,8 @@ LEAF(spurious_interrupt) */ lui t1,%hi(spurious_count) lw t0,%lo(spurious_count)(t1) - la v0,return addiu t0,1 - - jr ra + j ret_from_irq sw t0,%lo(spurious_count)(t1) END(spurious_interrupt) @@ -164,7 +114,7 @@ LEAF(spurious_interrupt) REG_S t0,PT_BVADDR(sp); #define __BUILD_silent(exception) -#define fmt "Got %s at %016Lx.\n" +#define fmt "Got %s at %08lx.\n" #define __BUILD_verbose(exception) \ la a1,8f; \ @@ -215,21 +165,6 @@ EXPORT(exception_count_##exception); \ BUILD_HANDLER(reserved,reserved,none,verbose) /* others */ /* - * Exception handler table with 32 entries. - * This might be extended to handle software exceptions - */ - .bss - .align PTRLOG -EXPORT(exception_handlers) - .fill 32,PTRSIZE,0 - -/* - * Interrupt handler table with 32 entries. - */ -EXPORT(IRQ_vectors) - .fill 32,PTRSIZE,0 - -/* * Table of syscalls */ .data diff --git a/arch/mips/kernel/fpe.c b/arch/mips/kernel/fpe.c index 46ff43bb4..ee47f016f 100644 --- a/arch/mips/kernel/fpe.c +++ b/arch/mips/kernel/fpe.c @@ -6,7 +6,7 @@ * * Copyright (C) 1997 Ralf Baechle * - * $Id:$ + * $Id: fpe.c,v 1.1 1997/08/11 04:17:18 ralf Exp $ */ #include <linux/kernel.h> #include <linux/module.h> diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S index bd7ef94fb..a379c5c5b 100644 --- a/arch/mips/kernel/gdb-low.S +++ b/arch/mips/kernel/gdb-low.S @@ -4,6 +4,8 @@ * gdb-low.S contains the low-level trap handler for the GDB stub. * * Copyright (C) 1995 Andreas Busse + * + * $Id:$ */ #include <linux/sys.h> diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 3251c89d9..d6e82febf 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -7,6 +7,8 @@ * Further modifications by David S. Miller * * Head.S contains the MIPS exception handler and startup code. + * + * $Id: head.S,v 1.10 1997/11/13 12:55:29 ralf Exp $ */ #include <linux/config.h> #include <linux/tasks.h> @@ -27,8 +29,10 @@ /* * Reserved space for exception handlers. * Necessary for machines which link their kernels at KSEG0. + * FIXME: We could overwrite some of the useless handlers + * with those actually being used. */ - .fill 512 + .fill 520 /* * This is space for the interrupt handlers. * After trap_init() they are located at virtual address KSEG0. @@ -93,6 +97,34 @@ eret END(except_vec0_r4600) + /* TLB refill, EXL == 0, R4xx0, non-R4600 version */ + .set noreorder + .set noat + LEAF(except_vec0_nevada) + .set mips3 + mfc0 k0, CP0_BADVADDR # Get faulting address + _GET_CURRENT(k1) # get current task ptr + srl k0, k0, 22 # get pgd only bits + lw k1, THREAD_PGDIR(k1) # get task pg_dir + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + lw k1, (k1) + mfc0 k0, CP0_CONTEXT # get context reg + srl k0, k0, 1 # get pte offset + and k0, k0, 0xff8 + addu k1, k1, k0 # add in offset + lw k0, 0(k1) # get even pte + lw k1, 4(k1) # get odd pte + srl k0, k0, 6 # convert to entrylo0 + mtc0 k0, CP0_ENTRYLO0 # load it + srl k1, k1, 6 # convert to entrylo1 + mtc0 k1, CP0_ENTRYLO1 # load it + tlbwr # write random tlb entry + nop + nop + eret # return from trap + END(except_vec0_nevada) + /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ LEAF(except_vec0_r45k_bvahwbug) .set mips3 @@ -109,6 +141,7 @@ addu k1, k1, k0 lw k0, 0(k1) lw k1, 4(k1) + nop /* XXX */ tlbp srl k0, k0, 6 mtc0 k0, CP0_ENTRYLO0 @@ -139,6 +172,7 @@ addu k1, k1, k0 lw k0, 0(k1) lw k1, 4(k1) + nop /* XXX */ tlbp srl k0, k0, 6 mtc0 k0, CP0_ENTRYLO0 @@ -199,6 +233,7 @@ addu k1, k1, k0 lw k0, 0(k1) lw k1, 4(k1) + nop /* XXX */ tlbp srl k0, k0, 6 mtc0 zero, CP0_ENTRYLO0 @@ -309,6 +344,17 @@ END(except_vec3_generic) .set at + /* + * Special interrupt vector for embedded MIPS. This is a + * dedicated interrupt vector which reduces interrupt processing + * overhead. The jump instruction will be inserted here at + * initialization time. This handler may only be 8 bytes in size! + */ + NESTED(except_vec4, 0, sp) +1: j 1b /* Dummy, will be replaced */ + nop + END(except_vec4) + /* * Kernel entry point */ @@ -357,13 +403,10 @@ probe_done: #ifndef CONFIG_SGI /* Clear BSS first so that there are no surprises... */ la t0, _edata - la t1, (_end - 4) - sw zero, (t0) -1: - addiu t0, 4 + la t1, _end +1: addiu t0, 1 bne t0, t1, 1b - sw zero, (t0) - nop + sb zero, -1(t0) #endif /* * Determine the mmu/cache attached to this machine, @@ -400,8 +443,9 @@ probe_done: /* * Stack for kernel and init */ -9: la sp, init_task_union+(KERNEL_STACK_SIZE-4*SZREG) - sw sp, kernelsp +9: la t0, init_task_union+KERNEL_STACK_SIZE-32 + sw t0, kernelsp + subu sp, t0, 4*SZREG /* Disable coprocessors */ mfc0 t0, CP0_STATUS @@ -604,6 +648,14 @@ LEAF(wire_mappings_r3000) b probe_done sw t2, (t3) 1: + li t2, PRID_IMP_NEVADA + bne t1, t2, 1f + nop + + li t2, CPU_NEVADA + b probe_done + sw t2, (t3) +1: li t2, CPU_UNKNOWN sw t2, (t3) diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index 26ae60b9e..a7c7bb7df 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -6,7 +6,6 @@ * * Based upon work which is: * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com). - * */ #include <linux/module.h> @@ -228,6 +227,7 @@ unsigned long * create_irix_tables(char * p, int argc, int envc, return sp; } + /* This is much more generalized than the library routine read function, * so we keep this separate. Technically the library read function * is only provided so that we can read a.out libraries that have @@ -679,7 +679,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm, start_code = 0xffffffff; end_code = 0; end_data = 0; - + retval = look_for_irix_interpreter(&elf_interpreter, &interpreter_dentry, &interp_elf_ex, elf_phdata, bprm, @@ -754,7 +754,6 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm, } } - set_fs(old_fs); kfree(elf_phdata); @@ -861,7 +860,7 @@ static inline int do_load_irix_library(int fd) /* Seek to the beginning of the file. */ if (file->f_op->llseek) { - if ((error = file->f_op->llseek(inode, file, 0, 0)) != 0) + if ((error = file->f_op->llseek(file, 0, 0)) != 0) return -ENOEXEC; } else file->f_pos = 0; @@ -1028,7 +1027,7 @@ static int dump_write(struct file *file, const void *addr, int nr) static int dump_seek(struct file *file, off_t off) { if (file->f_op->llseek) { - if (file->f_op->llseek(file->f_dentry->d_inode, file, off, 0) != off) + if (file->f_op->llseek(file, off, 0) != off) return 0; } else file->f_pos = off; diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c index a40178f36..c84a391a7 100644 --- a/arch/mips/kernel/irixsig.c +++ b/arch/mips/kernel/irixsig.c @@ -1,4 +1,4 @@ -/* $Id: irixsig.c,v 1.3 1997/07/29 03:04:27 ralf Exp $ +/* $Id: irixsig.c,v 1.4 1997/08/05 09:43:10 ralf Exp $ * irixsig.c: WHEEE, IRIX signals! YOW, am I compatable or what?!?! * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 81ac4846d..2f29b0ca5 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -4,7 +4,7 @@ * Copyright (C) 1992 Linus Torvalds * Copyright (C) 1994, 1995, 1996, 1997 Ralf Baechle * - * $Id: irq.c,v 1.4 1997/09/12 01:30:22 ralf Exp $ + * $Id: irq.c,v 1.7 1997/09/26 11:51:33 ralf Exp $ */ #include <linux/errno.h> #include <linux/init.h> @@ -86,8 +86,6 @@ void enable_irq(unsigned int irq_nr) * fast ones, then the bad ones. */ extern void interrupt(void); -extern void fast_interrupt(void); -extern void bad_interrupt(void); static struct irqaction *irq_action[32] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -130,48 +128,45 @@ atomic_t __mips_bh_counter; */ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { - struct irqaction * action = *(irq + irq_action); - int do_random, cpu = smp_processor_id(); + struct irqaction *action; + int do_random, cpu; + cpu = smp_processor_id(); irq_enter(cpu, irq); kstat.interrupts[irq]++; - /* slow interrupts run with interrupts enabled */ - sti(); - action = *(irq + irq_action); - do_random = 0; - while (action) { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - irq_exit(cpu, irq); -} + /* + * mask and ack quickly, we don't want the irq controller + * thinking we're snobs just because some other CPU has + * disabled global interrupts (we have already done the + * INT_ACK cycles, it's too late to try to pretend to the + * controller that we aren't taking the interrupt). + * + * Commented out because we've already done this in the + * machinespecific part of the handler. It's reasonable to + * do this here in a highlevel language though because that way + * we could get rid of a good part of duplicated code ... + */ + /* mask_and_ack_irq(irq); */ -/* - * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return - * stuff - the handler is also running with interrupts disabled unless - * it explicitly enables them later. - */ -asmlinkage void do_fast_IRQ(int irq) -{ - struct irqaction * action; - int do_random, cpu = smp_processor_id(); - - irq_enter(cpu, irq); - kstat.interrupts[irq]++; action = *(irq + irq_action); - do_random = 0; - while (action) { - do_random |= action->flags; - action->handler(irq, action->dev_id, NULL); - action = action->next; + 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(); } - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); irq_exit(cpu, irq); + + /* unmasking and bottom half handling is done magically for us. */ } /* @@ -211,10 +206,6 @@ int setup_x86_irq(int irq, struct irqaction * new) *p = new; if (!shared) { - if (new->flags & SA_INTERRUPT) - set_int_vector(irq,fast_interrupt); - else - set_int_vector(irq,interrupt); unmask_irq(irq); } restore_flags(flags); @@ -269,10 +260,8 @@ void free_irq(unsigned int irq, void *dev_id) /* Found it - now free it */ save_and_cli(flags); *p = action->next; - if (!irq[irq_action]) { + if (!irq[irq_action]) mask_irq(irq); - set_int_vector(irq, bad_interrupt); - } restore_flags(flags); kfree(action); return; @@ -321,9 +310,5 @@ int probe_irq_off (unsigned long irqs) __initfunc(void init_IRQ(void)) { - int i; - - for (i = 0; i < 32 ; i++) - set_int_vector(i, bad_interrupt); irq_setup(); } diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 83712649c..3e8fc275d 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/29 03:58:54 ralf Exp $ + * $Id: mips_ksyms.c,v 1.4 1997/08/11 04:17:18 ralf Exp $ */ #include <linux/config.h> #include <linux/module.h> @@ -62,11 +62,21 @@ EXPORT_SYMBOL(csum_partial_copy); */ EXPORT_SYMBOL(flush_page_to_ram); EXPORT_SYMBOL(fd_cacheflush); +EXPORT_SYMBOL(flush_cache_all); /* * Base address of ports for Intel style I/O. */ -EXPORT_SYMBOL(port_base); +EXPORT_SYMBOL(mips_io_port_base); + +/* + * Architecture specific stuff. + */ +#ifdef CONFIG_MIPS_JAZZ +EXPORT_SYMBOL(vdma_alloc); +EXPORT_SYMBOL(vdma_free); +EXPORT_SYMBOL(vdma_log2phys); +#endif #ifdef CONFIG_SGI EXPORT_SYMBOL(hpc3c0); diff --git a/arch/mips/kernel/pci.c b/arch/mips/kernel/pci.c index 25ea56fdd..6f7374fd2 100644 --- a/arch/mips/kernel/pci.c +++ b/arch/mips/kernel/pci.c @@ -13,7 +13,9 @@ #include <linux/types.h> #include <asm/pci.h> -#ifndef CONFIG_PCI +#ifdef CONFIG_PCI + +struct pci_ops *pci_ops; /* * BIOS32 replacement. @@ -24,15 +26,13 @@ __initfunc(unsigned long pcibios_init(unsigned long memory_start, return memory_start; } -#else /* defined(CONFIG_PCI) */ - /* * Following the generic parts of the MIPS BIOS32 code. */ int pcibios_present (void) { - return _pcibios_init != NULL; + return pci_ops != NULL; } /* @@ -87,68 +87,46 @@ int pcibios_find_class (unsigned int class_code, unsigned short index, * each PCI chipset configuration. We just run the hook to the machine * specific implementation. */ -unsigned long (*_pcibios_init)(unsigned long memory_start, unsigned long memory_end); -__initfunc(unsigned long pcibios_init(unsigned long memory_start, - unsigned long memory_end)) -{ - return _pcibios_init ? _pcibios_init(memory_start, memory_end) - : memory_start; -} - -unsigned long (*_pcibios_fixup) (unsigned long memory_start, - unsigned long memory_end); unsigned long pcibios_fixup (unsigned long memory_start, unsigned long memory_end) { - return _pcibios_fixup(memory_start, memory_end); + return pci_ops->pcibios_fixup(memory_start, memory_end); } -int (*_pcibios_read_config_byte) (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char *val); int pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn, unsigned char where, unsigned char *val) { - return _pcibios_read_config_byte(bus, dev_fn, where, val); + return pci_ops->pcibios_read_config_byte(bus, dev_fn, where, val); } -int (*_pcibios_read_config_word) (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short *val); int pcibios_read_config_word (unsigned char bus, unsigned char dev_fn, unsigned char where, unsigned short *val) { - return _pcibios_read_config_word(bus, dev_fn, where, val); + return pci_ops->pcibios_read_config_word(bus, dev_fn, where, val); } -int (*_pcibios_read_config_dword) (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int *val); int pcibios_read_config_dword (unsigned char bus, unsigned char dev_fn, unsigned char where, unsigned int *val) { - return _pcibios_read_config_dword(bus, dev_fn, where, val); + return pci_ops->pcibios_read_config_dword(bus, dev_fn, where, val); } -int (*_pcibios_write_config_byte) (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char val); int pcibios_write_config_byte (unsigned char bus, unsigned char dev_fn, unsigned char where, unsigned char val) { - return _pcibios_write_config_byte(bus, dev_fn, where, val); + return pci_ops->pcibios_write_config_byte(bus, dev_fn, where, val); } -int (*_pcibios_write_config_word) (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short val); int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn, unsigned char where, unsigned short val) { - return _pcibios_write_config_word(bus, dev_fn, where, val); + return pci_ops->pcibios_write_config_word(bus, dev_fn, where, val); } -int (*_pcibios_write_config_dword) (unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int val); int pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn, unsigned char where, unsigned int val) { - return _pcibios_write_config_dword(bus, dev_fn, where, val); + return pci_ops->pcibios_write_config_dword(bus, dev_fn, where, val); } #endif /* defined(CONFIG_PCI) */ diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 0e2803dd3..2c454c019 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -5,11 +5,12 @@ */ #include <linux/delay.h> #include <linux/kernel.h> +#include <linux/sched.h> #include <asm/bootinfo.h> #include <asm/mipsregs.h> +#include <asm/processor.h> +#include <asm/watch.h> -unsigned long dflushes = 0; -unsigned long iflushes = 0; unsigned long unaligned_instructions; /* @@ -27,8 +28,15 @@ int get_cpuinfo(char *buffer) const char *mach_dec_names[] = GROUP_DEC_NAMES; const char *mach_arc_names[] = GROUP_ARC_NAMES; const char *mach_sni_rm_names[] = GROUP_SNI_RM_NAMES; - const char **mach_group_to_name[] = { mach_unknown_names, mach_jazz_names, - mach_dec_names, mach_arc_names, mach_sni_rm_names}; + const char *mach_acn_names[] = GROUP_ACN_NAMES; + const char *mach_sgi_names[] = GROUP_SGI_NAMES; + const char **mach_group_to_name[] = { mach_unknown_names, + mach_jazz_names, + mach_dec_names, + mach_arc_names, + mach_sni_rm_names, + mach_acn_names, + mach_sgi_names }; unsigned int version = read_32bit_cp0_register(CP0_PRID); int len; @@ -51,12 +59,16 @@ int get_cpuinfo(char *buffer) #if defined (__MIPSEL__) len += sprintf(buffer + len, "byteorder\t\t: little endian\n"); #endif - len += sprintf(buffer + len, "D-cache flushes\t\t: %lu\n", - dflushes); - len += sprintf(buffer + len, "I-cache flushes\t\t: %lu\n", - iflushes); len += sprintf(buffer + len, "unaligned accesses\t: %lu\n", unaligned_instructions); + len += sprintf(buffer + len, "wait instruction\t: %s\n", + wait_available ? "yes" : "no"); + len += sprintf(buffer + len, "microsecond timers\t: %s\n", + cyclecounter_available ? "yes" : "no"); + len += sprintf(buffer + len, "extra interrupt vector\t: %s\n", + dedicated_iv_available ? "yes" : "no"); + len += sprintf(buffer + len, "hardware watchpoint\t: %s\n", + watch_available ? "yes" : "no"); return len; } diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 3ffb9b258..6d28d6e98 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -70,10 +70,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, struct pt_regs * childregs; long childksp; - childksp = (unsigned long)p + KERNEL_STACK_SIZE - 8; + childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32; /* set up new TSS. */ - childregs = ((struct pt_regs *) ((unsigned long)p + KERNEL_STACK_SIZE)) - 1; + childregs = (struct pt_regs *) childksp - 1; *childregs = *regs; childregs->regs[7] = 0; /* Clear error flag */ if(current->personality == PER_LINUX) { diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S index fc4e04617..6c699c74d 100644 --- a/arch/mips/kernel/r2300_fpu.S +++ b/arch/mips/kernel/r2300_fpu.S @@ -10,7 +10,7 @@ * Multi-arch abstraction and asm macros for easier reading: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r2300_fpu.S,v 1.2 1997/06/25 14:44:51 ralf Exp $ + * $Id: r2300_fpu.S,v 1.3 1997/12/01 16:54:20 ralf Exp $ */ #include <asm/asm.h> #include <asm/fpregdef.h> @@ -30,7 +30,7 @@ nop cfc1 t0,fcr31 - /* Store the 16 odd double precision registers */ + /* Store the 32 single precision registers */ swc1 $f0,(SC_FPREGS+0)(a0) swc1 $f1,(SC_FPREGS+8)(a0) swc1 $f2,(SC_FPREGS+16)(a0) @@ -76,7 +76,8 @@ .set macro END(r2300_save_fp_context) -/* Restore fpu state: +/* + * Restore fpu state: * - fp gp registers * - cp1 status/control register * @@ -91,7 +92,6 @@ bgez t0,1f nop - bgez t0,1f lw t0,SC_FPC_CSR(a0) /* Restore the 16 odd double precision registers only * when enabled in the cp0 status register. diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index c5c519f4e..72638d462 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S @@ -10,7 +10,7 @@ * Multi-arch abstraction and asm macros for easier reading: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r4k_fpu.S,v 1.2 1997/06/25 14:44:52 ralf Exp $ + * $Id: r4k_fpu.S,v 1.3 1997/12/01 16:56:06 ralf Exp $ */ #include <asm/asm.h> #include <asm/fpregdef.h> @@ -21,7 +21,7 @@ .set noreorder .set mips3 /* Save floating point context */ - LEAF(r4k_save_fp_context) +LEAF(r4k_save_fp_context) mfc0 t1,CP0_STATUS sll t2,t1,2 bgez t2,2f @@ -31,41 +31,41 @@ bgez t2,1f nop /* Store the 16 odd double precision registers */ - swc1 $f1,(SC_FPREGS+8)(a0) - swc1 $f3,(SC_FPREGS+24)(a0) - swc1 $f5,(SC_FPREGS+40)(a0) - swc1 $f7,(SC_FPREGS+56)(a0) - swc1 $f9,(SC_FPREGS+72)(a0) - swc1 $f11,(SC_FPREGS+88)(a0) - swc1 $f13,(SC_FPREGS+104)(a0) - swc1 $f15,(SC_FPREGS+120)(a0) - swc1 $f17,(SC_FPREGS+136)(a0) - swc1 $f19,(SC_FPREGS+152)(a0) - swc1 $f21,(SC_FPREGS+168)(a0) - swc1 $f23,(SC_FPREGS+184)(a0) - swc1 $f25,(SC_FPREGS+200)(a0) - swc1 $f27,(SC_FPREGS+216)(a0) - swc1 $f29,(SC_FPREGS+232)(a0) - swc1 $f31,(SC_FPREGS+248)(a0) + sdc1 $f1,(SC_FPREGS+8)(a0) + sdc1 $f3,(SC_FPREGS+24)(a0) + sdc1 $f5,(SC_FPREGS+40)(a0) + sdc1 $f7,(SC_FPREGS+56)(a0) + sdc1 $f9,(SC_FPREGS+72)(a0) + sdc1 $f11,(SC_FPREGS+88)(a0) + sdc1 $f13,(SC_FPREGS+104)(a0) + sdc1 $f15,(SC_FPREGS+120)(a0) + sdc1 $f17,(SC_FPREGS+136)(a0) + sdc1 $f19,(SC_FPREGS+152)(a0) + sdc1 $f21,(SC_FPREGS+168)(a0) + sdc1 $f23,(SC_FPREGS+184)(a0) + sdc1 $f25,(SC_FPREGS+200)(a0) + sdc1 $f27,(SC_FPREGS+216)(a0) + sdc1 $f29,(SC_FPREGS+232)(a0) + sdc1 $f31,(SC_FPREGS+248)(a0) /* Store the 16 even double precision registers */ 1: - swc1 $f0,(SC_FPREGS+0)(a0) - swc1 $f2,(SC_FPREGS+16)(a0) - swc1 $f4,(SC_FPREGS+32)(a0) - swc1 $f6,(SC_FPREGS+48)(a0) - swc1 $f8,(SC_FPREGS+64)(a0) - swc1 $f10,(SC_FPREGS+80)(a0) - swc1 $f12,(SC_FPREGS+96)(a0) - swc1 $f14,(SC_FPREGS+112)(a0) - swc1 $f16,(SC_FPREGS+128)(a0) - swc1 $f18,(SC_FPREGS+144)(a0) - swc1 $f20,(SC_FPREGS+160)(a0) - swc1 $f22,(SC_FPREGS+176)(a0) - swc1 $f24,(SC_FPREGS+192)(a0) - swc1 $f26,(SC_FPREGS+208)(a0) - swc1 $f28,(SC_FPREGS+224)(a0) - swc1 $f30,(SC_FPREGS+240)(a0) + sdc1 $f0,(SC_FPREGS+0)(a0) + sdc1 $f2,(SC_FPREGS+16)(a0) + sdc1 $f4,(SC_FPREGS+32)(a0) + sdc1 $f6,(SC_FPREGS+48)(a0) + sdc1 $f8,(SC_FPREGS+64)(a0) + sdc1 $f10,(SC_FPREGS+80)(a0) + sdc1 $f12,(SC_FPREGS+96)(a0) + sdc1 $f14,(SC_FPREGS+112)(a0) + sdc1 $f16,(SC_FPREGS+128)(a0) + sdc1 $f18,(SC_FPREGS+144)(a0) + sdc1 $f20,(SC_FPREGS+160)(a0) + sdc1 $f22,(SC_FPREGS+176)(a0) + sdc1 $f24,(SC_FPREGS+192)(a0) + sdc1 $f26,(SC_FPREGS+208)(a0) + sdc1 $f28,(SC_FPREGS+224)(a0) + sdc1 $f30,(SC_FPREGS+240)(a0) sw t1,SC_FPC_CSR(a0) cfc1 t0,$0 # implementation/version @@ -80,7 +80,8 @@ .set macro END(r4k_save_fp_context) -/* Restore fpu state: +/* + * Restore fpu state: * - fp gp registers * - cp1 status/control register * @@ -88,7 +89,7 @@ * frame on the current content of c0_status, not on the content of the * stack frame which might have been changed by the user. */ - LEAF(r4k_restore_fp_context) +LEAF(r4k_restore_fp_context) mfc0 t1,CP0_STATUS sll t0,t1,2 bgez t0,2f @@ -99,52 +100,46 @@ /* Restore the 16 odd double precision registers only * when enabled in the cp0 status register. */ - lwc1 $f1,(SC_FPREGS+8)(a0) - lwc1 $f3,(SC_FPREGS+24)(a0) - lwc1 $f5,(SC_FPREGS+40)(a0) - lwc1 $f7,(SC_FPREGS+56)(a0) - lwc1 $f9,(SC_FPREGS+72)(a0) - lwc1 $f11,(SC_FPREGS+88)(a0) - lwc1 $f13,(SC_FPREGS+104)(a0) - lwc1 $f15,(SC_FPREGS+120)(a0) - lwc1 $f17,(SC_FPREGS+136)(a0) - lwc1 $f19,(SC_FPREGS+152)(a0) - lwc1 $f21,(SC_FPREGS+168)(a0) - lwc1 $f23,(SC_FPREGS+184)(a0) - lwc1 $f25,(SC_FPREGS+200)(a0) - lwc1 $f27,(SC_FPREGS+216)(a0) - lwc1 $f29,(SC_FPREGS+232)(a0) - lwc1 $f31,(SC_FPREGS+248)(a0) + ldc1 $f1,(SC_FPREGS+8)(a0) + ldc1 $f3,(SC_FPREGS+24)(a0) + ldc1 $f5,(SC_FPREGS+40)(a0) + ldc1 $f7,(SC_FPREGS+56)(a0) + ldc1 $f9,(SC_FPREGS+72)(a0) + ldc1 $f11,(SC_FPREGS+88)(a0) + ldc1 $f13,(SC_FPREGS+104)(a0) + ldc1 $f15,(SC_FPREGS+120)(a0) + ldc1 $f17,(SC_FPREGS+136)(a0) + ldc1 $f19,(SC_FPREGS+152)(a0) + ldc1 $f21,(SC_FPREGS+168)(a0) + ldc1 $f23,(SC_FPREGS+184)(a0) + ldc1 $f25,(SC_FPREGS+200)(a0) + ldc1 $f27,(SC_FPREGS+216)(a0) + ldc1 $f29,(SC_FPREGS+232)(a0) + ldc1 $f31,(SC_FPREGS+248)(a0) - /* Restore the 16 even double precision registers + /* + * Restore the 16 even double precision registers * when cp1 was enabled in the cp0 status register. */ -1: - lwc1 $f0,(SC_FPREGS+0)(a0) - lwc1 $f2,(SC_FPREGS+16)(a0) - lwc1 $f4,(SC_FPREGS+32)(a0) - lwc1 $f6,(SC_FPREGS+48)(a0) - lwc1 $f8,(SC_FPREGS+64)(a0) - lwc1 $f10,(SC_FPREGS+80)(a0) - lwc1 $f12,(SC_FPREGS+96)(a0) - lwc1 $f14,(SC_FPREGS+112)(a0) - lwc1 $f16,(SC_FPREGS+128)(a0) - lwc1 $f18,(SC_FPREGS+144)(a0) - lwc1 $f20,(SC_FPREGS+160)(a0) - lwc1 $f22,(SC_FPREGS+176)(a0) - lwc1 $f24,(SC_FPREGS+192)(a0) - lwc1 $f26,(SC_FPREGS+208)(a0) - lwc1 $f28,(SC_FPREGS+224)(a0) - lwc1 $f30,(SC_FPREGS+240)(a0) - ctc1 t0,fcr31 - +1: ldc1 $f0,(SC_FPREGS+0)(a0) + ldc1 $f2,(SC_FPREGS+16)(a0) + ldc1 $f4,(SC_FPREGS+32)(a0) + ldc1 $f6,(SC_FPREGS+48)(a0) + ldc1 $f8,(SC_FPREGS+64)(a0) + ldc1 $f10,(SC_FPREGS+80)(a0) + ldc1 $f12,(SC_FPREGS+96)(a0) + ldc1 $f14,(SC_FPREGS+112)(a0) + ldc1 $f16,(SC_FPREGS+128)(a0) + ldc1 $f18,(SC_FPREGS+144)(a0) + ldc1 $f20,(SC_FPREGS+160)(a0) + ldc1 $f22,(SC_FPREGS+176)(a0) + ldc1 $f24,(SC_FPREGS+192)(a0) + ldc1 $f26,(SC_FPREGS+208)(a0) + ldc1 $f28,(SC_FPREGS+224)(a0) + ldc1 $f30,(SC_FPREGS+240)(a0) jr ra - .set nomacro - nop - .set macro -2: - jr ra - .set nomacro + ctc1 t0,fcr31 + +2: jr ra nop - .set macro END(r4k_restore_fp_context) diff --git a/arch/mips/kernel/r4k_misc.S b/arch/mips/kernel/r4k_misc.S index 090b3109f..2e0223260 100644 --- a/arch/mips/kernel/r4k_misc.S +++ b/arch/mips/kernel/r4k_misc.S @@ -6,7 +6,7 @@ * 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 $ + * $Id: r4k_misc.S,v 1.3 1997/09/07 04:51:07 ralf Exp $ */ #include <asm/asm.h> #include <asm/current.h> diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S index 66d4fa848..db471fa96 100644 --- a/arch/mips/kernel/r6000_fpu.S +++ b/arch/mips/kernel/r6000_fpu.S @@ -10,7 +10,7 @@ * Multi-arch abstraction and asm macros for easier reading: * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r6000_fpu.S,v 1.2 1997/06/25 14:44:52 ralf Exp $ + * $Id: r6000_fpu.S,v 1.3 1997/12/01 16:56:56 ralf Exp $ */ #include <asm/asm.h> #include <asm/fpregdef.h> @@ -44,18 +44,10 @@ sdc1 $f26,(SC_FPREGS+208)(a0) sdc1 $f28,(SC_FPREGS+224)(a0) sdc1 $f30,(SC_FPREGS+240)(a0) - sw t0,SC_FPC_CSR(a0) - cfc1 t0,$0 # implementation/version - - jr ra - .set nomacro - sw t0,SC_FPC_EIR(a0) - .set macro -1: jr ra - .set nomacro + sw t0,SC_FPC_CSR(a0) +1: jr ra nop - .set macro END(r6000_save_fp_context) /* Restore fpu state: @@ -89,14 +81,8 @@ ldc1 $f26,(SC_FPREGS+208)(a0) ldc1 $f28,(SC_FPREGS+224)(a0) ldc1 $f30,(SC_FPREGS+240)(a0) - jr ra - .set nomacro ctc1 t0,fcr31 - .set macro -1: - jr ra - .set nomacro +1: jr ra nop - .set macro END(r6000_restore_fp_context) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 3ebf269f5..a1932d117 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -5,7 +5,7 @@ * Copyright (C) 1995, 1996 Ralf Baechle * Copyright (C) 1996 Stoned Elipot * - * $Id:$ + * $Id: setup.c,v 1.4 1997/09/07 04:55:42 ralf Exp $ */ #include <linux/config.h> #include <linux/errno.h> @@ -122,6 +122,12 @@ static char command_line[CL_SIZE] = { 0, }; void (*irq_setup)(void); /* + * 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; + +/* * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped * for the processor. */ diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 4ff1a98b4..481a34147 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.5 1997/09/12 01:30:24 ralf Exp $ + * $Id: signal.c,v 1.8 1997/12/01 16:26:34 ralf Exp $ */ #include <linux/config.h> #include <linux/sched.h> @@ -174,7 +174,7 @@ static void setup_frame(struct sigaction * sa, struct pt_regs *regs, * Set up the return code ... * * .set noreorder - * addiu sp,24 + * addiu sp,0x20 * li v0,__NR_sigreturn * syscall * .set reorder diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 0a190e3ab..ffcf176e4 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -10,6 +10,8 @@ * TODO: Implement the compatibility syscalls. * Don't waste that much memory for empty entries in the syscall * table. + * + * $Id: syscall.c,v 1.4 1997/09/18 07:57:30 root Exp $ */ #undef CONF_PRINT_SYSCALLS #undef CONF_DEBUG_IRIX @@ -84,15 +86,17 @@ asmlinkage int sys_idle(void) current->counter = -100; for (;;) { /* - * R4[236]00 have wait, R4[04]00 don't. + * R4[36]00 have wait, R4[04]00 don't. * FIXME: We should save power by reducing the clock where - * possible. Should help alot for battery powered - * R4200/4300i systems. + * possible. Thiss will cut down the power consuption + * of R4200 systems to about 1/16th of normal, the + * same for logic clocked with the processor generated + * clocks. */ if (wait_available && !need_resched) __asm__(".set\tmips3\n\t" "wait\n\t" - ".set\tmips0\n\t"); + ".set\tmips0"); run_task_queue(&tq_scheduler); schedule(); } diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h index 3232af01c..159931b4b 100644 --- a/arch/mips/kernel/syscalls.h +++ b/arch/mips/kernel/syscalls.h @@ -5,9 +5,9 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1996, 1997 by Ralf Baechle + * Copyright (C) 1995, 1996 by Ralf Baechle * - * $Id: syscalls.h,v 1.6 1997/08/06 19:15:08 miguel Exp $ + * $Id: syscalls.h,v 1.5 1997/09/11 01:57:38 ralf Exp $ */ /* @@ -210,5 +210,3 @@ SYS(sys_poll, 3) SYS(sys_nfsservctl, 3) SYS(sys_setresgid, 3) /* 4190 */ SYS(sys_getresgid, 3) -SYS(sys_setresgid, 3) /* 4190 */ -SYS(sys_getresgid, 3) diff --git a/arch/mips/kernel/sysmips.c b/arch/mips/kernel/sysmips.c index e73598345..62f8687c0 100644 --- a/arch/mips/kernel/sysmips.c +++ b/arch/mips/kernel/sysmips.c @@ -7,7 +7,7 @@ * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle * - * $Id: sysmips.c,v 1.2 1997/07/01 08:59:08 ralf Exp $ + * $Id: sysmips.c,v 1.3 1997/07/18 06:26:02 ralf Exp $ */ #include <linux/errno.h> #include <linux/linkage.h> diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 886b9b35e..f2cbabd86 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -6,7 +6,7 @@ * This file contains the time handling details for PC-style clocks as * found in some MIPS systems. * - * $Id: time.c,v 1.2 1997/07/01 08:59:08 ralf Exp $ + * $Id: time.c,v 1.5 1997/11/12 12:12:12 ralf Exp $ */ #include <linux/errno.h> #include <linux/init.h> @@ -39,7 +39,6 @@ extern volatile unsigned long lost_ticks; /* Cycle counter value at the previous timer interrupt.. */ static unsigned int timerhi = 0, timerlo = 0; -static char cyclecounter_available = 1; /* * On MIPS only R4000 and better have a cycle counter. @@ -397,7 +396,7 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon, )*60 + sec; /* finally seconds */ } -static char cyclecounter_available; +char cyclecounter_available; static inline void init_cycle_counter(void) { @@ -437,7 +436,9 @@ static inline void init_cycle_counter(void) } } -static struct irqaction irq0 = { timer_interrupt, 0, 0, "timer", NULL, NULL}; +struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, + "timer", NULL, NULL}; + void (*board_time_init)(struct irqaction *irq); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 99ebc3aeb..fc0dd091c 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -8,7 +8,7 @@ * Copyright 1994, 1995, 1996, 1997 by Ralf Baechle * Modified for R3000 by Paul M. Antoine, 1995, 1996 * - * $Id: traps.c,v 1.3 1997/09/17 07:22:12 ralf Exp $ + * $Id: traps.c,v 1.7 1997/12/01 16:33:28 ralf Exp $ */ #include <linux/config.h> #include <linux/init.h> @@ -72,7 +72,8 @@ extern asmlinkage void handle_reserved(void); static char *cpu_names[] = CPU_NAMES; -unsigned int watch_available = 0; +char watch_available = 0; +char dedicated_iv_available = 0; void (*ibe_board_handler)(struct pt_regs *regs); void (*dbe_board_handler)(struct pt_regs *regs); @@ -175,7 +176,7 @@ void die_if_kernel(const char * str, struct pt_regs * regs, long err) return; #endif #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) - if (!(regs->cp0_status & 0x18)) + if (regs->cp0_status & ST0_KSU == KSU_USER) return; #endif console_verbose(); @@ -189,8 +190,6 @@ static void default_be_board_handler(struct pt_regs *regs) /* * Assume it would be too dangerous to continue ... */ - printk ("BE HANDLER\n"); - show_regs (regs); force_sig(SIGBUS, current); } @@ -427,6 +426,40 @@ static inline void watch_init(unsigned long cputype) } } +/* + * Some MIPS CPUs have a dedicated interrupt vector which reduces the + * interrupt processing overhead. Use it where available. + * FIXME: more CPUs than just the Nevada have this feature. + */ +static inline void setup_dedicated_int(void) +{ + extern void except_vec4(void); + switch(mips_cputype) { + case CPU_NEVADA: + memcpy((void *)(KSEG0 + 0x200), except_vec4, 8); + set_cp0_cause(CAUSEF_IV, CAUSEF_IV); + dedicated_iv_available = 1; + } +} + +unsigned long exception_handlers[32]; + +/* + * As a side effect of the way this is implemented we're limited + * to interrupt handlers in the address range from + * KSEG0 <= x < KSEG0 + 256mb on the Nevada. Oh well ... + */ +void set_except_vector(int n, void *addr) +{ + unsigned handler = (unsigned long) addr; + exception_handlers[n] = handler; + if (n == 0 && dedicated_iv_available) { + *(volatile u32 *)(KSEG0+0x200) = 0x08000000 | + (0x03ffffff & (handler >> 2)); + flush_icache_range(KSEG0+0x200, KSEG0 + 0x204); + } +} + typedef asmlinkage int (*syscall_t)(void *a0,...); asmlinkage int (*do_syscalls)(struct pt_regs *regs, syscall_t fun, int narg); extern asmlinkage int r4k_do_syscalls(struct pt_regs *regs, @@ -449,7 +482,8 @@ extern asmlinkage void r2300_resume(void *tsk); __initfunc(void trap_init(void)) { - extern char except_vec0_r4000, except_vec0_r4600, except_vec0_r2300; + extern char except_vec0_nevada, except_vec0_r4000; + extern char except_vec0_r4600, except_vec0_r2300; extern char except_vec1_generic, except_vec2_generic; extern char except_vec3_generic, except_vec3_r4000; unsigned long i; @@ -471,9 +505,11 @@ __initfunc(void trap_init(void)) set_except_vector(i, handle_reserved); /* - * Only some CPUs have the watch exception. + * Only some CPUs have the watch exceptions or a dedicated + * interrupt vector. */ watch_init(mips_cputype); + setup_dedicated_int(); /* * Handling the following exceptions depends mostly of the cpu type @@ -509,10 +545,12 @@ __initfunc(void trap_init(void)) case CPU_R4600: case CPU_R5000: case CPU_NEVADA: - if(mips_cputype != CPU_R4600) - memcpy((void *)KSEG0, &except_vec0_r4000, 0x80); - else + if(mips_cputype == CPU_NEVADA) { + memcpy((void *)KSEG0, &except_vec0_nevada, 0x80); + } else if (mips_cputype == CPU_R4600) memcpy((void *)KSEG0, &except_vec0_r4600, 0x80); + else + memcpy((void *)KSEG0, &except_vec0_r4000, 0x80); /* * The idea is that this special r4000 general exception @@ -611,5 +649,5 @@ __initfunc(void trap_init(void)) default: panic("Unknown CPU type"); } - flush_cache_all(); + flush_icache_range(KSEG0, KSEG0 + 0x200); } diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 696244b6c..ea81ba7db 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -407,11 +407,11 @@ do_ade(struct pt_regs *regs) { register_t pc = regs->cp0_epc; register_t badvaddr __attribute__ ((unused)) = regs->cp0_badvaddr; - char *adels; + char adels; lock_kernel(); adels = (((regs->cp0_cause & CAUSEF_EXCCODE) >> - CAUSEB_EXCCODE) == 4) ? "adel" : "ades"; + CAUSEB_EXCCODE) == 4) ? 'l' : 's'; #ifdef CONF_NO_UNALIGNED_KERNEL_ACCESS /* @@ -420,13 +420,8 @@ do_ade(struct pt_regs *regs) */ if (kernel_address(badvaddr) && !user_mode(regs)) { show_regs(regs); -#ifdef __mips64 - panic("Caught %s exception in kernel mode accessing %016Lx.", - adels, badvaddr); -#else - panic("Caught %s exception in kernel mode accessing %08lx.", - adels, badvaddr); -#endif + panic("Caught adel%c exception in kernel mode accessing %08lx.", + adels, badvaddr); } #endif /* CONF_NO_UNALIGNED_KERNEL_ACCESS */ @@ -435,15 +430,9 @@ do_ade(struct pt_regs *regs) register_t logpc = pc; if (regs->cp0_cause & CAUSEF_BD) logpc += 4; -#ifdef __mips64 - printk(KERN_DEBUG - "Caught %s in '%s' at 0x%016Lx accessing 0x%016Lx.\n", - adels, current->comm, logpc, regs->cp0_badvaddr); -#else printk(KERN_DEBUG - "Caught %s in '%s' at 0x%08lx accessing 0x%08lx.\n", + "Caught adel%c in '%s' at 0x%08lx accessing 0x%08lx.\n", adels, current->comm, logpc, regs->cp0_badvaddr); -#endif } #endif /* CONF_LOG_UNALIGNED_ACCESSES */ diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 32afe92dd..fd706165c 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -14,8 +14,8 @@ $(CC) $(CFLAGS) -c $< -o $*.o L_TARGET = lib.a -L_OBJS = beep.o checksum.o copy_user.o csum.o dump_tlb.o io.o memset.o \ - memcpy.o strlen_user.o strncpy_user.o tags.o watch.o +L_OBJS = beep.o checksum.o copy_user.o csum.o dump_tlb.o memset.o memcpy.o \ + strlen_user.o strncpy_user.o tags.o watch.o ifdef CONFIG_DECSTATION L_OBJS += pmaxcon.o pmaxio.o diff --git a/arch/mips/lib/checksum.c b/arch/mips/lib/checksum.c index d48dbb245..f3ef6295c 100644 --- a/arch/mips/lib/checksum.c +++ b/arch/mips/lib/checksum.c @@ -5,7 +5,7 @@ * * MIPS specific IP/TCP/UDP checksumming routines * - * Authors: Ralf Baechle, <ralf@gnu.ai.mit.edu> + * Authors: Ralf Baechle, <ralf@waldorf-gmbh.de> * Lots of code moved from tcp.c and ip.c; see those files * for more names. * @@ -14,7 +14,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * $Id:$ + * $Id: checksum.c,v 1.2 1997/07/29 18:37:35 ralf Exp $ */ #include <net/checksum.h> #include <linux/types.h> diff --git a/arch/mips/mm/loadmmu.c b/arch/mips/mm/loadmmu.c index c4b4258b7..1c166b661 100644 --- a/arch/mips/mm/loadmmu.c +++ b/arch/mips/mm/loadmmu.c @@ -3,7 +3,7 @@ * * 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 $ + * $Id: loadmmu.c,v 1.3 1997/09/19 08:44:20 ralf Exp $ */ #include <linux/kernel.h> @@ -29,6 +29,10 @@ void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page); void (*flush_cache_sigtramp)(unsigned long addr); void (*flush_page_to_ram)(unsigned long page); +/* DMA cache operations. */ +void (*flush_cache_pre_dma_out)(unsigned long start, unsigned long size); +void (*flush_cache_post_dma_in)(unsigned long start, unsigned long size); + /* TLB operations. */ void (*flush_tlb_all)(void); void (*flush_tlb_mm)(struct mm_struct *mm); diff --git a/arch/mips/mm/r4xx0.c b/arch/mips/mm/r4xx0.c index 7ac80eb46..9444207a4 100644 --- a/arch/mips/mm/r4xx0.c +++ b/arch/mips/mm/r4xx0.c @@ -3,7 +3,13 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: r4xx0.c,v 1.7 1997/09/12 01:30:27 ralf Exp $ + * $Id: r4xx0.c,v 1.9 1997/12/01 16:17:58 ralf Exp $ + * + * To do: + * + * - this code is a overbloated pig + * - many of the bug workarounds are not efficient at all, but at + * least they are functional ... */ #include <linux/config.h> @@ -118,7 +124,7 @@ static void r4k_clear_page_d32(unsigned long page) * IDT R4600 V1.7 errata: * * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, - * Hit_Invalidate_D and Create_Dirty_Exclusive_D should only be + * Hit_Invalidate_D and Create_Dirty_Excl_D should only be * executed if there is no other dcache activity. If the dcache is * accessed for another instruction immeidately preceding when these * cache instructions are executing, it is possible that the dcache @@ -177,6 +183,44 @@ static void r4k_clear_page_r4600_v1(unsigned long page) } /* + * And this one is for the R4600 V2.0 + */ +static void r4k_clear_page_r4600_v2(unsigned long page) +{ + unsigned int flags; + + save_and_cli(flags); + *(volatile unsigned int *)KSEG1; + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\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" + "cache\t%3,-32(%0)\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\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (page) + :"0" (page), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D) + :"$1","memory"); + restore_flags(flags); +} + + +/* * This is still inefficient. We only can do better if we know the * virtual address where the copy will be accessed. */ @@ -365,6 +409,74 @@ static void r4k_copy_page_r4600_v1(unsigned long to, unsigned long from) "i" (Create_Dirty_Excl_D)); } +static void r4k_copy_page_r4600_v2(unsigned long to, unsigned long from) +{ + unsigned long dummy1, dummy2; + unsigned long reg1, reg2, reg3, reg4; + unsigned int flags; + + __save_and_cli(flags); + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tnop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "\tcache\t%9,(%0)\n\t" + "lw\t%2,(%1)\n\t" + "lw\t%3,4(%1)\n\t" + "lw\t%4,8(%1)\n\t" + "lw\t%5,12(%1)\n\t" + "sw\t%2,(%0)\n\t" + "sw\t%3,4(%0)\n\t" + "sw\t%4,8(%0)\n\t" + "sw\t%5,12(%0)\n\t" + "lw\t%2,16(%1)\n\t" + "lw\t%3,20(%1)\n\t" + "lw\t%4,24(%1)\n\t" + "lw\t%5,28(%1)\n\t" + "sw\t%2,16(%0)\n\t" + "sw\t%3,20(%0)\n\t" + "sw\t%4,24(%0)\n\t" + "sw\t%5,28(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%9,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "lw\t%2,-32(%1)\n\t" + "lw\t%3,-28(%1)\n\t" + "lw\t%4,-24(%1)\n\t" + "lw\t%5,-20(%1)\n\t" + "sw\t%2,-32(%0)\n\t" + "sw\t%3,-28(%0)\n\t" + "sw\t%4,-24(%0)\n\t" + "sw\t%5,-20(%0)\n\t" + "lw\t%2,-16(%1)\n\t" + "lw\t%3,-12(%1)\n\t" + "lw\t%4,-8(%1)\n\t" + "lw\t%5,-4(%1)\n\t" + "sw\t%2,-16(%0)\n\t" + "sw\t%3,-12(%0)\n\t" + "sw\t%4,-8(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sw\t%5,-4(%0)\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), + "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); + restore_flags(flags); +} + /* * If you think for one second that this stuff coming up is a lot * of bulky code eating too many kernel cache lines. Think _again_. @@ -1437,7 +1549,8 @@ static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma, pte_t *ptep; int text; - /* If ownes no valid ASID yet, cannot possibly have gotten + /* + * If ownes no valid ASID yet, cannot possibly have gotten * this page into the cache. */ if(mm->context == 0) @@ -1768,7 +1881,9 @@ static void r4k_flush_page_to_ram_d32i32(unsigned long page) } /* - * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Invalidate_D, + * Writeback and invalidate the primary cache dcache before DMA. + * + * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only * operate correctly if the internal data cache refill buffer is empty. These * CACHE instructions should be separated from any potential data cache miss @@ -1776,6 +1891,104 @@ static void r4k_flush_page_to_ram_d32i32(unsigned long page) * (Revision 2.0 device errata from IDT available on http://www.idt.com/ * in .pdf format.) */ +static void +r4k_flush_cache_pre_dma_out_pc(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + unsigned int cmode, flags; + + cmode = read_32bit_cp0_register(CP0_CONFIG) & CONFIG_CM_CMASK; + if (cmode == CONFIG_CM_CACHABLE_WA || + cmode == CONFIG_CM_CACHABLE_NO_WA) { + /* primary dcache is writethrough, therefore memory + is already consistent with the caches. */ + return; + } + + if (size >= dcache_size) { + flush_cache_all(); + return; + } + + /* Workaround for R4600 bug. See comment above. */ + save_and_cli(flags); + *(volatile unsigned long *)KSEG1; + + a = addr & ~(dc_lsize - 1); + end = (addr + size) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) break; + a += dc_lsize; + } + restore_flags(flags); +} + +static void +r4k_flush_cache_pre_dma_out_sc(unsigned long addr, unsigned long size) +{ + unsigned long end; + unsigned long a; + + if (size >= scache_size) { + flush_cache_all(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(addr); /* Hit_Writeback_Inv_SD */ + if (addr == end) break; + addr += sc_lsize; + } + r4k_flush_cache_pre_dma_out_pc(addr, size); +} + +static void +r4k_flush_cache_post_dma_in_pc(unsigned long addr, unsigned long size) +{ + unsigned long end; + unsigned long a; + + if (size >= dcache_size) { + flush_cache_all(); + return; + } + + /* Workaround for R4600 bug. See comment above. */ + *(volatile unsigned long *)KSEG1; + + a = addr & ~(dc_lsize - 1); + end = (addr + size) & ~(dc_lsize - 1); + while (1) { + invalidate_dcache_line(a); /* Hit_Invalidate_D */ + if (a == end) break; + a += dc_lsize; + } +} + +static void +r4k_flush_cache_post_dma_in_sc(unsigned long addr, unsigned long size) +{ + unsigned long end; + unsigned long a; + + if (size >= scache_size) { + flush_cache_all(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size) & ~(sc_lsize - 1); + while (1) { + invalidate_scache_line(addr); /* Hit_Invalidate_SD */ + if (addr == end) break; + addr += sc_lsize; + } + r4k_flush_cache_pre_dma_out_pc(addr, size); +} + static void r4k_flush_page_to_ram_d32i32_r4600(unsigned long page) { page &= PAGE_MASK; @@ -1785,19 +1998,12 @@ static void r4k_flush_page_to_ram_d32i32_r4600(unsigned long page) #ifdef DEBUG_CACHE printk("r4600_cram[%08lx]", page); #endif - /* - * Workaround for R4600 bug. Explanation see above. - */ - *(volatile unsigned long *)KSEG1; - save_and_cli(flags); blast_dcache32_page(page); #ifdef CONFIG_SGI { unsigned long tmp1, tmp2; - /* - * SGI goo. Have to check this closer ... - */ + __asm__ __volatile__(" .set noreorder .set mips3 @@ -1834,18 +2040,41 @@ static void r4k_flush_page_to_ram_d32i32_r4600(unsigned long page) */ static void r4k_flush_cache_sigtramp(unsigned long addr) { - addr &= ~(dc_lsize - 1); - __asm__ __volatile__("nop;nop;nop;nop"); - protected_writeback_dcache_line(addr); - protected_writeback_dcache_line(addr + dc_lsize); - protected_flush_icache_line(addr); - protected_flush_icache_line(addr + dc_lsize); + unsigned long daddr, iaddr; + + daddr = addr & ~(dc_lsize - 1); + __asm__ __volatile__("nop;nop;nop;nop"); /* R4600 V1.7 */ + 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); +} + +static void r4600v20k_flush_cache_sigtramp(unsigned long addr) +{ + unsigned long daddr, iaddr; + unsigned int flags; + + daddr = addr & ~(dc_lsize - 1); + save_and_cli(flags); + + /* Clear internal cache refill buffer */ + *(volatile unsigned int *)KSEG1; + + 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); + restore_flags(flags); } #undef DEBUG_TLB #undef DEBUG_TLBUPDATE #define NTLB_ENTRIES 48 /* Fixed on all R4XX0 variants... */ + #define NTLB_ENTRIES_HALF 24 /* Fixed on all R4XX0 variants... */ static inline void r4k_flush_tlb_all(void) @@ -1866,7 +2095,7 @@ static inline void r4k_flush_tlb_all(void) set_entrylo1(0); BARRIER; - entry = get_wired(); + entry = 0; /* Blast 'em all away. */ while(entry < NTLB_ENTRIES) { @@ -1953,7 +2182,7 @@ static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) int oldpid, newpid, idx; #ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); + printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); #endif newpid = (vma->vm_mm->context & 0xff); page &= (PAGE_MASK << 1); @@ -2132,37 +2361,6 @@ static void r4k_show_regs(struct pt_regs * regs) printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n", regs->cp0_epc, regs->cp0_status, regs->cp0_cause); } - -static void r4k_add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - save_and_cli(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - flush_tlb_all(); - restore_flags(flags); -} /* Detect and size the various r4k caches. */ static void probe_icache(unsigned long config) @@ -2417,6 +2615,8 @@ static int probe_scache(unsigned long config) static void setup_noscache_funcs(void) { + unsigned int prid; + switch(dc_lsize) { case 16: clear_page = r4k_clear_page_d16; @@ -2428,9 +2628,13 @@ static void setup_noscache_funcs(void) flush_page_to_ram = r4k_flush_page_to_ram_d16i16; break; case 32: - if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2010) { + prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0; + if (prid == 0x2010) { /* R4600 V1.7 */ clear_page = r4k_clear_page_r4600_v1; copy_page = r4k_copy_page_r4600_v1; + } else if (prid == 0x2020) { /* R4600 V2.0 */ + clear_page = r4k_clear_page_r4600_v2; + copy_page = r4k_copy_page_r4600_v2; } else { clear_page = r4k_clear_page_d32; copy_page = r4k_copy_page_d32; @@ -2442,6 +2646,8 @@ static void setup_noscache_funcs(void) flush_page_to_ram = r4k_flush_page_to_ram_d32i32; break; } + flush_cache_pre_dma_out = r4k_flush_cache_pre_dma_out_pc; + flush_cache_post_dma_in = r4k_flush_cache_post_dma_in_pc; } static void setup_scache_funcs(void) @@ -2534,6 +2740,10 @@ static void setup_scache_funcs(void) }; break; } + + /* XXX Do these for Indy style caches also. No need for now ... */ + flush_cache_pre_dma_out = r4k_flush_cache_pre_dma_out_sc; + flush_cache_post_dma_in = r4k_flush_cache_post_dma_in_sc; } typedef int (*probe_func_t)(unsigned long); @@ -2600,6 +2810,9 @@ void ld_mmu_r4xx0(void) /* XXX Handle true second level cache w/ split I/D */ flush_cache_sigtramp = r4k_flush_cache_sigtramp; + if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) { + flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp; + } flush_tlb_all = r4k_flush_tlb_all; flush_tlb_mm = r4k_flush_tlb_mm; diff --git a/arch/mips/sgi/kernel/indyIRQ.S b/arch/mips/sgi/kernel/indyIRQ.S index a8a4c764a..3820a172d 100644 --- a/arch/mips/sgi/kernel/indyIRQ.S +++ b/arch/mips/sgi/kernel/indyIRQ.S @@ -1,4 +1,4 @@ -/* $Id: indyIRQ.S,v 1.5 1996/06/29 12:41:12 dm Exp $ +/* $Id: indyIRQ.S,v 1.2 1997/09/20 19:20:14 root Exp $ * indyIRQ.S: Interrupt exception dispatch code for FullHouse and * Guiness. * @@ -72,7 +72,7 @@ jal indy_timer_interrupt nop # delay slot - j ret_from_sys_call + j ret_from_irq nop # delay slot 1: @@ -83,7 +83,7 @@ jal indy_local0_irqdispatch move a0, sp # delay slot - j ret_from_sys_call + j ret_from_irq nop # delay slot 1: @@ -95,7 +95,7 @@ jal indy_local1_irqdispatch nop - j ret_from_sys_call + j ret_from_irq nop 1: @@ -107,7 +107,7 @@ jal indy_buserror_irq nop - j ret_from_sys_call + j ret_from_irq nop 1: @@ -124,6 +124,6 @@ jal indy_8254timer_irq nop 1: - j ret_from_sys_call + j ret_from_irq nop END(indyIRQ) diff --git a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c index 343a71f9e..01b065359 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.3 1997/08/26 04:34:55 miguel Exp $ + * $Id: indy_int.c,v 1.4 1997/09/20 19:20:15 root Exp $ */ #include <linux/config.h> @@ -269,46 +269,49 @@ atomic_t __mips_bh_counter; */ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { - struct irqaction * action = *(irq + irq_action); - int cpu = smp_processor_id (); - - lock_kernel(); - irq_enter (cpu, irq); - kstat.interrupts[irq]++; - printk("Got irq %d, press a key.", irq); - prom_getchar(); - romvec->imode(); - while (action) { - if (action->flags & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - action->handler(irq, action->dev_id, regs); - action = action->next; - } - irq_exit (cpu, irq); - unlock_kernel(); -} + struct irqaction *action; + int do_random, cpu; -/* - * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return - * stuff - the handler is also running with interrupts disabled unless - * it explicitly enables them later. - */ -asmlinkage void do_fast_IRQ(int irq) -{ - struct irqaction * action = *(irq + irq_action); + cpu = smp_processor_id(); + irq_enter(cpu, irq); + kstat.interrupts[irq]++; - lock_kernel(); printk("Got irq %d, press a key.", irq); prom_getchar(); romvec->imode(); - kstat.interrupts[irq]++; - while (action) { - if (action->flags & SA_SAMPLE_RANDOM) + + /* + * mask and ack quickly, we don't want the irq controller + * thinking we're snobs just because some other CPU has + * disabled global interrupts (we have already done the + * INT_ACK cycles, it's too late to try to pretend to the + * controller that we aren't taking the interrupt). + * + * Commented out because we've already done this in the + * machinespecific part of the handler. It's reasonable to + * do this here in a highlevel language though because that way + * we could get rid of a good part of duplicated code ... + */ + /* mask_and_ack_irq(irq); */ + + action = *(irq + irq_action); + if (action) { + if (!(action->flags & SA_INTERRUPT)) + __sti(); + action = *(irq + irq_action); + do_random = 0; + do { + do_random |= action->flags; + action->handler(irq, action->dev_id, regs); + action = action->next; + } while (action); + if (do_random & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); - action->handler(irq, action->dev_id, NULL); - action = action->next; - } - unlock_kernel(); + __cli(); + } + irq_exit(cpu, irq); + + /* unmasking and bottom half handling is done magically for us. */ } int request_local_irq(unsigned int lirq, void (*func)(int, void *, struct pt_regs *), @@ -415,10 +418,6 @@ void free_irq(unsigned int irq, void *dev_id) void init_IRQ(void) { - int i; - - for (i = 0; i < 16 ; i++) - set_int_vector(i, 0); irq_setup(); } diff --git a/arch/mips/sgi/kernel/indy_timer.c b/arch/mips/sgi/kernel/indy_timer.c index d0ba84929..4b7bfd941 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/07/01 09:00:59 ralf Exp $ + * $Id: indy_timer.c,v 1.3 1997/08/11 04:37:09 ralf Exp $ */ #include <linux/errno.h> diff --git a/arch/mips/sgi/kernel/setup.c b/arch/mips/sgi/kernel/setup.c index c84a28aaa..982319bc2 100644 --- a/arch/mips/sgi/kernel/setup.c +++ b/arch/mips/sgi/kernel/setup.c @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: setup.c,v 1.4 1997/09/11 08:13:11 shaver Exp $ + * $Id: setup.c,v 1.5 1997/09/13 02:19:18 ralf Exp $ */ #include <linux/kernel.h> #include <linux/sched.h> diff --git a/arch/mips/sgi/kernel/system.c b/arch/mips/sgi/kernel/system.c index 769eb733d..affb009f2 100644 --- a/arch/mips/sgi/kernel/system.c +++ b/arch/mips/sgi/kernel/system.c @@ -3,7 +3,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: system.c,v 1.2 1997/07/01 08:51:04 ralf Exp $ + * $Id: system.c,v 1.3 1997/09/13 02:19:18 ralf Exp $ */ #include <linux/kernel.h> #include <linux/types.h> diff --git a/arch/mips/sni/hw-access.c b/arch/mips/sni/hw-access.c index 5ffa6fdd9..5bc31e103 100644 --- a/arch/mips/sni/hw-access.c +++ b/arch/mips/sni/hw-access.c @@ -7,7 +7,7 @@ * * Copyright (C) 1996, 1997 by Ralf Baechle * - * $Id: hw-access.c,v 1.2 1997/07/23 17:41:07 ralf Exp $ + * $Id: hw-access.c,v 1.3 1997/07/29 17:46:46 ralf Exp $ */ #include <linux/delay.h> #include <linux/kbdcntrlr.h> @@ -47,69 +47,69 @@ fd_outb(unsigned char value, unsigned int port) * How to access the floppy DMA functions. */ static void -fd_enable_dma(void) +fd_enable_dma(int channel) { - enable_dma(FLOPPY_DMA); + enable_dma(channel); } static void -fd_disable_dma(void) +fd_disable_dma(int channel) { - disable_dma(FLOPPY_DMA); + disable_dma(channel); } static int -fd_request_dma(void) +fd_request_dma(int channel) { - return request_dma(FLOPPY_DMA, "floppy"); + return request_dma(channel, "floppy"); } static void -fd_free_dma(void) +fd_free_dma(int channel) { - free_dma(FLOPPY_DMA); + free_dma(channel); } static void -fd_clear_dma_ff(void) +fd_clear_dma_ff(int channel) { - clear_dma_ff(FLOPPY_DMA); + clear_dma_ff(channel); } static void -fd_set_dma_mode(char mode) +fd_set_dma_mode(int channel, char mode) { - set_dma_mode(FLOPPY_DMA, mode); + set_dma_mode(channel, mode); } static void -fd_set_dma_addr(unsigned int addr) +fd_set_dma_addr(int channel, unsigned int addr) { - set_dma_addr(FLOPPY_DMA, addr); + set_dma_addr(channel, addr); } static void -fd_set_dma_count(unsigned int count) +fd_set_dma_count(int channel, unsigned int count) { - set_dma_count(FLOPPY_DMA, count); + set_dma_count(channel, count); } static int -fd_get_dma_residue(void) +fd_get_dma_residue(int channel) { - return get_dma_residue(FLOPPY_DMA); + return get_dma_residue(channel); } static void -fd_enable_irq(void) +fd_enable_irq(int irq) { - enable_irq(FLOPPY_IRQ); + enable_irq(irq); } static void -fd_disable_irq(void) +fd_disable_irq(int irq) { - disable_irq(FLOPPY_IRQ); + disable_irq(irq); } void diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S index d051c8b13..b69c44bf8 100644 --- a/arch/mips/sni/int-handler.S +++ b/arch/mips/sni/int-handler.S @@ -2,6 +2,8 @@ * SNI RM200 PCI specific interrupt handler code. * * Copyright (C) 1994 - 1997 by Ralf Baechle + * + * $Id: int-handler.S,v 1.3 1997/12/01 16:39:24 ralf Exp $ */ #include <asm/asm.h> #include <linux/config.h> @@ -18,18 +20,77 @@ SAVE_ALL REG_S sp,PT_OR2(sp) CLI - /* - * Asume we received an interrupt from the PCI ASIC. - */ .set at - lui s0,%hi(SNI_PORT_BASE) + + lb t0,led_cache + addiu t0,1 + sb t0,led_cache + sb t0,PCIMT_CSLED + .data +led_cache: .byte 0 + .text + + mfc0 t0,CP0_STATUS + mfc0 t1,CP0_CAUSE + and t0,t1 + + andi t1,t0,0x0800 # hardware interrupt 1 + bnez t1,hwint1 + andi t1,t0,0x4000 # hardware interrupt 4 + bnez t1,eth_int + + andi t1,t0,0x1000 # hardware interrupt 2 + bnez t1,hwint2 + andi t1,t0,0x2000 # hardware interrupt 3 + bnez t1,hwint3 + andi t1,t0,0x8000 # hardware interrupt 5 + bnez t1,hwint5 + andi t1,t0,0x0400 # hardware interrupt 0 + bnez t1,hwint0 + nop + + j spurious_interrupt # Nothing up ... + nop + + ############################################################################## + +swint0: PANIC("swint0") +swint1: PANIC("swint1") + + /* ------------------------------------------------------------------------ */ + +hwint1: lbu t0,PCIMT_CSITPEND + + andi t1,t0,0x20 + bnez t1,eisa_int + +#ifdef CONFIG_SCSI_NCR53C8XX + andi t1,t0,0x40 + beqz t1,scsi_int +#endif + nop + + j spurious_interrupt + nop + + /* ------------------------------------------------------------------------ */ + +hwint0: lbu t0,PCIMT_CSITPEND + + andi t1,t0,0x01 + beqz t1,int2 + +go_spurious: j spurious_interrupt # we got fooled + nop + +eisa_int: lui s0,%hi(SNI_PORT_BASE) li a0,0x0f sb a0,%lo(SNI_PORT_BASE+0x20)(s0) # poll command lb a0,%lo(SNI_PORT_BASE+0x20)(s0) # read result bgtz a0,poll_second - andi a0,7 + andi a0,7 beq a0,2,poll_second # cascade? - li s1,1 # delay slot + li s1,1 /* * Acknowledge first pic */ @@ -45,12 +106,8 @@ /* * Now call the real handler */ - la t3,IRQ_vectors - sll t2,a0,PTRLOG - addu t3,t2 - LONG_L t3,(t3) - jalr t3 - nop # delay slot + jal do_IRQ + move a1,sp /* * Unblock first pic */ @@ -59,8 +116,8 @@ nor s1,zero,s1 and t1,s1 sb t1,%lo(cache_21)(s4) - jr v0 - sb t1,%lo(SNI_PORT_BASE+0x21)(s0) # delay slot + j ret_from_irq + sb t1,%lo(SNI_PORT_BASE+0x21)(s0) /* * Cascade interrupt from second PIC @@ -69,8 +126,8 @@ poll_second: li a0,0x0f sb a0,%lo(SNI_PORT_BASE+0xa0)(s0) # poll command lb a0,%lo(SNI_PORT_BASE+0xa0)(s0) # read result - bgtz a0,3f - andi a0,7 + bgtz a0,go_spurious + andi a0,7 /* * Acknowledge second pic */ @@ -87,13 +144,9 @@ poll_second: li a0,0x0f /* * Now call the real handler */ - la t3,IRQ_vectors addiu a0,8 - sll t2,a0,PTRLOG - addu t3,t2 - LONG_L t3,(t3) - jalr t3 - nop # delay slot + jal do_IRQ + move a1,sp /* * Unblock second pic */ @@ -103,72 +156,49 @@ poll_second: li a0,0x0f nor s1,zero,s1 and t1,t1,s1 sb t1,%lo(cache_A1)(s4) - jr v0 - sb t1,%lo(SNI_PORT_BASE+0xa1)(s0) # delay slot - -/* - * FIXME: This is definatly wrong but I'll have to do it this way - * 'till I get more hardware info. - * XXX: Apparently the Lance is attached to interrupt #5. - */ -#ifdef CONFIG_PCNET32 - -/* - * FIXME: detect this address - */ -#define LANCE_BASE 0xbb000100 - -/* Offsets from base I/O address. */ -#define LANCE_DATA 0x10 -#define LANCE_ADDR 0x12 -#define LANCE_RESET 0x14 -#define LANCE_BUS_IF 0x16 -#define LANCE_TOTAL_SIZE 0x18 + j ret_from_irq + sb t1,%lo(SNI_PORT_BASE+0xa1)(s0) /* * ... check if we were interrupted by the Lance ... */ -3: lh s0,LANCE_BASE+LANCE_ADDR - sh zero,LANCE_BASE+LANCE_ADDR - lh t1,LANCE_BASE+LANCE_DATA - andi t2,t1,0x80 - beqz t1,3f # no Lance interrupt? - mfc0 t0,CP0_STATUS # delay slot - ori t0,0x041f - xori t0,0x041e +eth_int: mfc0 s0,CP0_STATUS + ori t0,s0,0x4000 + xori t0,0x4000 mtc0 t0,CP0_STATUS + li a0,PCIMT_IRQ_ETHERNET jal do_IRQ - move a1,sp # delay slot - sh s0,LANCE_BASE+LANCE_ADDR - mfc0 t0,CP0_STATUS - ori t0,0x0401 - xori t0,0x0001 - mtc0 t0,CP0_STATUS - j ret_from_sys_call - nop # delay slot + move a1,sp -#endif /* CONFIG_PCNET32 */ + mtc0 s0,CP0_STATUS + + j ret_from_irq + nop #ifdef CONFIG_SCSI_NCR53C8XX /* * ... check if we were interrupted by the NCR ... */ -3: lb t0,PCIMT_CSITPEND - andi t0,0x40 - bnez t0,3f # bit 6 == 0 -> SCSI IRQ - nop # delay slot - jal do_fast_IRQ - li a0,PCIMT_IRQ_SCSI # delay slot - j return - nop # delay slot +scsi_int: li a0,PCIMT_IRQ_SCSI + jal do_IRQ + move a1,sp + j ret_from_irq + nop #endif /* CONFIG_SCSI_NCR53C8XX */ -/* - * "Jump extender" to reach spurious_interrupt - */ -3: j spurious_interrupt - nop # delay slot +pci_int: PANIC("Received PCI interrupt but no handler yet ...\n") +1: j 1b + nop + +int2: PANIC("Received int2 but no handler yet ...\n") +1: j 1b + nop + +hwint2: PANIC("hwint2 and no handler yet") +hwint3: PANIC("hwint3 and no handler yet") +hwint5: PANIC("hwint5 and no handler yet") + END(sni_rm200_pci_handle_int) diff --git a/arch/mips/sni/pci.c b/arch/mips/sni/pci.c index 917d07a81..8a8016e70 100644 --- a/arch/mips/sni/pci.c +++ b/arch/mips/sni/pci.c @@ -119,17 +119,14 @@ static int sni_rm200_pcibios_write_config_dword (unsigned char bus, return PCIBIOS_SUCCESSFUL; } -__initfunc(unsigned long sni_rm200_pcibios_init(unsigned long memory_start, unsigned long memory_end)) -{ - _pcibios_fixup = sni_rm200_pcibios_fixup; - _pcibios_read_config_byte = sni_rm200_pcibios_read_config_byte; - _pcibios_read_config_word = sni_rm200_pcibios_read_config_word; - _pcibios_read_config_dword = sni_rm200_pcibios_read_config_dword; - _pcibios_write_config_byte = sni_rm200_pcibios_write_config_byte; - _pcibios_write_config_word = sni_rm200_pcibios_write_config_word; - _pcibios_write_config_dword = sni_rm200_pcibios_write_config_dword; - - return memory_start; -} +struct pci_ops sni_pci_ops = { + sni_rm200_pcibios_fixup, + sni_rm200_pcibios_read_config_byte, + sni_rm200_pcibios_read_config_word, + sni_rm200_pcibios_read_config_dword, + sni_rm200_pcibios_write_config_byte, + sni_rm200_pcibios_write_config_word, + sni_rm200_pcibios_write_config_dword +}; #endif /* CONFIG_PCI */ diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index b73c857b4..41f64b618 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c @@ -6,6 +6,8 @@ * for more details. * * Copyright (C) 1996, 1997 by Ralf Baechle + * + * $Id: setup.c,v 1.5 1997/12/01 16:19:12 ralf Exp $ */ #include <asm/ptrace.h> #include <linux/ioport.h> @@ -54,7 +56,7 @@ __initfunc(static void sni_irq_setup(void)) * I don't know how to handle the debug button interrupt, so * don't use this button yet or bad things happen ... */ - set_cp0_status(ST0_IM, IE_IRQ0); + set_cp0_status(ST0_IM, IE_IRQ1 | IE_IRQ4); } void (*board_time_init)(struct irqaction *irq); @@ -69,8 +71,7 @@ __initfunc(static void sni_rm200_pci_time_init(struct irqaction *irq)) } unsigned char aux_device_present; -extern unsigned long sni_rm200_pcibios_init (unsigned long memory_start, - unsigned long memory_end); +extern struct pci_ops sni_pci_ops; extern unsigned char sni_map_isa_cache; /* @@ -81,7 +82,7 @@ static inline void sni_pcimt_detect(void) char boardtype[80]; unsigned char csmsr; char *p = boardtype; - int asic; + unsigned int asic, cacheconf; csmsr = *(volatile unsigned char *)PCIMT_CSMSR; @@ -93,6 +94,30 @@ static inline void sni_pcimt_detect(void) asic = (csmsr & 0x08) ? asic : !asic; p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1"); printk("%s.\n", boardtype); + + cacheconf = *(volatile unsigned int *)PCIMT_CACHECONF; + switch(cacheconf & 7) { + case 0: + printk("Secondary cache disabled\n"); + break; + case 1: + printk("256kb secondary cache\n"); + break; + case 2: + printk("512kb secondary cache\n"); + break; + case 3: + printk("1mb secondary cache\n"); + break; + case 4: + printk("2mb secondary cache\n"); + break; + case 5: + printk("4mb secondary cache\n"); + break; + default: + panic("invalid secondary cache size\n"); + } } __initfunc(void sni_rm200_pci_setup(void)) @@ -128,7 +153,7 @@ __initfunc(void sni_rm200_pci_setup(void)) irq_setup = sni_irq_setup; fd_cacheflush = sni_fd_cacheflush; // Will go away feature = &sni_rm200_pci_feature; - port_base = SNI_PORT_BASE; + mips_io_port_base = SNI_PORT_BASE; keyboard_setup = sni_rm200_keyboard_setup; /* @@ -157,5 +182,5 @@ __initfunc(void sni_rm200_pci_setup(void)) * the I/O port space ... */ request_region(0xcfc,0x04,"PCI config data"); - _pcibios_init = sni_rm200_pcibios_init; + pci_ops = &sni_pci_ops; } diff --git a/arch/mips/tools/Makefile b/arch/mips/tools/Makefile index 7216277b3..94cfc08a0 100644 --- a/arch/mips/tools/Makefile +++ b/arch/mips/tools/Makefile @@ -3,6 +3,8 @@ # Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) # Copyright (C) 1997 Ralf Baechle (ralf@gnu.ai.mit.edu) # +# $Id: Makefile,v 1.2 1997/09/23 06:23:49 ralf Exp $ +# TARGET := $(TOPDIR)/include/asm-$(ARCH)/offset.h .S.s: @@ -21,6 +23,6 @@ offset.h: offset.s offset.s: offset.c clean: - rm -f offset.s $(TARGET).new + rm -f offset.[hs] $(TARGET).new include $(TOPDIR)/Rules.make diff --git a/arch/mips/tools/offset.c b/arch/mips/tools/offset.c index 3ea39e133..cc6b7b7d3 100644 --- a/arch/mips/tools/offset.c +++ b/arch/mips/tools/offset.c @@ -3,6 +3,8 @@ * * Copyright (C) 1996 David S. Miller * Made portable by Ralf Baechle + * + * $Id: offset.c,v 1.3 1997/07/29 18:57:11 ralf Exp $ */ #include <linux/types.h> @@ -21,10 +23,10 @@ #define linefeed text("") text("/* DO NOT TOUCH, AUTOGENERATED BY OFFSET.C */"); -text(""); +linefeed; text("#ifndef _MIPS_OFFSET_H"); text("#define _MIPS_OFFSET_H"); -text(""); +linefeed; void output_ptreg_defines(void) { |