boot/efi/arm: remove identity mapping for EFI code and data segments

All the regions allocated via platform_allocate_region() are mapped to a
high virtual address so there's no need to do identity mapping for them
any more.

Copy kernel_args to a region allocated via platform_allocate_region() so it
will be mapped similarly.

Identity mapping is still needed for trampoline code for jumping to the kernel

Change-Id: I844a7a789b440a38521db49adc077bb77e658ddf
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4865
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com>
Reviewed-by: Alex von Gluck IV <kallisti5@unixzen.com>
This commit is contained in:
David Karoly 2022-01-14 15:52:15 +01:00 committed by Adrien Destugues
parent 5f8b4d4d2e
commit 933430df22
2 changed files with 26 additions and 20 deletions

View File

@ -27,6 +27,10 @@ static uint32_t *sNextPageTable = NULL;
static uint32_t *sLastPageTable = NULL;
extern "C" void arch_enter_kernel(uint32_t ttbr, struct kernel_args *kernelArgs,
addr_t kernelEntry, addr_t kernelStackTop);
static void
dump_page_dir(void)
{
@ -153,8 +157,6 @@ build_physical_memory_list(size_t memory_map_size,
switch (entry->Type) {
case EfiLoaderCode:
case EfiLoaderData:
entry->VirtualStart = entry->PhysicalStart;
break;
case EfiBootServicesCode:
case EfiBootServicesData:
case EfiConventionalMemory: {
@ -308,21 +310,6 @@ arch_mmu_generate_post_efi_page_tables(size_t memory_map_size,
build_physical_memory_list(memory_map_size, memory_map,
descriptor_size, descriptor_version);
for (size_t i = 0; i < memory_map_size / descriptor_size; ++i) {
efi_memory_descriptor* entry =
(efi_memory_descriptor *)(memory_map_addr + i * descriptor_size);
switch (entry->Type) {
case EfiLoaderCode:
case EfiLoaderData:
map_range(entry->VirtualStart, entry->PhysicalStart,
entry->NumberOfPages * B_PAGE_SIZE,
ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_C | ARM_MMU_L2_FLAG_AP_RW);
break;
default:
;
}
}
for (size_t i = 0; i < memory_map_size / descriptor_size; ++i) {
efi_memory_descriptor* entry =
(efi_memory_descriptor *)(memory_map_addr + i * descriptor_size);
@ -341,6 +328,10 @@ arch_mmu_generate_post_efi_page_tables(size_t memory_map_size,
ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_C | ARM_MMU_L2_FLAG_AP_RW);
}
// identity mapping for entry.S trampoline
map_range((uint32_t)arch_enter_kernel, (uint32_t)arch_enter_kernel, B_PAGE_SIZE,
ARM_MMU_L2_FLAG_B | ARM_MMU_L2_FLAG_C | ARM_MMU_L2_FLAG_AP_RW);
map_range_to_new_area(gKernelArgs.arch_args.uart.regs, ARM_MMU_L2_FLAG_B);
sort_address_ranges(gKernelArgs.virtual_allocated_range,

View File

@ -16,7 +16,7 @@
#define ALIGN_MEMORY_MAP 4
extern "C" void arch_enter_kernel(uint32_t ttbr, struct kernel_args *kernelArgs,
extern "C" void arch_enter_kernel(uint32_t ttbr, addr_t kernelArgs,
addr_t kernelEntry, addr_t kernelStackTop);
// From arch_mmu.cpp
@ -79,6 +79,16 @@ memory_region_type_str(int type)
void
arch_start_kernel(addr_t kernelEntry)
{
// Allocate virtual memory for kernel args
struct kernel_args *kernelArgs = NULL;
if (platform_allocate_region((void **)&kernelArgs,
sizeof(struct kernel_args), 0, false) != B_OK)
panic("Failed to allocate kernel args.");
addr_t virtKernelArgs;
platform_bootloader_address_to_kernel_address((void*)kernelArgs,
&virtKernelArgs);
// Prepare to exit EFI boot services.
// Read the memory map.
// First call is to determine the buffer size.
@ -164,14 +174,19 @@ arch_start_kernel(addr_t kernelEntry)
arch_mmu_post_efi_setup(memory_map_size, memory_map,
descriptor_size, descriptor_version);
// Copy final kernel args
// This should be the last step before jumping to the kernel
// as there are some fixups happening to kernel_args even in the last minute
memcpy(kernelArgs, &gKernelArgs, sizeof(struct kernel_args));
//smp_boot_other_cpus(final_pml4, kernelEntry);
// Enter the kernel!
dprintf("arch_enter_kernel(ttbr0: 0x%08x, kernelArgs: 0x%08x, "
"kernelEntry: 0x%08x, sp: 0x%08x)\n",
final_ttbr0, (uint32_t)&gKernelArgs, (uint32_t)kernelEntry,
final_ttbr0, (uint32_t)virtKernelArgs, (uint32_t)kernelEntry,
(uint32_t)(gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size));
arch_enter_kernel(final_ttbr0, &gKernelArgs, kernelEntry,
arch_enter_kernel(final_ttbr0, virtKernelArgs, kernelEntry,
gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size);
}