Skip to content

Commit

Permalink
[app][uefi] Make allocate_pool return identity mapped memory
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangxp1998 committed Oct 24, 2024
1 parent d74411b commit 275d618
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 10 deletions.
1 change: 1 addition & 0 deletions kernel/include/kernel/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion kernel/vm/pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
90 changes: 85 additions & 5 deletions lib/uefi/boot_service_provider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -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;
Expand All @@ -122,15 +140,78 @@ 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;
}
return OUT_OF_RESOURCES;
}

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

Expand Down Expand Up @@ -224,8 +305,7 @@ EfiStatus allocate_pages(EfiAllocatorType type, EfiMemoryType memory_type,
memory_type, pages, *memory);
return UNSUPPORTED;
}
*memory =
reinterpret_cast<EfiPhysicalAddr>(memalign(PAGE_SIZE, pages * PAGE_SIZE));
*memory = reinterpret_cast<EfiPhysicalAddr>(alloc_page(pages * PAGE_SIZE));
if (*memory == 0) {
return OUT_OF_RESOURCES;
}
Expand Down Expand Up @@ -283,7 +363,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;
Expand Down
6 changes: 5 additions & 1 deletion lib/uefi/boot_service_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
6 changes: 6 additions & 0 deletions lib/uefi/include/boot_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 0 additions & 3 deletions lib/uefi/uefi.cpp
Original file line number Diff line number Diff line change
@@ -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 <lib/bio.h>
Expand All @@ -11,7 +9,6 @@
#include <lk/debug.h>
#include <lk/err.h>
#include <lk/trace.h>
#include <math.h>
#include <platform.h>
#include <stdio.h>
#include <string.h>
Expand Down

0 comments on commit 275d618

Please sign in to comment.