diff options
Diffstat (limited to 'arch/mips/sni/int-handler.S')
-rw-r--r-- | arch/mips/sni/int-handler.S | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S new file mode 100644 index 000000000..367c07d84 --- /dev/null +++ b/arch/mips/sni/int-handler.S @@ -0,0 +1,193 @@ +/* + * SNI RM200 PCI specific interrupt handler code. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle + * + * This is a verbose copy of the Tyne/rPC44 interrupt handler. We + * don't share the code because the SNI machine has some extra interrupt + * features that want to be supported. + */ +#include <asm/asm.h> +#include <linux/config.h> +#include <asm/mipsconfig.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + + .text + .set noreorder + .set noat + .align 5 + NESTED(sni_rm200_pci_handle_int, FR_SIZE, sp) + SAVE_ALL + REG_S sp,FR_ORIG_REG2(sp) + CLI + .set at + lui s0,%hi(PORT_BASE_SNI) + li a0,0x0f + sb a0,%lo(PORT_BASE_SNI+0x20)(s0) # poll command + lb a0,%lo(PORT_BASE_SNI+0x20)(s0) # read result + bgtz a0,poll_second + andi a0,7 + beq a0,2,poll_second # cascade? + li s1,1 # delay slot + /* + * Acknowledge first pic + */ + lb t2,%lo(PORT_BASE_SNI+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(PORT_BASE_SNI+0x21)(s0) + lui s3,%hi(intr_count) + lw s7,%lo(intr_count)(s3) + li t2,0x20 + sb t2,%lo(PORT_BASE_SNI+0x20)(s0) + /* + * Now call the real handler + */ + la t3,IRQ_vectors + sll t2,a0,PTRLOG + addu t3,t2 + LONG_L t3,(t3) + addiu t0,s7,1 + jalr t3 + sw t0,%lo(intr_count)(s3) + sw s7,%lo(intr_count)(s3) + /* + * Unblock first pic + */ + lbu t1,%lo(PORT_BASE_SNI+0x21)(s0) + lb t1,%lo(cache_21)(s4) + nor s1,zero,s1 + and t1,s1 + sb t1,%lo(cache_21)(s4) + jr v0 + sb t1,%lo(PORT_BASE_SNI+0x21)(s0) # delay slot + + /* + * Cascade interrupt from second PIC + */ + .align 5 +poll_second: li a0,0x0f + sb a0,%lo(PORT_BASE_SNI+0xa0)(s0) # poll command + lb a0,%lo(PORT_BASE_SNI+0xa0)(s0) # read result + bgtz a0,3f + andi a0,7 + /* + * Acknowledge second pic + */ + lbu t2,%lo(PORT_BASE_SNI+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(PORT_BASE_SNI+0xa1)(s0) + li t3,0x20 + sb t3,%lo(PORT_BASE_SNI+0xa0)(s0) + lui s3,%hi(intr_count) + lw s7,%lo(intr_count)(s3) + sb t3,%lo(PORT_BASE_SNI+0x20)(s0) + /* + * Now call the real handler + */ + la t3,IRQ_vectors + addiu a0,8 + sll t2,a0,PTRLOG + addu t3,t2 + LONG_L t3,(t3) + addiu t0,s7,1 + jalr t3 + sw t0,%lo(intr_count)(s3) # delay slot + sw s7,%lo(intr_count)(s3) + /* + * Unblock second pic + */ + lb t1,%lo(PORT_BASE_SNI+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) + jr v0 + sb t1,%lo(PORT_BASE_SNI+0xa1)(s0) # delay slot + +/* + * FIXME: This is definatly wrong but I'll have to do it this way + * 'till I get more hardware info. + */ +#ifdef CONFIG_LANCE32 + +/* + * 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 + +/* + * ... 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 + mtc0 t0,CP0_STATUS + jal do_IRQ + li a0,10 # 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 + +#endif /* CONFIG_LANCE32 */ + +/* + * FIXME: This is definatly wrong but I'll have to do it this way + * 'till I get more hardware info. + */ +#ifdef CONFIG_SCSI_NCR53C8XX + +/* + * FIXME: detect this address + */ +#define NCR_BASE 0xb8000000 + +/* Offsets from base I/O address. */ +#define NCR_INTF 0x14 + +/* + * ... check if we were interrupted by the NCR ... + */ +3: lb t0,NCR_BASE+NCR_INTF + andi t0,7 + beqz t0,3f # no NCR interrupt? + nop # delay slot + jal do_fast_IRQ + li a0,5 # delay slot + j return + nop # delay slot + +#endif /* CONFIG_SCSI_NCR53C8XX */ + +/* + * "Jump extender" to reach spurious_interrupt + */ +3: j spurious_interrupt + nop # delay slot + END(sni_rm200_pci_handle_int) |