From: Amelia Coutard <eliottulio.coutard@gmail.com>
Date: Mon, 11 Dec 2023 12:49:48 +0000 (+0100)
Subject: Simplified on_all_pages and added logging the global memory map
X-Git-Url: https://git.ameliathe1st.gay/?a=commitdiff_plain;h=edb2147c99463c190774f02f5f152dd1960139ff;p=voyage-au-centre-des-fichiers.git

Simplified on_all_pages and added logging the global memory map
---

diff --git a/kernel/src/kernel.cpp b/kernel/src/kernel.cpp
index 9babbd5..f2624b6 100644
--- a/kernel/src/kernel.cpp
+++ b/kernel/src/kernel.cpp
@@ -39,6 +39,11 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
 	os::paging::global_PML4T = old_PML4T;
 	// /TODO
 	os::paging::load_pml4t(os::phys_ptr<os::paging::PML4T>{std::uintptr_t(&os::paging::global_PML4T) - 0xFFFF'FFFF'8000'0000});
+	os::print("Begin MMAP print.\n");
+	os::paging::on_all_pages(os::paging::global_PML4T, []<std::size_t depth>(os::paging::page<depth>* vaddr, os::phys_ptr<os::paging::page<depth>> paddr) {
+		os::print("{} -> {} ({})\n", vaddr, (void*)paddr.get_phys_addr(), depth);
+	});
+	os::print("End MMAP print.\n");
 
 	if (!os::init_serial_port()) {
 		while (true) {
diff --git a/kernel/src/paging.cpp b/kernel/src/paging.cpp
index 845e69a..f752858 100644
--- a/kernel/src/paging.cpp
+++ b/kernel/src/paging.cpp
@@ -16,57 +16,6 @@
 
 os::paging::PML4T os::paging::global_PML4T;
 
-namespace {
-void on_all_pages(const os::paging::PT& PT, void f(os::paging::page<0>*, os::phys_ptr<os::paging::page<0>>, std::size_t), std::size_t PT_virt_address) {
-	for (std::size_t i = 0; i < 512; i++) {
-		if (!PT.contents[i].page.P) {
-			continue;
-		}
-		std::uint64_t virt_address = PT_virt_address | (i * 0x1000ull);
-		f(reinterpret_cast<os::paging::page<0>*>(virt_address), os::paging::get_page_base_address(PT.contents[i]), 0x1000ull);
-	}
-}
-void on_all_pages(const os::paging::PDT& PDT, void f(os::paging::page<0>*, os::phys_ptr<os::paging::page<0>>, std::size_t), std::size_t PDT_virt_address) {
-	for (std::size_t i = 0; i < 512; i++) {
-		if (!PDT.contents[i].page.P) {
-			continue;
-		}
-		std::uint64_t virt_address = PDT_virt_address | (i * 0x1000ull * 512ull);
-		if (os::paging::is_page(PDT.contents[i])) {
-			f(reinterpret_cast<os::paging::page<0>*>(virt_address),
-				os::phys_ptr<os::paging::page<0>>(os::paging::get_page_base_address(PDT.contents[i]).get_phys_addr()), 0x1000ull * 512ull);
-		} else {
-			on_all_pages(*os::paging::get_base_address(PDT.contents[i]), f, virt_address);
-		}
-	}
-}
-void on_all_pages(const os::paging::PDPT& PDPT, void f(os::paging::page<0>*, os::phys_ptr<os::paging::page<0>>, std::size_t), std::size_t PDPT_virt_address) {
-	for (std::size_t i = 0; i < 512; i++) {
-		if (!PDPT.contents[i].page.P) {
-			continue;
-		}
-		std::uint64_t virt_address = PDPT_virt_address | (i * 0x1000ull * 512ull * 512ull);
-		if (os::paging::is_page(PDPT.contents[i])) {
-			f(reinterpret_cast<os::paging::page<0>*>(virt_address),
-				os::phys_ptr<os::paging::page<0>>(os::paging::get_page_base_address(PDPT.contents[i]).get_phys_addr()), 0x1000ull * 512ull * 512ull);
-		} else {
-			on_all_pages(*os::paging::get_base_address(PDPT.contents[i]), f, virt_address);
-		}
-	}
-}
-
-} // namespace
-
-void os::paging::on_all_pages(const os::paging::PML4T& PML4T, void f(page<0>*, phys_ptr<page<0>>, std::size_t)) {
-	for (std::size_t i = 0; i < 512; i++) {
-		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);
-		::on_all_pages(*os::paging::get_base_address(PML4T.contents[i]), f, virt_address);
-	}
-}
-
 void os::paging::load_pml4t(phys_ptr<PML4T> PML4T) {
 	asm volatile("mov %0, %%cr3" :: "r" (PML4T.get_phys_addr()) : "memory");
 }
diff --git a/kernel/src/paging.hpp b/kernel/src/paging.hpp
index 09ba64e..c30d2c3 100644
--- a/kernel/src/paging.hpp
+++ b/kernel/src/paging.hpp
@@ -176,6 +176,10 @@ 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.");
@@ -196,10 +200,9 @@ template <size_t depth> void set_page_base_address(paging_entry<depth>& entry, p
 }
 
 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>> phys_addr, decltype(paging_entry<depth>::page) page_info);
-
-// For all present page mappings, calls f(virtual address, physical address, page size in bytes (4KiB, 2MiB or 1GiB)).
-void on_all_pages(const PML4T& PML4T, void f(page<0>*, phys_ptr<page<0>>, std::size_t));
+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);
+template <std::size_t depth>
+void on_all_pages(const paging_table<depth>& paging_table, auto f, std::size_t vaddr_offset = 0);
 
 void load_pml4t(phys_ptr<PML4T> PML4T);
 
@@ -232,13 +235,13 @@ private:
 };
 
 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>> phys_addr, 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, decltype(paging_entry<depth>::page) 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], phys_addr);
+		set_page_base_address(paging_table.contents[index], paddr);
 		invlpg(vaddr);
 	} else {
 		if (paging_table.contents[index].non_page.P == 1) {
@@ -250,7 +253,29 @@ void map_page(paging_table<paging_depth>& paging_table, page<depth> const* vaddr
 			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()});
 		}
-		map_page<depth, paging_depth - 1>(*get_base_address(paging_table.contents[index]), vaddr, phys_addr, page_info);
+		map_page<depth, paging_depth - 1>(*get_base_address(paging_table.contents[index]), vaddr, paddr, page_info);
+	}
+}
+
+template <std::size_t depth>
+void on_all_pages(const paging_table<depth>& paging_table, auto f, std::size_t vaddr_offset) {
+	for (std::size_t i = 0; i < 512; i++) {
+		if (!is_present(paging_table.contents[i])) {
+			continue;
+		}
+		std::size_t const new_offset = ([&]() {
+			std::size_t const new_offset = vaddr_offset + (i << (12 + 9 * depth));
+			return new_offset | (new_offset >> 47 ? 0xFFFF'8000'0000'0000 : 0);
+		})();
+		if constexpr (depth == 3) {
+			on_all_pages(*get_base_address(paging_table.contents[i]), f, new_offset);
+		} else if constexpr (depth == 0) {
+			f((page<depth>*)(new_offset), get_page_base_address(paging_table.contents[i]));
+		} else if (is_page(paging_table.contents[i])) {
+			f((page<depth>*)(new_offset), get_page_base_address(paging_table.contents[i]));
+		} else {
+			on_all_pages(*get_base_address(paging_table.contents[i]), f, new_offset);
+		}
 	}
 }