Rev 1767 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1767 | Rev 1780 | ||
---|---|---|---|
Line 63... | Line 63... | ||
63 | * @param istate Pointer to interrupted state. |
63 | * @param istate Pointer to interrupted state. |
64 | * @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
64 | * @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
65 | * @return PTE on success, NULL otherwise. |
65 | * @return PTE on success, NULL otherwise. |
66 | * |
66 | * |
67 | */ |
67 | */ |
68 | static pte_t *find_mapping_and_check(as_t *as, bool lock, __address badvaddr, int access, |
68 | static pte_t *find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, |
69 | istate_t *istate, int *pfrc) |
69 | istate_t *istate, int *pfrc) |
70 | { |
70 | { |
71 | /* |
71 | /* |
72 | * Check if the mapping exists in page tables. |
72 | * Check if the mapping exists in page tables. |
73 | */ |
73 | */ |
Line 111... | Line 111... | ||
111 | } |
111 | } |
112 | } |
112 | } |
113 | } |
113 | } |
114 | 114 | ||
115 | 115 | ||
116 | static void pht_refill_fail(__address badvaddr, istate_t *istate) |
116 | static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate) |
117 | { |
117 | { |
118 | char *symbol = ""; |
118 | char *symbol = ""; |
119 | char *sym2 = ""; |
119 | char *sym2 = ""; |
120 | 120 | ||
121 | char *s = get_symtab_entry(istate->pc); |
121 | char *s = get_symtab_entry(istate->pc); |
Line 126... | Line 126... | ||
126 | sym2 = s; |
126 | sym2 = s; |
127 | panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2); |
127 | panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2); |
128 | } |
128 | } |
129 | 129 | ||
130 | 130 | ||
131 | static void pht_insert(const __address vaddr, const pfn_t pfn) |
131 | static void pht_insert(const uintptr_t vaddr, const pfn_t pfn) |
132 | { |
132 | { |
133 | __u32 page = (vaddr >> 12) & 0xffff; |
133 | uint32_t page = (vaddr >> 12) & 0xffff; |
134 | __u32 api = (vaddr >> 22) & 0x3f; |
134 | uint32_t api = (vaddr >> 22) & 0x3f; |
135 | __u32 vsid; |
135 | uint32_t vsid; |
136 | 136 | ||
137 | asm volatile ( |
137 | asm volatile ( |
138 | "mfsrin %0, %1\n" |
138 | "mfsrin %0, %1\n" |
139 | : "=r" (vsid) |
139 | : "=r" (vsid) |
140 | : "r" (vaddr) |
140 | : "r" (vaddr) |
141 | ); |
141 | ); |
142 | 142 | ||
143 | /* Primary hash (xor) */ |
143 | /* Primary hash (xor) */ |
144 | __u32 h = 0; |
144 | uint32_t h = 0; |
145 | __u32 hash = vsid ^ page; |
145 | uint32_t hash = vsid ^ page; |
146 | __u32 base = (hash & 0x3ff) << 3; |
146 | uint32_t base = (hash & 0x3ff) << 3; |
147 | __u32 i; |
147 | uint32_t i; |
148 | bool found = false; |
148 | bool found = false; |
149 | 149 | ||
150 | /* Find unused or colliding |
150 | /* Find unused or colliding |
151 | PTE in PTEG */ |
151 | PTE in PTEG */ |
152 | for (i = 0; i < 8; i++) { |
152 | for (i = 0; i < 8; i++) { |
Line 156... | Line 156... | ||
156 | } |
156 | } |
157 | } |
157 | } |
158 | 158 | ||
159 | if (!found) { |
159 | if (!found) { |
160 | /* Secondary hash (not) */ |
160 | /* Secondary hash (not) */ |
161 | __u32 base2 = (~hash & 0x3ff) << 3; |
161 | uint32_t base2 = (~hash & 0x3ff) << 3; |
162 | 162 | ||
163 | /* Find unused or colliding |
163 | /* Find unused or colliding |
164 | PTE in PTEG */ |
164 | PTE in PTEG */ |
165 | for (i = 0; i < 8; i++) { |
165 | for (i = 0; i < 8; i++) { |
166 | if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) { |
166 | if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) { |
Line 194... | Line 194... | ||
194 | * @param istate Interrupted register context. |
194 | * @param istate Interrupted register context. |
195 | * |
195 | * |
196 | */ |
196 | */ |
197 | void pht_refill(bool data, istate_t *istate) |
197 | void pht_refill(bool data, istate_t *istate) |
198 | { |
198 | { |
199 | __address badvaddr; |
199 | uintptr_t badvaddr; |
200 | pte_t *pte; |
200 | pte_t *pte; |
201 | int pfrc; |
201 | int pfrc; |
202 | as_t *as; |
202 | as_t *as; |
203 | bool lock; |
203 | bool lock; |
204 | 204 | ||
Line 250... | Line 250... | ||
250 | } |
250 | } |
251 | 251 | ||
252 | 252 | ||
253 | void pht_init(void) |
253 | void pht_init(void) |
254 | { |
254 | { |
255 | memsetb((__address) phte, 1 << PHT_BITS, 0); |
255 | memsetb((uintptr_t) phte, 1 << PHT_BITS, 0); |
256 | } |
256 | } |
257 | 257 | ||
258 | 258 | ||
259 | void page_arch_init(void) |
259 | void page_arch_init(void) |
260 | { |
260 | { |
261 | if (config.cpu_active == 1) { |
261 | if (config.cpu_active == 1) { |
262 | page_mapping_operations = &pt_mapping_operations; |
262 | page_mapping_operations = &pt_mapping_operations; |
263 | 263 | ||
264 | __address cur; |
264 | uintptr_t cur; |
265 | int flags; |
265 | int flags; |
266 | 266 | ||
267 | /* Frames below 128 MB are mapped using BAT, |
267 | /* Frames below 128 MB are mapped using BAT, |
268 | map rest of the physical memory */ |
268 | map rest of the physical memory */ |
269 | for (cur = 128 << 20; cur < last_frame; cur += FRAME_SIZE) { |
269 | for (cur = 128 << 20; cur < last_frame; cur += FRAME_SIZE) { |
Line 274... | Line 274... | ||
274 | } |
274 | } |
275 | 275 | ||
276 | /* Allocate page hash table */ |
276 | /* Allocate page hash table */ |
277 | phte_t *physical_phte = (phte_t *) frame_alloc(PHT_ORDER, FRAME_KA | FRAME_ATOMIC); |
277 | phte_t *physical_phte = (phte_t *) frame_alloc(PHT_ORDER, FRAME_KA | FRAME_ATOMIC); |
278 | 278 | ||
279 | ASSERT((__address) physical_phte % (1 << PHT_BITS) == 0); |
279 | ASSERT((uintptr_t) physical_phte % (1 << PHT_BITS) == 0); |
280 | pht_init(); |
280 | pht_init(); |
281 | 281 | ||
282 | asm volatile ( |
282 | asm volatile ( |
283 | "mtsdr1 %0\n" |
283 | "mtsdr1 %0\n" |
284 | : |
284 | : |
285 | : "r" ((__address) physical_phte) |
285 | : "r" ((uintptr_t) physical_phte) |
286 | ); |
286 | ); |
287 | } |
287 | } |
288 | } |
288 | } |
289 | 289 | ||
290 | 290 | ||
291 | __address hw_map(__address physaddr, size_t size) |
291 | uintptr_t hw_map(uintptr_t physaddr, size_t size) |
292 | { |
292 | { |
293 | if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
293 | if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
294 | panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
294 | panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
295 | 295 | ||
296 | __address virtaddr = PA2KA(last_frame); |
296 | uintptr_t virtaddr = PA2KA(last_frame); |
297 | pfn_t i; |
297 | pfn_t i; |
298 | for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) |
298 | for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) |
299 | page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE); |
299 | page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE); |
300 | 300 | ||
301 | last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
301 | last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |