From 4af12fe51782c73017b25c8f80d2ca2b6aed2a9a Mon Sep 17 00:00:00 2001 From: Andy-Python-Programmer Date: Thu, 27 Jan 2022 15:01:59 +1100 Subject: [PATCH] paging: emulate support for 1gib pages if not avaliable Signed-off-by: Andy-Python-Programmer --- stage23/mm/vmm.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/stage23/mm/vmm.c b/stage23/mm/vmm.c index d16233c8..2f99193a 100644 --- a/stage23/mm/vmm.c +++ b/stage23/mm/vmm.c @@ -39,6 +39,24 @@ pagemap_t new_pagemap(int lv) { return pagemap; } +static bool is_1gib_page_supported() { + // Cache the cpuid result :^) + static bool CACHE_INIT = false; + static bool CACHE = false; + + if (!CACHE_INIT) { + // Check if 1GiB pages are supported: + uint32_t eax, ebx, ecx, edx; + + CACHE = cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx) && ((edx & 1 << 26) == 1 << 26); + CACHE_INIT = true; + + print("paging: 1GiB pages are %s!\n", CACHE ? "supported" : "not supported"); + } + + return CACHE; +} + void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size pg_size) { // Calculate the indices in the various tables using the virtual address size_t pml5_entry = (virt_addr & ((uint64_t)0x1ff << 48)) >> 48; @@ -67,8 +85,17 @@ level4: pml3 = get_next_level(pml4, pml4_entry); if (pg_size == Size1GiB) { - pml3[pml3_entry] = (pt_entry_t)(phys_addr | flags | (1 << 7)); - return; + // Check if 1GiB pages are avaliable. + if (is_1gib_page_supported()) { + pml3[pml3_entry] = (pt_entry_t)(phys_addr | flags | (1 << 7)); + return; + } else { + // If 1GiB pages are not supported then emulate it by splitting them into + // 2MiB pages. + for (uint64_t i = 0; i < 0x40000000; i += 0x200000) { + map_page(pagemap, virt_addr + i, phys_addr + i, flags, Size2MiB); + } + } } pml2 = get_next_level(pml3, pml3_entry);