stivale2: Implement unmap NULL using 4KiB pages
diff --git a/stage23/mm/vmm.c b/stage23/mm/vmm.c
index 46c59eb6..ef681d50 100644
--- a/stage23/mm/vmm.c
+++ b/stage23/mm/vmm.c
@@ -31,14 +31,15 @@ pagemap_t new_pagemap(int lv) {
return pagemap;
}
-void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags) {
+void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, bool hugepages) {
// Calculate the indices in the various tables using the virtual address
size_t pml5_entry = (virt_addr & ((uint64_t)0x1ff << 48)) >> 48;
size_t pml4_entry = (virt_addr & ((uint64_t)0x1ff << 39)) >> 39;
size_t pml3_entry = (virt_addr & ((uint64_t)0x1ff << 30)) >> 30;
size_t pml2_entry = (virt_addr & ((uint64_t)0x1ff << 21)) >> 21;
+ size_t pml1_entry = (virt_addr & ((uint64_t)0x1ff << 12)) >> 12;
- pt_entry_t *pml5, *pml4, *pml3, *pml2;
+ pt_entry_t *pml5, *pml4, *pml3, *pml2, *pml1;
// Paging levels
switch (pagemap.levels) {
@@ -58,8 +59,12 @@ level4:
pml3 = get_next_level(pml4, pml4_entry);
pml2 = get_next_level(pml3, pml3_entry);
- // Set the entry as present and point it to the passed physical address
- // Also set the specified flags
- // We only use 2MiB pages else we would not have enough space
- pml2[pml2_entry] = (pt_entry_t)(phys_addr | flags | (1 << 7));
+ if (hugepages) {
+ pml2[pml2_entry] = (pt_entry_t)(phys_addr | flags | (1 << 7));
+ return;
+ }
+
+ pml1 = get_next_level(pml2, pml2_entry);
+
+ pml1[pml1_entry] = (pt_entry_t)(phys_addr | flags | (1 << 7));
}
diff --git a/stage23/mm/vmm.h b/stage23/mm/vmm.h
index fe265903..9aa096c5 100644
--- a/stage23/mm/vmm.h
+++ b/stage23/mm/vmm.h
@@ -2,8 +2,7 @@
#define __MM__VMM_H__
#include <stdint.h>
-
-#define PAGE_SIZE ((uint64_t)0x200000)
+#include <stdbool.h>
typedef struct {
int levels;
@@ -11,6 +10,6 @@ typedef struct {
} pagemap_t;
pagemap_t new_pagemap(int lv);
-void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags);
+void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, bool hugepages);
#endif
diff --git a/stage23/protos/stivale.c b/stage23/protos/stivale.c
index 5f910ea6..a9d055a2 100644
--- a/stage23/protos/stivale.c
+++ b/stage23/protos/stivale.c
@@ -218,15 +218,21 @@ pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null) {
uint64_t higher_half_base = level5pg ? 0xff00000000000000 : 0xffff800000000000;
// Map 0 to 2GiB at 0xffffffff80000000
- for (uint64_t i = 0; i < 0x80000000; i += PAGE_SIZE) {
- map_page(pagemap, 0xffffffff80000000 + i, i, 0x03);
+ for (uint64_t i = 0; i < 0x80000000; i += 0x200000) {
+ map_page(pagemap, 0xffffffff80000000 + i, i, 0x03, true);
}
- // Map 0 to 4GiB at higher half base and 0
- for (uint64_t i = 0; i < 0x100000000; i += PAGE_SIZE) {
+ // Sub 2MiB mappings
+ for (uint64_t i = 0; i < 0x200000; i += 0x1000) {
if (!(i == 0 && unmap_null))
- map_page(pagemap, i, i, 0x03);
- map_page(pagemap, higher_half_base + i, i, 0x03);
+ map_page(pagemap, i, i, 0x03, false);
+ map_page(pagemap, higher_half_base + i, i, 0x03, false);
+ }
+
+ // Map 2MiB to 4GiB at higher half base and 0
+ for (uint64_t i = 0x200000; i < 0x100000000; i += 0x200000) {
+ map_page(pagemap, i, i, 0x03, true);
+ map_page(pagemap, higher_half_base + i, i, 0x03, true);
}
size_t _memmap_entries = memmap_entries;
@@ -247,14 +253,14 @@ pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null) {
if (base >= top)
continue;
- uint64_t aligned_base = ALIGN_DOWN(base, PAGE_SIZE);
- uint64_t aligned_top = ALIGN_UP(top, PAGE_SIZE);
+ uint64_t aligned_base = ALIGN_DOWN(base, 0x200000);
+ uint64_t aligned_top = ALIGN_UP(top, 0x200000);
uint64_t aligned_length = aligned_top - aligned_base;
- for (uint64_t i = 0; i < aligned_length; i += PAGE_SIZE) {
+ for (uint64_t i = 0; i < aligned_length; i += 0x200000) {
uint64_t page = aligned_base + i;
- map_page(pagemap, page, page, 0x03);
- map_page(pagemap, higher_half_base + page, page, 0x03);
+ map_page(pagemap, page, page, 0x03, true);
+ map_page(pagemap, higher_half_base + page, page, 0x03, true);
}
}
diff --git a/test/stivale2.c b/test/stivale2.c
index b51c0a35..e196eecd 100644
--- a/test/stivale2.c
+++ b/test/stivale2.c
@@ -23,15 +23,15 @@ struct stivale2_header_tag_smp smp_request = {
.flags = 0
};
-struct stivale2_tag fb_mtrr_request = {
- .identifier = STIVALE2_HEADER_TAG_FB_MTRR_ID,
+struct stivale2_tag unmap_null_request = {
+ .identifier = STIVALE2_HEADER_TAG_UNMAP_NULL_ID,
.next = (uint64_t)&smp_request
};
struct stivale2_header_tag_framebuffer framebuffer_request = {
.tag = {
.identifier = STIVALE2_HEADER_TAG_FRAMEBUFFER_ID,
- .next = (uint64_t)&fb_mtrr_request
+ .next = (uint64_t)&unmap_null_request
},
.framebuffer_width = 0,
.framebuffer_height = 0,
