/* * 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 #include #include #include #include /* * 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 i8259_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 return 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