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 |