Rev 830 | Rev 958 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 830 | Rev 831 | ||
---|---|---|---|
Line 43... | Line 43... | ||
43 | static void tlb_invalid_fail(struct exception_regdump *pstate); |
43 | static void tlb_invalid_fail(struct exception_regdump *pstate); |
44 | static void tlb_modified_fail(struct exception_regdump *pstate); |
44 | static void tlb_modified_fail(struct exception_regdump *pstate); |
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, int c, __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); |
50 | 50 | ||
51 | /** Initialize TLB |
51 | /** Initialize TLB |
52 | * |
52 | * |
53 | * Initialize TLB. |
53 | * Initialize TLB. |
Line 102... | Line 102... | ||
102 | * Record access to PTE. |
102 | * Record access to PTE. |
103 | */ |
103 | */ |
104 | pte->a = 1; |
104 | pte->a = 1; |
105 | 105 | ||
106 | prepare_entry_hi(&hi, AS->asid, badvaddr); |
106 | prepare_entry_hi(&hi, AS->asid, badvaddr); |
107 | prepare_entry_lo(&lo, pte->lo.g, pte->lo.v, pte->lo.d, pte->lo.c, pte->lo.pfn); |
107 | prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
108 | 108 | ||
109 | /* |
109 | /* |
110 | * New entry is to be inserted into TLB |
110 | * New entry is to be inserted into TLB |
111 | */ |
111 | */ |
112 | cp0_entry_hi_write(hi.value); |
112 | cp0_entry_hi_write(hi.value); |
Line 176... | Line 176... | ||
176 | /* |
176 | /* |
177 | * Record access to PTE. |
177 | * Record access to PTE. |
178 | */ |
178 | */ |
179 | pte->a = 1; |
179 | pte->a = 1; |
180 | 180 | ||
181 | prepare_entry_lo(&lo, pte->lo.g, pte->lo.v, pte->lo.d, pte->lo.c, pte->lo.pfn); |
181 | prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
182 | 182 | ||
183 | /* |
183 | /* |
184 | * The entry is to be updated in TLB. |
184 | * The entry is to be updated in TLB. |
185 | */ |
185 | */ |
186 | if ((badvaddr/PAGE_SIZE) % 2 == 0) |
186 | if ((badvaddr/PAGE_SIZE) % 2 == 0) |
Line 250... | Line 250... | ||
250 | 250 | ||
251 | /* |
251 | /* |
252 | * Record access and write to PTE. |
252 | * Record access and write to PTE. |
253 | */ |
253 | */ |
254 | pte->a = 1; |
254 | pte->a = 1; |
255 | pte->lo.d = 1; |
255 | pte->d = 1; |
256 | 256 | ||
257 | prepare_entry_lo(&lo, pte->lo.g, pte->lo.v, pte->w, pte->lo.c, pte->lo.pfn); |
257 | prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn); |
258 | 258 | ||
259 | /* |
259 | /* |
260 | * The entry is to be updated in TLB. |
260 | * The entry is to be updated in TLB. |
261 | */ |
261 | */ |
262 | if ((badvaddr/PAGE_SIZE) % 2 == 0) |
262 | if ((badvaddr/PAGE_SIZE) % 2 == 0) |
Line 335... | Line 335... | ||
335 | 335 | ||
336 | /* |
336 | /* |
337 | * Check if the mapping exists in page tables. |
337 | * Check if the mapping exists in page tables. |
338 | */ |
338 | */ |
339 | pte = page_mapping_find(AS, badvaddr); |
339 | pte = page_mapping_find(AS, badvaddr); |
340 | if (pte && pte->lo.v) { |
340 | if (pte && pte->p) { |
341 | /* |
341 | /* |
342 | * Mapping found in page tables. |
342 | * Mapping found in page tables. |
343 | * Immediately succeed. |
343 | * Immediately succeed. |
344 | */ |
344 | */ |
345 | return pte; |
345 | return pte; |
Line 352... | Line 352... | ||
352 | /* |
352 | /* |
353 | * The higher-level page fault handler succeeded, |
353 | * The higher-level page fault handler succeeded, |
354 | * The mapping ought to be in place. |
354 | * The mapping ought to be in place. |
355 | */ |
355 | */ |
356 | pte = page_mapping_find(AS, badvaddr); |
356 | pte = page_mapping_find(AS, badvaddr); |
357 | ASSERT(pte && pte->lo.v); |
357 | ASSERT(pte && pte->p); |
358 | return pte; |
358 | return pte; |
359 | } |
359 | } |
360 | } |
360 | } |
361 | 361 | ||
362 | /* |
362 | /* |
Line 368... | Line 368... | ||
368 | } |
368 | } |
369 | 369 | ||
370 | /* |
370 | /* |
371 | * Handler cannot succeed if the mapping is marked as invalid. |
371 | * Handler cannot succeed if the mapping is marked as invalid. |
372 | */ |
372 | */ |
373 | if (!pte->lo.v) { |
373 | if (!pte->p) { |
374 | printf("Invalid mapping.\n"); |
374 | printf("Invalid mapping.\n"); |
375 | return NULL; |
375 | return NULL; |
376 | } |
376 | } |
377 | 377 | ||
378 | return pte; |
378 | return pte; |
379 | } |
379 | } |
380 | 380 | ||
381 | void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn) |
381 | void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn) |
382 | { |
382 | { |
383 | lo->value = 0; |
383 | lo->value = 0; |
384 | lo->g = g; |
384 | lo->g = g; |
385 | lo->v = v; |
385 | lo->v = v; |
386 | lo->d = d; |
386 | lo->d = d; |
387 | lo->c = c; |
387 | lo->c = cacheable ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED; |
388 | lo->pfn = pfn; |
388 | lo->pfn = pfn; |
389 | } |
389 | } |
390 | 390 | ||
391 | void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr) |
391 | void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr) |
392 | { |
392 | { |