diff --git a/kernel/include/kernel/vm.h b/kernel/include/kernel/vm.h index b06c28d5f..b9bc6f3a3 100644 --- a/kernel/include/kernel/vm.h +++ b/kernel/include/kernel/vm.h @@ -46,6 +46,7 @@ __BEGIN_CDECLS #define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE) #define IS_PAGE_ALIGNED(x) IS_ALIGNED(x, PAGE_SIZE) +extern struct list_node arena_list; struct mmu_initial_mapping { paddr_t phys; diff --git a/kernel/vm/pmm.c b/kernel/vm/pmm.c index 7a5673695..bfe6e48bf 100644 --- a/kernel/vm/pmm.c +++ b/kernel/vm/pmm.c @@ -21,7 +21,7 @@ #define LOCAL_TRACE 0 -static struct list_node arena_list = LIST_INITIAL_VALUE(arena_list); +struct list_node arena_list = LIST_INITIAL_VALUE(arena_list); static mutex_t lock = MUTEX_INITIAL_VALUE(lock); #define PAGE_BELONGS_TO_ARENA(page, arena) \ diff --git a/lib/uefi/boot_service_provider.cpp b/lib/uefi/boot_service_provider.cpp index 3835849bf..afb258470 100644 --- a/lib/uefi/boot_service_provider.cpp +++ b/lib/uefi/boot_service_provider.cpp @@ -2,6 +2,7 @@ #include "boot_service_provider.h" #include "boot_service.h" #include "kernel/vm.h" +#include "lib/dlmalloc.h" #include "types.h" #include #include @@ -114,6 +115,23 @@ EfiStatus handle_protocol(EfiHandle handle, const EfiGuid *protocol, return UNSUPPORTED; } +constexpr size_t kHeapSize = 8ul * 1024 * 1024; +void *get_heap() { + static auto heap = alloc_page(kHeapSize); + return heap; +} + +mspace create_mspace_with_base_limit(void *base, size_t capacity, int locked) { + auto space = create_mspace_with_base(get_heap(), kHeapSize, 1); + mspace_set_footprint_limit(space, capacity); + return space; +} + +mspace get_mspace() { + static auto space = create_mspace_with_base_limit(get_heap(), kHeapSize, 1); + return space; +} + EfiStatus allocate_pool(EfiMemoryType pool_type, size_t size, void **buf) { if (buf == nullptr) { return INVALID_PARAMETER; @@ -122,7 +140,7 @@ EfiStatus allocate_pool(EfiMemoryType pool_type, size_t size, void **buf) { *buf = nullptr; return SUCCESS; } - *buf = malloc(size); + *buf = mspace_malloc(get_mspace(), size); if (*buf != nullptr) { return SUCCESS; } @@ -130,7 +148,70 @@ EfiStatus allocate_pool(EfiMemoryType pool_type, size_t size, void **buf) { } EfiStatus free_pool(void *mem) { - free(mem); + mspace_free(get_mspace(), mem); + return SUCCESS; +} + +size_t get_aspace_entry_count(vmm_aspace_t *aspace) { + vmm_region_t *region = nullptr; + size_t num_entries = 0; + list_for_every_entry(&aspace->region_list, region, vmm_region_t, node) { + num_entries++; + } + return num_entries; +} + +void fill_memory_map_entry(vmm_aspace_t *aspace, EfiMemoryDescriptor *entry, + const vmm_region_t *region) { + entry->virtual_start = region->base; + entry->physical_start = entry->virtual_start; + entry->number_of_pages = region->size / PAGE_SIZE; + paddr_t pa{}; + uint flags{}; + status_t err = + arch_mmu_query(&aspace->arch_aspace, region->base, &pa, &flags); + if (err >= 0) { + entry->physical_start = pa; + } + if ((flags & ARCH_MMU_FLAG_CACHE_MASK) == ARCH_MMU_FLAG_CACHED) { + entry->attributes |= EFI_MEMORY_WB | EFI_MEMORY_WC | EFI_MEMORY_WT; + } +} + +EfiStatus get_physical_memory_map(size_t *memory_map_size, + EfiMemoryDescriptor *memory_map, + size_t *map_key, size_t *desc_size, + uint32_t *desc_version) { + if (memory_map_size == nullptr) { + return INVALID_PARAMETER; + } + if (map_key) { + *map_key = 0; + } + if (desc_size) { + *desc_size = sizeof(EfiMemoryDescriptor); + } + if (desc_version) { + *desc_version = 1; + } + pmm_arena_t *a{}; + size_t num_entries = 0; + list_for_every_entry(&arena_list, a, pmm_arena_t, node) { num_entries++; } + const size_t size_needed = num_entries * sizeof(EfiMemoryDescriptor); + if (*memory_map_size < size_needed) { + *memory_map_size = size_needed; + return BUFFER_TOO_SMALL; + } + *memory_map_size = size_needed; + size_t i = 0; + memset(memory_map, 0, size_needed); + list_for_every_entry(&arena_list, a, pmm_arena_t, node) { + memory_map[i].physical_start = a->base; + memory_map[i].number_of_pages = a->size / PAGE_SIZE; + memory_map[i].attributes |= EFI_MEMORY_WB; + memory_map[i].memory_type = LOADER_CODE; + i++; + } return SUCCESS; } @@ -283,7 +364,7 @@ void setup_boot_service_table(EfiBootService *service) { service->handle_protocol = handle_protocol; service->allocate_pool = allocate_pool; service->free_pool = free_pool; - service->get_memory_map = get_memory_map; + service->get_memory_map = get_physical_memory_map; service->register_protocol_notify = register_protocol_notify; service->locate_handle = locate_handle; service->locate_protocol = locate_protocol; diff --git a/lib/uefi/boot_service_provider.h b/lib/uefi/boot_service_provider.h index 287bdcf8b..8e25764bb 100644 --- a/lib/uefi/boot_service_provider.h +++ b/lib/uefi/boot_service_provider.h @@ -3,6 +3,7 @@ #include "arch/defines.h" #include "boot_service.h" +#include "kernel/vm.h" #include "system_table.h" void setup_boot_service_table(EfiBootService *service); @@ -74,9 +75,12 @@ struct EFI_LOADED_IMAGE_PROTOCOL { EFI_IMAGE_UNLOAD Unload; }; -static constexpr size_t EFI_LOADED_IMAGE_PROTOCOL_REVISION = 0x1000; +vmm_aspace_t *get_address_space(); void *alloc_page(void *addr, size_t size, size_t align_log2 = PAGE_SIZE_SHIFT); void *alloc_page(size_t size, size_t align_log2 = PAGE_SIZE_SHIFT); +void *identity_map(void *addr, size_t size); + +static constexpr size_t EFI_LOADED_IMAGE_PROTOCOL_REVISION = 0x1000; #endif diff --git a/lib/uefi/include/boot_service.h b/lib/uefi/include/boot_service.h index 5959f0092..ac510edb3 100644 --- a/lib/uefi/include/boot_service.h +++ b/lib/uefi/include/boot_service.h @@ -49,6 +49,12 @@ typedef enum EFI_OPEN_PROTOCOL_ATTRIBUTE : uint32_t { EXCLUSIVE = 0x00000020, } EfiOpenProtocolAttributes; +#define EFI_MEMORY_UC 0x0000000000000001ULL +#define EFI_MEMORY_WC 0x0000000000000002ULL +#define EFI_MEMORY_WT 0x0000000000000004ULL +#define EFI_MEMORY_WB 0x0000000000000008ULL +#define EFI_MEMORY_UCE 0x0000000000000010ULL + typedef struct { uint32_t memory_type; uint32_t padding; diff --git a/lib/uefi/uefi.cpp b/lib/uefi/uefi.cpp index e11a9c311..ca6795cf4 100644 --- a/lib/uefi/uefi.cpp +++ b/lib/uefi/uefi.cpp @@ -1,8 +1,6 @@ -#include "arch/mmu.h" #include "boot_service.h" #include "boot_service_provider.h" #include "defer.h" -#include "kernel/vm.h" #include "pe.h" #include @@ -11,7 +9,6 @@ #include #include #include -#include #include #include #include