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 <waddlesplash@gmail.com>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
David Karoly 2022-09-25 11:26:12 +02:00 committed by waddlesplash
parent c907db6c62
commit a3c9f71efd
11 changed files with 267 additions and 442 deletions

View File

@ -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 ] ;
}
}

View File

@ -14,8 +14,9 @@
#include <efi/types.h>
#include <efi/boot-services.h>
#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) {

View File

@ -11,6 +11,7 @@
#include <boot/stdio.h>
#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)
{

View File

@ -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 ] ;
}
}

View File

@ -6,8 +6,9 @@
#include <boot/platform.h>
#include <boot/stage2.h>
#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");

View File

@ -9,6 +9,7 @@
#include <boot/stdio.h>
#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)
{

View File

@ -0,0 +1,141 @@
/*
* Copyright 2022 Haiku, Inc. All rights reserved.
* Released under the terms of the MIT License.
*/
#include "generic_mmu.h"
#include <algorithm>
#include <boot/stage2.h>
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";
}
}

View File

@ -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 <SupportDefs.h>
#include <efi/types.h>
#include <efi/boot-services.h>
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 */

View File

@ -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 ] ;
}
}

View File

@ -16,6 +16,7 @@
#include <efi/boot-services.h>
#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

View File

@ -10,6 +10,7 @@
#include <boot/stdio.h>
#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)
{