From a3c9f71efdb5ac071381fde1e223aa22cf414f50 Mon Sep 17 00:00:00 2001 From: David Karoly Date: Sun, 25 Sep 2022 11:26:12 +0200 Subject: [PATCH] boot/efi: factor out generic mmu functions This change moves the common functions related to EFI memory map to arch/generic for arm, arm64, x86. riscv64 and x86_64 shall be handled separately as they use some more architecture-specific logic: * riscv64 needs special treatment for the M-mode resident code located at 0x80000000 which is reported as available in the EFI memory map provided by u-boot. * x86_64 has a slightly different logic for building the memory regions list so some additional rework and testing will be needed before it can be unified with the generic mmu functions. Change-Id: I430c84dfc693c5b6f04c170dec8ffb1db2c2ace1 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5694 Reviewed-by: waddlesplash Tested-by: Commit checker robot --- src/system/boot/platform/efi/arch/arm/Jamfile | 55 ++++--- .../boot/platform/efi/arch/arm/arch_mmu.cpp | 91 +---------- .../boot/platform/efi/arch/arm/arch_start.cpp | 41 +---- .../boot/platform/efi/arch/arm64/Jamfile | 61 ++++---- .../boot/platform/efi/arch/arm64/arch_mmu.cpp | 100 +------------ .../platform/efi/arch/arm64/arch_start.cpp | 41 +---- .../platform/efi/arch/generic/generic_mmu.cpp | 141 ++++++++++++++++++ .../platform/efi/arch/generic/generic_mmu.h | 24 +++ src/system/boot/platform/efi/arch/x86/Jamfile | 11 +- .../boot/platform/efi/arch/x86/arch_mmu.cpp | 103 +------------ .../boot/platform/efi/arch/x86/arch_start.cpp | 41 +---- 11 files changed, 267 insertions(+), 442 deletions(-) create mode 100644 src/system/boot/platform/efi/arch/generic/generic_mmu.cpp create mode 100644 src/system/boot/platform/efi/arch/generic/generic_mmu.h diff --git a/src/system/boot/platform/efi/arch/arm/Jamfile b/src/system/boot/platform/efi/arch/arm/Jamfile index 3f33160510..94ce331346 100644 --- a/src/system/boot/platform/efi/arch/arm/Jamfile +++ b/src/system/boot/platform/efi/arch/arm/Jamfile @@ -1,6 +1,7 @@ SubDir HAIKU_TOP src system boot platform efi arch arm ; -SubDirHdrs $(HAIKU_TOP) src system boot platform efi ; +SubDirHdrs $(SUBDIR) $(DOTDOT) $(DOTDOT) ; +SubDirHdrs $(SUBDIR) $(DOTDOT) generic ; UseLibraryHeaders [ FDirName libfdt ] ; @@ -11,29 +12,37 @@ UsePrivateHeaders [ FDirName kernel boot platform efi ] ; local platform ; for platform in [ MultiBootSubDirSetup efi ] { - on $(platform) { - { - local defines = _BOOT_MODE _BOOT_PLATFORM_EFI ; - defines = [ FDefines $(defines) ] ; - SubDirCcFlags $(defines) ; - SubDirC++Flags $(defines) -fno-rtti ; - } + on $(platform) { + { + local defines = _BOOT_MODE _BOOT_PLATFORM_EFI ; + defines = [ FDefines $(defines) ] ; + SubDirCcFlags $(defines) ; + SubDirC++Flags $(defines) -fno-rtti ; + } - local arch_src = - crt0-efi-$(TARGET_ARCH).S - entry.S - cache.S - relocation_func.cpp - arch_cpu.cpp - arch_dtb.cpp - arch_mmu.cpp - arch_smp.cpp - arch_start.cpp - arch_timer.cpp - ; + local arch_src = + crt0-efi-$(TARGET_ARCH).S + entry.S + cache.S + relocation_func.cpp + arch_cpu.cpp + arch_dtb.cpp + arch_mmu.cpp + arch_smp.cpp + arch_start.cpp + arch_timer.cpp + ; - BootMergeObject boot_platform_efi_arm.o : - $(arch_src) - ; + local generic_src = + generic_mmu.cpp + ; + + BootMergeObject boot_platform_efi_arm.o : + $(arch_src) + $(generic_src) + ; + + SEARCH on [ FGristFiles $(generic_src) ] + = [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; } } 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 0ac59a4a3f..0a9d9d88a3 100644 --- a/src/system/boot/platform/efi/arch/arm/arch_mmu.cpp +++ b/src/system/boot/platform/efi/arch/arm/arch_mmu.cpp @@ -14,8 +14,9 @@ #include #include -#include "mmu.h" #include "efi_platform.h" +#include "generic_mmu.h" +#include "mmu.h" //#define TRACE_MMU @@ -29,6 +30,10 @@ //#define TRACE_MEMORY_MAP //#define TRACE_PAGE_DIRECTORY +// Ignore memory above 512GB +#define PHYSICAL_MEMORY_LOW 0x00000000 +#define PHYSICAL_MEMORY_HIGH 0x8000000000ull + #define ALIGN_PAGEDIR (1024 * 16) #define MAX_PAGE_TABLES 192 #define PAGE_TABLE_AREA_SIZE (MAX_PAGE_TABLES * ARM_MMU_L2_COARSE_TABLE_SIZE) @@ -160,87 +165,6 @@ map_range_to_new_area(efi_memory_descriptor *entry, uint32_t flags) } -static void -build_physical_memory_list(size_t memoryMapSize, - efi_memory_descriptor *memoryMap, size_t descriptorSize, - uint32_t descriptorVersion) -{ - addr_t addr = (addr_t)memoryMap; - - gKernelArgs.num_physical_memory_ranges = 0; - - // First scan: Add all usable ranges - for (size_t i = 0; i < memoryMapSize / descriptorSize; ++i) { - efi_memory_descriptor* entry = (efi_memory_descriptor *)(addr + i * descriptorSize); - switch (entry->Type) { - case EfiLoaderCode: - case EfiLoaderData: - case EfiBootServicesCode: - case EfiBootServicesData: - case EfiConventionalMemory: { - // Usable memory. - uint64_t base = entry->PhysicalStart; - uint64_t size = entry->NumberOfPages * B_PAGE_SIZE; - insert_physical_memory_range(base, size); - break; - } - default: - break; - } - } - - uint64_t initialPhysicalMemory = total_physical_memory(); - - // Second scan: Remove everything reserved that may overlap - for (size_t i = 0; i < memoryMapSize / descriptorSize; ++i) { - efi_memory_descriptor* entry = (efi_memory_descriptor *)(addr + i * descriptorSize); - switch (entry->Type) { - case EfiLoaderCode: - case EfiLoaderData: - case EfiBootServicesCode: - case EfiBootServicesData: - case EfiConventionalMemory: - break; - default: - uint64_t base = entry->PhysicalStart; - uint64_t size = entry->NumberOfPages * B_PAGE_SIZE; - remove_physical_memory_range(base, size); - } - } - - gKernelArgs.ignored_physical_memory - += initialPhysicalMemory - total_physical_memory(); - - sort_address_ranges(gKernelArgs.physical_memory_range, - gKernelArgs.num_physical_memory_ranges); -} - - -static void -build_physical_allocated_list(size_t memoryMapSize, - efi_memory_descriptor *memoryMap, size_t descriptorSize, - uint32_t descriptorVersion) -{ - addr_t addr = (addr_t)memoryMap; - for (size_t i = 0; i < memoryMapSize / descriptorSize; ++i) { - efi_memory_descriptor* entry = (efi_memory_descriptor *)(addr + i * descriptorSize); - switch (entry->Type) { - case EfiLoaderData: { - uint64_t base = entry->PhysicalStart; - uint64_t size = entry->NumberOfPages * B_PAGE_SIZE; - insert_physical_allocated_range(base, size); - break; - } - default: - ; - } - } - - sort_address_ranges(gKernelArgs.physical_allocated_range, - gKernelArgs.num_physical_allocated_ranges); -} - - void arch_mmu_post_efi_setup(size_t memoryMapSize, efi_memory_descriptor *memoryMap, size_t descriptorSize, @@ -317,7 +241,8 @@ arch_mmu_generate_post_efi_page_tables(size_t memoryMapSize, arch_mmu_allocate_page_tables(); build_physical_memory_list(memoryMapSize, memoryMap, - descriptorSize, descriptorVersion); + descriptorSize, descriptorVersion, + PHYSICAL_MEMORY_LOW, PHYSICAL_MEMORY_HIGH); addr_t memoryMapAddr = (addr_t)memoryMap; for (size_t i = 0; i < memoryMapSize / descriptorSize; ++i) { 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 ef67f2ca56..ea424a7abc 100644 --- a/src/system/boot/platform/efi/arch/arm/arch_start.cpp +++ b/src/system/boot/platform/efi/arch/arm/arch_start.cpp @@ -11,6 +11,7 @@ #include #include "efi_platform.h" +#include "generic_mmu.h" #include "mmu.h" #include "serial.h" #include "smp.h" @@ -53,46 +54,6 @@ arch_convert_kernel_args(void) } -static const char* -memory_region_type_str(int type) -{ - switch (type) { - case EfiReservedMemoryType: - return "ReservedMemoryType"; - case EfiLoaderCode: - return "LoaderCode"; - case EfiLoaderData: - return "LoaderData"; - case EfiBootServicesCode: - return "BootServicesCode"; - case EfiBootServicesData: - return "BootServicesData"; - case EfiRuntimeServicesCode: - return "RuntimeServicesCode"; - case EfiRuntimeServicesData: - return "RuntimeServicesData"; - case EfiConventionalMemory: - return "ConventionalMemory"; - case EfiUnusableMemory: - return "UnusableMemory"; - case EfiACPIReclaimMemory: - return "ACPIReclaimMemory"; - case EfiACPIMemoryNVS: - return "ACPIMemoryNVS"; - case EfiMemoryMappedIO: - return "MMIO"; - case EfiMemoryMappedIOPortSpace: - return "MMIOPortSpace"; - case EfiPalCode: - return "PalCode"; - case EfiPersistentMemory: - return "PersistentMemory"; - default: - return "unknown"; - } -} - - static void * allocate_trampoline_page(void) { diff --git a/src/system/boot/platform/efi/arch/arm64/Jamfile b/src/system/boot/platform/efi/arch/arm64/Jamfile index 292fdef6a5..0f1510e94f 100644 --- a/src/system/boot/platform/efi/arch/arm64/Jamfile +++ b/src/system/boot/platform/efi/arch/arm64/Jamfile @@ -1,6 +1,7 @@ SubDir HAIKU_TOP src system boot platform efi arch arm64 ; -SubDirHdrs $(HAIKU_TOP) src system boot platform efi ; +SubDirHdrs $(SUBDIR) $(DOTDOT) $(DOTDOT) ; +SubDirHdrs $(SUBDIR) $(DOTDOT) generic ; UseLibraryHeaders [ FDirName libfdt ] ; @@ -9,32 +10,40 @@ UsePrivateHeaders [ FDirName kernel boot platform efi ] ; local platform ; for platform in [ MultiBootSubDirSetup efi ] { - on $(platform) { - { - local defines = _BOOT_MODE _BOOT_PLATFORM_EFI ; - defines = [ FDefines $(defines) ] ; - SubDirCcFlags $(defines) ; - SubDirC++Flags $(defines) -fno-rtti ; - } + on $(platform) { + { + local defines = _BOOT_MODE _BOOT_PLATFORM_EFI ; + defines = [ FDefines $(defines) ] ; + SubDirCcFlags $(defines) ; + SubDirC++Flags $(defines) -fno-rtti ; + } - local arch_src = - crt0-efi-$(TARGET_ARCH).S - entry.S - transition.S - exceptions.S - cache.S - relocation_func.cpp - arch_acpi.cpp - arch_cache.cpp - arch_dtb.cpp - arch_mmu.cpp - arch_smp.cpp - arch_start.cpp - arch_timer.cpp - ; + local arch_src = + crt0-efi-$(TARGET_ARCH).S + entry.S + transition.S + exceptions.S + cache.S + relocation_func.cpp + arch_acpi.cpp + arch_cache.cpp + arch_dtb.cpp + arch_mmu.cpp + arch_smp.cpp + arch_start.cpp + arch_timer.cpp + ; - BootMergeObject boot_platform_efi_arm64.o : - $(arch_src) - ; + local generic_src = + generic_mmu.cpp + ; + + BootMergeObject boot_platform_efi_arm64.o : + $(arch_src) + $(generic_src) + ; + + SEARCH on [ FGristFiles $(generic_src) ] + = [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; } } diff --git a/src/system/boot/platform/efi/arch/arm64/arch_mmu.cpp b/src/system/boot/platform/efi/arch/arm64/arch_mmu.cpp index 16a6f410a5..fb07a409d4 100644 --- a/src/system/boot/platform/efi/arch/arm64/arch_mmu.cpp +++ b/src/system/boot/platform/efi/arch/arm64/arch_mmu.cpp @@ -6,8 +6,9 @@ #include #include -#include "mmu.h" #include "efi_platform.h" +#include "generic_mmu.h" +#include "mmu.h" #include "aarch64.h" #include "arch_mmu.h" @@ -23,6 +24,9 @@ //#define TRACE_MEMORY_MAP //#define TRACE_PAGE_DIRECTORY +// Ignore memory above 512GB +#define PHYSICAL_MEMORY_LOW 0x00000000 +#define PHYSICAL_MEMORY_HIGH 0x8000000000ull ARMv8TranslationRegime::TranslationDescriptor translation4Kb48bits = { {L0_SHIFT, L0_ADDR_MASK, false, true, false }, @@ -268,97 +272,6 @@ map_range(addr_t virt_addr, phys_addr_t phys_addr, size_t size, uint64_t flags) } -static void -build_physical_memory_list(size_t memory_map_size, - efi_memory_descriptor* memory_map, size_t descriptor_size, - uint32_t descriptor_version) -{ - addr_t addr = (addr_t)memory_map; - - gKernelArgs.num_physical_memory_ranges = 0; - - // First scan: Add all usable ranges - for (size_t i = 0; i < memory_map_size / descriptor_size; ++i) { - efi_memory_descriptor* entry = (efi_memory_descriptor*)(addr + i * descriptor_size); - switch (entry->Type) { - case EfiLoaderCode: - case EfiLoaderData: - entry->VirtualStart = entry->PhysicalStart; - break; - case EfiBootServicesCode: - case EfiBootServicesData: - case EfiConventionalMemory: { - // Usable memory. - uint64_t base = entry->PhysicalStart; - uint64_t size = entry->NumberOfPages * B_PAGE_SIZE; - insert_physical_memory_range(base, size); - break; - } - case EfiACPIReclaimMemory: - // ACPI reclaim -- physical memory we could actually use later - break; - case EfiRuntimeServicesCode: - case EfiRuntimeServicesData: - entry->VirtualStart = entry->PhysicalStart; - break; - case EfiMemoryMappedIO: - entry->VirtualStart = entry->PhysicalStart; - break; - } - } - - uint64_t initialPhysicalMemory = total_physical_memory(); - - // Second scan: Remove everything reserved that may overlap - for (size_t i = 0; i < memory_map_size / descriptor_size; ++i) { - efi_memory_descriptor* entry = (efi_memory_descriptor*)(addr + i * descriptor_size); - switch (entry->Type) { - case EfiLoaderCode: - case EfiLoaderData: - case EfiBootServicesCode: - case EfiBootServicesData: - case EfiConventionalMemory: - break; - default: - uint64_t base = entry->PhysicalStart; - uint64_t size = entry->NumberOfPages * B_PAGE_SIZE; - remove_physical_memory_range(base, size); - } - } - - gKernelArgs.ignored_physical_memory - += initialPhysicalMemory - total_physical_memory(); - - sort_address_ranges(gKernelArgs.physical_memory_range, - gKernelArgs.num_physical_memory_ranges); -} - - -static void -build_physical_allocated_list(size_t memory_map_size, - efi_memory_descriptor* memory_map, size_t descriptor_size, - uint32_t descriptor_version) -{ - addr_t addr = (addr_t)memory_map; - for (size_t i = 0; i < memory_map_size / descriptor_size; ++i) { - efi_memory_descriptor* entry = (efi_memory_descriptor*)(addr + i * descriptor_size); - switch (entry->Type) { - case EfiLoaderData: { - uint64_t base = entry->PhysicalStart; - uint64_t size = entry->NumberOfPages * B_PAGE_SIZE; - insert_physical_allocated_range(base, size); - break; - } - default: - ; - } - } - - sort_address_ranges(gKernelArgs.physical_allocated_range, - gKernelArgs.num_physical_allocated_ranges); -} - - void arch_mmu_init() { @@ -459,7 +372,8 @@ arch_mmu_generate_post_efi_page_tables(size_t memory_map_size, arch_mmu_allocate_kernel_page_tables(); build_physical_memory_list(memory_map_size, memory_map, - descriptor_size, descriptor_version); + descriptor_size, descriptor_version, + PHYSICAL_MEMORY_LOW, PHYSICAL_MEMORY_HIGH); TRACE("Mapping Code & Data\n"); diff --git a/src/system/boot/platform/efi/arch/arm64/arch_start.cpp b/src/system/boot/platform/efi/arch/arm64/arch_start.cpp index 02d75dfef2..9f7e7545fb 100644 --- a/src/system/boot/platform/efi/arch/arm64/arch_start.cpp +++ b/src/system/boot/platform/efi/arch/arm64/arch_start.cpp @@ -9,6 +9,7 @@ #include #include "efi_platform.h" +#include "generic_mmu.h" #include "mmu.h" #include "serial.h" @@ -28,46 +29,6 @@ extern void arch_mmu_post_efi_setup(size_t memory_map_size, efi_memory_descripto extern void arch_mmu_setup_EL1(uint64 tcr); -static const char* -memory_region_type_str(int type) -{ - switch (type) { - case EfiReservedMemoryType: - return "ReservedMemoryType"; - case EfiLoaderCode: - return "LoaderCode"; - case EfiLoaderData: - return "LoaderData"; - case EfiBootServicesCode: - return "BootServicesCode"; - case EfiBootServicesData: - return "BootServicesData"; - case EfiRuntimeServicesCode: - return "RuntimeServicesCode"; - case EfiRuntimeServicesData: - return "RuntimeServicesData"; - case EfiConventionalMemory: - return "ConventionalMemory"; - case EfiUnusableMemory: - return "UnusableMemory"; - case EfiACPIReclaimMemory: - return "ACPIReclaimMemory"; - case EfiACPIMemoryNVS: - return "ACPIMemoryNVS"; - case EfiMemoryMappedIO: - return "MMIO"; - case EfiMemoryMappedIOPortSpace: - return "MMIOPortSpace"; - case EfiPalCode: - return "PalCode"; - case EfiPersistentMemory: - return "PersistentMemory"; - default: - return "unknown"; - } -} - - void arch_convert_kernel_args(void) { diff --git a/src/system/boot/platform/efi/arch/generic/generic_mmu.cpp b/src/system/boot/platform/efi/arch/generic/generic_mmu.cpp new file mode 100644 index 0000000000..df0e5cbe73 --- /dev/null +++ b/src/system/boot/platform/efi/arch/generic/generic_mmu.cpp @@ -0,0 +1,141 @@ +/* + * Copyright 2022 Haiku, Inc. All rights reserved. + * Released under the terms of the MIT License. + */ + +#include "generic_mmu.h" + +#include +#include + + +void +build_physical_memory_list(size_t memoryMapSize, efi_memory_descriptor* memoryMap, + size_t descriptorSize, uint32_t descriptorVersion, + uint64_t physicalMemoryLow, uint64_t physicalMemoryHigh) +{ + addr_t addr = (addr_t)memoryMap; + + gKernelArgs.num_physical_memory_ranges = 0; + + // First scan: Add all usable ranges + for (size_t i = 0; i < memoryMapSize / descriptorSize; ++i) { + efi_memory_descriptor* entry = (efi_memory_descriptor *)(addr + i * descriptorSize); + switch (entry->Type) { + case EfiLoaderCode: + case EfiLoaderData: + case EfiBootServicesCode: + case EfiBootServicesData: + case EfiConventionalMemory: { + uint64_t base = entry->PhysicalStart; + uint64_t end = entry->PhysicalStart + entry->NumberOfPages * B_PAGE_SIZE; + uint64_t originalSize = end - base; + base = std::max(base, physicalMemoryLow); + end = std::min(end, physicalMemoryHigh); + + gKernelArgs.ignored_physical_memory + += originalSize - (max_c(end, base) - base); + + if (base >= end) + break; + uint64_t size = end - base; + + insert_physical_memory_range(base, size); + break; + } + default: + break; + } + } + + uint64_t initialPhysicalMemory = total_physical_memory(); + + // Second scan: Remove everything reserved that may overlap + for (size_t i = 0; i < memoryMapSize / descriptorSize; ++i) { + efi_memory_descriptor* entry = (efi_memory_descriptor *)(addr + i * descriptorSize); + switch (entry->Type) { + case EfiLoaderCode: + case EfiLoaderData: + case EfiBootServicesCode: + case EfiBootServicesData: + case EfiConventionalMemory: + break; + default: + uint64_t base = entry->PhysicalStart; + uint64_t size = entry->NumberOfPages * B_PAGE_SIZE; + remove_physical_memory_range(base, size); + } + } + + gKernelArgs.ignored_physical_memory + += initialPhysicalMemory - total_physical_memory(); + + sort_address_ranges(gKernelArgs.physical_memory_range, + gKernelArgs.num_physical_memory_ranges); +} + + +void +build_physical_allocated_list(size_t memoryMapSize, efi_memory_descriptor* memoryMap, + size_t descriptorSize, uint32_t descriptorVersion) +{ + gKernelArgs.num_physical_allocated_ranges = 0; + + addr_t addr = (addr_t)memoryMap; + for (size_t i = 0; i < memoryMapSize / descriptorSize; ++i) { + efi_memory_descriptor* entry = (efi_memory_descriptor *)(addr + i * descriptorSize); + switch (entry->Type) { + case EfiLoaderData: { + uint64_t base = entry->PhysicalStart; + uint64_t size = entry->NumberOfPages * B_PAGE_SIZE; + insert_physical_allocated_range(base, size); + break; + } + default: + ; + } + } + + sort_address_ranges(gKernelArgs.physical_allocated_range, + gKernelArgs.num_physical_allocated_ranges); +} + + +const char* +memory_region_type_str(int type) +{ + switch (type) { + case EfiReservedMemoryType: + return "EfiReservedMemoryType"; + case EfiLoaderCode: + return "EfiLoaderCode"; + case EfiLoaderData: + return "EfiLoaderData"; + case EfiBootServicesCode: + return "EfiBootServicesCode"; + case EfiBootServicesData: + return "EfiBootServicesData"; + case EfiRuntimeServicesCode: + return "EfiRuntimeServicesCode"; + case EfiRuntimeServicesData: + return "EfiRuntimeServicesData"; + case EfiConventionalMemory: + return "EfiConventionalMemory"; + case EfiUnusableMemory: + return "EfiUnusableMemory"; + case EfiACPIReclaimMemory: + return "EfiACPIReclaimMemory"; + case EfiACPIMemoryNVS: + return "EfiACPIMemoryNVS"; + case EfiMemoryMappedIO: + return "EfiMemoryMappedIO"; + case EfiMemoryMappedIOPortSpace: + return "EfiMemoryMappedIOPortSpace"; + case EfiPalCode: + return "EfiPalCode"; + case EfiPersistentMemory: + return "EfiPersistentMemory"; + default: + return "unknown"; + } +} diff --git a/src/system/boot/platform/efi/arch/generic/generic_mmu.h b/src/system/boot/platform/efi/arch/generic/generic_mmu.h new file mode 100644 index 0000000000..cf612bf12f --- /dev/null +++ b/src/system/boot/platform/efi/arch/generic/generic_mmu.h @@ -0,0 +1,24 @@ +/* + * Copyright 2022 Haiku, Inc. All rights reserved. + * Released under the terms of the MIT License. + */ +#ifndef EFI_GENERIC_MMU_H +#define EFI_GENERIC_MMU_H + + +#include +#include +#include + + +void build_physical_memory_list(size_t memoryMapSize, efi_memory_descriptor *memoryMap, + size_t descriptorSize, uint32_t descriptorVersion, + uint64_t physicalMemoryLow, uint64_t physicalMemoryHigh); + +void build_physical_allocated_list(size_t memoryMapSize, efi_memory_descriptor *memoryMap, + size_t descriptorSize, uint32_t descriptorVersion); + +const char* memory_region_type_str(int type); + + +#endif /* EFI_GENERIC_MMU_H */ diff --git a/src/system/boot/platform/efi/arch/x86/Jamfile b/src/system/boot/platform/efi/arch/x86/Jamfile index db715bf1e4..a1e7855834 100644 --- a/src/system/boot/platform/efi/arch/x86/Jamfile +++ b/src/system/boot/platform/efi/arch/x86/Jamfile @@ -1,6 +1,7 @@ SubDir HAIKU_TOP src system boot platform efi arch x86 ; -SubDirHdrs $(HAIKU_TOP) src system boot platform efi ; +SubDirHdrs $(SUBDIR) $(DOTDOT) $(DOTDOT) ; +SubDirHdrs $(SUBDIR) $(DOTDOT) generic ; UsePrivateHeaders [ FDirName kernel platform ] ; UsePrivateHeaders [ FDirName kernel boot platform efi ] ; @@ -28,8 +29,16 @@ for platform in [ MultiBootSubDirSetup efi ] { arch_timer.cpp ; + local generic_src = + generic_mmu.cpp + ; + BootMergeObject boot_platform_efi_x86.o : $(arch_src) + $(generic_src) ; + + SEARCH on [ FGristFiles $(generic_src) ] + = [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; } } diff --git a/src/system/boot/platform/efi/arch/x86/arch_mmu.cpp b/src/system/boot/platform/efi/arch/x86/arch_mmu.cpp index 111d0d5543..9b62196a50 100644 --- a/src/system/boot/platform/efi/arch/x86/arch_mmu.cpp +++ b/src/system/boot/platform/efi/arch/x86/arch_mmu.cpp @@ -16,6 +16,7 @@ #include #include "efi_platform.h" +#include "generic_mmu.h" #include "mmu.h" @@ -30,6 +31,10 @@ //#define TRACE_MEMORY_MAP //#define TRACE_PAGE_DIRECTORY +// Ignore memory below 1M and above 64GB (maximum amount of physical memory on x86 with PAE) +#define PHYSICAL_MEMORY_LOW 0x00100000 +#define PHYSICAL_MEMORY_HIGH 0x1000000000ull + #define VADDR_TO_PDENT(va) (((va) / B_PAGE_SIZE) / 1024) #define VADDR_TO_PTENT(va) (((va) / B_PAGE_SIZE) % 1024) #define X86_PDE_ADDRESS_MASK 0xfffff000 @@ -175,101 +180,6 @@ map_range(addr_t virtAddr, phys_addr_t physAddr, size_t size, uint32_t flags) } -static void -build_physical_memory_list(size_t memoryMapSize, - efi_memory_descriptor *memoryMap, size_t descriptorSize, - uint32_t descriptorVersion) -{ - addr_t addr = (addr_t)memoryMap; - - gKernelArgs.num_physical_memory_ranges = 0; - - // First scan: Add all usable ranges - for (size_t i = 0; i < memoryMapSize / descriptorSize; ++i) { - efi_memory_descriptor* entry = (efi_memory_descriptor *)(addr + i * descriptorSize); - switch (entry->Type) { - case EfiLoaderCode: - case EfiLoaderData: - case EfiBootServicesCode: - case EfiBootServicesData: - case EfiConventionalMemory: { - // Usable memory. - // Ignore memory below 1MB and above 512GB. - uint64_t base = entry->PhysicalStart; - uint64_t end = entry->PhysicalStart + entry->NumberOfPages * B_PAGE_SIZE; - uint64_t originalSize = end - base; - if (base < 0x100000) - base = 0x100000; - if (end > (512ull * 1024 * 1024 * 1024)) - end = 512ull * 1024 * 1024 * 1024; - - gKernelArgs.ignored_physical_memory - += originalSize - (max_c(end, base) - base); - - if (base >= end) - break; - uint64_t size = end - base; - - insert_physical_memory_range(base, size); - break; - } - default: - break; - } - } - - uint64_t initialPhysicalMemory = total_physical_memory(); - - // Second scan: Remove everything reserved that may overlap - for (size_t i = 0; i < memoryMapSize / descriptorSize; ++i) { - efi_memory_descriptor* entry = (efi_memory_descriptor *)(addr + i * descriptorSize); - switch (entry->Type) { - case EfiLoaderCode: - case EfiLoaderData: - case EfiBootServicesCode: - case EfiBootServicesData: - case EfiConventionalMemory: - break; - default: - uint64_t base = entry->PhysicalStart; - uint64_t size = entry->NumberOfPages * B_PAGE_SIZE; - remove_physical_memory_range(base, size); - } - } - - gKernelArgs.ignored_physical_memory - += initialPhysicalMemory - total_physical_memory(); - - sort_address_ranges(gKernelArgs.physical_memory_range, - gKernelArgs.num_physical_memory_ranges); -} - - -static void -build_physical_allocated_list(size_t memoryMapSize, - efi_memory_descriptor *memoryMap, size_t descriptorSize, - uint32_t descriptorVersion) -{ - addr_t addr = (addr_t)memoryMap; - for (size_t i = 0; i < memoryMapSize / descriptorSize; ++i) { - efi_memory_descriptor* entry = (efi_memory_descriptor *)(addr + i * descriptorSize); - switch (entry->Type) { - case EfiLoaderData: { - uint64_t base = entry->PhysicalStart; - uint64_t size = entry->NumberOfPages * B_PAGE_SIZE; - insert_physical_allocated_range(base, size); - break; - } - default: - ; - } - } - - sort_address_ranges(gKernelArgs.physical_allocated_range, - gKernelArgs.num_physical_allocated_ranges); -} - - void arch_mmu_post_efi_setup(size_t memoryMapSize, efi_memory_descriptor *memoryMap, size_t descriptorSize, @@ -329,7 +239,8 @@ arch_mmu_generate_post_efi_page_tables(size_t memoryMapSize, uint32_t descriptorVersion) { build_physical_memory_list(memoryMapSize, memoryMap, - descriptorSize, descriptorVersion); + descriptorSize, descriptorVersion, + PHYSICAL_MEMORY_LOW, PHYSICAL_MEMORY_HIGH); //TODO: find out how to map EFI runtime services //they are not mapped for now because the kernel doesn't use them anyway diff --git a/src/system/boot/platform/efi/arch/x86/arch_start.cpp b/src/system/boot/platform/efi/arch/x86/arch_start.cpp index ce5e1f6a21..1acae6bd9b 100644 --- a/src/system/boot/platform/efi/arch/x86/arch_start.cpp +++ b/src/system/boot/platform/efi/arch/x86/arch_start.cpp @@ -10,6 +10,7 @@ #include #include "efi_platform.h" +#include "generic_mmu.h" #include "mmu.h" #include "serial.h" #include "smp.h" @@ -50,46 +51,6 @@ arch_convert_kernel_args(void) } -static const char* -memory_region_type_str(int type) -{ - switch (type) { - case EfiReservedMemoryType: - return "ReservedMemoryType"; - case EfiLoaderCode: - return "LoaderCode"; - case EfiLoaderData: - return "LoaderData"; - case EfiBootServicesCode: - return "BootServicesCode"; - case EfiBootServicesData: - return "BootServicesData"; - case EfiRuntimeServicesCode: - return "RuntimeServicesCode"; - case EfiRuntimeServicesData: - return "RuntimeServicesData"; - case EfiConventionalMemory: - return "ConventionalMemory"; - case EfiUnusableMemory: - return "UnusableMemory"; - case EfiACPIReclaimMemory: - return "ACPIReclaimMemory"; - case EfiACPIMemoryNVS: - return "ACPIMemoryNVS"; - case EfiMemoryMappedIO: - return "MMIO"; - case EfiMemoryMappedIOPortSpace: - return "MMIOPortSpace"; - case EfiPalCode: - return "PalCode"; - case EfiPersistentMemory: - return "PersistentMemory"; - default: - return "unknown"; - } -} - - void arch_start_kernel(addr_t kernelEntry) {