Rev 3674 | Rev 4339 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3674 | Rev 4338 | ||
|---|---|---|---|
| Line 242... | Line 242... | ||
| 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 | cr_ivr_t ivr; |
246 | cr_ivr_t ivr; |
| - | 247 | irq_t *irq; |
|
| 247 | 248 | ||
| 248 | ivr.value = ivr_read(); |
249 | ivr.value = ivr_read(); |
| 249 | srlz_d(); |
250 | srlz_d(); |
| 250 | 251 | ||
| 251 | switch (ivr.vector) { |
252 | switch (ivr.vector) { |
| 252 | case INTERRUPT_SPURIOUS: |
253 | case INTERRUPT_SPURIOUS: |
| 253 | #ifdef CONFIG_DEBUG |
254 | #ifdef CONFIG_DEBUG |
| 254 | printf("cpu%d: spurious interrupt\n", CPU->id); |
255 | printf("cpu%d: spurious interrupt\n", CPU->id); |
| 255 | #endif |
256 | #endif |
| 256 | break; |
257 | break; |
| 257 | 258 | ||
| 258 | #ifdef CONFIG_SMP |
259 | #ifdef CONFIG_SMP |
| 259 | case VECTOR_TLB_SHOOTDOWN_IPI: |
260 | case VECTOR_TLB_SHOOTDOWN_IPI: |
| 260 | tlb_shootdown_ipi_recv(); |
261 | tlb_shootdown_ipi_recv(); |
| 261 | end_of_local_irq(); |
262 | end_of_local_irq(); |
| 262 | break; |
263 | break; |
| 263 | #endif |
264 | #endif |
| 264 | 265 | ||
| 265 | case INTERRUPT_TIMER: |
266 | case INTERRUPT_TIMER: |
| 266 | { |
- | |
| 267 | - | ||
| 268 | irq_t *irq = irq_dispatch_and_lock(ivr.vector); |
267 | irq = irq_dispatch_and_lock(ivr.vector); |
| 269 | if (irq) { |
268 | if (irq) { |
| 270 | irq->handler(irq, irq->arg); |
269 | irq->handler(irq, irq->arg); |
| 271 | spinlock_unlock(&irq->lock); |
270 | spinlock_unlock(&irq->lock); |
| 272 | } else { |
271 | } else { |
| 273 | panic("\nUnhandled Internal Timer Interrupt (%d)\n",ivr.vector); |
272 | panic("\nUnhandled Internal Timer Interrupt (%d)\n", |
| 274 | } |
273 | ivr.vector); |
| 275 | } |
274 | } |
| 276 | break; |
275 | break; |
| 277 | - | ||
| 278 | default: |
276 | default: |
| 279 | { |
- | |
| 280 | - | ||
| 281 | int ack=false; |
- | |
| 282 | irq_t *irq = irq_dispatch_and_lock(ivr.vector); |
277 | irq = irq_dispatch_and_lock(ivr.vector); |
| 283 | if (irq) { |
278 | if (irq) { |
| 284 | /* |
279 | /* |
| 285 | * The IRQ handler was found. |
280 | * The IRQ handler was found. |
| 286 | */ |
281 | */ |
| 287 | - | ||
| 288 | if (irq->preack) { |
282 | if (irq->preack) { |
| 289 | /* Send EOI before processing the interrupt */ |
283 | /* Send EOI before processing the interrupt */ |
| 290 | end_of_local_irq(); |
284 | end_of_local_irq(); |
| 291 | ack=true; |
- | |
| 292 | } |
285 | } |
| 293 | irq->handler(irq, irq->arg); |
286 | irq->handler(irq, irq->arg); |
| - | 287 | if (!irq->preack) |
|
| - | 288 | end_of_local_irq(); |
|
| 294 | spinlock_unlock(&irq->lock); |
289 | spinlock_unlock(&irq->lock); |
| 295 | } else { |
290 | } else { |
| 296 | /* |
291 | /* |
| 297 | * Unhandled interrupt. |
292 | * Unhandled interrupt. |
| 298 | */ |
293 | */ |
| 299 | end_of_local_irq(); |
294 | end_of_local_irq(); |
| 300 | ack=true; |
- | |
| 301 | #ifdef CONFIG_DEBUG |
295 | #ifdef CONFIG_DEBUG |
| 302 | printf("\nUnhandled External Interrupt Vector %d\n",ivr.vector); |
296 | printf("\nUnhandled External Interrupt Vector %d\n", |
| - | 297 | ivr.vector); |
|
| 303 | #endif |
298 | #endif |
| 304 | } |
- | |
| 305 | if(!ack) end_of_local_irq(); |
- | |
| 306 | - | ||
| 307 | } |
- | |
| 308 | - | ||
| 309 | - | ||
| 310 | break; |
- | |
| 311 | } |
299 | } |
| - | 300 | break; |
|
| - | 301 | } |
|
| 312 | } |
302 | } |
| 313 | 303 | ||
| 314 | /** @} |
304 | /** @} |
| 315 | */ |
305 | */ |