diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-26 22:26:48 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-26 22:27:09 +0100 |
| commit | eba8b7ddd0a455d9e49f32dcae712c5612c0093c (patch) | |
| tree | 749a3d34546d055507a920bce4ab10e8a9945719 /Private/Source/PageManager.cxx | |
| parent | dd192787a70a973f2474720aea49af3f6ddabb7a (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.cxx | 146 |
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 |
