]> git.ameliathe1st.gay Git - voyage-au-centre-des-fichiers.git/commitdiff
Simplification des structures qui gèrent la mémoire virtuelle
authorAmelia Coutard <eliottulio.coutard@gmail.com>
Sat, 16 Dec 2023 00:35:31 +0000 (01:35 +0100)
committerAmelia Coutard <eliottulio.coutard@gmail.com>
Sat, 16 Dec 2023 00:35:31 +0000 (01:35 +0100)
kernel/src/elf64.cpp
kernel/src/interrupts.cpp
kernel/src/kernel.cpp
kernel/src/paging.hpp

index e4de1cdfe331f47be3a199e44a9714aeb2436a49..1223fcca72ea5eced584351f2579a23c36fea467 100644 (file)
@@ -33,7 +33,9 @@ void os::elf::load_elf(os::process& result, std::byte* start, std::size_t length
        constexpr std::size_t stack_size = 16 * 0x1000 /* 64KiB */;
        std::byte* const stack = (std::byte*)0x0000'8000'0000'0000 - stack_size;
 
-       result.PML4T = phys_ptr<paging::PML4T>(os::paging::page_allocator.allocate(1).ptr.get_phys_addr());
+       const auto page = os::paging::page_allocator.allocate(1);
+       os::assert(page.ptr != nullptr, "Not enough memory for elf file loading.");
+       result.PML4T = phys_ptr<paging::PML4T>(page.ptr.get_phys_addr());
        result.rip = std::uint64_t(elf_header.entry);
        result.rsp = std::uint64_t(stack + stack_size);
        result.rax = 0;
@@ -75,8 +77,11 @@ void os::elf::load_elf(os::process& result, std::byte* start, std::size_t length
                for (std::size_t i = 0; i < nb_pages; i++) {
                        auto const alloc = os::paging::page_allocator.allocate(1);
                        os::assert(alloc.ptr != nullptr, "Failed to allocate enough memory for loading of elf binary.");
-                       os::paging::map_page(*result.PML4T, (os::paging::page<0>*)(program_header.p_vaddr + i * 0x1000), alloc.ptr,
-                               {.R_W = (program_header.flags & 2) >> 1, .U_S = 1, .PWT = 0, .PCD = 0, .PAT = 0, .G = 0, .base_address = 0, .NX = 1 - (program_header.flags & 1)});
+                       os::paging::map_page(*result.PML4T, (os::paging::page<0>*)(program_header.p_vaddr + i * 0x1000), alloc.ptr, {
+                               .RW = ((program_header.flags & 2) >> 1) != 0,
+                               .US = true, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = false, .AVL = 0,
+                               .NX = (program_header.flags & 1) == 0,
+                       });
                        memcpy((void*)alloc.ptr, start + program_header.p_offset, clamp(0ul, program_header.p_filesz - i * 0x1000, 0x1000ul));
                }
        }
index 028a672a39c114db2a4053b3a41fd3eca38d2c5a..a2b6defb5c5cfaf5853fc4c67c20faf0693bdafc 100644 (file)
@@ -114,7 +114,7 @@ extern "C" void int_page_fault(std::uint32_t err_code, std::uint64_t vaddr) {
                auto const alloc = os::paging::page_allocator.allocate(1);
                os::assert(alloc.ptr != nullptr, "Out of memory.");
                os::paging::map_page(os::paging::global_PML4T, (os::paging::page<0>*)vaddr, alloc.ptr,
-                       {.R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .PAT = 0, .G = 1, .base_address = 0, .NX = 1});
+                       {.RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = true});
                return;
        } else if (
                (0x0000'7FFF'FFFF'0000 <= vaddr && vaddr < 0x0000'8000'0000'0000) // stack
@@ -123,7 +123,7 @@ extern "C" void int_page_fault(std::uint32_t err_code, std::uint64_t vaddr) {
                auto const alloc = os::paging::page_allocator.allocate(1);
                os::assert(alloc.ptr != nullptr, "Out of memory.");
                os::paging::map_page(*os::get_process(os::current_pid).PML4T, (os::paging::page<0>*)vaddr, alloc.ptr,
-                       {.R_W = 1, .U_S = 1, .PWT = 0, .PCD = 0, .PAT = 0, .G = 0, .base_address = 0, .NX = 1});
+                       {.RW = true, .US = true, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = false, .AVL = 0, .NX = true});
                return;
        }
        os::print("Interrupt: Page Fault.\n");
