1 /*
2 * arch/mips/kernel/pica.S
3 *
4 * Copyright (C) 1995 Waldorf Electronics
5 * written by Ralf Baechle and Andreas Busse
6 *
7 * Acer PICA 61 specific stuff
8 */
9 #include <asm/asm.h>
10 #include <asm/mipsregs.h>
11 #include <asm/jazz.h>
12 #include <asm/pica.h>
13 #include <asm/stackframe.h>
14
15 /*
16 * acer_pica_61_handle_int: Interrupt handler for the ACER Pica-61 boards
17 * FIXME: this is *very* experimental!
18 */
19 .set noreorder
20
21 NESTED(acer_pica_61_handle_int, FR_SIZE, ra)
22 .set noat
23 SAVE_ALL
24 CLI
25 .set at
26
27 /*
28 * Get pending interrupts
29 */
30 mfc0 t0,CP0_CAUSE # get pending interrupts
31 mfc0 t1,CP0_STATUS # get enabled interrupts
32 and t0,t1 # isolate allowed ones
33 andi t0,0xff00 # isolate pending bits
34 beqz t0,spurious_interrupt
35 sll t0,16 # delay slot
36
37 /*
38 * Find irq with highest priority
39 * FIXME: This is slow - use binary search
40 */
41 la t1,ll_vectors
42 1: bltz t0,2f # found pending irq
43 sll t0,1
44 b 1b
45 subu t1,PTRSIZE # delay slot
46
47 /*
48 * Do the low-level stuff
49 */
50 2: lw t0,(t1)
51 jr t0
52 nop # delay slot
53 END(acer_pica_61_handle_int)
54
55 /*
56 * Used for keyboard driver's fake_keyboard_interrupt()
57 */
58 ll_sw0: li s1,~IE_SW0
59 mfc0 t0,CP0_CAUSE
60 and t0,s1
61 mtc0 t0,CP0_CAUSE
62 PRINT("sw0 received...\n")
63 li t1,1
64 b call_real
65 li t3,PTRSIZE # delay slot, re-map to irq level 1
66
67 ll_sw1: li s1,~IE_SW1
68 PANIC("Unimplemented sw1 handler")
69
70 ll_local_dma: li s1,~IE_IRQ0
71 PANIC("Unimplemented local_dma handler")
72
73 ll_local_dev: lbu t0,JAZZ_IO_IRQ_SOURCE
74 #if __mips == 3
75 dsll t0,1
76 ld t0,local_vector(t0)
77 #else /* 32 bit */
78 lw t0,local_vector(t0)
79 #endif
80 jr t0
81 nop
82
83
84 loc_no_irq: PANIC("Unimplemented loc_no_irq handler")
85 /*
86 * Parallel port IRQ, remapped to level 5
87 */
88 loc_parallel: li s1,~JAZZ_IE_PARALLEL
89 li t1,JAZZ_PARALLEL_IRQ
90 b loc_call
91 li t3,PTRSIZE*JAZZ_PARALLEL_IRQ # delay slot
92
93 /*
94 * Floppy IRQ, remapped to level 6
95 */
96 loc_floppy: li s1,~JAZZ_IE_FLOPPY
97 li t1,JAZZ_FLOPPY_IRQ
98 b loc_call
99 li t3,PTRSIZE*JAZZ_FLOPPY_IRQ # delay slot
100
101 /*
102 * Now call the real handler
103 */
104 loc_call: lui s3,%hi(intr_count)
105 lw t2,%lo(intr_count)(s3)
106 la t0,IRQ_vectors # delay slot
107 addiu t2,1
108 sw t2,%lo(intr_count)(s3)
109
110 /*
111 * Temporarily disable interrupt source
112 */
113 lhu t2,JAZZ_IO_IRQ_ENABLE
114 addu t0,t3 # make ptr to IRQ handler
115 lw t0,(t0)
116 and t2,s1 # delay slot
117 sh t2,JAZZ_IO_IRQ_ENABLE
118 jalr t0 # call IRQ handler
119 nor s1,zero,s1 # delay slot
120
121 /*
122 * Reenable interrupt
123 */
124 lhu t2,JAZZ_IO_IRQ_ENABLE
125 lw t1,%lo(intr_count)(s3) # delay slot
126 or t2,s1
127 sh t2,JAZZ_IO_IRQ_ENABLE
128
129 subu t1,1
130 jr v0
131 sw t1,%lo(intr_count)(s3) # delay slot
132
133 ll_isa_irq: li s1,~IE_IRQ2
134 PANIC("Unimplemented isa_irq handler")
135
136 ll_isa_nmi: li s1,~IE_IRQ3
137 PANIC("Unimplemented isa_nmi handler")
138
139 /*
140 * Timer IRQ
141 * We remap the timer irq to be more similar to an IBM compatible
142 */
143 ll_timer: lw zero,JAZZ_TIMER_REGISTER # timer irq cleared on read
144 li s1,~IE_IRQ4
145 li t1,0
146 b call_real
147 li t3,0 # delay slot, re-map to irq level 0
148
149 /*
150 * CPU count/compare IRQ (unused)
151 */
152 ll_count: j return
153 mtc0 zero,CP0_COMPARE
154
155 /*
156 * Now call the real handler
157 */
158 call_real: lui s3,%hi(intr_count)
159 lw t2,%lo(intr_count)(s3)
160 la t0,IRQ_vectors
161 addiu t2,1
162 sw t2,%lo(intr_count)(s3)
163
164 /*
165 * temporarily disable interrupt
166 */
167 mfc0 t2,CP0_STATUS
168 and t2,s1
169
170 addu t0,t3
171 lw t0,(t0)
172 mtc0 t2,CP0_STATUS # delay slot
173 jalr t0
174 nor s1,zero,s1 # delay slot
175
176 /*
177 * reenable interrupt
178 */
179 mfc0 t2,CP0_STATUS
180 or t2,s1
181 mtc0 t2,CP0_STATUS
182
183 lw t2,%lo(intr_count)(s3)
184 subu t2,1
185
186 jr v0
187 sw t2,%lo(intr_count)(s3)
188
189 .data
190 PTR ll_sw0 # SW0
191 PTR ll_sw1 # SW1
192 PTR ll_local_dma # Local DMA
193 PTR ll_local_dev # Local devices
194 PTR ll_isa_irq # ISA IRQ
195 PTR ll_isa_nmi # ISA NMI
196 PTR ll_timer # Timer
197 ll_vectors: PTR ll_count # Count/Compare IRQ
198
199
200 /*
201 * Sound? What sound hardware (whistle) ???
202 */
203 loc_sound: PANIC("Unimplemented loc_sound handler")
204 loc_video: PANIC("Unimplemented loc_video handler")
205
206 /*
207 * Ethernet interrupt handler, remapped to level 2
208 */
209 loc_ethernet: li s1,~JAZZ_IE_ETHERNET
210 li t1,JAZZ_ETHERNET_IRQ
211 b loc_call
212 li t3,PTRSIZE*JAZZ_ETHERNET_IRQ # delay slot
213
214 loc_scsi: PANIC("Unimplemented loc_scsi handler")
215
216 /*
217 * Keyboard interrupt handler
218 */
219 loc_keyboard: li s1,~JAZZ_IE_KEYBOARD
220 li t1,JAZZ_KEYBOARD_IRQ
221 b loc_call
222 li t3,PTRSIZE*JAZZ_KEYBOARD_IRQ # re-map to irq level 1
223
224 loc_mouse: PANIC("Unimplemented loc_mouse handler")
225
226 /*
227 * Serial port 1 IRQ, remapped to level 3
228 */
229 loc_serial1: li s1,~JAZZ_IE_SERIAL1
230 li t1,JAZZ_SERIAL1_IRQ
231 b loc_call
232 li t3,PTRSIZE*JAZZ_SERIAL1_IRQ # delay slot
233
234 /*
235 * Serial port 2 IRQ, remapped to level 4
236 */
237 loc_serial2: li s1,~JAZZ_IE_SERIAL2
238 li t1,JAZZ_SERIAL2_IRQ
239 b loc_call
240 li t3,PTRSIZE*JAZZ_SERIAL2_IRQ # delay slot
241
242 .data
243 local_vector: PTR loc_no_irq
244 PTR loc_parallel
245 PTR loc_floppy
246 PTR loc_sound
247 PTR loc_video
248 PTR loc_ethernet
249 PTR loc_scsi
250 PTR loc_keyboard
251 PTR loc_mouse
252 PTR loc_serial1
253 PTR loc_serial2
254
255 .align 5
256 .text
257 LEAF(spurious_interrupt)
258 /*
259 * Nothing happened... (whistle)
260 */
261 lui t1,%hi(spurious_count)
262 lw t0,%lo(spurious_count)(t1)
263 la v0,return
264 addiu t0,1
265 jr ra
266 sw t0,%lo(spurious_count)(t1)
267 END(spurious_interrupt)
268