diff --git a/src/system/boot/platform/efi/arch/arm/arch_mmu.cpp b/src/system/boot/platform/efi/arch/arm/arch_mmu.cpp index f22291e29b..5d316b13c8 100644 --- a/src/system/boot/platform/efi/arch/arm/arch_mmu.cpp +++ b/src/system/boot/platform/efi/arch/arm/arch_mmu.cpp @@ -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, diff --git a/src/system/boot/platform/efi/arch/arm/arch_start.cpp b/src/system/boot/platform/efi/arch/arm/arch_start.cpp index 761edcbb1f..d97cbb5628 100644 --- a/src/system/boot/platform/efi/arch/arm/arch_start.cpp +++ b/src/system/boot/platform/efi/arch/arm/arch_start.cpp @@ -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); }