summaryrefslogtreecommitdiffhomepage
path: root/Private/Source/PageManager.cxx
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-01-26 22:26:48 +0100
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-01-26 22:27:09 +0100
commiteba8b7ddd0a455d9e49f32dcae712c5612c0093c (patch)
tree749a3d34546d055507a920bce4ab10e8a9945719 /Private/Source/PageManager.cxx
parentdd192787a70a973f2474720aea49af3f6ddabb7a (diff)
Kernel: Major repository refactor.
Rework the repo into Private and Public modules. Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Private/Source/PageManager.cxx')
-rw-r--r--Private/Source/PageManager.cxx146
1 files changed, 146 insertions, 0 deletions
diff --git a/Private/Source/PageManager.cxx b/Private/Source/PageManager.cxx
new file mode 100644
index 00000000..fc6b8e80
--- /dev/null
+++ b/Private/Source/PageManager.cxx
@@ -0,0 +1,146 @@
+/*
+ * ========================================================
+ *
+ * hCore
+ * Copyright 2024 Mahrouss Logic, all rights reserved.
+ *
+ * ========================================================
+ */
+
+#include <KernelKit/DebugOutput.hpp>
+#include <NewKit/PageManager.hpp>
+
+namespace hCore
+{
+ PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr)
+ : m_Rw(Rw),
+ m_User(User),
+ m_ExecDisable(ExecDisable),
+ m_VirtAddr(VirtAddr),
+ m_Cache(false),
+ m_Shareable(false),
+ m_Wt(false),
+ m_Present(true),
+ m_Accessed(false)
+ {
+ // special case for the null region.
+ if (VirtAddr == 0)
+ {
+ m_Wt = false;
+ m_Rw = false;
+ m_Cache = false;
+ m_Shareable = false;
+ }
+ }
+
+ PTEWrapper::~PTEWrapper()
+ {
+ PTE* raw = reinterpret_cast<PTE*>(m_VirtAddr);
+
+ MUST_PASS(raw);
+ MUST_PASS(!raw->Accessed);
+
+ if (raw->Present)
+ raw->Present = false;
+ }
+
+ void PTEWrapper::FlushTLB(Ref<PageManager> &pm)
+ {
+ pm.Leak().FlushTLB(this->m_VirtAddr);
+ }
+
+ void PageManager::FlushTLB(UIntPtr VirtAddr)
+ {
+ if (VirtAddr == kBadAddress)
+ return;
+
+ flush_tlb(VirtAddr);
+ }
+
+ bool PTEWrapper::Reclaim()
+ {
+ if (!this->m_Present)
+ {
+ this->m_Present = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ PTEWrapper *PageManager::Request(Boolean Rw, Boolean User, Boolean ExecDisable)
+ {
+ PTEWrapper *PageTableEntry =
+ reinterpret_cast<PTEWrapper*>(hCore::HAL::hal_alloc_page(sizeof(PTEWrapper), Rw, User));
+
+ if (PageTableEntry == nullptr) {
+ kcout << "PTEWrapper : Page table is nullptr!, kernel_new_ptr failed!";
+ return nullptr;
+ }
+
+ *PageTableEntry = PTEWrapper{Rw, User, ExecDisable, Detail::create_page_wrapper(Rw, User)};
+ return PageTableEntry;
+ }
+
+ bool PageManager::Free(Ref<PTEWrapper*> &wrapper)
+ {
+ if (wrapper) {
+ if (!Detail::page_disable(wrapper->VirtualAddress()))
+ return false;
+
+ this->FlushTLB(wrapper->VirtualAddress());
+ return true;
+ }
+
+ return false;
+ }
+
+ const UIntPtr &PTEWrapper::VirtualAddress()
+ {
+ return m_VirtAddr;
+ }
+
+ bool PTEWrapper::Shareable()
+ {
+ auto raw = reinterpret_cast<PTE*>(m_VirtAddr);
+
+ if (raw->Present)
+ {
+ m_Shareable = raw->Shared;
+ return m_Shareable;
+ }
+ else
+ {
+ kcout << "[PTEWrapper::Shareable] page is not present!";
+ return false;
+ }
+ }
+
+ bool PTEWrapper::Present()
+ {
+ auto raw = reinterpret_cast<PTE*>(m_VirtAddr);
+
+ if (raw->Present)
+ {
+ m_Present = raw->Present;
+ return m_Present;
+ }
+ else
+ {
+ kcout << "[PTEWrapper::Present] page is not present!";
+ return false;
+ }
+ }
+
+ bool PTEWrapper::Access()
+ {
+ auto raw = reinterpret_cast<PTE*>(m_VirtAddr);
+
+ if (raw->Present)
+ {
+ m_Accessed = raw->Accessed;
+ }
+
+ return m_Accessed;
+ }
+} // namespace hCore