Rev 831 | Rev 983 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 831 | Rev 958 | ||
|---|---|---|---|
| Line 37... | Line 37... | ||
| 37 | #include <symtab.h> |
37 | #include <symtab.h> |
| 38 | #include <synch/spinlock.h> |
38 | #include <synch/spinlock.h> |
| 39 | #include <print.h> |
39 | #include <print.h> |
| 40 | #include <debug.h> |
40 | #include <debug.h> |
| 41 | 41 | ||
| 42 | static void tlb_refill_fail(struct exception_regdump *pstate); |
42 | static void tlb_refill_fail(istate_t *istate); |
| 43 | static void tlb_invalid_fail(struct exception_regdump *pstate); |
43 | static void tlb_invalid_fail(istate_t *istate); |
| 44 | static void tlb_modified_fail(struct exception_regdump *pstate); |
44 | static void tlb_modified_fail(istate_t *istate); |
| 45 | 45 | ||
| 46 | static pte_t *find_mapping_and_check(__address badvaddr); |
46 | static pte_t *find_mapping_and_check(__address badvaddr); |
| 47 | 47 | ||
| 48 | static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn); |
48 | static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn); |
| 49 | static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr); |
49 | static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr); |
| Line 79... | Line 79... | ||
| 79 | 79 | ||
| 80 | /** Process TLB Refill Exception |
80 | /** Process TLB Refill Exception |
| 81 | * |
81 | * |
| 82 | * Process TLB Refill Exception. |
82 | * Process TLB Refill Exception. |
| 83 | * |
83 | * |
| 84 | * @param pstate Interrupted register context. |
84 | * @param istate Interrupted register context. |
| 85 | */ |
85 | */ |
| 86 | void tlb_refill(struct exception_regdump *pstate) |
86 | void tlb_refill(istate_t *istate) |
| 87 | { |
87 | { |
| 88 | entry_lo_t lo; |
88 | entry_lo_t lo; |
| 89 | entry_hi_t hi; |
89 | entry_hi_t hi; |
| 90 | __address badvaddr; |
90 | __address badvaddr; |
| 91 | pte_t *pte; |
91 | pte_t *pte; |
| Line 124... | Line 124... | ||
| 124 | spinlock_unlock(&AS->lock); |
124 | spinlock_unlock(&AS->lock); |
| 125 | return; |
125 | return; |
| 126 | 126 | ||
| 127 | fail: |
127 | fail: |
| 128 | spinlock_unlock(&AS->lock); |
128 | spinlock_unlock(&AS->lock); |
| 129 | tlb_refill_fail(pstate); |
129 | tlb_refill_fail(istate); |
| 130 | } |
130 | } |
| 131 | 131 | ||
| 132 | /** Process TLB Invalid Exception |
132 | /** Process TLB Invalid Exception |
| 133 | * |
133 | * |
| 134 | * Process TLB Invalid Exception. |
134 | * Process TLB Invalid Exception. |
| 135 | * |
135 | * |
| 136 | * @param pstate Interrupted register context. |
136 | * @param istate Interrupted register context. |
| 137 | */ |
137 | */ |
| 138 | void tlb_invalid(struct exception_regdump *pstate) |
138 | void tlb_invalid(istate_t *istate) |
| 139 | { |
139 | { |
| 140 | tlb_index_t index; |
140 | tlb_index_t index; |
| 141 | __address badvaddr; |
141 | __address badvaddr; |
| 142 | entry_lo_t lo; |
142 | entry_lo_t lo; |
| 143 | entry_hi_t hi; |
143 | entry_hi_t hi; |
| Line 193... | Line 193... | ||
| 193 | spinlock_unlock(&AS->lock); |
193 | spinlock_unlock(&AS->lock); |
| 194 | return; |
194 | return; |
| 195 | 195 | ||
| 196 | fail: |
196 | fail: |
| 197 | spinlock_unlock(&AS->lock); |
197 | spinlock_unlock(&AS->lock); |
| 198 | tlb_invalid_fail(pstate); |
198 | tlb_invalid_fail(istate); |
| 199 | } |
199 | } |
| 200 | 200 | ||
| 201 | /** Process TLB Modified Exception |
201 | /** Process TLB Modified Exception |
| 202 | * |
202 | * |
| 203 | * Process TLB Modified Exception. |
203 | * Process TLB Modified Exception. |
| 204 | * |
204 | * |
| 205 | * @param pstate Interrupted register context. |
205 | * @param istate Interrupted register context. |
| 206 | */ |
206 | */ |
| 207 | void tlb_modified(struct exception_regdump *pstate) |
207 | void tlb_modified(istate_t *istate) |
| 208 | { |
208 | { |
| 209 | tlb_index_t index; |
209 | tlb_index_t index; |
| 210 | __address badvaddr; |
210 | __address badvaddr; |
| 211 | entry_lo_t lo; |
211 | entry_lo_t lo; |
| 212 | entry_hi_t hi; |
212 | entry_hi_t hi; |
| Line 269... | Line 269... | ||
| 269 | spinlock_unlock(&AS->lock); |
269 | spinlock_unlock(&AS->lock); |
| 270 | return; |
270 | return; |
| 271 | 271 | ||
| 272 | fail: |
272 | fail: |
| 273 | spinlock_unlock(&AS->lock); |
273 | spinlock_unlock(&AS->lock); |
| 274 | tlb_modified_fail(pstate); |
274 | tlb_modified_fail(istate); |
| 275 | } |
275 | } |
| 276 | 276 | ||
| 277 | void tlb_refill_fail(struct exception_regdump *pstate) |
277 | void tlb_refill_fail(istate_t *istate) |
| 278 | { |
278 | { |
| 279 | char *symbol = ""; |
279 | char *symbol = ""; |
| 280 | char *sym2 = ""; |
280 | char *sym2 = ""; |
| 281 | 281 | ||
| 282 | char *s = get_symtab_entry(pstate->epc); |
282 | char *s = get_symtab_entry(istate->epc); |
| 283 | if (s) |
283 | if (s) |
| 284 | symbol = s; |
284 | symbol = s; |
| 285 | s = get_symtab_entry(pstate->ra); |
285 | s = get_symtab_entry(istate->ra); |
| 286 | if (s) |
286 | if (s) |
| 287 | sym2 = s; |
287 | sym2 = s; |
| 288 | panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(), pstate->epc, symbol, sym2); |
288 | panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(), istate->epc, symbol, sym2); |
| 289 | } |
289 | } |
| 290 | 290 | ||
| 291 | 291 | ||
| 292 | void tlb_invalid_fail(struct exception_regdump *pstate) |
292 | void tlb_invalid_fail(istate_t *istate) |
| 293 | { |
293 | { |
| 294 | char *symbol = ""; |
294 | char *symbol = ""; |
| 295 | 295 | ||
| 296 | char *s = get_symtab_entry(pstate->epc); |
296 | char *s = get_symtab_entry(istate->epc); |
| 297 | if (s) |
297 | if (s) |
| 298 | symbol = s; |
298 | symbol = s; |
| 299 | panic("%X: TLB Invalid Exception at %X(%s)\n", cp0_badvaddr_read(), pstate->epc, symbol); |
299 | panic("%X: TLB Invalid Exception at %X(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
| 300 | } |
300 | } |
| 301 | 301 | ||
| 302 | void tlb_modified_fail(struct exception_regdump *pstate) |
302 | void tlb_modified_fail(istate_t *istate) |
| 303 | { |
303 | { |
| 304 | char *symbol = ""; |
304 | char *symbol = ""; |
| 305 | 305 | ||
| 306 | char *s = get_symtab_entry(pstate->epc); |
306 | char *s = get_symtab_entry(istate->epc); |
| 307 | if (s) |
307 | if (s) |
| 308 | symbol = s; |
308 | symbol = s; |
| 309 | panic("%X: TLB Modified Exception at %X(%s)\n", cp0_badvaddr_read(), pstate->epc, symbol); |
309 | panic("%X: TLB Modified Exception at %X(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
| 310 | } |
310 | } |
| 311 | 311 | ||
| 312 | /** Try to find PTE for faulting address |
312 | /** Try to find PTE for faulting address |
| 313 | * |
313 | * |
| 314 | * Try to find PTE for faulting address. |
314 | * Try to find PTE for faulting address. |