Rev 1702 | Rev 1726 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1702 | Rev 1708 | ||
|---|---|---|---|
| Line 65... | Line 65... | ||
| 65 | * @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
65 | * @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
| 66 | * @return PTE on success, NULL otherwise. |
66 | * @return PTE on success, NULL otherwise. |
| 67 | * |
67 | * |
| 68 | */ |
68 | */ |
| 69 | static pte_t *find_mapping_and_check(as_t *as, bool lock, __address badvaddr, int access, |
69 | static pte_t *find_mapping_and_check(as_t *as, bool lock, __address badvaddr, int access, |
| 70 | istate_t *istate, int *pfcr) |
70 | istate_t *istate, int *pfrc) |
| 71 | { |
71 | { |
| 72 | /* |
72 | /* |
| 73 | * Check if the mapping exists in page tables. |
73 | * Check if the mapping exists in page tables. |
| 74 | */ |
74 | */ |
| 75 | pte_t *pte = page_mapping_find(as, badvaddr); |
75 | pte_t *pte = page_mapping_find(as, badvaddr); |
| Line 97... | Line 97... | ||
| 97 | pte = page_mapping_find(as, badvaddr); |
97 | pte = page_mapping_find(as, badvaddr); |
| 98 | ASSERT((pte) && (pte->p)); |
98 | ASSERT((pte) && (pte->p)); |
| 99 | return pte; |
99 | return pte; |
| 100 | case AS_PF_DEFER: |
100 | case AS_PF_DEFER: |
| 101 | page_table_lock(as, lock); |
101 | page_table_lock(as, lock); |
| 102 | *pfcr = rc; |
102 | *pfrc = rc; |
| 103 | return NULL; |
103 | return NULL; |
| 104 | case AS_PF_FAULT: |
104 | case AS_PF_FAULT: |
| 105 | page_table_lock(as, lock); |
105 | page_table_lock(as, lock); |
| 106 | printf("Page fault.\n"); |
106 | printf("Page fault.\n"); |
| 107 | *pfcr = rc; |
107 | *pfrc = rc; |
| 108 | return NULL; |
108 | return NULL; |
| 109 | default: |
109 | default: |
| 110 | panic("unexpected rc (%d)\n", rc); |
110 | panic("unexpected rc (%d)\n", rc); |
| 111 | } |
111 | } |
| 112 | } |
112 | } |
| Line 188... | Line 188... | ||
| 188 | } |
188 | } |
| 189 | 189 | ||
| 190 | 190 | ||
| 191 | /** Process Instruction/Data Storage Interrupt |
191 | /** Process Instruction/Data Storage Interrupt |
| 192 | * |
192 | * |
| 193 | * @param data True if Data Storage Interrupt. |
193 | * @param n Interrupt vector number. |
| 194 | * @param istate Interrupted register context. |
194 | * @param istate Interrupted register context. |
| 195 | * |
195 | * |
| 196 | */ |
196 | */ |
| 197 | void pht_refill(int n, istate_t *istate) |
197 | void pht_refill(int n, istate_t *istate) |
| 198 | { |
198 | { |
| 199 | __address badvaddr; |
199 | __address badvaddr; |
| 200 | pte_t *pte; |
200 | pte_t *pte; |
| 201 | int pfcr; |
201 | int pfrc; |
| 202 | as_t *as; |
202 | as_t *as; |
| 203 | bool lock; |
203 | bool lock; |
| 204 | 204 | ||
| 205 | if (AS == NULL) { |
205 | if (AS == NULL) { |
| 206 | as = AS_KERNEL; |
206 | as = AS_KERNEL; |
| Line 218... | Line 218... | ||
| 218 | } else |
218 | } else |
| 219 | badvaddr = istate->pc; |
219 | badvaddr = istate->pc; |
| 220 | 220 | ||
| 221 | page_table_lock(as, lock); |
221 | page_table_lock(as, lock); |
| 222 | 222 | ||
| 223 | pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfcr); |
223 | pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc); |
| 224 | if (!pte) { |
224 | if (!pte) { |
| 225 | switch (pfcr) { |
225 | switch (pfrc) { |
| 226 | case AS_PF_FAULT: |
226 | case AS_PF_FAULT: |
| 227 | goto fail; |
227 | goto fail; |
| 228 | break; |
228 | break; |
| 229 | case AS_PF_DEFER: |
229 | case AS_PF_DEFER: |
| 230 | /* |
230 | /* |
| Line 232... | Line 232... | ||
| 232 | * or copy_to_uspace(). |
232 | * or copy_to_uspace(). |
| 233 | */ |
233 | */ |
| 234 | page_table_unlock(as, lock); |
234 | page_table_unlock(as, lock); |
| 235 | return; |
235 | return; |
| 236 | default: |
236 | default: |
| 237 | panic("Unexpected pfrc (%d)\n", pfcr); |
237 | panic("Unexpected pfrc (%d)\n", pfrc); |
| 238 | } |
238 | } |
| 239 | } |
239 | } |
| 240 | 240 | ||
| 241 | pte->a = 1; /* Record access to PTE */ |
241 | pte->a = 1; /* Record access to PTE */ |
| 242 | pht_insert(badvaddr, pte->pfn); |
242 | pht_insert(badvaddr, pte->pfn); |