index cc4d0c1593a20d1e2733e4be5f86051f60ec9c4c..f1c1459507882e7db55e322f1231f8a87d4bc5f6 100644 (file)
@@ -50,30 +50,30 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
        for (std::size_t i = std::size_t(&_kernel_phys_start); i < std::size_t(&_kernel_phys_rw_start); ) {
                if (i % (1024 * 1024 * 1024) == 0 && i + 1024 * 1024 * 1024 < std::size_t(&_kernel_phys_rw_start)) {
                        os::paging::map_page<2, 3>(os::paging::global_PML4T, (os::paging::page<2>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<2>>(i),
-                               { .R_W = 0, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .NX = 0 });
+                               { .RW = false, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = false });
                        i += 1024 * 1024 * 1024;
                } else if (i % (1024 * 1024 * 2) == 0 && i + 1024 * 1024 * 2 < std::size_t(&_kernel_phys_rw_start)) {
                        os::paging::map_page<1, 3>(os::paging::global_PML4T, (os::paging::page<1>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<1>>(i),
-                               { .R_W = 0, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .NX = 0 });
+                               { .RW = false, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = false });
                        i += 1024 * 1024 * 2;
                } else {
                        os::paging::map_page<0, 3>(os::paging::global_PML4T, (os::paging::page<0>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<0>>(i),
-                               { .R_W = 0, .U_S = 0, .PWT = 0, .PCD = 0, .PAT = 0, .G = 1, .base_address = 0, .NX = 0 });
+                               { .RW = false, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = false });
                        i += 1024 * 4;
                }
        }
        for (std::size_t i = std::size_t(&_kernel_phys_rw_start); i < std::size_t(&_kernel_phys_end); ) {
                if (i % (1024 * 1024 * 1024) == 0 && i + 1024 * 1024 * 1024 < std::size_t(&_kernel_phys_rw_start)) {
                        os::paging::map_page<2, 3>(os::paging::global_PML4T, (os::paging::page<2>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<2>>(i),
-                               { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .NX = 1 });
+                               { .RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = true });
                        i += 1024 * 1024 * 1024;
                } else if (i % (1024 * 1024 * 2) == 0 && i + 1024 * 1024 * 2 < std::size_t(&_kernel_phys_rw_start)) {
                        os::paging::map_page<1, 3>(os::paging::global_PML4T, (os::paging::page<1>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<1>>(i),
-                               { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .NX = 1 });
+                               { .RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = true });
                        i += 1024 * 1024 * 2;
                } else {
                        os::paging::map_page<0, 3>(os::paging::global_PML4T, (os::paging::page<0>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<0>>(i),
-                               { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .PAT = 0, .G = 1, .base_address = 0, .NX = 1 });
+                               { .RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = true });
                        i += 1024 * 4;
                }
        }
@@ -100,19 +100,22 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
                                                        os::paging::global_PML4T,
                                                        (os::paging::page<2>*)(0xFFFF'8000'0000'0000 + j),
                                                        os::phys_ptr<os::paging::page<2>>(j),
-                                                       { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .NX = 1 });
+                                                       { .RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .D = false,
+                                                         .PAT = false, .G = true, .AVL = 0, .NX = true });
                                                j += 1024 * 1024 * 1024;
                                        } else if (j % (1024 * 1024 * 2) == 0 && j + 1024 * 1024 * 2 < e) {
                                                os::paging::map_page<1, 3>(os::paging::global_PML4T,
                                                        (os::paging::page<1>*)(0xFFFF'8000'0000'0000 + j),
                                                        os::phys_ptr<os::paging::page<1>>(j),
-                                                       { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .NX = 1 });
+                                                       { .RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .D = false,
+                                                         .PAT = false, .G = true, .AVL = 0, .NX = true });
                                                j += 1024 * 1024 * 2;
                                        } else {
                                                os::paging::map_page<0, 3>(os::paging::global_PML4T,
                                                        (os::paging::page<0>*)(0xFFFF'8000'0000'0000 + j),
                                                        os::phys_ptr<os::paging::page<0>>(j),
-                                                       { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .PAT = 0, .G = 1, .base_address = 0, .NX = 1 });
+                                                       { .RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .D = false,
+                                                         .PAT = false, .G = true, .AVL = 0, .NX = true });
                                                j += 1024 * 4;
                                        }
                                }
