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 | */ |