Rev 3431 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3431 | Rev 4377 | ||
---|---|---|---|
Line 39... | Line 39... | ||
39 | #include <arch/cp0.h> |
39 | #include <arch/cp0.h> |
40 | #include <arch/types.h> |
40 | #include <arch/types.h> |
41 | #include <arch.h> |
41 | #include <arch.h> |
42 | #include <debug.h> |
42 | #include <debug.h> |
43 | #include <proc/thread.h> |
43 | #include <proc/thread.h> |
44 | #include <symtab.h> |
- | |
45 | #include <print.h> |
44 | #include <print.h> |
46 | #include <interrupt.h> |
45 | #include <interrupt.h> |
47 | #include <func.h> |
46 | #include <func.h> |
48 | #include <console/kconsole.h> |
- | |
49 | #include <ddi/irq.h> |
47 | #include <ddi/irq.h> |
50 | #include <arch/debugger.h> |
48 | #include <arch/debugger.h> |
51 | #include <udebug/udebug.h> |
49 | #include <udebug/udebug.h> |
- | 50 | #include <symtab.h> |
|
52 | 51 | ||
53 | static char * exctable[] = { |
52 | static char * exctable[] = { |
54 | "Interrupt", |
53 | "Interrupt", |
55 | "TLB Modified", |
54 | "TLB Modified", |
56 | "TLB Invalid", |
55 | "TLB Invalid", |
Line 73... | Line 72... | ||
73 | "Virtual Coherency - data", |
72 | "Virtual Coherency - data", |
74 | }; |
73 | }; |
75 | 74 | ||
76 | static void print_regdump(istate_t *istate) |
75 | static void print_regdump(istate_t *istate) |
77 | { |
76 | { |
78 | char *pcsymbol = ""; |
77 | char *pcsymbol, *rasymbol; |
79 | char *rasymbol = ""; |
- | |
80 | 78 | ||
81 | char *s = get_symtab_entry(istate->epc); |
79 | pcsymbol = symtab_fmt_name_lookup(istate->epc); |
82 | if (s) |
- | |
83 | pcsymbol = s; |
- | |
84 | s = get_symtab_entry(istate->ra); |
80 | rasymbol = symtab_fmt_name_lookup(istate->ra); |
85 | if (s) |
- | |
86 | rasymbol = s; |
- | |
87 | 81 | ||
88 | printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol, istate->ra, rasymbol, istate->sp); |
82 | printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol, |
- | 83 | istate->ra, rasymbol, istate->sp); |
|
89 | } |
84 | } |
90 | 85 | ||
91 | static void unhandled_exception(int n, istate_t *istate) |
86 | static void unhandled_exception(int n, istate_t *istate) |
92 | { |
87 | { |
93 | fault_if_from_uspace(istate, "unhandled exception %s", exctable[n]); |
88 | fault_if_from_uspace(istate, "Unhandled exception %s.", exctable[n]); |
94 | 89 | ||
95 | print_regdump(istate); |
90 | print_regdump(istate); |
96 | panic("unhandled exception %s\n", exctable[n]); |
91 | panic("Unhandled exception %s.", exctable[n]); |
97 | } |
92 | } |
98 | 93 | ||
99 | static void reserved_instr_exception(int n, istate_t *istate) |
94 | static void reserved_instr_exception(int n, istate_t *istate) |
100 | { |
95 | { |
101 | if (*((uint32_t *)istate->epc) == 0x7c03e83b) { |
96 | if (*((uint32_t *)istate->epc) == 0x7c03e83b) { |
Line 140... | Line 135... | ||
140 | static void cpuns_exception(int n, istate_t *istate) |
135 | static void cpuns_exception(int n, istate_t *istate) |
141 | { |
136 | { |
142 | if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id) |
137 | if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id) |
143 | scheduler_fpu_lazy_request(); |
138 | scheduler_fpu_lazy_request(); |
144 | else { |
139 | else { |
145 | fault_if_from_uspace(istate, "unhandled Coprocessor Unusable Exception"); |
140 | fault_if_from_uspace(istate, "Unhandled Coprocessor Unusable Exception."); |
146 | panic("unhandled Coprocessor Unusable Exception\n"); |
141 | panic("Unhandled Coprocessor Unusable Exception."); |
147 | } |
142 | } |
148 | } |
143 | } |
149 | #endif |
144 | #endif |
150 | 145 | ||
151 | static void interrupt_exception(int n, istate_t *istate) |
146 | static void interrupt_exception(int n, istate_t *istate) |
152 | { |
147 | { |
153 | uint32_t cause; |
148 | uint32_t cause; |
154 | int i; |
149 | int i; |
155 | 150 | ||
156 | /* decode interrupt number and process the interrupt */ |
151 | /* decode interrupt number and process the interrupt */ |
157 | cause = (cp0_cause_read() >> 8) &0xff; |
152 | cause = (cp0_cause_read() >> 8) & 0xff; |
158 | 153 | ||
159 | for (i = 0; i < 8; i++) { |
154 | for (i = 0; i < 8; i++) { |
160 | if (cause & (1 << i)) { |
155 | if (cause & (1 << i)) { |
161 | irq_t *irq = irq_dispatch_and_lock(i); |
156 | irq_t *irq = irq_dispatch_and_lock(i); |
162 | if (irq) { |
157 | if (irq) { |
163 | /* |
158 | /* |
164 | * The IRQ handler was found. |
159 | * The IRQ handler was found. |
165 | */ |
160 | */ |
166 | irq->handler(irq, irq->arg); |
161 | irq->handler(irq); |
167 | spinlock_unlock(&irq->lock); |
162 | spinlock_unlock(&irq->lock); |
168 | } else { |
163 | } else { |
169 | /* |
164 | /* |
170 | * Spurious interrupt. |
165 | * Spurious interrupt. |
171 | */ |
166 | */ |
172 | #ifdef CONFIG_DEBUG |
167 | #ifdef CONFIG_DEBUG |
173 | printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, i); |
168 | printf("cpu%u: spurious interrupt (inum=%d)\n", |
- | 169 | CPU->id, i); |
|
174 | #endif |
170 | #endif |
175 | } |
171 | } |
176 | } |
172 | } |
177 | } |
173 | } |
178 | } |
174 | } |
179 | 175 | ||
180 | /** Handle syscall userspace call */ |
176 | /** Handle syscall userspace call */ |
181 | static void syscall_exception(int n, istate_t *istate) |
177 | static void syscall_exception(int n, istate_t *istate) |
182 | { |
178 | { |
183 | panic("Syscall is handled through shortcut"); |
179 | panic("Syscall is handled through shortcut."); |
184 | } |
180 | } |
185 | 181 | ||
186 | void exception_init(void) |
182 | void exception_init(void) |
187 | { |
183 | { |
188 | int i; |
184 | int i; |