@@ -166,7 +169,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
                os::paging::map_page<0, 3>(os::paging::global_PML4T,
                        (os::paging::page<0>*)(0xFFFF'8000'fee0'0000),
                        os::phys_ptr<os::paging::page<0>>(0x0000'0000'fee0'0000),
-                       { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 1, .PAT = 0, .G = 1, .base_address = 0, .NX = 1 });
+                       { .RW = true, .US = false, .PWT = false, .PCD = true, .A = false, .D = false, .PAT = false, .G = true, .AVL = 0, .NX = true });
                os::enable_interrupts(isr_info, idt);
        }
 
@@ -175,10 +178,10 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
        static_assert(sizeof(os::processes) <= 1024 * 1024 * 1024, "Error: processes array too big.");
        {
                std::size_t const index = (std::uint64_t(&os::processes) >> (12 + 9 * 3)) & 0x1FF;
-               os::paging::global_PML4T.contents[index] = {.non_page = {.P = 1, .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}};
+               os::paging::global_PML4T.contents[index].paging_table_info({.RW = true, .US = false, .PWT = false, .PCD = false, .A = false, .AVL = 0, .NX = false});
                const auto PDPT_alloc = os::paging::page_allocator.allocate(1);
                os::memset((void*)PDPT_alloc.ptr, 0, 0x1000);
-               set_base_address(os::paging::global_PML4T.contents[index], os::phys_ptr<os::paging::PDPT>(PDPT_alloc.ptr.get_phys_addr()));
+               os::paging::global_PML4T.contents[index].paging_table_ptr(os::phys_ptr<os::paging::PDPT>(PDPT_alloc.ptr.get_phys_addr()));
        }
 
        {
index a5d42374fa3dec221eebdf80fcb4aa1b9aa096d0..e085523556bd66676b8b9d52fa667048f2af77ce 100644 (file)
 namespace os { namespace paging {
 
 template <std::size_t depth> struct paging_entry;
+template <std::size_t depth> struct paging_table;
+template <std::size_t depth> struct page;
+
+struct page_info {
+       bool RW;
+       bool US;
+       bool PWT;
+       bool PCD;
+       bool A;
+       bool D;
+       bool PAT;
+       bool G;
+       std::uint16_t AVL; // Only 14 bits, actually.
+       bool NX;
+};
+struct paging_table_info {
+       bool RW;
+       bool US;
+       bool PWT;
+       bool PCD;
+       bool A;
+       std::uint16_t AVL; // Really 16 bits !
+       bool NX;
+};
+
+template <std::size_t depth> struct paging_entry {
+       std::uint64_t data = 0;
+
+       bool is_present() {
+               return (data & (1 << 0)) != 0;
+       }
+       bool is_page() {
+               os::assert(is_present(), "Cannot check if a paging_entry is a page if it's not present.");
+               return depth == 0 || (data & (1 << 7)) != 0;
+       }
+
+       paging::page_info page_info() {
+               os::assert(is_page(), "Cannot access page info for a non-page.");
+               return {
+                       .RW = (data & (1ull << 1)) != 0,
+                       .US = (data & (1ull << 2)) != 0,
+                       .PWT = (data & (1ull << 3)) != 0,
+                       .PCD = (data & (1ull << 4)) != 0,
+                       .A = (data & (1ull << 5)) != 0,
+                       .D = (data & (1ull << 6)) != 0,
+                       .PAT = depth == 0
+                               ? (data & (1ull << 7)) != 0
+                               : (data & (1ull << 12)) != 0,
+                       .G = (data & (1ull << 8)) != 0,
+                       .AVL = ((data >> 9) & 0x7)
+                               | (((data >> 52) & 0x7FF) << 3),
+                       .NX = (data & (1ull << 63)) != 0,
+               };
+       }
+       os::phys_ptr<os::paging::page<depth>> page_ptr() {
+               os::assert(is_page(), "Cannot access page physical pointer for a non-page.");
+               std::uintptr_t addr = data & (depth == 0 ? 0x0000'FFFF'FFFF'F000 : 0x0000'FFFF'FFFF'E000);
+               return os::phys_ptr<os::paging::page<depth>>(addr | ((addr & 0x0000'8000'0000'0000) != 0 ? 0xFFFF'8000'0000'0000 : 0));
+       }
+       void page_ptr(os::phys_ptr<os::paging::page<depth>> page) {
+               os::assert(is_page(), "Cannot access page physical pointer for a non-page.");
+               if (depth == 0) {
+                       data = (data & ~0x0000'FFFF'FFFF'F000) | page.get_phys_addr();
+               } else {
+                       data = (data & ~0x0000'FFFF'FFFF'E000) | page.get_phys_addr();
+               }
+       }
+       paging::paging_table_info paging_table_info() {
+               os::assert(!is_page(), "Cannot access paging table info for a page.");
+               return {
+                       .RW = (data & (1ull << 1)) != 0,
+                       .US = (data & (1ull << 2)) != 0,
+                       .PWT = (data & (1ull << 3)) != 0,
+                       .PCD = (data & (1ull << 4)) != 0,
+                       .A = (data & (1ull << 5)) != 0,
+                       .AVL = ((data >> 6) & 0x1)
+                               | (((data >> 8) & 0xF) << 1)
+                               | (((data >> 52) & 0x7FF) << 5),
+                       .NX = (data & (1ull << 63)) != 0,
+               };
+       }
+       os::phys_ptr<os::paging::paging_table<depth - 1>> paging_table_ptr() {
+               os::assert(!is_page(), "Cannot access paging table physical pointer for a page.");
+               std::uintptr_t addr = data & 0x0000'FFFF'FFFF'F000;
+               return os::phys_ptr<os::paging::paging_table<depth - 1>>(addr | ((addr & 0x0000'8000'0000'0000) != 0 ? 0xFFFF'8000'0000'0000 : 0));
+       }
+       void paging_table_ptr(os::phys_ptr<os::paging::paging_table<depth - 1>> table) {
+               os::assert(!is_page(), "Cannot access paging table physical pointer for a page.");
+               data = (data & ~0x0000'FFFF'FFFF'F000) | table.get_phys_addr();
+       }
+       void remove() {
+               data = 0;
+       }
+       void page_info(os::paging::page_info info) {
+               data = (1ull << 0) // P
+                    | (depth != 0 ? (1 << 7) : 0) // Because it is a large page.
+                    | (info.RW ? (1ull << 1) : 0)
+                    | (info.US ? (1ull << 2) : 0)
+                    | (info.PWT ? (1ull << 3) : 0)
+                    | (info.PCD ? (1ull << 4) : 0)
+                    | (info.A ? (1ull << 5) : 0)
+                    | (info.D ? (1ull << 6) : 0)
+                    | (info.PAT ? (depth == 0 ? 1 << 7: 1 << 12) : 0)
+                    | (info.G ? (1ull << 8) : 0)
+                    | (std::uint64_t(info.AVL & 0x7) << 9)
+                    | (std::uint64_t(info.AVL & 0x3FF8) << 49)
+                    | (info.NX ? (1ull << 63) : 0);
+       }
+       void paging_table_info(os::paging::paging_table_info info) {
+               data = (1ull << 0) // P
+                    | (info.RW ? (1ull << 1) : 0)
+                    | (info.US ? (1ull << 2) : 0)
+                    | (info.PWT ? (1ull << 3) : 0)
+                    | (info.PCD ? (1ull << 4) : 0)
+                    | (info.A ? (1ull << 5) : 0)
+                    | (std::uint64_t(info.AVL & 0x1) << 6)
+                    | (std::uint64_t(info.AVL & 0x1E) << 7)
+                    | (std::uint64_t(info.AVL & 0xFFE0) << 47)
+                    | (info.NX ? (1ull << 63) : 0);
+       }
+};
 template <std::size_t depth> struct __attribute__((aligned(0x1000))) paging_table {
        paging_entry<depth> contents[512];
 };
-
-using PML4T = paging_table<3>;
-using PML4E = paging_entry<3>;
-using PDPT = paging_table<2>;
-using PDPE = paging_entry<2>;
-using PDT = paging_table<1>;
-using PDE = paging_entry<1>;
-using PT = paging_table<0>;
-using PE = paging_entry<0>;
 // Alignment should be the same as size, but that's literally too big for the compiler.
 template <std::size_t depth> struct __attribute__((aligned(0x1000))) page {
        std::byte contents[0x1000ull << (9 * depth)];
 };
+
 static_assert(sizeof(page<0>) == 0x1000);
 static_assert(sizeof(page<1>) == 0x1000 * 512);
 static_assert(sizeof(page<2>) == 0x1000ull * 512 * 512);
-
-extern PML4T global_PML4T;
-
-template<> struct paging_entry<3> {
-       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(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);
-
-template<> struct paging_entry<2> {
-union {
-       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_0 : 1 = 0;
-               std::uint64_t zero : 1 = 0;
-               std::uint64_t IGN_1 : 1 = 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;
-       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 one : 1 = 1;
-               std::uint64_t G : 1;
-               std::uint64_t AVL_low : 3 = 0;
-               std::uint64_t PAT : 1;
-               std::uint64_t reserved : 17 = 0;
-               std::uint64_t base_address : 22;
-               std::uint64_t AVL_high : 7 = 0;
-               std::uint64_t AVL_or_MPK : 4 = 0;
-               std::uint64_t NX : 1;
-       } page;
-};
-};
 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);
-
-template <> struct paging_entry<1> {
-union {
-       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_0 : 1 = 0;
-               std::uint64_t zero : 1 = 0;
-               std::uint64_t IGN_1 : 1 = 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;
-       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 one : 1 = 1;
-               std::uint64_t G : 1;
-               std::uint64_t AVL_low : 3 = 0;
-               std::uint64_t PAT : 1;
-               std::uint64_t reserved : 8 = 0;
-               std::uint64_t base_address : 31;
-               std::uint64_t AVL_high : 7 = 0;
-               std::uint64_t AVL_or_MPK : 4 = 0;
-               std::uint64_t NX : 1;
-       } page;
-};
-};
 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);
-
-template <> struct paging_entry<0> {
-       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(paging_table<0>) == 0x1000);
 static_assert(alignof(paging_table<0>) == 0x1000);
 static_assert(alignof(paging_entry<0>) == 8);
 static_assert(sizeof(paging_entry<0>) == 8);
 
+using PML4T = paging_table<3>;
+using PML4E = paging_entry<3>;
+using PDPT = paging_table<2>;
+using PDPE = paging_entry<2>;
+using PDT = paging_table<1>;
+using PDE = paging_entry<1>;
+using PT = paging_table<0>;
+using PE = paging_entry<0>;
 
-inline bool is_page(PML4E) { return false; }
-inline bool is_page(PDPE PDPE) { return PDPE.page.one == 1; }
-inline bool is_page(PDE PDE) { return PDE.page.one == 1; }
-inline bool is_page(PE) { return true; }
-inline bool is_present(PML4E PML4E) { return PML4E.non_page.P == 1; }
-inline bool is_present(PDPE PDPE) { return PDPE.page.P == 1; }
-inline bool is_present(PDE PDE) { return PDE.page.P == 1; }
-inline bool is_present(PE PE) { return PE.page.P == 1; }
-
-template <size_t depth> phys_ptr<paging_table<depth - 1>> get_base_address(paging_entry<depth> entry) {
-       os::assert(!is_page(entry), "Tried to get non-page out of a page paging.");
-       return phys_ptr<paging_table<depth - 1>>{entry.non_page.base_address * 0x1000ull};
-}
-template <size_t depth> phys_ptr<page<depth>> get_page_base_address(paging_entry<depth> entry) {
-       os::assert(is_page(entry), "Tried to get page out of a non-page paging.");
-       return phys_ptr<page<depth>>{entry.page.base_address * sizeof(page<depth>)};
-}
-
-template <size_t depth> void set_base_address(paging_entry<depth>& entry, phys_ptr<paging_table<depth - 1>> ptr) {
-       os::assert(!is_page(entry), "Tried to get non-page out of a page paging.");
-       entry.non_page.base_address = ptr.get_phys_addr() / 0x1000ull;
-}
-template <size_t depth> void set_page_base_address(paging_entry<depth>& entry, phys_ptr<page<depth>> ptr) {
-       os::assert(is_page(entry), "Tried to get page out of a non-page paging.");
-       entry.page.base_address = ptr.get_phys_addr() / sizeof(page<depth>);
-}
+extern PML4T global_PML4T;
 
 template <std::size_t depth, std::size_t paging_depth = 3>
-void map_page(paging_table<paging_depth>& paging_table, page<depth> const* vaddr, phys_ptr<page<depth>> paddr, decltype(paging_entry<depth>::page) page_info);
+void map_page(paging_table<paging_depth>& paging_table, page<depth> const* vaddr, phys_ptr<page<depth>> paddr, os::paging::page_info page_info);
 template <std::size_t depth>
 void on_all_pages(const paging_table<depth>& paging_table, auto f, std::size_t vaddr_offset = 0);
 
@@ -235,25 +217,25 @@ private:
 };
 
 template <std::size_t depth, std::size_t paging_depth>
-void map_page(paging_table<paging_depth>& paging_table, page<depth> const* vaddr, phys_ptr<page<depth>> paddr, decltype(paging_entry<depth>::page) page_info) {
+void map_page(paging_table<paging_depth>& paging_table, page<depth> const* vaddr, phys_ptr<page<depth>> paddr, os::paging::page_info page_info) {
        std::size_t const index = (std::uint64_t(vaddr) >> (12 + 9 * paging_depth)) & 0x1FF;
        if constexpr (depth == paging_depth) {
-               os::assert(paging_table.contents[index].page.P == 0, "Virtual address 0x{} is already mapped.", vaddr);
-               paging_table.contents[index].page = page_info;
-               paging_table.contents[index].page.P = 1;
-               set_page_base_address(paging_table.contents[index], paddr);
+               os::assert(!paging_table.contents[index].is_present(), "Virtual address 0x{} is already mapped.", vaddr);
+               paging_table.contents[index].page_info(page_info);
+               paging_table.contents[index].page_ptr(paddr);
                invlpg(vaddr);
        } else {
-               if (paging_table.contents[index].non_page.P == 1) {
-                       assert(!is_page(paging_table.contents[index]), "Virtual address 0x{} is already in a mapped page.", vaddr);
+               if (paging_table.contents[index].is_present()) {
+                       assert(!paging_table.contents[index].is_page(), "Virtual address 0x{} is already in a mapped page.", vaddr);
                } else {
                        auto const alloc = page_allocator.allocate(1);
                        assert(alloc.ptr != nullptr, "Not enough RAM to create the paging structures.");
                        memset((void*)alloc.ptr, 0, 0x1000);
-                       paging_table.contents[index].non_page = {.P = 1, .R_W = 1, .U_S = page_info.U_S, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0};
-                       set_base_address(paging_table.contents[index], os::phys_ptr<os::paging::paging_table<paging_depth - 1>>{alloc.ptr.get_phys_addr()});
+                       paging_table.contents[index].paging_table_info(
+                               {.RW = true, .US = page_info.US, .PWT = false, .PCD = false, .A = false, .AVL = 0, .NX = false});
+                       paging_table.contents[index].paging_table_ptr(os::phys_ptr<os::paging::paging_table<paging_depth - 1>>{alloc.ptr.get_phys_addr()});
                }
-               map_page<depth, paging_depth - 1>(*get_base_address(paging_table.contents[index]), vaddr, paddr, page_info);
+               map_page<depth, paging_depth - 1>(*paging_table.contents[index].paging_table_ptr(), vaddr, paddr, page_info);
        }
 }