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 <[email protected]> Reviewed-by: Fredrik Holmqvist <[email protected]> Reviewed-by: Alex von Gluck IV <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
5f8b4d4d2e
commit
933430df22
@@ -27,6 +27,10 @@ static uint32_t *sNextPageTable = NULL;
|
|||||||
static uint32_t *sLastPageTable = 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
|
static void
|
||||||
dump_page_dir(void)
|
dump_page_dir(void)
|
||||||
{
|
{
|
||||||
@@ -153,8 +157,6 @@ build_physical_memory_list(size_t memory_map_size,
|
|||||||
switch (entry->Type) {
|
switch (entry->Type) {
|
||||||
case EfiLoaderCode:
|
case EfiLoaderCode:
|
||||||
case EfiLoaderData:
|
case EfiLoaderData:
|
||||||
entry->VirtualStart = entry->PhysicalStart;
|
|
||||||
break;
|
|
||||||
case EfiBootServicesCode:
|
case EfiBootServicesCode:
|
||||||
case EfiBootServicesData:
|
case EfiBootServicesData:
|
||||||
case EfiConventionalMemory: {
|
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,
|
build_physical_memory_list(memory_map_size, memory_map,
|
||||||
descriptor_size, descriptor_version);
|
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) {
|
for (size_t i = 0; i < memory_map_size / descriptor_size; ++i) {
|
||||||
efi_memory_descriptor* entry =
|
efi_memory_descriptor* entry =
|
||||||
(efi_memory_descriptor *)(memory_map_addr + i * descriptor_size);
|
(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);
|
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);
|
map_range_to_new_area(gKernelArgs.arch_args.uart.regs, ARM_MMU_L2_FLAG_B);
|
||||||
|
|
||||||
sort_address_ranges(gKernelArgs.virtual_allocated_range,
|
sort_address_ranges(gKernelArgs.virtual_allocated_range,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#define ALIGN_MEMORY_MAP 4
|
#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);
|
addr_t kernelEntry, addr_t kernelStackTop);
|
||||||
|
|
||||||
// From arch_mmu.cpp
|
// From arch_mmu.cpp
|
||||||
@@ -79,6 +79,16 @@ memory_region_type_str(int type)
|
|||||||
void
|
void
|
||||||
arch_start_kernel(addr_t kernelEntry)
|
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.
|
// Prepare to exit EFI boot services.
|
||||||
// Read the memory map.
|
// Read the memory map.
|
||||||
// First call is to determine the buffer size.
|
// 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,
|
arch_mmu_post_efi_setup(memory_map_size, memory_map,
|
||||||
descriptor_size, descriptor_version);
|
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);
|
//smp_boot_other_cpus(final_pml4, kernelEntry);
|
||||||
|
|
||||||
// Enter the kernel!
|
// Enter the kernel!
|
||||||
dprintf("arch_enter_kernel(ttbr0: 0x%08x, kernelArgs: 0x%08x, "
|
dprintf("arch_enter_kernel(ttbr0: 0x%08x, kernelArgs: 0x%08x, "
|
||||||
"kernelEntry: 0x%08x, sp: 0x%08x)\n",
|
"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));
|
(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);
|
gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user