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); |