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