Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[sfrench/cifs-2.6.git] / arch / mips / jazz / int-handler.S
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
47 1:              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                  */
55 2:              lw      t0,(t1)
56                 jr      t0
57                 nop                             # delay slot
58                 END(jazz_handle_int)
59
60 ll_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
66 ll_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
72 ll_local_dma:   li      s1,~IE_IRQ0
73                 PANIC("Unimplemented local_dma handler")
74
75 ll_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  */
91 ll_isa_irq:     lw      a0, JAZZ_EISA_IRQ_ACK
92
93                 jal     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  */
104 ll_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  */
118 ll_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  */
136 ll_count:       j       ret_from_irq
137                  mtc0   zero,CP0_COMPARE
138
139 #if 0
140 /*
141  * Call the handler for the interrupt
142  * (Currently unused)
143  */
144 call_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
170 ll_vectors:     PTR     ll_count                # Count/Compare IRQ
171
172                 /*
173                  * Interrupt handlers for local devices.
174                  */
175                 .text
176                 .set    reorder
177 loc_no_irq:     PANIC("Unimplemented loc_no_irq handler")
178 /*
179  * Parallel port IRQ
180  */
181 loc_parallel:   li      s1,~JAZZ_IE_PARALLEL
182                 li      a0,JAZZ_PARALLEL_IRQ
183                 b       loc_call
184
185 /*
186  * Floppy IRQ
187  */
188 loc_floppy:     li      s1,~JAZZ_IE_FLOPPY
189                 li      a0,JAZZ_FLOPPY_IRQ
190                 b       loc_call
191
192 /*
193  * Sound IRQ
194  */
195 loc_sound:      PANIC("Unimplemented loc_sound handler")
196 loc_video:      PANIC("Unimplemented loc_video handler")
197
198 /*
199  * Ethernet interrupt handler
200  */
201 loc_ethernet:   li      s1,~JAZZ_IE_ETHERNET
202                 li      a0,JAZZ_ETHERNET_IRQ
203                 b       loc_call
204
205 /*
206  * SCSI interrupt handler
207  */
208 loc_scsi:       li      s1,~JAZZ_IE_SCSI
209                 li      a0,JAZZ_SCSI_IRQ
210                 b       loc_call
211
212 /*
213  * Keyboard interrupt handler
214  */
215 loc_keyboard:   li      s1,~JAZZ_IE_KEYBOARD
216                 li      a0,JAZZ_KEYBOARD_IRQ
217                 b       loc_call
218
219 /*
220  * Mouse interrupt handler
221  */
222 loc_mouse:      li      s1,~JAZZ_IE_MOUSE
223                 li      a0,JAZZ_MOUSE_IRQ
224                 b       loc_call
225
226 /*
227  * Serial port 1 IRQ
228  */
229 loc_serial1:    li      s1,~JAZZ_IE_SERIAL1
230                 li      a0,JAZZ_SERIAL1_IRQ
231                 b       loc_call
232
233 /*
234  * Serial port 2 IRQ
235  */
236 loc_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  */
244 loc_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  */
266 3:              j       spurious_interrupt
267
268 /*
269  * Vectors for interrupts generated by local devices
270  */
271                 .data
272 local_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