pmm: Allow allocations above 4GiB and use them in freadall()
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 0749ff96..cd89f3de 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);
