aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/src/kapi/memory.cpp74
-rw-r--r--kapi/include/kapi/memory/address.hpp11
2 files changed, 82 insertions, 3 deletions
diff --git a/arch/x86_64/src/kapi/memory.cpp b/arch/x86_64/src/kapi/memory.cpp
index 99dcb5c..f34729a 100644
--- a/arch/x86_64/src/kapi/memory.cpp
+++ b/arch/x86_64/src/kapi/memory.cpp
@@ -1,28 +1,34 @@
#include "kapi/memory.hpp"
-#include "kapi/memory/frame.hpp"
-#include "kapi/memory/frame_allocator.hpp"
+#include "kapi/cio.hpp"
#include "kapi/system.hpp"
#include "x86_64/boot/boot.hpp"
#include "x86_64/boot/ld.hpp"
#include "x86_64/cpu/registers.hpp"
+#include "x86_64/memory/mmu.hpp"
+#include "x86_64/memory/page_table.hpp"
+#include "x86_64/memory/paging_root.hpp"
#include "x86_64/memory/region_allocator.hpp"
#include <multiboot2/information.hpp>
#include <atomic>
+#include <memory>
#include <span>
namespace teachos::memory
{
std::size_t const PLATFORM_FRAME_SIZE{4096};
+ std::size_t const PLATFORM_PAGE_SIZE{PLATFORM_FRAME_SIZE};
namespace
{
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
auto constinit allocator = static_cast<frame_allocator *>(nullptr);
+ constexpr auto static unused_page_address = 0x0000'7fff'cafe'faceuz;
+
auto create_memory_information() -> x86_64::region_allocator::memory_information
{
auto const & mbi = boot::bootstrap_information.mbi;
@@ -51,6 +57,67 @@ namespace teachos::memory
cpu::x86_64::cr0::set(cpu::x86_64::cr0::flags::write_protect);
cpu::x86_64::i32_efer::set(cpu::x86_64::i32_efer::flags::execute_disable_bit_enable);
}
+
+ auto inject_faux_pml4(frame_allocator & allocator) -> void
+ {
+ using entry_flags = x86_64::page_table::entry::flags;
+ using page_table = x86_64::page_table;
+
+ auto temporary_page = page::containing(linear_address{unused_page_address});
+ auto temporary_page_address = temporary_page.start_address();
+
+ auto & pml4 = x86_64::paging_root::get();
+
+ // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
+ auto faux_pml4_frame =
+ allocator.allocate()
+ .and_then([&](auto frame) -> auto {
+ auto index = temporary_page_address >> 39 & 0x1ffu;
+ pml4[index].frame(frame, entry_flags::present | entry_flags::writable);
+ return pml4.next(index);
+ })
+ .and_then([&](auto pml) -> auto {
+ std::construct_at(pml);
+ auto index = temporary_page_address >> 30 & 0x1ffu;
+ (*pml)[index].frame(*allocator.allocate(), entry_flags::present | entry_flags::writable);
+ return pml->next(index);
+ })
+ .and_then([&](auto pml) -> auto {
+ std::construct_at(pml);
+ auto index = temporary_page_address >> 21 & 0x1ffu;
+ (*pml)[index].frame(*allocator.allocate(), entry_flags::present | entry_flags::writable);
+ return pml->next(index);
+ })
+ .transform([&](auto pml) -> auto {
+ std::construct_at(pml);
+ auto index = temporary_page_address >> 12 & 0x1ffu;
+ (*pml)[index].frame(*allocator.allocate(), entry_flags::present | entry_flags::writable);
+ return pml;
+ })
+ .and_then([&](auto pml) -> auto {
+ auto faux_pml4_pointer = std::bit_cast<page_table *>(temporary_page_address.raw());
+ auto faux_pml4 = std::construct_at<page_table>(faux_pml4_pointer);
+
+ auto index = temporary_page_address >> 12 & 0x1ffu;
+ auto frame = (*pml)[index].frame();
+
+ (*faux_pml4)[510].frame(*frame, entry_flags::present | entry_flags::writable);
+ return frame;
+ });
+ // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
+
+ if (!faux_pml4_frame)
+ {
+ system::panic("[MEM] Failed to map and construct faux PML4");
+ }
+
+ // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
+ pml4[510].frame(*faux_pml4_frame, entry_flags::present | entry_flags::writable);
+ x86_64::tlb_flush_all();
+
+ cio::println("[MEM] Injected faux PML4 as recursive map.");
+ }
+
} // namespace
auto active_allocator() -> frame_allocator &
@@ -71,8 +138,9 @@ namespace teachos::memory
system::panic("[x86_64] Memory management has already been initialized.");
}
- [[maybe_unused]] auto allocator = create_early_frame_allocator();
+ auto allocator = create_early_frame_allocator();
enable_cpu_protections();
+ inject_faux_pml4(allocator);
// paging::kernel_mapper kernel(allocator, memory_information);
// kernel.remap_kernel();
diff --git a/kapi/include/kapi/memory/address.hpp b/kapi/include/kapi/memory/address.hpp
index 19615e4..ad82f20 100644
--- a/kapi/include/kapi/memory/address.hpp
+++ b/kapi/include/kapi/memory/address.hpp
@@ -33,6 +33,17 @@ namespace teachos::memory
return std::bit_cast<std::byte *>(m_value);
}
+ constexpr auto operator>>(std::size_t n) const noexcept -> address
+ {
+ return address{m_value >> n};
+ }
+
+ template<typename MaskType>
+ constexpr auto operator&(MaskType mask) const noexcept -> MaskType
+ {
+ return static_cast<MaskType>(m_value & mask);
+ }
+
constexpr auto operator<=>(address const &) const noexcept -> std::strong_ordering = default;
constexpr auto operator==(address const &) const noexcept -> bool = default;