From e1a71e1cb6872052c2f6166e9df1d0e3ed4f6a2d Mon Sep 17 00:00:00 2001 From: Amelia Coutard Date: Tue, 5 Dec 2023 15:19:39 +0100 Subject: [PATCH] Made the paging structures templates. No point yet, but soon --- Makefile | 2 +- kernel/src/kernel.cpp | 4 +- kernel/src/paging.cpp | 12 ++-- kernel/src/paging.hpp | 142 ++++++++++++++++++++++-------------------- 4 files changed, 82 insertions(+), 78 deletions(-) diff --git a/Makefile b/Makefile index fadfa31..bd44b19 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ endif build: # Build as default target CXXFLAGS ?= -O2 -CXXFLAGS := $(CXXFLAGS) -std=c++20 -fno-strict-aliasing -Wall -Wextra -Werror -Wfatal-errors \ +CXXFLAGS := $(CXXFLAGS) -std=c++20 -fno-strict-aliasing -Wall -Wextra -Werror \ -mgeneral-regs-only -fno-exceptions -fno-rtti -ffreestanding LDFLAGS ?= -O2 LDFLAGS := $(LDFLAGS) -std=c++20 -Wall -Wextra -Werror -ffreestanding diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp index 802f825..82ac43f 100644 --- a/kernel/src/kernel.cpp +++ b/kernel/src/kernel.cpp @@ -86,7 +86,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr(PDPT_alloc.ptr.get_phys_addr())); @@ -185,7 +185,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr(get_base_address(PML4T.contents[0]).get_phys_addr()), .size = 1}); os::invlpg((void*)0x0); diff --git a/kernel/src/paging.cpp b/kernel/src/paging.cpp index f53bc15..8fec68d 100644 --- a/kernel/src/paging.cpp +++ b/kernel/src/paging.cpp @@ -16,8 +16,8 @@ std::byte* os::paging::setup_page(os::paging::PML4T& PML4T, const void* vaddr, bool R_W, bool U_S) { const auto indices = os::paging::calc_page_table_indices(vaddr); - if (PML4T.contents[indices.pml4e].P == 0) { - PML4T.contents[indices.pml4e] = {.P = 1, .R_W = 1, .U_S = U_S, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}; + if (PML4T.contents[indices.pml4e].non_page.P == 0) { + PML4T.contents[indices.pml4e] = {.non_page = {.P = 1, .R_W = 1, .U_S = U_S, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}}; const auto PDPT_alloc = os::paging::page_allocator.allocate(1); memset((void*)PDPT_alloc.ptr, 0, 0x1000); set_base_address(PML4T.contents[indices.pml4e], os::phys_ptr(PDPT_alloc.ptr.get_phys_addr())); @@ -43,9 +43,9 @@ std::byte* os::paging::setup_page(os::paging::PML4T& PML4T, const void* vaddr, b "Cannot map memory address 0x{} because it is inside a 2MiB page", std::uintptr_t(vaddr)); } os::paging::PT& PT = *get_base_address(PDT.contents[indices.pde]); - os::assert(PT.contents[indices.pe].P == 0, "Memory at address 0x{} has already been mapped.", std::uintptr_t(vaddr)); + os::assert(PT.contents[indices.pe].page.P == 0, "Memory at address 0x{} has already been mapped.", std::uintptr_t(vaddr)); PT.contents[indices.pe] = - {.P = 1, .R_W = R_W, .U_S = U_S, .PWT = 0, .PCD = 0, .PAT = 0, .G = (indices.pml4e < 128) ? 0ul : 1ul, .base_address = 0, .NX = 0}; + {.page = {.P = 1, .R_W = R_W, .U_S = U_S, .PWT = 0, .PCD = 0, .PAT = 0, .G = (indices.pml4e < 128) ? 0ul : 1ul, .base_address = 0, .NX = 0}}; const auto page_alloc = os::paging::page_allocator.allocate(1); memset((void*)page_alloc.ptr, 0, 0x1000); set_page_base_address(PT.contents[indices.pe], os::phys_ptr(page_alloc.ptr.get_phys_addr())); @@ -56,7 +56,7 @@ std::byte* os::paging::setup_page(os::paging::PML4T& PML4T, const void* vaddr, b namespace { void on_all_pages(const os::paging::PT& PT, void f(os::paging::page*, os::phys_ptr, std::size_t), std::size_t PT_virt_address) { for (std::size_t i = 0; i < 512; i++) { - if (!PT.contents[i].P) { + if (!PT.contents[i].page.P) { continue; } std::uint64_t virt_address = PT_virt_address | (i * 0x1000ull); @@ -94,7 +94,7 @@ void on_all_pages(const os::paging::PDPT& PDPT, void f(os::paging::page*, os::ph void os::paging::on_all_pages(const os::paging::PML4T& PML4T, void f(page*, phys_ptr, std::size_t)) { for (std::size_t i = 0; i < 512; i++) { - if (!PML4T.contents[i].P) { + if (!PML4T.contents[i].non_page.P) { continue; } std::uint64_t virt_address = (i < 256 ? 0x0000'0000'0000'0000 : 0xFFFF'8000'0000'0000) | (i * 0x1000ull * 512ull * 512ull * 512ull); diff --git a/kernel/src/paging.hpp b/kernel/src/paging.hpp index d218d38..41ac1be 100644 --- a/kernel/src/paging.hpp +++ b/kernel/src/paging.hpp @@ -20,44 +20,49 @@ namespace os { namespace paging { -struct PML4E; -struct PML4T; -union PDPE; -struct PDPT; -union PDE; -struct PDT; -struct PE; -struct PT; -struct page; - -struct PML4E { - std::uint64_t P : 1 = 0; - std::uint64_t R_W : 1; - std::uint64_t U_S : 1; - std::uint64_t PWT : 1; - std::uint64_t PCD : 1; - std::uint64_t A : 1 = 0; - std::uint64_t IGN : 1 = 0; - std::uint64_t MBZ : 2 = 0; - std::uint64_t AVL_low : 3 = 0; - std::uint64_t base_address : 40; - std::uint64_t AVL_high : 11 = 0; - std::uint64_t NX : 1; +template struct paging_entry; +template struct __attribute__((aligned(0x1000))) paging_table { + paging_entry contents[512]; }; -static_assert(sizeof(PML4E) == 8); -struct __attribute__((aligned(0x1000))) PML4T { - PML4E contents[512]; +template <> struct __attribute__((aligned(0x1000))) paging_table<0> { + std::byte contents[4096]; }; -static_assert(sizeof(PML4T) == 0x1000); -static_assert(alignof(PML4T) == 0x1000); +static_assert(sizeof(paging_table<0>) == 0x1000); +static_assert(alignof(paging_table<0>) == 0x1000); + +using PML4T = paging_table<4>; +using PML4E = paging_entry<4>; +using PDPT = paging_table<3>; +using PDPE = paging_entry<3>; +using PDT = paging_table<2>; +using PDE = paging_entry<2>; +using PT = paging_table<1>; +using PE = paging_entry<1>; +using page = paging_table<0>; -struct __attribute__((aligned(0x1000))) page { - char contents[0x1000]; +template<> struct paging_entry<4> { + struct { + std::uint64_t P : 1 = 0; + std::uint64_t R_W : 1; + std::uint64_t U_S : 1; + std::uint64_t PWT : 1; + std::uint64_t PCD : 1; + std::uint64_t A : 1 = 0; + std::uint64_t IGN : 1 = 0; + std::uint64_t MBZ : 2 = 0; + std::uint64_t AVL_low : 3 = 0; + std::uint64_t base_address : 40; + std::uint64_t AVL_high : 11 = 0; + std::uint64_t NX : 1; + } non_page; }; -static_assert(sizeof(page) == 0x1000); -static_assert(alignof(page) == 0x1000); +static_assert(sizeof(paging_table<4>) == 0x1000); +static_assert(alignof(paging_table<4>) == 0x1000); +static_assert(alignof(paging_entry<4>) == 8); +static_assert(sizeof(paging_entry<4>) == 8); -union PDPE { +template<> struct paging_entry<3> { +union { struct { std::uint64_t P : 1 = 0; std::uint64_t R_W : 1; @@ -92,14 +97,14 @@ union PDPE { std::uint64_t NX : 1; } page; }; -static_assert(sizeof(PDPE) == 8); -struct __attribute__((aligned(0x1000))) PDPT { - PDPE contents[512]; }; -static_assert(sizeof(PDPT) == 0x1000); -static_assert(alignof(PDPT) == 0x1000); +static_assert(sizeof(paging_table<3>) == 0x1000); +static_assert(alignof(paging_table<3>) == 0x1000); +static_assert(alignof(paging_entry<3>) == 8); +static_assert(sizeof(paging_entry<3>) == 8); -union PDE { +template <> struct paging_entry<2> { +union { struct { std::uint64_t P : 1 = 0; std::uint64_t R_W : 1; @@ -134,35 +139,34 @@ union PDE { std::uint64_t NX : 1; } page; }; -static_assert(sizeof(PDE) == 8); -struct __attribute__((aligned(0x1000))) PDT { - PDE contents[512]; }; -static_assert(sizeof(PDT) == 0x1000); -static_assert(alignof(PDT) == 0x1000); +static_assert(sizeof(paging_table<2>) == 0x1000); +static_assert(alignof(paging_table<2>) == 0x1000); +static_assert(alignof(paging_entry<2>) == 8); +static_assert(sizeof(paging_entry<2>) == 8); -struct PE { - std::uint64_t P : 1 = 0; - std::uint64_t R_W : 1; - std::uint64_t U_S : 1; - std::uint64_t PWT : 1; - std::uint64_t PCD : 1; - std::uint64_t A : 1 = 0; - std::uint64_t D : 1 = 0; - std::uint64_t PAT : 1; - std::uint64_t G : 1; - std::uint64_t AVL_low : 3 = 0; - std::uint64_t base_address : 40; - std::uint64_t AVL_high : 7 = 0; - std::uint64_t AVL_or_MPK : 4 = 0; - std::uint64_t NX : 1; -}; -static_assert(sizeof(PE) == 8); -struct __attribute__((aligned(0x1000))) PT { - PE contents[512]; +template <> struct paging_entry<1> { + struct { + std::uint64_t P : 1 = 0; + std::uint64_t R_W : 1; + std::uint64_t U_S : 1; + std::uint64_t PWT : 1; + std::uint64_t PCD : 1; + std::uint64_t A : 1 = 0; + std::uint64_t D : 1 = 0; + std::uint64_t PAT : 1; + std::uint64_t G : 1; + std::uint64_t AVL_low : 3 = 0; + std::uint64_t base_address : 40; + std::uint64_t AVL_high : 7 = 0; + std::uint64_t AVL_or_MPK : 4 = 0; + std::uint64_t NX : 1; + } page; }; -static_assert(sizeof(PT) == 0x1000); -static_assert(alignof(PT) == 0x1000); +static_assert(sizeof(paging_table<1>) == 0x1000); +static_assert(alignof(paging_table<1>) == 0x1000); +static_assert(alignof(paging_entry<1>) == 8); +static_assert(sizeof(paging_entry<1>) == 8); inline bool is_page(const PML4E __attribute__((unused))& PML4E) { return false; } @@ -172,7 +176,7 @@ inline bool is_page(const PE __attribute__((unused))& PE) { return true; } inline phys_ptr get_base_address(const PML4E& PML4E) { os::assert(!is_page(PML4E), "Tried to get non-page out of a page paging."); - return phys_ptr{PML4E.base_address * 0x1000ull}; + return phys_ptr{PML4E.non_page.base_address * 0x1000ull}; } inline phys_ptr get_base_address(const PDPE& PDPE) { os::assert(!is_page(PDPE), "Tried to get non-page out of a page paging."); @@ -192,12 +196,12 @@ inline phys_ptr get_page_base_address(const PDE& PDE) { } inline phys_ptr get_page_base_address(const PE& PE) { os::assert(is_page(PE), "Tried to get page out of a non-page paging."); - return phys_ptr{PE.base_address * 0x1000ull}; + return phys_ptr{PE.page.base_address * 0x1000ull}; } inline void set_base_address(PML4E& PML4E, phys_ptr ptr) { os::assert(!is_page(PML4E), "Tried to get non-page out of a page paging."); - PML4E.base_address = ptr.get_phys_addr() / 0x1000ull; + PML4E.non_page.base_address = ptr.get_phys_addr() / 0x1000ull; } inline void set_base_address(PDPE& PDPE, phys_ptr ptr) { os::assert(!is_page(PDPE), "Tried to get non-page out of a page paging."); @@ -217,7 +221,7 @@ inline void set_page_base_address(PDE& PDE, phys_ptr ptr) { } inline void set_page_base_address(PE& PE, phys_ptr ptr) { os::assert(is_page(PE), "Tried to get page out of a non-page paging."); - PE.base_address = ptr.get_phys_addr() / 0x1000ull; + PE.page.base_address = ptr.get_phys_addr() / 0x1000ull; } struct page_table_indices { -- 2.47.0