From 5323bce11768dc914babe7d7d29477db4e92cf93 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Wed, 4 Oct 2023 20:23:22 -0500 Subject: [PATCH] pmm: Allow allocations above 4GiB and use them in freadall() --- common/fs/file.h | 1 + common/fs/file.s2.c | 6 +++++- common/mm/pmm.h | 1 + common/mm/pmm.s2.c | 27 ++++++--------------------- common/protos/limine.c | 2 +- 5 files changed, 14 insertions(+), 23 deletions(-) diff --git a/common/fs/file.h b/common/fs/file.h index 2efd246a..155b47df 100644 --- a/common/fs/file.h +++ b/common/fs/file.h @@ -36,5 +36,6 @@ struct file_handle *fopen(struct volume *part, const char *filename); void fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count); void fclose(struct file_handle *fd); void *freadall(struct file_handle *fd, uint32_t type); +void *freadall_mode(struct file_handle *fd, uint32_t type, bool allow_high_allocs); #endif diff --git a/common/fs/file.s2.c b/common/fs/file.s2.c index aa603e6f..68fb354f 100644 --- a/common/fs/file.s2.c +++ b/common/fs/file.s2.c @@ -96,6 +96,10 @@ void fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count) { } void *freadall(struct file_handle *fd, uint32_t type) { + return freadall_mode(fd, type, false); +} + +void *freadall_mode(struct file_handle *fd, uint32_t type, bool allow_high_allocs) { if (fd->is_memfile) { if (fd->readall) { return fd->fd; @@ -104,7 +108,7 @@ void *freadall(struct file_handle *fd, uint32_t type) { fd->readall = true; return fd->fd; } else { - void *ret = ext_mem_alloc_type(fd->size, type); + void *ret = ext_mem_alloc_type_aligned_mode(fd->size, type, 4096, allow_high_allocs); fd->read(fd, ret, 0, fd->size); fd->close(fd); fd->fd = ret; diff --git a/common/mm/pmm.h b/common/mm/pmm.h index dcbc9763..52e24404 100644 --- a/common/mm/pmm.h +++ b/common/mm/pmm.h @@ -56,6 +56,7 @@ void pmm_randomise_memory(void); void *ext_mem_alloc(size_t count); void *ext_mem_alloc_type(size_t count, uint32_t type); void *ext_mem_alloc_type_aligned(size_t count, uint32_t type, size_t alignment); +void *ext_mem_alloc_type_aligned_mode(size_t count, uint32_t type, size_t alignment, bool allow_high_allocs); void *conv_mem_alloc(size_t count); diff --git a/common/mm/pmm.s2.c b/common/mm/pmm.s2.c index 86841748..0f4ea051 100644 --- a/common/mm/pmm.s2.c +++ b/common/mm/pmm.s2.c @@ -356,25 +356,6 @@ void init_memmap(void) { uint64_t base = entry->PhysicalStart; uint64_t length = entry->NumberOfPages * 4096; - // We only manage memory below 4GiB. For anything above that, make it - // EFI reclaimable. - if (our_type == MEMMAP_USABLE) { - if (base + length > 0x100000000) { - if (base < 0x100000000) { - memmap[memmap_entries].base = base; - memmap[memmap_entries].length = 0x100000000 - base; - memmap[memmap_entries].type = our_type; - - base = 0x100000000; - length -= memmap[memmap_entries].length; - - memmap_entries++; - } - - our_type = MEMMAP_EFI_RECLAIMABLE; - } - } - memmap[memmap_entries].base = base; memmap[memmap_entries].length = length; memmap[memmap_entries].type = our_type; @@ -565,8 +546,12 @@ void *ext_mem_alloc_type(size_t count, uint32_t type) { return ext_mem_alloc_type_aligned(count, type, 4096); } -// Allocate memory top down, hopefully without bumping into kernel or modules void *ext_mem_alloc_type_aligned(size_t count, uint32_t type, size_t alignment) { + return ext_mem_alloc_type_aligned_mode(count, type, alignment, false); +} + +// Allocate memory top down. +void *ext_mem_alloc_type_aligned_mode(size_t count, uint32_t type, size_t alignment, bool allow_high_allocs) { count = ALIGN_UP(count, alignment); if (allocations_disallowed) @@ -580,7 +565,7 @@ void *ext_mem_alloc_type_aligned(size_t count, uint32_t type, size_t alignment) int64_t entry_top = (int64_t)(memmap[i].base + memmap[i].length); // Let's make sure the entry is not > 4GiB - if (entry_top >= 0x100000000) { + if (entry_top >= 0x100000000 && !allow_high_allocs) { entry_top = 0x100000000; if (entry_base >= entry_top) continue; diff --git a/common/protos/limine.c b/common/protos/limine.c index a7798e30..049042fb 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -250,7 +250,7 @@ static struct limine_file get_file(struct file_handle *file, char *cmdline) { ret.path = reported_addr(path); - ret.address = reported_addr(freadall(file, MEMMAP_KERNEL_AND_MODULES)); + ret.address = reported_addr(freadall_mode(file, MEMMAP_KERNEL_AND_MODULES, true)); ret.size = file->size; ret.cmdline = reported_addr(cmdline);