kernel/arm: don't require identity mapping of initial page tables
Remove the dependency on identity mapping for the initial page tables used in MapEarly / _EarlyQuery. The initial page tables have to satisfy the following conditions instead: * the inital page tables shall be allocated in the same region as the initial page directory * this region shall be mapped contiguously * the page tables shall be mapped at a higher address than the page directory Change-Id: I34854ef93826aa48f5d90582b52905e553f3d275 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4857 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
parent
dc3e1761e6
commit
9103470bd3
@ -361,13 +361,15 @@ ARMPagingMethod32Bit::CreateTranslationMap(bool kernel, VMTranslationMap** _map)
|
||||
}
|
||||
|
||||
|
||||
static phys_addr_t
|
||||
get_free_pgtable(kernel_args* args)
|
||||
static void
|
||||
get_free_pgtable(kernel_args* args, phys_addr_t* phys_addr, addr_t* virt_addr)
|
||||
{
|
||||
phys_addr_t phys = args->arch_args.phys_pgdir + args->arch_args.next_pagetable;
|
||||
//addr_t virt = args->arch_args.vir_pgdir + args->arch_args.next_pagetable;
|
||||
addr_t virt = args->arch_args.vir_pgdir + args->arch_args.next_pagetable;
|
||||
args->arch_args.next_pagetable += ARM_MMU_L2_COARSE_TABLE_SIZE;
|
||||
return phys;
|
||||
|
||||
*phys_addr = phys;
|
||||
*virt_addr = virt;
|
||||
}
|
||||
|
||||
status_t
|
||||
@ -378,24 +380,28 @@ ARMPagingMethod32Bit::MapEarly(kernel_args* args, addr_t virtualAddress,
|
||||
// check to see if a page table exists for this range
|
||||
int index = VADDR_TO_PDENT(virtualAddress);
|
||||
if ((fKernelVirtualPageDirectory[index] & ARM_PDE_TYPE_MASK) == 0) {
|
||||
phys_addr_t pgtable;
|
||||
phys_addr_t pgtable_phys;
|
||||
addr_t pgtable_virt;
|
||||
page_directory_entry *e;
|
||||
|
||||
// we need to allocate a pgtable
|
||||
pgtable = get_free_pgtable(args);
|
||||
get_free_pgtable(args, &pgtable_phys, &pgtable_virt);
|
||||
|
||||
TRACE("ARMPagingMethod32Bit::MapEarly(): asked for free page for "
|
||||
"pgtable. %#" B_PRIxPHYSADDR "\n", pgtable);
|
||||
"pgtable. phys=%#" B_PRIxPHYSADDR ", virt=%#" B_PRIxADDR "\n",
|
||||
pgtable_phys, pgtable_virt);
|
||||
|
||||
// put it in the pgdir
|
||||
e = &fKernelVirtualPageDirectory[index];
|
||||
PutPageTableInPageDir(e, pgtable, attributes);
|
||||
PutPageTableInPageDir(e, pgtable_phys, attributes);
|
||||
|
||||
// zero it out in it's new mapping
|
||||
memset((void*)pgtable, 0, B_PAGE_SIZE);
|
||||
memset((void*)pgtable_virt, 0, B_PAGE_SIZE);
|
||||
}
|
||||
|
||||
page_table_entry* ptEntry = (page_table_entry*)
|
||||
(fKernelVirtualPageDirectory[index] & ARM_PDE_ADDRESS_MASK);
|
||||
phys_addr_t ptEntryPhys = fKernelVirtualPageDirectory[index] & ARM_PDE_ADDRESS_MASK;
|
||||
addr_t ptEntryVirt = ptEntryPhys - args->arch_args.phys_pgdir + args->arch_args.vir_pgdir;
|
||||
page_table_entry* ptEntry = (page_table_entry*)ptEntryVirt;
|
||||
ptEntry += VADDR_TO_PTENT(virtualAddress);
|
||||
|
||||
ASSERT_PRINT(
|
||||
@ -566,8 +572,12 @@ ARMPagingMethod32Bit::_EarlyQuery(addr_t virtualAddress,
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
page_table_entry* entry = (page_table_entry*)
|
||||
(method->KernelVirtualPageDirectory()[index] & ARM_PDE_ADDRESS_MASK);
|
||||
phys_addr_t ptEntryPhys = method->KernelVirtualPageDirectory()[index] & ARM_PDE_ADDRESS_MASK;
|
||||
addr_t ptEntryVirt = ptEntryPhys -
|
||||
(uint32_t)method->KernelPhysicalPageDirectory() +
|
||||
(uint32_t)method->KernelVirtualPageDirectory();
|
||||
|
||||
page_table_entry* entry = (page_table_entry*)ptEntryVirt;
|
||||
entry += VADDR_TO_PTENT(virtualAddress);
|
||||
|
||||
if ((*entry & ARM_PTE_TYPE_MASK) == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user