Rev 3675 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3675 | Rev 4377 | ||
|---|---|---|---|
| Line 36... | Line 36... | ||
| 36 | #include <arch/interrupt.h> |
36 | #include <arch/interrupt.h> |
| 37 | #include <interrupt.h> |
37 | #include <interrupt.h> |
| 38 | #include <ddi/irq.h> |
38 | #include <ddi/irq.h> |
| 39 | #include <panic.h> |
39 | #include <panic.h> |
| 40 | #include <print.h> |
40 | #include <print.h> |
| 41 | #include <symtab.h> |
- | |
| 42 | #include <debug.h> |
41 | #include <debug.h> |
| 43 | #include <console/console.h> |
42 | #include <console/console.h> |
| 44 | #include <arch/types.h> |
43 | #include <arch/types.h> |
| 45 | #include <arch/asm.h> |
44 | #include <arch/asm.h> |
| 46 | #include <arch/barrier.h> |
45 | #include <arch/barrier.h> |
| Line 52... | Line 51... | ||
| 52 | #include <ipc/sysipc.h> |
51 | #include <ipc/sysipc.h> |
| 53 | #include <ipc/irq.h> |
52 | #include <ipc/irq.h> |
| 54 | #include <ipc/ipc.h> |
53 | #include <ipc/ipc.h> |
| 55 | #include <synch/spinlock.h> |
54 | #include <synch/spinlock.h> |
| 56 | #include <mm/tlb.h> |
55 | #include <mm/tlb.h> |
| - | 56 | #include <symtab.h> |
|
| - | 57 | #include <putchar.h> |
|
| 57 | 58 | ||
| 58 | #define VECTORS_64_BUNDLE 20 |
59 | #define VECTORS_64_BUNDLE 20 |
| 59 | #define VECTORS_16_BUNDLE 48 |
60 | #define VECTORS_16_BUNDLE 48 |
| 60 | #define VECTORS_16_BUNDLE_START 0x5000 |
61 | #define VECTORS_16_BUNDLE_START 0x5000 |
| 61 | #define VECTOR_MAX 0x7f00 |
62 | #define VECTOR_MAX 0x7f00 |
| Line 135... | Line 136... | ||
| 135 | 136 | ||
| 136 | void dump_interrupted_context(istate_t *istate) |
137 | void dump_interrupted_context(istate_t *istate) |
| 137 | { |
138 | { |
| 138 | char *ifa, *iipa, *iip; |
139 | char *ifa, *iipa, *iip; |
| 139 | 140 | ||
| 140 | ifa = get_symtab_entry(istate->cr_ifa); |
141 | ifa = symtab_fmt_name_lookup(istate->cr_ifa); |
| 141 | iipa = get_symtab_entry(istate->cr_iipa); |
142 | iipa = symtab_fmt_name_lookup(istate->cr_iipa); |
| 142 | iip = get_symtab_entry(istate->cr_iip); |
143 | iip = symtab_fmt_name_lookup(istate->cr_iip); |
| 143 | 144 | ||
| 144 | putchar('\n'); |
145 | putchar('\n'); |
| 145 | printf("Interrupted context dump:\n"); |
146 | printf("Interrupted context dump:\n"); |
| 146 | printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp, |
147 | printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp, |
| 147 | istate->ar_bspstore); |
148 | istate->ar_bspstore); |
| Line 184... | Line 185... | ||
| 184 | default: |
185 | default: |
| 185 | desc = "unknown"; |
186 | desc = "unknown"; |
| 186 | break; |
187 | break; |
| 187 | } |
188 | } |
| 188 | 189 | ||
| 189 | fault_if_from_uspace(istate, "General Exception (%s)", desc); |
190 | fault_if_from_uspace(istate, "General Exception (%s).", desc); |
| 190 | 191 | ||
| 191 | dump_interrupted_context(istate); |
192 | dump_interrupted_context(istate); |
| 192 | panic("General Exception (%s)\n", desc); |
193 | panic("General Exception (%s).", desc); |
| 193 | } |
194 | } |
| 194 | 195 | ||
| 195 | void disabled_fp_register(uint64_t vector, istate_t *istate) |
196 | void disabled_fp_register(uint64_t vector, istate_t *istate) |
| 196 | { |
197 | { |
| 197 | #ifdef CONFIG_FPU_LAZY |
198 | #ifdef CONFIG_FPU_LAZY |
| 198 | scheduler_fpu_lazy_request(); |
199 | scheduler_fpu_lazy_request(); |
| 199 | #else |
200 | #else |
| 200 | fault_if_from_uspace(istate, "Interruption: %#hx (%s)", |
201 | fault_if_from_uspace(istate, "Interruption: %#hx (%s).", |
| 201 | (uint16_t) vector, vector_to_string(vector)); |
202 | (uint16_t) vector, vector_to_string(vector)); |
| 202 | dump_interrupted_context(istate); |
203 | dump_interrupted_context(istate); |
| 203 | panic("Interruption: %#hx (%s)\n", (uint16_t) vector, |
204 | panic("Interruption: %#hx (%s).", (uint16_t) vector, |
| 204 | vector_to_string(vector)); |
205 | vector_to_string(vector)); |
| 205 | #endif |
206 | #endif |
| 206 | } |
207 | } |
| 207 | 208 | ||
| 208 | void nop_handler(uint64_t vector, istate_t *istate) |
209 | void nop_handler(uint64_t vector, istate_t *istate) |
| Line 226... | Line 227... | ||
| 226 | istate->in3, istate->in4, istate->in5, istate->in6); |
227 | istate->in3, istate->in4, istate->in5, istate->in6); |
| 227 | } |
228 | } |
| 228 | 229 | ||
| 229 | void universal_handler(uint64_t vector, istate_t *istate) |
230 | void universal_handler(uint64_t vector, istate_t *istate) |
| 230 | { |
231 | { |
| 231 | fault_if_from_uspace(istate, "Interruption: %#hx (%s)\n", |
232 | fault_if_from_uspace(istate, "Interruption: %#hx (%s).", |
| 232 | (uint16_t) vector, vector_to_string(vector)); |
233 | (uint16_t) vector, vector_to_string(vector)); |
| 233 | dump_interrupted_context(istate); |
234 | dump_interrupted_context(istate); |
| 234 | panic("Interruption: %#hx (%s)\n", (uint16_t) vector, |
235 | panic("Interruption: %#hx (%s).", (uint16_t) vector, |
| 235 | vector_to_string(vector)); |
236 | vector_to_string(vector)); |
| 236 | } |
237 | } |
| 237 | 238 | ||
| 238 | static void end_of_local_irq(void) |
239 | static void end_of_local_irq(void) |
| 239 | { |
240 | { |
| Line 242... | Line 243... | ||
| 242 | 243 | ||
| 243 | 244 | ||
| 244 | void external_interrupt(uint64_t vector, istate_t *istate) |
245 | void external_interrupt(uint64_t vector, istate_t *istate) |
| 245 | { |
246 | { |
| 246 | cr_ivr_t ivr; |
247 | cr_ivr_t ivr; |
| - | 248 | irq_t *irq; |
|
| 247 | 249 | ||
| 248 | ivr.value = ivr_read(); |
250 | ivr.value = ivr_read(); |
| 249 | srlz_d(); |
251 | srlz_d(); |
| 250 | 252 | ||
| 251 | switch (ivr.vector) { |
253 | switch (ivr.vector) { |
| 252 | case INTERRUPT_SPURIOUS: |
254 | case INTERRUPT_SPURIOUS: |
| 253 | #ifdef CONFIG_DEBUG |
255 | #ifdef CONFIG_DEBUG |
| 254 | printf("cpu%d: spurious interrupt\n", CPU->id); |
256 | printf("cpu%d: spurious interrupt\n", CPU->id); |
| 255 | #endif |
257 | #endif |
| 256 | break; |
258 | break; |
| 257 | 259 | ||
| 258 | #ifdef CONFIG_SMP |
260 | #ifdef CONFIG_SMP |
| 259 | case VECTOR_TLB_SHOOTDOWN_IPI: |
261 | case VECTOR_TLB_SHOOTDOWN_IPI: |
| 260 | tlb_shootdown_ipi_recv(); |
262 | tlb_shootdown_ipi_recv(); |
| 261 | end_of_local_irq(); |
263 | end_of_local_irq(); |
| 262 | break; |
264 | break; |
| 263 | #endif |
265 | #endif |
| 264 | 266 | ||
| 265 | case INTERRUPT_TIMER: |
267 | case INTERRUPT_TIMER: |
| 266 | { |
- | |
| 267 | - | ||
| 268 | irq_t *irq = irq_dispatch_and_lock(ivr.vector); |
268 | irq = irq_dispatch_and_lock(ivr.vector); |
| 269 | if (irq) { |
269 | if (irq) { |
| 270 | irq->handler(irq, irq->arg); |
270 | irq->handler(irq); |
| 271 | spinlock_unlock(&irq->lock); |
271 | spinlock_unlock(&irq->lock); |
| 272 | } else { |
272 | } else { |
| 273 | panic("\nUnhandled Internal Timer Interrupt (%d)\n",ivr.vector); |
273 | panic("Unhandled Internal Timer Interrupt (%d).", |
| 274 | } |
274 | ivr.vector); |
| 275 | } |
275 | } |
| 276 | break; |
276 | break; |
| 277 | - | ||
| 278 | default: |
277 | default: |
| 279 | { |
- | |
| 280 | - | ||
| 281 | int ack=false; |
- | |
| 282 | irq_t *irq = irq_dispatch_and_lock(ivr.vector); |
278 | irq = irq_dispatch_and_lock(ivr.vector); |
| 283 | if (irq) { |
279 | if (irq) { |
| 284 | /* |
280 | /* |
| 285 | * The IRQ handler was found. |
281 | * The IRQ handler was found. |
| 286 | */ |
282 | */ |
| 287 | - | ||
| 288 | if (irq->preack) { |
283 | if (irq->preack) { |
| 289 | /* Send EOI before processing the interrupt */ |
284 | /* Send EOI before processing the interrupt */ |
| 290 | end_of_local_irq(); |
285 | end_of_local_irq(); |
| 291 | ack=true; |
- | |
| 292 | } |
286 | } |
| 293 | irq->handler(irq, irq->arg); |
287 | irq->handler(irq); |
| - | 288 | if (!irq->preack) |
|
| - | 289 | end_of_local_irq(); |
|
| 294 | spinlock_unlock(&irq->lock); |
290 | spinlock_unlock(&irq->lock); |
| 295 | } else { |
291 | } else { |
| 296 | /* |
292 | /* |
| 297 | * Unhandled interrupt. |
293 | * Unhandled interrupt. |
| 298 | */ |
294 | */ |
| 299 | end_of_local_irq(); |
295 | end_of_local_irq(); |
| 300 | ack=true; |
- | |
| 301 | #ifdef CONFIG_DEBUG |
296 | #ifdef CONFIG_DEBUG |
| 302 | printf("\nUnhandled External Interrupt Vector %d\n",ivr.vector); |
297 | printf("\nUnhandled External Interrupt Vector %d\n", |
| - | 298 | ivr.vector); |
|
| 303 | #endif |
299 | #endif |
| 304 | } |
- | |
| 305 | if(!ack) end_of_local_irq(); |
- | |
| 306 | - | ||
| 307 | } |
- | |
| 308 | - | ||
| 309 | - | ||
| 310 | break; |
- | |
| 311 | } |
300 | } |
| - | 301 | break; |
|
| - | 302 | } |
|
| - | 303 | } |
|
| - | 304 | ||
| - | 305 | void trap_virtual_enable_irqs(uint16_t irqmask) |
|
| - | 306 | { |
|
| 312 | } |
307 | } |
| 313 | 308 | ||
| 314 | /** @} |
309 | /** @} |
| 315 | */ |
310 | */ |