Rev 2745 | Rev 3392 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2745 | Rev 3228 | ||
|---|---|---|---|
| Line 51... | Line 51... | ||
| 51 | static void tlb_invalid_fail(istate_t *istate); |
51 | static void tlb_invalid_fail(istate_t *istate); |
| 52 | static void tlb_modified_fail(istate_t *istate); |
52 | static void tlb_modified_fail(istate_t *istate); |
| 53 | 53 | ||
| 54 | static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc); |
54 | static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc); |
| 55 | 55 | ||
| 56 | static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn); |
- | |
| 57 | static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr); |
- | |
| 58 | - | ||
| 59 | /** Initialize TLB |
56 | /** Initialize TLB |
| 60 | * |
57 | * |
| 61 | * Initialize TLB. |
58 | * Initialize TLB. |
| 62 | * Invalidate all entries and mark wired entries. |
59 | * Invalidate all entries and mark wired entries. |
| 63 | */ |
60 | */ |
| Line 74... | Line 71... | ||
| 74 | 71 | ||
| 75 | for (i = 0; i < TLB_ENTRY_COUNT; i++) { |
72 | for (i = 0; i < TLB_ENTRY_COUNT; i++) { |
| 76 | cp0_index_write(i); |
73 | cp0_index_write(i); |
| 77 | tlbwi(); |
74 | tlbwi(); |
| 78 | } |
75 | } |
| 79 | - | ||
| 80 | 76 | ||
| 81 | /* |
77 | /* |
| 82 | * The kernel is going to make use of some wired |
78 | * The kernel is going to make use of some wired |
| 83 | * entries (e.g. mapping kernel stacks in kseg3). |
79 | * entries (e.g. mapping kernel stacks in kseg3). |
| 84 | */ |
80 | */ |
| Line 129... | Line 125... | ||
| 129 | /* |
125 | /* |
| 130 | * Record access to PTE. |
126 | * Record access to PTE. |
| 131 | */ |
127 | */ |
| 132 | pte->a = 1; |
128 | pte->a = 1; |
| 133 | 129 | ||
| 134 | prepare_entry_hi(&hi, asid, badvaddr); |
130 | tlb_prepare_entry_hi(&hi, asid, badvaddr); |
| 135 | prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
131 | tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
| 136 | 132 | ||
| 137 | /* |
133 | /* |
| 138 | * New entry is to be inserted into TLB |
134 | * New entry is to be inserted into TLB |
| 139 | */ |
135 | */ |
| 140 | cp0_entry_hi_write(hi.value); |
136 | cp0_entry_hi_write(hi.value); |
| Line 176... | Line 172... | ||
| 176 | 172 | ||
| 177 | /* |
173 | /* |
| 178 | * Locate the faulting entry in TLB. |
174 | * Locate the faulting entry in TLB. |
| 179 | */ |
175 | */ |
| 180 | hi.value = cp0_entry_hi_read(); |
176 | hi.value = cp0_entry_hi_read(); |
| 181 | prepare_entry_hi(&hi, hi.asid, badvaddr); |
177 | tlb_prepare_entry_hi(&hi, hi.asid, badvaddr); |
| 182 | cp0_entry_hi_write(hi.value); |
178 | cp0_entry_hi_write(hi.value); |
| 183 | tlbp(); |
179 | tlbp(); |
| 184 | index.value = cp0_index_read(); |
180 | index.value = cp0_index_read(); |
| 185 | 181 | ||
| 186 | page_table_lock(AS, true); |
182 | page_table_lock(AS, true); |
| Line 219... | Line 215... | ||
| 219 | /* |
215 | /* |
| 220 | * Record access to PTE. |
216 | * Record access to PTE. |
| 221 | */ |
217 | */ |
| 222 | pte->a = 1; |
218 | pte->a = 1; |
| 223 | 219 | ||
| 224 | prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
220 | tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
| 225 | 221 | ||
| 226 | /* |
222 | /* |
| 227 | * The entry is to be updated in TLB. |
223 | * The entry is to be updated in TLB. |
| 228 | */ |
224 | */ |
| 229 | if ((badvaddr/PAGE_SIZE) % 2 == 0) |
225 | if ((badvaddr/PAGE_SIZE) % 2 == 0) |
| Line 260... | Line 256... | ||
| 260 | 256 | ||
| 261 | /* |
257 | /* |
| 262 | * Locate the faulting entry in TLB. |
258 | * Locate the faulting entry in TLB. |
| 263 | */ |
259 | */ |
| 264 | hi.value = cp0_entry_hi_read(); |
260 | hi.value = cp0_entry_hi_read(); |
| 265 | prepare_entry_hi(&hi, hi.asid, badvaddr); |
261 | tlb_prepare_entry_hi(&hi, hi.asid, badvaddr); |
| 266 | cp0_entry_hi_write(hi.value); |
262 | cp0_entry_hi_write(hi.value); |
| 267 | tlbp(); |
263 | tlbp(); |
| 268 | index.value = cp0_index_read(); |
264 | index.value = cp0_index_read(); |
| 269 | 265 | ||
| 270 | page_table_lock(AS, true); |
266 | page_table_lock(AS, true); |
| Line 310... | Line 306... | ||
| 310 | * Record access and write to PTE. |
306 | * Record access and write to PTE. |
| 311 | */ |
307 | */ |
| 312 | pte->a = 1; |
308 | pte->a = 1; |
| 313 | pte->d = 1; |
309 | pte->d = 1; |
| 314 | 310 | ||
| 315 | prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn); |
311 | tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn); |
| 316 | 312 | ||
| 317 | /* |
313 | /* |
| 318 | * The entry is to be updated in TLB. |
314 | * The entry is to be updated in TLB. |
| 319 | */ |
315 | */ |
| 320 | if ((badvaddr/PAGE_SIZE) % 2 == 0) |
316 | if ((badvaddr/PAGE_SIZE) % 2 == 0) |
| Line 443... | Line 439... | ||
| 443 | } |
439 | } |
| 444 | 440 | ||
| 445 | } |
441 | } |
| 446 | } |
442 | } |
| 447 | 443 | ||
| 448 | void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn) |
444 | void tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn) |
| 449 | { |
445 | { |
| 450 | lo->value = 0; |
446 | lo->value = 0; |
| 451 | lo->g = g; |
447 | lo->g = g; |
| 452 | lo->v = v; |
448 | lo->v = v; |
| 453 | lo->d = d; |
449 | lo->d = d; |
| 454 | lo->c = cacheable ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED; |
450 | lo->c = cacheable ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED; |
| 455 | lo->pfn = pfn; |
451 | lo->pfn = pfn; |
| 456 | } |
452 | } |
| 457 | 453 | ||
| 458 | void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr) |
454 | void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr) |
| 459 | { |
455 | { |
| 460 | hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2); |
456 | hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2); |
| 461 | hi->asid = asid; |
457 | hi->asid = asid; |
| 462 | } |
458 | } |
| 463 | 459 | ||
| Line 583... | Line 579... | ||
| 583 | hi_save.value = cp0_entry_hi_read(); |
579 | hi_save.value = cp0_entry_hi_read(); |
| 584 | ipl = interrupts_disable(); |
580 | ipl = interrupts_disable(); |
| 585 | 581 | ||
| 586 | for (i = 0; i < cnt + 1; i += 2) { |
582 | for (i = 0; i < cnt + 1; i += 2) { |
| 587 | hi.value = 0; |
583 | hi.value = 0; |
| 588 | prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); |
584 | tlb_prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); |
| 589 | cp0_entry_hi_write(hi.value); |
585 | cp0_entry_hi_write(hi.value); |
| 590 | 586 | ||
| 591 | tlbp(); |
587 | tlbp(); |
| 592 | index.value = cp0_index_read(); |
588 | index.value = cp0_index_read(); |
| 593 | 589 | ||