Rev 1288 | Rev 1595 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1288 | Rev 1411 | ||
|---|---|---|---|
| Line 42... | Line 42... | ||
| 42 | 42 | ||
| 43 | static void tlb_refill_fail(istate_t *istate); |
43 | static void tlb_refill_fail(istate_t *istate); |
| 44 | static void tlb_invalid_fail(istate_t *istate); |
44 | static void tlb_invalid_fail(istate_t *istate); |
| 45 | static void tlb_modified_fail(istate_t *istate); |
45 | static void tlb_modified_fail(istate_t *istate); |
| 46 | 46 | ||
| 47 | static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfrc); |
47 | static pte_t *find_mapping_and_check(__address badvaddr, int access, istate_t *istate, int *pfrc); |
| 48 | 48 | ||
| 49 | static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn); |
49 | static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn); |
| 50 | static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr); |
50 | static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, __address addr); |
| 51 | 51 | ||
| 52 | /** Initialize TLB |
52 | /** Initialize TLB |
| Line 99... | Line 99... | ||
| 99 | asid = AS->asid; |
99 | asid = AS->asid; |
| 100 | spinlock_unlock(&AS->lock); |
100 | spinlock_unlock(&AS->lock); |
| 101 | 101 | ||
| 102 | page_table_lock(AS, true); |
102 | page_table_lock(AS, true); |
| 103 | 103 | ||
| 104 | pte = find_mapping_and_check(badvaddr, istate, &pfrc); |
104 | pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc); |
| 105 | if (!pte) { |
105 | if (!pte) { |
| 106 | switch (pfrc) { |
106 | switch (pfrc) { |
| 107 | case AS_PF_FAULT: |
107 | case AS_PF_FAULT: |
| 108 | goto fail; |
108 | goto fail; |
| 109 | break; |
109 | break; |
| Line 184... | Line 184... | ||
| 184 | if (index.p) { |
184 | if (index.p) { |
| 185 | printf("TLB entry not found.\n"); |
185 | printf("TLB entry not found.\n"); |
| 186 | goto fail; |
186 | goto fail; |
| 187 | } |
187 | } |
| 188 | 188 | ||
| 189 | pte = find_mapping_and_check(badvaddr, istate, &pfrc); |
189 | pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc); |
| 190 | if (!pte) { |
190 | if (!pte) { |
| 191 | switch (pfrc) { |
191 | switch (pfrc) { |
| 192 | case AS_PF_FAULT: |
192 | case AS_PF_FAULT: |
| 193 | goto fail; |
193 | goto fail; |
| 194 | break; |
194 | break; |
| Line 268... | Line 268... | ||
| 268 | if (index.p) { |
268 | if (index.p) { |
| 269 | printf("TLB entry not found.\n"); |
269 | printf("TLB entry not found.\n"); |
| 270 | goto fail; |
270 | goto fail; |
| 271 | } |
271 | } |
| 272 | 272 | ||
| 273 | pte = find_mapping_and_check(badvaddr, istate, &pfrc); |
273 | pte = find_mapping_and_check(badvaddr, PF_ACCESS_WRITE, istate, &pfrc); |
| 274 | if (!pte) { |
274 | if (!pte) { |
| 275 | switch (pfrc) { |
275 | switch (pfrc) { |
| 276 | case AS_PF_FAULT: |
276 | case AS_PF_FAULT: |
| 277 | goto fail; |
277 | goto fail; |
| 278 | break; |
278 | break; |
| Line 364... | Line 364... | ||
| 364 | * |
364 | * |
| 365 | * Try to find PTE for faulting address. |
365 | * Try to find PTE for faulting address. |
| 366 | * The AS->lock must be held on entry to this function. |
366 | * The AS->lock must be held on entry to this function. |
| 367 | * |
367 | * |
| 368 | * @param badvaddr Faulting virtual address. |
368 | * @param badvaddr Faulting virtual address. |
| - | 369 | * @param access Access mode that caused the fault. |
|
| 369 | * @param istate Pointer to interrupted state. |
370 | * @param istate Pointer to interrupted state. |
| 370 | * @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
371 | * @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
| 371 | * |
372 | * |
| 372 | * @return PTE on success, NULL otherwise. |
373 | * @return PTE on success, NULL otherwise. |
| 373 | */ |
374 | */ |
| 374 | pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfrc) |
375 | pte_t *find_mapping_and_check(__address badvaddr, int access, istate_t *istate, int *pfrc) |
| 375 | { |
376 | { |
| 376 | entry_hi_t hi; |
377 | entry_hi_t hi; |
| 377 | pte_t *pte; |
378 | pte_t *pte; |
| 378 | 379 | ||
| 379 | hi.value = cp0_entry_hi_read(); |
380 | hi.value = cp0_entry_hi_read(); |
| Line 402... | Line 403... | ||
| 402 | /* |
403 | /* |
| 403 | * Mapping not found in page tables. |
404 | * Mapping not found in page tables. |
| 404 | * Resort to higher-level page fault handler. |
405 | * Resort to higher-level page fault handler. |
| 405 | */ |
406 | */ |
| 406 | page_table_unlock(AS, true); |
407 | page_table_unlock(AS, true); |
| 407 | switch (rc = as_page_fault(badvaddr, istate)) { |
408 | switch (rc = as_page_fault(badvaddr, access, istate)) { |
| 408 | case AS_PF_OK: |
409 | case AS_PF_OK: |
| 409 | /* |
410 | /* |
| 410 | * The higher-level page fault handler succeeded, |
411 | * The higher-level page fault handler succeeded, |
| 411 | * The mapping ought to be in place. |
412 | * The mapping ought to be in place. |
| 412 | */ |
413 | */ |