diff options
| author | Amlal <amlalelmahrouss@icloud.com> | 2024-05-11 06:43:54 +0000 |
|---|---|---|
| committer | Amlal <amlalelmahrouss@icloud.com> | 2024-05-11 06:43:54 +0000 |
| commit | ca675beb41dba8d7d16c5793b55d1672f38be3b4 (patch) | |
| tree | c995ada42729ac2059a0ed87a4539d1a7e10b14a /Kernel/HALKit/AMD64/HalPageAlloc.cpp | |
| parent | 2b4a4792abf51487ab4a16106f9376f43acf381a (diff) | |
| parent | bc57a29a24b98b00ba17710ba84ec2188ab73504 (diff) | |
Merged in MHR-23 (pull request #12)
MHR-23: Merge work.
Diffstat (limited to 'Kernel/HALKit/AMD64/HalPageAlloc.cpp')
| -rw-r--r-- | Kernel/HALKit/AMD64/HalPageAlloc.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/Kernel/HALKit/AMD64/HalPageAlloc.cpp b/Kernel/HALKit/AMD64/HalPageAlloc.cpp new file mode 100644 index 00000000..db2aad73 --- /dev/null +++ b/Kernel/HALKit/AMD64/HalPageAlloc.cpp @@ -0,0 +1,103 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include <ArchKit/ArchKit.hpp> +#include <HALKit/AMD64/HalPageAlloc.hpp> +#include <NewKit/Defines.hpp> +#include <NewKit/KernelCheck.hpp> + +STATIC NewOS::Boolean kAllocationInProgress = false; + +namespace NewOS +{ + namespace HAL + { + namespace Detail + { + struct VirtualMemoryHeader + { + UInt32 Magic; + Boolean Present; + Boolean ReadWrite; + Boolean User; + SizeT PageSize; + }; + + struct VirtualMemoryHeaderTraits + { + /// @brief Get next header. + /// @param current + /// @return + VirtualMemoryHeader* Next(VirtualMemoryHeader* current) + { + return current + sizeof(PTE) + current->PageSize; + } + + /// @brief Get previous header. + /// @param current + /// @return + VirtualMemoryHeader* Prev(VirtualMemoryHeader* current) + { + return current - sizeof(PTE) - current->PageSize; + } + }; + } // namespace Detail + + /// @brief Allocates a new page of memory. + /// @param sz the size of it. + /// @param rw read/write flag. + /// @param user user flag. + /// @return the page table of it. + STATIC auto hal_try_alloc_new_page(Boolean rw, Boolean user, SizeT size) -> VoidPtr + { + if (kAllocationInProgress) + return nullptr; + + kAllocationInProgress = true; + + constexpr auto cVMTMagic = 0xDEEFD00D; + + ///! fetch from the start. + Detail::VirtualMemoryHeader* vmHeader = reinterpret_cast<Detail::VirtualMemoryHeader*>(kKernelVirtualStart); + Detail::VirtualMemoryHeaderTraits traits; + + while (vmHeader->Present && + vmHeader->Magic != cVMTMagic) + { + vmHeader = traits.Next(vmHeader); + } + + vmHeader->Magic = cVMTMagic; + vmHeader->Present = true; + vmHeader->ReadWrite = rw; + vmHeader->User = user; + vmHeader->PageSize = size; + + kAllocationInProgress = false; + + return reinterpret_cast<VoidPtr>(vmHeader); + } + + /// @brief Allocate a new page to be used by the OS. + /// @param rw read/write bit. + /// @param user user bit. + /// @return + auto hal_alloc_page(Boolean rw, Boolean user, SizeT size) -> VoidPtr + { + /// Wait for a ongoing allocation to complete. + while (kAllocationInProgress) + { + ; + } + + if (size == 0) + ++size; + + /// allocate new page. + return hal_try_alloc_new_page(rw, user, size); + } + } // namespace HAL +} // namespace NewOS |
