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