Rev 3626 | Rev 3661 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3626 | Rev 3657 | ||
---|---|---|---|
Line 233... | Line 233... | ||
233 | dump_interrupted_context(istate); |
233 | dump_interrupted_context(istate); |
234 | panic("Interruption: %#hx (%s)\n", (uint16_t) vector, |
234 | panic("Interruption: %#hx (%s)\n", (uint16_t) vector, |
235 | vector_to_string(vector)); |
235 | vector_to_string(vector)); |
236 | } |
236 | } |
237 | 237 | ||
238 | static void end_of_local_irq() |
238 | static void end_of_local_irq(void) |
239 | { |
239 | { |
240 | asm volatile ("mov cr.eoi=r0;;"); |
240 | asm volatile ("mov cr.eoi=r0;;"); |
241 | } |
241 | } |
242 | 242 | ||
243 | 243 | ||
244 | void external_interrupt(uint64_t vector, istate_t *istate) |
244 | void external_interrupt(uint64_t vector, istate_t *istate) |
245 | { |
245 | { |
246 | irq_t *irq; |
- | |
247 | cr_ivr_t ivr; |
246 | cr_ivr_t ivr; |
248 | 247 | ||
249 | ivr.value = ivr_read(); |
248 | ivr.value = ivr_read(); |
250 | srlz_d(); |
249 | srlz_d(); |
251 | 250 | ||
252 | irq = irq_dispatch_and_lock(ivr.vector); |
- | |
253 | if (irq) { |
- | |
254 | irq->handler(irq, irq->arg); |
- | |
255 | spinlock_unlock(&irq->lock); |
- | |
256 | } else { |
- | |
257 | switch (ivr.vector) { |
251 | switch (ivr.vector) { |
258 | case INTERRUPT_SPURIOUS: |
252 | case INTERRUPT_SPURIOUS: |
259 | #ifdef CONFIG_DEBUG |
253 | #ifdef CONFIG_DEBUG |
260 | printf("cpu%d: spurious interrupt\n", CPU->id); |
254 | printf("cpu%d: spurious interrupt\n", CPU->id); |
261 | #endif |
255 | #endif |
Line 268... | Line 262... | ||
268 | break; |
262 | break; |
269 | #endif |
263 | #endif |
270 | 264 | ||
271 | 265 | ||
272 | default: |
266 | default: |
- | 267 | { |
|
- | 268 | ||
- | 269 | int ack=false; |
|
- | 270 | irq_t *irq = irq_dispatch_and_lock(ivr.vector); |
|
- | 271 | if (irq) { |
|
- | 272 | /* |
|
- | 273 | * The IRQ handler was found. |
|
- | 274 | */ |
|
- | 275 | ||
- | 276 | if (irq->preack) { |
|
- | 277 | /* Send EOI before processing the interrupt */ |
|
- | 278 | end_of_local_irq(); |
|
- | 279 | ack=true; |
|
- | 280 | } |
|
- | 281 | irq->handler(irq, irq->arg); |
|
- | 282 | spinlock_unlock(&irq->lock); |
|
- | 283 | } else { |
|
- | 284 | /* |
|
- | 285 | * Unhandled interrupt. |
|
- | 286 | */ |
|
- | 287 | end_of_local_irq(); |
|
- | 288 | ack=true; |
|
- | 289 | #ifdef CONFIG_DEBUG |
|
273 | panic("\nUnhandled External Interrupt Vector %d\n", |
290 | printf("\nUnhandled External Interrupt Vector %d\n",ivr.vector); |
- | 291 | #endif |
|
- | 292 | } |
|
274 | ivr.vector); |
293 | if(!ack) end_of_local_irq(); |
- | 294 | ||
- | 295 | } |
|
- | 296 | ||
- | 297 | ||
275 | break; |
298 | break; |
276 | } |
299 | } |
277 | } |
- | |
278 | } |
300 | } |
279 | 301 | ||
280 | /** @} |
302 | /** @} |
281 | */ |
303 | */ |