patch-2.3.9 linux/arch/mips/sni/int-handler.S
Next file: linux/arch/mips/sni/io.c
Previous file: linux/arch/mips/sni/hw-access.c
Back to the patch index
Back to the overall index
- Lines: 269
- Date:
Fri Jun 25 17:40:13 1999
- Orig file:
v2.3.8/linux/arch/mips/sni/int-handler.S
- Orig date:
Tue Oct 20 13:52:55 1998
diff -u --recursive --new-file v2.3.8/linux/arch/mips/sni/int-handler.S linux/arch/mips/sni/int-handler.S
@@ -1,17 +1,22 @@
-/* $Id: int-handler.S,v 1.4 1998/05/07 14:17:47 ralf Exp $
+/* $Id: int-handler.S,v 1.4 1999/01/04 16:03:58 ralf Exp $
*
* SNI RM200 PCI specific interrupt handler code.
*
* Copyright (C) 1994 - 1997 by Ralf Baechle
*/
#include <asm/asm.h>
-#include <linux/config.h>
#include <asm/mipsconfig.h>
#include <asm/mipsregs.h>
#include <asm/regdef.h>
#include <asm/sni.h>
#include <asm/stackframe.h>
+/* The PCI ASIC has the nasty property that it may delay writes if it is busy.
+ As a consequence from writes that have not graduated when we exit from the
+ interrupt handler we might catch a spurious interrupt. To avoid this we
+ force the PCI ASIC to graduate all writes by executing a read from the
+ PCI bus. */
+
.set noreorder
.set noat
.align 5
@@ -20,34 +25,38 @@
CLI
.set at
- lb t0,led_cache
- addiu t0,1
- sb t0,led_cache
- sb t0,PCIMT_CSLED
+ /* Blinken light ... */
+ lb t0, led_cache
+ addiu t0, 1
+ sb t0, led_cache
+ sb t0, PCIMT_CSLED # write only register
.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
+ mfc0 t0, CP0_STATUS
+ mfc0 t1, CP0_CAUSE
+ and t0, t1
+
+ /* The following interrupt dispatch tests for hwint 1 /
+ EISA bridge first such that the timer interrupt get the
+ highest priority. */
+ andi t1, t0, 0x0800 # hardware interrupt 1
+ bnez t1, hwint1
+ andi t1, t0, 0x4000 # hardware interrupt 4
+ bnez t1, hwint4
+
+ 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 ...
+ j return # spurious interrupt
nop
##############################################################################
@@ -57,146 +66,61 @@
/* ------------------------------------------------------------------------ */
-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
+/* hwint1 deals with EISA and SCSI interrupts. */
+hwint1: lbu s0, PCIMT_CSITPEND
-go_spurious: j spurious_interrupt # we got fooled
+ andi t1, s0, 0x20
+ beqz t1, 1f
+ andi s1, s0, 0x40
+ lbu a0, PCIMT_INT_ACKNOWLEDGE # IACK cycle
+ xori t0, a0, 0xff
+ beqz t0, 1f # spurious interrupt?
nop
+ jal i8259_do_irq # call real handler
+ move a1, sp
-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
- beq a0,2,poll_second # cascade?
- li s1,1
- /*
- * Acknowledge first pic
- */
- lb t2,%lo(SNI_PORT_BASE+0x21)(s0)
- lui s4,%hi(cache_21)
- lb t0,%lo(cache_21)(s4)
- sllv s1,s1,a0
- or t0,s1
- sb t0,%lo(cache_21)(s4)
- sb t0,%lo(SNI_PORT_BASE+0x21)(s0)
- li t2,0x20
- sb t2,%lo(SNI_PORT_BASE+0x20)(s0)
- /*
- * Now call the real handler
- */
+1: bnez s1, 1f
+ li a0, PCIMT_IRQ_SCSI
jal do_IRQ
- move a1,sp
- /*
- * Unblock first pic
- */
- lbu t1,%lo(SNI_PORT_BASE+0x21)(s0)
- lb t1,%lo(cache_21)(s4)
- nor s1,zero,s1
- and t1,s1
- sb t1,%lo(cache_21)(s4)
- j ret_from_irq
- sb t1,%lo(SNI_PORT_BASE+0x21)(s0)
+ move a1, sp
- /*
- * Cascade interrupt from second PIC
- */
- .align 5
-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,go_spurious
- andi a0,7
- /*
- * Acknowledge second pic
- */
- lbu t2,%lo(SNI_PORT_BASE+0xa1)(s0)
- lui s4,%hi(cache_A1)
- lb t3,%lo(cache_A1)(s4)
- sllv s1,s1,a0
- or t3,s1
- sb t3,%lo(cache_A1)(s4)
- sb t3,%lo(SNI_PORT_BASE+0xa1)(s0)
- li t3,0x20
- sb t3,%lo(SNI_PORT_BASE+0xa0)(s0)
- sb t3,%lo(SNI_PORT_BASE+0x20)(s0)
- /*
- * Now call the real handler
- */
- addiu a0,8
- jal do_IRQ
- move a1,sp
- /*
- * Unblock second pic
- */
- lb t1,%lo(SNI_PORT_BASE+0xa1)(s0)
- lb t1,%lo(cache_A1)(s4)
- subu t0,1
- nor s1,zero,s1
- and t1,t1,s1
- sb t1,%lo(cache_A1)(s4)
+1: lui t0, %hi(PCIMT_CSITPEND)
j ret_from_irq
- sb t1,%lo(SNI_PORT_BASE+0xa1)(s0)
-
-/*
- * ... check if we were interrupted by the Lance ...
- */
-eth_int: mfc0 s0,CP0_STATUS
- ori t0,s0,0x4000
- xori t0,0x4000
- mtc0 t0,CP0_STATUS
+ lbu zero, %lo(PCIMT_CSITPEND)(t0)
- li a0,PCIMT_IRQ_ETHERNET
- jal do_IRQ
- move a1,sp
+ /* ------------------------------------------------------------------------ */
- mtc0 s0,CP0_STATUS
+/* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
+ button interrupts. */
+hwint0: PANIC("Received int0 but no handler yet ...\n")
+1: j 1b
+ nop
- j ret_from_irq
+go_spurious: j spurious_interrupt # we got fooled
nop
-#ifdef CONFIG_SCSI_NCR53C8XX
+/* hwint4 is used for only the onboard PCnet 32. */
+hwint4: mfc0 s0, CP0_STATUS
+ ori t0, s0, 0x4000
+ xori t0, 0x4000
+ mtc0 t0, CP0_STATUS
-/*
- * ... check if we were interrupted by the NCR ...
- */
-scsi_int: li a0,PCIMT_IRQ_SCSI
+ li a0, PCIMT_IRQ_ETHERNET
jal do_IRQ
- move a1,sp
- j ret_from_irq
- nop
-
-#endif /* CONFIG_SCSI_NCR53C8XX */
+ move a1, sp
-pci_int: PANIC("Received PCI interrupt but no handler yet ...\n")
-1: j 1b
- nop
+ mtc0 s0, CP0_STATUS
-int2: PANIC("Received int2 but no handler yet ...\n")
-1: j 1b
+ j ret_from_irq
nop
+/* This interrupt was used for the com1 console on the first prototypes. */
hwint2: PANIC("hwint2 and no handler yet")
+
+/* hwint3 should deal with the PCI A - D interrupts. */
hwint3: PANIC("hwint3 and no handler yet")
+
+/* hwint5 is the r4k count / compare interrupt */
hwint5: PANIC("hwint5 and no handler yet")
END(sni_rm200_pci_handle_int)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)