114,7 → 114,6 |
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2); |
} |
|
|
static void pht_insert(const __address vaddr, const pfn_t pfn) |
{ |
__u32 page = (vaddr >> 12) & 0xffff; |
131,32 → 130,16 |
__u32 hash = ((vsid ^ page) & 0x3ff) << 3; |
|
__u32 i; |
bool found = false; |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte[hash + i].v) { |
found = true; |
if (!phte[hash + i].v) |
break; |
} |
} |
|
if (!found) { |
/* Secondary hash (not) */ |
hash = ~hash; |
// TODO: Check access/change bits, secondary hash |
|
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte[hash + i].v) { |
found = true; |
break; |
} |
} |
|
if (!found) { |
// TODO: A/C precedence groups |
if (i == 8) |
i = page % 8; |
} |
} |
|
phte[hash + i].v = 1; |
phte[hash + i].vsid = vsid; |
212,6 → 195,7 |
return; |
default: |
panic("Unexpected pfrc (%d)\n", pfcr); |
break; |
} |
} |
|
230,7 → 214,16 |
void pht_init(void) |
{ |
memsetb((__address) phte, 1 << PHT_BITS, 0); |
|
/* Insert global kernel mapping */ |
|
__address cur; |
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) { |
pte_t *pte = page_mapping_find(AS_KERNEL, PA2KA(cur)); |
if ((pte) && (pte->p) && (pte->g)) |
pht_insert(PA2KA(cur), pte->pfn); |
} |
} |
|
|
void page_arch_init(void) |
263,5 → 256,9 |
: |
: "r" ((__address) physical_phte) |
); |
|
/* Invalidate block address translation registers, |
thus remove the temporary mapping */ |
// invalidate_bat(); |
} |
} |