From: Amelia Coutard 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{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, [](os::paging::page* vaddr, os::phys_ptr> 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>, 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*>(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>, 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*>(virt_address), - os::phys_ptr>(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>, 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*>(virt_address), - os::phys_ptr>(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>, 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) { 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 phys_ptr> get_base_address(paging_entry entry) { os::assert(!is_page(entry), "Tried to get non-page out of a page paging."); @@ -196,10 +200,9 @@ template void set_page_base_address(paging_entry& entry, p } template -void map_page(paging_table& paging_table, page const* vaddr, phys_ptr> phys_addr, decltype(paging_entry::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>, std::size_t)); +void map_page(paging_table& paging_table, page const* vaddr, phys_ptr> paddr, decltype(paging_entry::page) page_info); +template +void on_all_pages(const paging_table& paging_table, auto f, std::size_t vaddr_offset = 0); void load_pml4t(phys_ptr PML4T); @@ -232,13 +235,13 @@ private: }; template -void map_page(paging_table& paging_table, page const* vaddr, phys_ptr> phys_addr, decltype(paging_entry::page) page_info) { +void map_page(paging_table& paging_table, page const* vaddr, phys_ptr> paddr, decltype(paging_entry::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_table, page 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>{alloc.ptr.get_phys_addr()}); } - map_page(*get_base_address(paging_table.contents[index]), vaddr, phys_addr, page_info); + map_page(*get_base_address(paging_table.contents[index]), vaddr, paddr, page_info); + } +} + +template +void on_all_pages(const paging_table& 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*)(new_offset), get_page_base_address(paging_table.contents[i])); + } else if (is_page(paging_table.contents[i])) { + f((page*)(new_offset), get_page_base_address(paging_table.contents[i])); + } else { + on_all_pages(*get_base_address(paging_table.contents[i]), f, new_offset); + } } }