From: Amelia Coutard <eliottulio.coutard@gmail.com>
Date: Tue, 5 Dec 2023 14:19:39 +0000 (+0100)
Subject: Made the paging structures templates. No point yet, but soon
X-Git-Url: https://git.ameliathe1st.gay/?a=commitdiff_plain;h=e1a71e1cb6872052c2f6166e9df1d0e3ed4f6a2d;p=voyage-au-centre-des-fichiers.git

Made the paging structures templates. No point yet, but soon
---

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<const multiboot2::info_s
 	static_assert(sizeof(os::processes) <= 1024 * 1024 * 1024, "Error: processes array too big.");
 	{
 		const auto index = os::paging::calc_page_table_indices(&os::processes).pml4e;
-		PML4T.contents[index] = {.P = 1, .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0};
+		PML4T.contents[index] = {.non_page = {.P = 1, .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}};
 		const auto PDPT_alloc = os::paging::page_allocator.allocate(1);
 		os::memset((void*)PDPT_alloc.ptr, 0, 0x1000);
 		set_base_address(PML4T.contents[index], os::phys_ptr<os::paging::PDPT>(PDPT_alloc.ptr.get_phys_addr()));
@@ -185,7 +185,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
 	os::print("RAM END\n");
 
 	// Unmap low RAM, and free corresponding page.
-	PML4T.contents[0].P = false;
+	PML4T.contents[0].non_page.P = false;
 	os::paging::page_allocator.deallocate({.ptr = os::phys_ptr<os::paging::page>(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<os::paging::PDPT>(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<os::paging::page>(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<os::paging::page>, 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<page>, 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 <std::size_t depth> struct paging_entry;
+template <std::size_t depth> struct __attribute__((aligned(0x1000))) paging_table {
+	paging_entry<depth> 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<PDPT> get_base_address(const PML4E& PML4E) {
 	os::assert(!is_page(PML4E), "Tried to get non-page out of a page paging.");
-	return phys_ptr<PDPT>{PML4E.base_address * 0x1000ull};
+	return phys_ptr<PDPT>{PML4E.non_page.base_address * 0x1000ull};
 }
 inline phys_ptr<PDT> 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<page> get_page_base_address(const PDE& PDE) {
 }
 inline phys_ptr<page> 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<page>{PE.base_address * 0x1000ull};
+	return phys_ptr<page>{PE.page.base_address * 0x1000ull};
 }
 
 inline void set_base_address(PML4E& PML4E, phys_ptr<PDPT> 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<PDT> 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<page> ptr) {
 }
 inline void set_page_base_address(PE& PE, phys_ptr<page> 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 {