1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle and Andreas Busse
7 *
8 * Jazz family specific interrupt stuff
9 *
10 * To do: On Jazz machines we remap some non-ISA interrupts to ISA
11 *        interrupts.  These interrupts should use their own vectors.
12 *        Squeeze the last cycles out of the handlers.  Only a dead
13 *        cycle is a good cycle.
14 */
15#include <asm/asm.h>
16#include <asm/mipsregs.h>
17#include <asm/jazz.h>
18#include <asm/regdef.h>
19#include <asm/stackframe.h>
20
21/*
22 * jazz_handle_int: Interrupt handler for the ACER Pica-61 boards
23 */
24		.set	noreorder
25
26		NESTED(jazz_handle_int, PT_SIZE, ra)
27		.set	noat
28		SAVE_ALL
29		CLI
30		.set	at
31
32		/*
33		 * Get pending interrupts
34		 */
35		mfc0	t0,CP0_CAUSE		# get pending interrupts
36		mfc0	t1,CP0_STATUS		# get enabled interrupts
37		and	t0,t1			# isolate allowed ones
38		andi	t0,0xff00		# isolate pending bits
39		beqz	t0,3f
40		sll	t0,16			# delay slot
41
42		/*
43		 * Find irq with highest priority
44		 * FIXME: This is slow - use binary search
45		 */
46		la	t1,ll_vectors
471:		bltz	t0,2f			# found pending irq
48		sll	t0,1
49		b	1b
50		subu	t1,PTRSIZE		# delay slot
51
52		/*
53		 * Do the low-level stuff
54		 */
552:		lw	t0,(t1)
56		jr	t0
57		nop				# delay slot
58		END(jazz_handle_int)
59
60ll_sw0:		li	s1,~IE_SW0
61		mfc0	t0,CP0_CAUSE
62		and	t0,s1
63		mtc0	t0,CP0_CAUSE
64		PANIC("Unimplemented sw0 handler")
65
66ll_sw1:		li	s1,~IE_SW1
67		mfc0	t0,CP0_CAUSE
68		and	t0,s1
69		mtc0	t0,CP0_CAUSE
70		PANIC("Unimplemented sw1 handler")
71
72ll_local_dma:	li	s1,~IE_IRQ0
73		PANIC("Unimplemented local_dma handler")
74
75ll_local_dev:	lbu	t0,JAZZ_IO_IRQ_SOURCE
76#if PTRSIZE == 8	/* True 64 bit kernel */
77		dsll	t0,1
78#endif
79		.set	reorder
80		LONG_L	t0,local_vector(t0)
81		jr	t0
82		.set	noreorder
83
84/*
85 * The braindead PICA hardware gives us no way to distinguish if we really
86 * received interrupt 7 from the (E)ISA bus or if we just received an
87 * interrupt with no findable cause.  This sometimes happens with braindead
88 * cards.  Oh well - for all the Jazz boxes slots are more or less just
89 * whistles and bells and we're aware of the problem.
90 */
91ll_isa_irq:	lw	a0,JAZZ_EISA_IRQ_ACK
92
93		jal	i8259_do_irq
94		 move	a1,sp
95
96		j	ret_from_irq
97		nop
98
99/*
100 * Hmm...  This is not just a plain PC clone so the question is
101 * which devices on Jazz machines can generate an (E)ISA NMI?
102 * (Writing to nonexistent memory?)
103 */
104ll_isa_nmi:	li	s1,~IE_IRQ3
105		PANIC("Unimplemented isa_nmi handler")
106
107/*
108 * Timer IRQ - remapped to be more similar to an IBM compatible.
109 *
110 * The timer interrupt is handled specially to ensure that the jiffies
111 * variable is updated at all times.  Specifically, the timer interrupt is
112 * just like the complete handlers except that it is invoked with interrupts
113 * disabled and should never re-enable them.  If other interrupts were
114 * allowed to be processed while the timer interrupt is active, then the
115 * other interrupts would have to avoid using the jiffies variable for delay
116 * and interval timing operations to avoid hanging the system.
117 */
118ll_timer:	lw	zero,JAZZ_TIMER_REGISTER # timer irq cleared on read
119		li	s1,~IE_IRQ4
120
121		li	a0, JAZZ_TIMER_IRQ
122		jal	do_IRQ
123		 move	a1,sp
124
125		mfc0	t0,CP0_STATUS		# disable interrupts again
126		ori	t0,1
127		xori	t0,1
128		mtc0	t0,CP0_STATUS
129
130		j	ret_from_irq
131		 nop
132
133/*
134 * CPU count/compare IRQ (unused)
135 */
136ll_count:	j	return
137		 mtc0	zero,CP0_COMPARE
138
139#if 0
140/*
141 * Call the handler for the interrupt
142 * (Currently unused)
143 */
144call_real:	/*
145		 * temporarily disable interrupt
146		 */
147		mfc0	t2,CP0_STATUS
148		and	t2,s1
149		mtc0	t2,CP0_STATUS
150		nor	s1,zero,s1
151		jal	do_IRQ
152
153		/*
154		 * reenable interrupt
155		 */
156		mfc0	t2,CP0_STATUS
157		or	t2,s1
158		mtc0	t2,CP0_STATUS
159		j	ret_from_irq
160#endif
161
162		.data
163		PTR	ll_sw0			# SW0
164		PTR	ll_sw1			# SW1
165		PTR	ll_local_dma		# Local DMA
166		PTR	ll_local_dev		# Local devices
167		PTR	ll_isa_irq		# ISA IRQ
168		PTR	ll_isa_nmi		# ISA NMI
169		PTR	ll_timer		# Timer
170ll_vectors:	PTR	ll_count		# Count/Compare IRQ
171
172		/*
173		 * Interrupt handlers for local devices.
174		 */
175		.text
176		.set	reorder
177loc_no_irq:	PANIC("Unimplemented loc_no_irq handler")
178/*
179 * Parallel port IRQ
180 */
181loc_parallel:	li	s1,~JAZZ_IE_PARALLEL
182		li	a0,JAZZ_PARALLEL_IRQ
183		b	loc_call
184
185/*
186 * Floppy IRQ
187 */
188loc_floppy:	li	s1,~JAZZ_IE_FLOPPY
189		li	a0,JAZZ_FLOPPY_IRQ
190		b	loc_call
191
192/*
193 * Sound IRQ
194 */
195loc_sound:	PANIC("Unimplemented loc_sound handler")
196loc_video:	PANIC("Unimplemented loc_video handler")
197
198/*
199 * Ethernet interrupt handler
200 */
201loc_ethernet: 	li	s1,~JAZZ_IE_ETHERNET
202		li	a0,JAZZ_ETHERNET_IRQ
203		b	loc_call
204
205/*
206 * SCSI interrupt handler
207 */
208loc_scsi:	li	s1,~JAZZ_IE_SCSI
209		li	a0,JAZZ_SCSI_IRQ
210		b	loc_call
211
212/*
213 * Keyboard interrupt handler
214 */
215loc_keyboard:	li	s1,~JAZZ_IE_KEYBOARD
216		li	a0,JAZZ_KEYBOARD_IRQ
217		b	loc_call
218
219/*
220 * Mouse interrupt handler
221 */
222loc_mouse:	li	s1,~JAZZ_IE_MOUSE
223		li	a0,JAZZ_MOUSE_IRQ
224		b	loc_call
225
226/*
227 * Serial port 1 IRQ
228 */
229loc_serial1:	li	s1,~JAZZ_IE_SERIAL1
230		li	a0,JAZZ_SERIAL1_IRQ
231		b	loc_call
232
233/*
234 * Serial port 2 IRQ
235 */
236loc_serial2:	li	s1,~JAZZ_IE_SERIAL2
237		li	a0,JAZZ_SERIAL2_IRQ
238		b	loc_call
239
240/*
241 * Call the interrupt handler for an interrupt generated by a
242 * local device.
243 */
244loc_call:	/*
245		 * Temporarily disable interrupt source
246		 */
247		lhu	t2,JAZZ_IO_IRQ_ENABLE
248		and	t2,s1
249		sh	t2,JAZZ_IO_IRQ_ENABLE
250
251 		nor	s1,zero,s1
252		jal	do_IRQ
253
254 		/*
255 		 * Reenable interrupt
256 		 */
257		lhu	t2,JAZZ_IO_IRQ_ENABLE
258 		or	t2,s1
259		sh	t2,JAZZ_IO_IRQ_ENABLE
260
261 		j	ret_from_irq
262
263/*
264 * "Jump extender" to reach spurious_interrupt
265 */
2663:		j	spurious_interrupt
267
268/*
269 * Vectors for interrupts generated by local devices
270 */
271		.data
272local_vector:	PTR	loc_no_irq
273		PTR	loc_parallel
274		PTR	loc_floppy
275		PTR	loc_sound
276		PTR	loc_video
277		PTR	loc_ethernet
278		PTR	loc_scsi
279		PTR	loc_keyboard
280		PTR	loc_mouse
281		PTR	loc_serial1
282		PTR	loc_serial2
283