aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/jazz/int-handler.S
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/mips/jazz/int-handler.S
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/mips/jazz/int-handler.S')
-rw-r--r--arch/mips/jazz/int-handler.S282
1 files changed, 282 insertions, 0 deletions
diff --git a/arch/mips/jazz/int-handler.S b/arch/mips/jazz/int-handler.S
new file mode 100644
index 00000000000..4dbcf91db88
--- /dev/null
+++ b/arch/mips/jazz/int-handler.S
@@ -0,0 +1,282 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle and Andreas Busse
+ *
+ * Jazz family specific interrupt stuff
+ *
+ * To do: On Jazz machines we remap some non-ISA interrupts to ISA
+ * interrupts. These interrupts should use their own vectors.
+ * Squeeze the last cycles out of the handlers. Only a dead
+ * cycle is a good cycle.
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/jazz.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * jazz_handle_int: Interrupt handler for the ACER Pica-61 boards
+ */
+ .set noreorder
+
+ NESTED(jazz_handle_int, PT_SIZE, ra)
+ .set noat
+ SAVE_ALL
+ CLI
+ .set at
+
+ /*
+ * Get pending interrupts
+ */
+ mfc0 t0,CP0_CAUSE # get pending interrupts
+ mfc0 t1,CP0_STATUS # get enabled interrupts
+ and t0,t1 # isolate allowed ones
+ andi t0,0xff00 # isolate pending bits
+ beqz t0,3f
+ sll t0,16 # delay slot
+
+ /*
+ * Find irq with highest priority
+ * FIXME: This is slow - use binary search
+ */
+ la t1,ll_vectors
+1: bltz t0,2f # found pending irq
+ sll t0,1
+ b 1b
+ subu t1,PTRSIZE # delay slot
+
+ /*
+ * Do the low-level stuff
+ */
+2: lw t0,(t1)
+ jr t0
+ nop # delay slot
+ END(jazz_handle_int)
+
+ll_sw0: li s1,~IE_SW0
+ mfc0 t0,CP0_CAUSE
+ and t0,s1
+ mtc0 t0,CP0_CAUSE
+ PANIC("Unimplemented sw0 handler")
+
+ll_sw1: li s1,~IE_SW1
+ mfc0 t0,CP0_CAUSE
+ and t0,s1
+ mtc0 t0,CP0_CAUSE
+ PANIC("Unimplemented sw1 handler")
+
+ll_local_dma: li s1,~IE_IRQ0
+ PANIC("Unimplemented local_dma handler")
+
+ll_local_dev: lbu t0,JAZZ_IO_IRQ_SOURCE
+#if PTRSIZE == 8 /* True 64 bit kernel */
+ dsll t0,1
+#endif
+ .set reorder
+ LONG_L t0,local_vector(t0)
+ jr t0
+ .set noreorder
+
+/*
+ * The braindead PICA hardware gives us no way to distinguish if we really
+ * received interrupt 7 from the (E)ISA bus or if we just received an
+ * interrupt with no findable cause. This sometimes happens with braindead
+ * cards. Oh well - for all the Jazz boxes slots are more or less just
+ * whistles and bells and we're aware of the problem.
+ */
+ll_isa_irq: lw a0, JAZZ_EISA_IRQ_ACK
+
+ jal do_IRQ
+ move a1,sp
+
+ j ret_from_irq
+ nop
+
+/*
+ * Hmm... This is not just a plain PC clone so the question is
+ * which devices on Jazz machines can generate an (E)ISA NMI?
+ * (Writing to nonexistent memory?)
+ */
+ll_isa_nmi: li s1,~IE_IRQ3
+ PANIC("Unimplemented isa_nmi handler")
+
+/*
+ * Timer IRQ - remapped to be more similar to an IBM compatible.
+ *
+ * The timer interrupt is handled specially to ensure that the jiffies
+ * variable is updated at all times. Specifically, the timer interrupt is
+ * just like the complete handlers except that it is invoked with interrupts
+ * disabled and should never re-enable them. If other interrupts were
+ * allowed to be processed while the timer interrupt is active, then the
+ * other interrupts would have to avoid using the jiffies variable for delay
+ * and interval timing operations to avoid hanging the system.
+ */
+ll_timer: lw zero,JAZZ_TIMER_REGISTER # timer irq cleared on read
+ li s1,~IE_IRQ4
+
+ li a0, JAZZ_TIMER_IRQ
+ jal do_IRQ
+ move a1,sp
+
+ mfc0 t0,CP0_STATUS # disable interrupts again
+ ori t0,1
+ xori t0,1
+ mtc0 t0,CP0_STATUS
+
+ j ret_from_irq
+ nop
+
+/*
+ * CPU count/compare IRQ (unused)
+ */
+ll_count: j ret_from_irq
+ mtc0 zero,CP0_COMPARE
+
+#if 0
+/*
+ * Call the handler for the interrupt
+ * (Currently unused)
+ */
+call_real: /*
+ * temporarily disable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ and t2,s1
+ mtc0 t2,CP0_STATUS
+ nor s1,zero,s1
+ jal do_IRQ
+
+ /*
+ * reenable interrupt
+ */
+ mfc0 t2,CP0_STATUS
+ or t2,s1
+ mtc0 t2,CP0_STATUS
+ j ret_from_irq
+#endif
+
+ .data
+ PTR ll_sw0 # SW0
+ PTR ll_sw1 # SW1
+ PTR ll_local_dma # Local DMA
+ PTR ll_local_dev # Local devices
+ PTR ll_isa_irq # ISA IRQ
+ PTR ll_isa_nmi # ISA NMI
+ PTR ll_timer # Timer
+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
+ */
+loc_parallel: li s1,~JAZZ_IE_PARALLEL
+ li a0,JAZZ_PARALLEL_IRQ
+ b loc_call
+
+/*
+ * Floppy IRQ
+ */
+loc_floppy: li s1,~JAZZ_IE_FLOPPY
+ li a0,JAZZ_FLOPPY_IRQ
+ b loc_call
+
+/*
+ * Sound IRQ
+ */
+loc_sound: PANIC("Unimplemented loc_sound handler")
+loc_video: PANIC("Unimplemented loc_video handler")
+
+/*
+ * Ethernet interrupt handler
+ */
+loc_ethernet: li s1,~JAZZ_IE_ETHERNET
+ li a0,JAZZ_ETHERNET_IRQ
+ b loc_call
+
+/*
+ * SCSI interrupt handler
+ */
+loc_scsi: li s1,~JAZZ_IE_SCSI
+ li a0,JAZZ_SCSI_IRQ
+ b loc_call
+
+/*
+ * Keyboard interrupt handler
+ */
+loc_keyboard: li s1,~JAZZ_IE_KEYBOARD
+ li a0,JAZZ_KEYBOARD_IRQ
+ b loc_call
+
+/*
+ * Mouse interrupt handler
+ */
+loc_mouse: li s1,~JAZZ_IE_MOUSE
+ li a0,JAZZ_MOUSE_IRQ
+ b loc_call
+
+/*
+ * Serial port 1 IRQ
+ */
+loc_serial1: li s1,~JAZZ_IE_SERIAL1
+ li a0,JAZZ_SERIAL1_IRQ
+ b loc_call
+
+/*
+ * Serial port 2 IRQ
+ */
+loc_serial2: li s1,~JAZZ_IE_SERIAL2
+ li a0,JAZZ_SERIAL2_IRQ
+ b loc_call
+
+/*
+ * Call the interrupt handler for an interrupt generated by a
+ * local device.
+ */
+loc_call: /*
+ * Temporarily disable interrupt source
+ */
+ lhu t2,JAZZ_IO_IRQ_ENABLE
+ and t2,s1
+ sh t2,JAZZ_IO_IRQ_ENABLE
+
+ nor s1,zero,s1
+ jal do_IRQ
+
+ /*
+ * Reenable interrupt
+ */
+ lhu t2,JAZZ_IO_IRQ_ENABLE
+ or t2,s1
+ sh t2,JAZZ_IO_IRQ_ENABLE
+
+ j ret_from_irq
+
+/*
+ * "Jump extender" to reach spurious_interrupt
+ */
+3: j spurious_interrupt
+
+/*
+ * Vectors for interrupts generated by local devices
+ */
+ .data
+local_vector: PTR loc_no_irq
+ PTR loc_parallel
+ PTR loc_floppy
+ PTR loc_sound
+ PTR loc_video
+ PTR loc_ethernet
+ PTR loc_scsi
+ PTR loc_keyboard
+ PTR loc_mouse
+ PTR loc_serial1
+ PTR loc_serial2