From 4ba02280f19b8a2beb1ad8445be7df6b7f9e1805 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 20 Mar 2024 14:47:08 +0100 Subject: kernel: Reworking kernel to support virtual memory. Signed-off-by: Amlal El Mahrouss --- Private/HALKit/AMD64/HalControlRegister.s | 2 +- Private/HALKit/AMD64/HalKernelMain.cxx | 28 ++------- Private/HALKit/AMD64/HalPageAlloc.cpp | 41 +++++++------ Private/HALKit/AMD64/HalPageAlloc.hpp | 2 +- Private/KernelKit/DebugOutput.hpp | 2 + Private/KernelKit/KernelHeap.hpp | 19 ++++++ Private/KernelKit/LockDelegate.hpp | 64 +++++++++++++++++++ Private/KernelKit/ProcessScheduler.hpp | 4 +- Private/KernelKit/UserHeap.hpp | 40 ++++++++++++ Private/NewBoot/Source/HEL/AMD64/BootATA.cxx | 12 ++-- Private/NewKit/Defines.hpp | 4 +- Private/NewKit/KernelHeap.hpp | 20 ------ Private/NewKit/LockDelegate.hpp | 64 ------------------- Private/NewKit/New.hpp | 2 +- Private/NewKit/NewKit.hpp | 4 +- Private/NewKit/PageManager.hpp | 4 +- Private/NewKit/Pmm.hpp | 15 +++-- Private/NewKit/UserHeap.hpp | 40 ------------ Private/Source/KernelHeap.cxx | 91 +++++++--------------------- Private/Source/LockDelegate.cxx | 2 +- Private/Source/New+Delete.cxx | 45 ++++++-------- Private/Source/PEFCodeManager.cxx | 2 +- Private/Source/PageManager.cxx | 37 +++++------ Private/Source/Pmm.cxx | 33 +++++----- Private/Source/ProcessScheduler.cxx | 6 +- Private/Source/UserHeap.cxx | 30 ++++----- 26 files changed, 271 insertions(+), 342 deletions(-) create mode 100644 Private/KernelKit/KernelHeap.hpp create mode 100644 Private/KernelKit/LockDelegate.hpp create mode 100644 Private/KernelKit/UserHeap.hpp delete mode 100644 Private/NewKit/KernelHeap.hpp delete mode 100644 Private/NewKit/LockDelegate.hpp delete mode 100644 Private/NewKit/UserHeap.hpp diff --git a/Private/HALKit/AMD64/HalControlRegister.s b/Private/HALKit/AMD64/HalControlRegister.s index 1f1f4512..74dda36c 100644 --- a/Private/HALKit/AMD64/HalControlRegister.s +++ b/Private/HALKit/AMD64/HalControlRegister.s @@ -18,7 +18,7 @@ hal_flush_tlb: ret hal_read_cr3: - movq %rax, %cr3 + movq %cr3, %rax ret hal_read_cr0: diff --git a/Private/HALKit/AMD64/HalKernelMain.cxx b/Private/HALKit/AMD64/HalKernelMain.cxx index b82dccd7..2b420bb9 100644 --- a/Private/HALKit/AMD64/HalKernelMain.cxx +++ b/Private/HALKit/AMD64/HalKernelMain.cxx @@ -13,26 +13,13 @@ #include #include #include -#include -#include +#include +#include ///! @brief Disk contains HCore files. #define kInstalledMedia 0xDD EXTERN_C HCore::VoidPtr kInterruptVectorTable[]; -EXTERN_C HCore::Void _hal_init_mouse(); -EXTERN_C HCore::Void _hal_mouse_handler(); -EXTERN_C HCore::Void _hal_mouse_draw(); - -namespace Detail { -STATIC HCore::Void ke_page_protect_nullptr(HCore::Void) { - HCore::PTEWrapper wrapper(false, false, false, 0); - HCore::PageManager pageManager; - HCore::Ref refMan(pageManager); - - wrapper.FlushTLB(refMan); -} -} // namespace Detail EXTERN_C void RuntimeMain( HCore::HEL::HandoverInformationHeader* HandoverHeader) { @@ -42,9 +29,11 @@ EXTERN_C void RuntimeMain( kKernelVirtualSize = HandoverHeader->f_VirtualSize; kKernelVirtualStart = HandoverHeader->f_VirtualStart; - kKernelPhysicalSize = HandoverHeader->f_PhysicalSize - kPTEAlign; + kKernelPhysicalSize = HandoverHeader->f_PhysicalSize; kKernelPhysicalStart = HandoverHeader->f_PhysicalStart; + hal_write_cr3((HCore::UIntPtr)kKernelVirtualStart); + STATIC HCore::HAL::Detail::HCoreGDT GDT = { {0, 0, 0, 0x00, 0x00, 0}, // null entry {0, 0, 0, 0x9a, 0xaf, 0}, // kernel code @@ -84,7 +73,6 @@ EXTERN_C void RuntimeMain( /// START POST HCore::HAL::Detail::_ke_power_on_self_test(); - Detail::ke_page_protect_nullptr(); /// END POST @@ -98,11 +86,5 @@ EXTERN_C void RuntimeMain( /// TODO: Install hcore on host. } - _hal_init_mouse(); - - while (1) { - _hal_mouse_draw(); - } - HCore::ke_stop(RUNTIME_CHECK_BOOTSTRAP); } diff --git a/Private/HALKit/AMD64/HalPageAlloc.cpp b/Private/HALKit/AMD64/HalPageAlloc.cpp index 867f39cb..91bde617 100644 --- a/Private/HALKit/AMD64/HalPageAlloc.cpp +++ b/Private/HALKit/AMD64/HalPageAlloc.cpp @@ -24,27 +24,37 @@ namespace HAL { /// @param user user flag. /// @return the page table of it. STATIC auto hal_try_alloc_new_page(SizeT sz, Boolean rw, Boolean user) - -> PageTable64 * { - kAllocationInProgress = true; + -> VoidPtr { MUST_PASS(sz > 0); - PageTable64 *pte = reinterpret_cast(kKernelVirtualStart); + kAllocationInProgress = true; + PDE* cr3 = (PDE*)hal_read_cr3(); + + kcout << "HCoreKrnl.exe: CR3: " << hex_number((UIntPtr)cr3) << endl; - pte->Rw = rw; - pte->User = user; - pte->Present = true; - pte->PhysicalAddress = (UIntPtr)kKernelPhysicalStart; + for (size_t i = 0; i < kPTESize; ++i) + { + if (cr3->Pte[i].Present) continue; + kcout << "HCoreKrnl.exe: Page index: " << hex_number(i) << endl; - kKernelVirtualStart = (VoidPtr)((UIntPtr)kKernelVirtualStart + kKernelPagingPadding); - kKernelPhysicalStart = (VoidPtr)((UIntPtr)kKernelPhysicalStart + kKernelPagingPadding); + cr3->Pte[i].Rw = rw; + cr3->Pte[i].User = user; + cr3->Pte[i].Present = true; - ++kPageCnt; + ++kPageCnt; + kAllocationInProgress = false; + kcout << "HCoreKrnl.exe: Allocation done for: " << hex_number(i) << endl; + return (VoidPtr)cr3->Pte[i].PhysicalAddress; + } + kAllocationInProgress = false; - return pte; + return nullptr; } -auto hal_alloc_page(SizeT sz, Boolean rw, Boolean user) -> PageTable64 * { +auto hal_alloc_page(SizeT sz, Boolean rw, Boolean user) -> VoidPtr { + while (kAllocationInProgress) {} + if (sz == 0) ++sz; @@ -53,12 +63,7 @@ auto hal_alloc_page(SizeT sz, Boolean rw, Boolean user) -> PageTable64 * { } auto hal_create_page(Boolean rw, Boolean user) -> UIntPtr { - while (kAllocationInProgress) {} - - PageTable64 *new_pte = hal_alloc_page(sizeof(PageTable64), rw, user); - MUST_PASS(new_pte); - - return reinterpret_cast(new_pte); + return reinterpret_cast(hal_alloc_page(sizeof(PageTable64), rw, user)); } } // namespace HAL } // namespace HCore diff --git a/Private/HALKit/AMD64/HalPageAlloc.hpp b/Private/HALKit/AMD64/HalPageAlloc.hpp index 34d76d3d..2ce56b5a 100644 --- a/Private/HALKit/AMD64/HalPageAlloc.hpp +++ b/Private/HALKit/AMD64/HalPageAlloc.hpp @@ -72,7 +72,7 @@ struct PageDirectory64 final { PageTable64 ALIGN(kPTEAlign) Pte[kPTEMax]; }; -PageTable64* hal_alloc_page(SizeT sz, Boolean rw, Boolean user); +VoidPtr hal_alloc_page(SizeT sz, Boolean rw, Boolean user); UIntPtr hal_create_page(Boolean rw, Boolean user); } // namespace HCore::HAL diff --git a/Private/KernelKit/DebugOutput.hpp b/Private/KernelKit/DebugOutput.hpp index 88ed2448..0eb59da2 100644 --- a/Private/KernelKit/DebugOutput.hpp +++ b/Private/KernelKit/DebugOutput.hpp @@ -83,6 +83,8 @@ inline TerminalDevice _write_number_hex(const Long &x, TerminalDevice& term) { inline TerminalDevice hex_number(const Long &x) { TerminalDevice selfTerm = TerminalDevice::Shared(); + + selfTerm << "0x"; Detail::_write_number_hex(x, selfTerm); return selfTerm; diff --git a/Private/KernelKit/KernelHeap.hpp b/Private/KernelKit/KernelHeap.hpp new file mode 100644 index 00000000..974cf0f3 --- /dev/null +++ b/Private/KernelKit/KernelHeap.hpp @@ -0,0 +1,19 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +#pragma once + +// last-rev 30/01/24 +// file: KernelHeap.hpp +// description: heap allocation for the kernel. + +#include + +namespace HCore { +Int32 ke_delete_ke_heap(voidPtr allocatedPtr); +Boolean ke_is_valid_ptr(VoidPtr ptr); +voidPtr ke_new_ke_heap(SizeT sz, const bool rw, const bool user); +} // namespace HCore diff --git a/Private/KernelKit/LockDelegate.hpp b/Private/KernelKit/LockDelegate.hpp new file mode 100644 index 00000000..0fd9ba63 --- /dev/null +++ b/Private/KernelKit/LockDelegate.hpp @@ -0,0 +1,64 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +#pragma once + +#include +#include + +#define kLockDone (200U) /* job is done */ +#define kLockTimedOut (100U) /* job has timed out */ + +namespace HCore +{ +/// @brief Lock condition pointer. +typedef Boolean* LockPtr; + +/// @brief Locking delegate class, hangs until limit. +/// @tparam N the amount of cycles to wait. +template +class LockDelegate final +{ + public: + LockDelegate() = delete; + + public: + explicit LockDelegate(LockPtr expr) + { + auto spin = 0U; + + while (spin != N) + { + if (*expr) + { + m_LockStatus | kLockDone; + break; + } + } + + if (spin == N) + m_LockStatus | kLockTimedOut; + } + + ~LockDelegate() = default; + + LockDelegate &operator=(const LockDelegate &) = delete; + LockDelegate(const LockDelegate &) = delete; + + bool Done() + { + return m_LockStatus[kLockDone] == kLockDone; + } + + bool HasTimedOut() + { + return m_LockStatus[kLockTimedOut] != kLockTimedOut; + } + + private: + Atom m_LockStatus; +}; +} // namespace HCore diff --git a/Private/KernelKit/ProcessScheduler.hpp b/Private/KernelKit/ProcessScheduler.hpp index e3cbbe86..caff1125 100644 --- a/Private/KernelKit/ProcessScheduler.hpp +++ b/Private/KernelKit/ProcessScheduler.hpp @@ -10,9 +10,9 @@ #include #include #include -#include +#include #include -#include +#include #define kMinMicroTime AffinityKind::kHartStandard #define kPIDInvalid (-1) diff --git a/Private/KernelKit/UserHeap.hpp b/Private/KernelKit/UserHeap.hpp new file mode 100644 index 00000000..d66eb356 --- /dev/null +++ b/Private/KernelKit/UserHeap.hpp @@ -0,0 +1,40 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +/// @version 5/11/23 +/// @file UserHeap.hpp +/// @brief memory heap for user programs. + +#define kUserHeapMaxSz (4096) +#define kUserHeapMag (0x5500A1) + +namespace HCore { +typedef enum { + kUserHeapHypervisor = 0x2, + kUserHeapShared = 0x4, + kUserHeapUser = 0x6, + kUserHeapRw = 0x8, +} kUserHeapFlags; + +/// @brief Allocate a process heap, no zero out is done here. +/// @param flags +/// @return The process's heap. +VoidPtr rt_new_heap(Int32 flags); + +/// @brief Frees the process heap. +/// @param pointer The process heap pointer. +/// @return +Int32 rt_free_heap(voidPtr pointer); +} // namespace HCore diff --git a/Private/NewBoot/Source/HEL/AMD64/BootATA.cxx b/Private/NewBoot/Source/HEL/AMD64/BootATA.cxx index 21f3f256..0ee16d82 100644 --- a/Private/NewBoot/Source/HEL/AMD64/BootATA.cxx +++ b/Private/NewBoot/Source/HEL/AMD64/BootATA.cxx @@ -152,6 +152,8 @@ Void boot_ata_read(UInt32 Lba, UInt8 IO, UInt8 Master, CharacterType* Buf, Out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); + boot_ata_wait_io(IO); + for (SizeT IndexOff = 0; IndexOff < 256; ++IndexOff) { Buf[Offset + IndexOff] = In16(IO + ATA_REG_DATA); } @@ -172,6 +174,8 @@ Void boot_ata_write(UInt32 Lba, UInt8 IO, UInt8 Master, CharacterType* Buf, Out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); + boot_ata_wait_io(IO); + for (SizeT IndexOff = 0; IndexOff < 256; ++IndexOff) { Out16(IO + ATA_REG_DATA, Buf[Offset + IndexOff]); } @@ -225,7 +229,7 @@ BDeviceATA& BDeviceATA::Read(CharacterType* Buf, const SizeT& SectorSz) { return *this; } - Leak().mErr = false; + this->Leak().mErr = false; if (!Buf || SectorSz < 1) return *this; @@ -233,8 +237,6 @@ BDeviceATA& BDeviceATA::Read(CharacterType* Buf, const SizeT& SectorSz) { boot_ata_read(this->Leak().mBase + i, this->Leak().mBus, this->Leak().mMaster, Buf, i); - - boot_ata_wait_io(this->Leak().mBus); } return *this; @@ -262,15 +264,13 @@ BDeviceATA& BDeviceATA::Write(CharacterType* Buf, const SizeT& SectorSz) { Buf, Off); Off += kATASectorSize; - - boot_ata_wait_io(this->Leak().mBus); } return *this; } /** - * @brief ATA Config getter. + * @brief ATA trait getter. * @return BDeviceATA::ATATrait& the drive config. */ BDeviceATA::ATATrait& BDeviceATA::Leak() { return mTrait; } diff --git a/Private/NewKit/Defines.hpp b/Private/NewKit/Defines.hpp index c111f80f..18506e8f 100644 --- a/Private/NewKit/Defines.hpp +++ b/Private/NewKit/Defines.hpp @@ -99,12 +99,12 @@ public: public: template - Char* AsBytes(T type) { + Char* AsBytes(T type) noexcept { return reinterpret_cast(type); } template - Y As(T type) { + Y As(T type) noexcept { return reinterpret_cast(type); } diff --git a/Private/NewKit/KernelHeap.hpp b/Private/NewKit/KernelHeap.hpp deleted file mode 100644 index 489138cd..00000000 --- a/Private/NewKit/KernelHeap.hpp +++ /dev/null @@ -1,20 +0,0 @@ -/* ------------------------------------------- - - Copyright Mahrouss Logic - -------------------------------------------- */ - -#pragma once - -// last-rev 30/01/24 -// file: KernelHeap.hpp -// description: heap allocation for the kernel. - -#include -#include - -namespace HCore { -Int32 ke_delete_ke_heap(voidPtr allocatedPtr); -Boolean ke_is_valid_ptr(VoidPtr ptr); -voidPtr ke_new_ke_heap(SizeT sz, const bool rw, const bool user); -} // namespace HCore diff --git a/Private/NewKit/LockDelegate.hpp b/Private/NewKit/LockDelegate.hpp deleted file mode 100644 index 0fd9ba63..00000000 --- a/Private/NewKit/LockDelegate.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* ------------------------------------------- - - Copyright Mahrouss Logic - -------------------------------------------- */ - -#pragma once - -#include -#include - -#define kLockDone (200U) /* job is done */ -#define kLockTimedOut (100U) /* job has timed out */ - -namespace HCore -{ -/// @brief Lock condition pointer. -typedef Boolean* LockPtr; - -/// @brief Locking delegate class, hangs until limit. -/// @tparam N the amount of cycles to wait. -template -class LockDelegate final -{ - public: - LockDelegate() = delete; - - public: - explicit LockDelegate(LockPtr expr) - { - auto spin = 0U; - - while (spin != N) - { - if (*expr) - { - m_LockStatus | kLockDone; - break; - } - } - - if (spin == N) - m_LockStatus | kLockTimedOut; - } - - ~LockDelegate() = default; - - LockDelegate &operator=(const LockDelegate &) = delete; - LockDelegate(const LockDelegate &) = delete; - - bool Done() - { - return m_LockStatus[kLockDone] == kLockDone; - } - - bool HasTimedOut() - { - return m_LockStatus[kLockTimedOut] != kLockTimedOut; - } - - private: - Atom m_LockStatus; -}; -} // namespace HCore diff --git a/Private/NewKit/New.hpp b/Private/NewKit/New.hpp index ac2587a9..c828b979 100644 --- a/Private/NewKit/New.hpp +++ b/Private/NewKit/New.hpp @@ -6,7 +6,7 @@ ------------------------------------------- */ #pragma once -#include +#include typedef __SIZE_TYPE__ size_t; // gcc will complain about that diff --git a/Private/NewKit/NewKit.hpp b/Private/NewKit/NewKit.hpp index 6711e151..79993091 100644 --- a/Private/NewKit/NewKit.hpp +++ b/Private/NewKit/NewKit.hpp @@ -12,11 +12,11 @@ #include #include #include -#include +#include #include #include #include #include #include -#include +#include #include diff --git a/Private/NewKit/PageManager.hpp b/Private/NewKit/PageManager.hpp index ace13233..dab9ac73 100644 --- a/Private/NewKit/PageManager.hpp +++ b/Private/NewKit/PageManager.hpp @@ -31,7 +31,7 @@ class PTEWrapper final { PTEWrapper(const PTEWrapper &) = default; public: - void FlushTLB(Ref &pm); + void Flush(); const UIntPtr VirtualAddress(); void NoExecute(const bool enable = false); @@ -67,7 +67,7 @@ struct PageManager final { PageManager(const PageManager &) = default; public: - PTEWrapper *Request(Boolean Rw, Boolean User, Boolean ExecDisable); + PTEWrapper Request(Boolean Rw, Boolean User, Boolean ExecDisable); bool Free(Ref &wrapper); private: diff --git a/Private/NewKit/Pmm.hpp b/Private/NewKit/Pmm.hpp index f004904c..e8b4f05f 100644 --- a/Private/NewKit/Pmm.hpp +++ b/Private/NewKit/Pmm.hpp @@ -22,14 +22,13 @@ class Pmm final { Pmm &operator=(const Pmm &) = delete; Pmm(const Pmm &) = default; - Ref RequestPage(Boolean user = false, - Boolean readWrite = false); - Boolean FreePage(Ref refPage); - - Boolean ToggleRw(Ref refPage, Boolean enable = true); - Boolean TogglePresent(Ref refPage, Boolean enable = true); - Boolean ToggleUser(Ref refPage, Boolean enable = true); - Boolean ToggleShare(Ref refPage, Boolean enable = true); + Ref RequestPage(Boolean user = false, Boolean readWrite = false); + Boolean FreePage(Ref refPage); + + Boolean ToggleRw(Ref refPage, Boolean enable = true); + Boolean TogglePresent(Ref refPage, Boolean enable = true); + Boolean ToggleUser(Ref refPage, Boolean enable = true); + Boolean ToggleShare(Ref refPage, Boolean enable = true); /// @brief Get the page manager of this. Ref &Leak() { return m_PageManager; } diff --git a/Private/NewKit/UserHeap.hpp b/Private/NewKit/UserHeap.hpp deleted file mode 100644 index 09a7d31e..00000000 --- a/Private/NewKit/UserHeap.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* ------------------------------------------- - - Copyright Mahrouss Logic - -------------------------------------------- */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -/// last-rev 5/11/23 -/// @file UserHeap.hpp -/// @brief memory heap for user programs. - -#define kPoolMaxSz (4096) -#define kPoolMag (0x5500A1) - -namespace HCore { -typedef enum { - kPoolHypervisor = 0x2, - kPoolShared = 0x4, - kPoolUser = 0x6, - kPoolRw = 0x8, -} kPoolFlags; - -/// @brief Allocate a process heap, no zero out is done here. -/// @param flags -/// @return The process's heap. -VoidPtr rt_new_heap(Int32 flags); - -/// @brief Frees the process heap. -/// @param pointer The process heap pointer. -/// @return -Int32 rt_free_heap(voidPtr pointer); -} // namespace HCore diff --git a/Private/Source/KernelHeap.cxx b/Private/Source/KernelHeap.cxx index e7dd09ed..359e3cbd 100644 --- a/Private/Source/KernelHeap.cxx +++ b/Private/Source/KernelHeap.cxx @@ -5,50 +5,35 @@ ------------------------------------------- */ #include -#include +#include +#include -//! @file KernelHeap.cpp +//! @file KernelHeap.cxx //! @brief Kernel allocator. -#define kHeapMaxWrappers (4096 * 8) -#define kHeapMagic 0xAA55 +#define kHeapMagic 0xD4D7 namespace HCore { -STATIC Ref kWrapperList[kHeapMaxWrappers]; -STATIC SizeT kHeapCount = 0UL; -STATIC Ref kLastWrapper; -STATIC PageManager kPageManager; +STATIC SizeT kHeapCount = 0UL; +STATIC Ref kHeapLastWrapper; +STATIC PageManager kHeapPageManager; namespace Detail { /// @brief Kernel heap information block. -/// Located before the address. -/// | HIB | ADDRESS | +/// Located before the address bytes. +/// | HIB | ADDRESS | struct HeapInformationBlock final { - UInt16 hMagic; + UInt16 hMagic; Boolean hPresent; - Int32 hCRC32; - Int64 hSizeAddress; - VoidPtr hAddress; + Int32 hCRC32; + Int64 hSizeAddress; + UIntPtr hAddress; }; typedef HeapInformationBlock *HeapInformationBlockPtr; - -STATIC VoidPtr ke_find_heap(const SizeT &sz, const bool rw, const bool user) { - for (SizeT indexWrapper = 0; indexWrapper < kHeapMaxWrappers; - ++indexWrapper) { - if (!kWrapperList[indexWrapper]->Present()) { - kWrapperList[indexWrapper] - ->Reclaim(); /* very straight-forward as you can see. */ - return reinterpret_cast( - kWrapperList[indexWrapper]->VirtualAddress()); - } - } - - return nullptr; -} } // namespace Detail -/// @brief Allocate pointer. +/// @brief allocate chunk of memory. /// @param sz size of pointer /// @param rw read write (true to enable it) /// @param user is it accesible by user processes? @@ -56,28 +41,21 @@ STATIC VoidPtr ke_find_heap(const SizeT &sz, const bool rw, const bool user) { VoidPtr ke_new_ke_heap(SizeT sz, const bool rw, const bool user) { if (sz == 0) ++sz; - if (auto ptr = Detail::ke_find_heap(sz, rw, user); ptr) return ptr; - - Ref wrapper = kPageManager.Request(user, rw, false); - - Ref refMan(kPageManager); - wrapper->FlushTLB(refMan); - - kLastWrapper = wrapper; + auto wrapper = kHeapPageManager.Request(rw, user, false); + kHeapLastWrapper = wrapper; Detail::HeapInformationBlockPtr heapInfo = reinterpret_cast( - wrapper->VirtualAddress()); + wrapper.VirtualAddress()); heapInfo->hSizeAddress = sz; heapInfo->hMagic = kHeapMagic; - heapInfo->hCRC32 = ke_calculate_crc32((Char *)wrapper->VirtualAddress(), sz); - heapInfo->hAddress = (VoidPtr)wrapper->VirtualAddress(); + heapInfo->hCRC32 = 0; // dont fill it for now. + heapInfo->hAddress = wrapper.VirtualAddress(); - kWrapperList[kHeapCount] = wrapper; ++kHeapCount; - return reinterpret_cast(wrapper->VirtualAddress() + + return reinterpret_cast(wrapper.VirtualAddress() + sizeof(Detail::HeapInformationBlock)); } @@ -90,35 +68,12 @@ Int32 ke_delete_ke_heap(VoidPtr ptr) { reinterpret_cast(ptr) - sizeof(Detail::HeapInformationBlock); - if (kLastWrapper && virtualAddress->hMagic == kHeapMagic && - (UIntPtr)virtualAddress->hAddress == kLastWrapper->VirtualAddress()) { - if (kPageManager.Free(kLastWrapper)) { + if (kHeapLastWrapper && virtualAddress->hMagic == kHeapMagic && + virtualAddress->hAddress == kHeapLastWrapper.Leak().VirtualAddress()) { virtualAddress->hSizeAddress = 0UL; virtualAddress->hPresent = false; - return true; - } - - return false; - } - - Ref wrapper{nullptr}; - - for (SizeT indexWrapper = 0; indexWrapper < kHeapCount; ++indexWrapper) { - if (kWrapperList[indexWrapper]->VirtualAddress() == - (UIntPtr)virtualAddress->hAddress) { - wrapper = kWrapperList[indexWrapper]; - - // if page is no more, then mark it also as non executable. - if (kPageManager.Free(wrapper)) { - virtualAddress->hSizeAddress = 0UL; - virtualAddress->hPresent = false; - - return true; - } - - return false; - } + return true; } } diff --git a/Private/Source/LockDelegate.cxx b/Private/Source/LockDelegate.cxx index 30366a86..34cb490d 100644 --- a/Private/Source/LockDelegate.cxx +++ b/Private/Source/LockDelegate.cxx @@ -4,4 +4,4 @@ ------------------------------------------- */ -#include +#include diff --git a/Private/Source/New+Delete.cxx b/Private/Source/New+Delete.cxx index fbcc7787..d8901ce0 100644 --- a/Private/Source/New+Delete.cxx +++ b/Private/Source/New+Delete.cxx @@ -4,48 +4,37 @@ ------------------------------------------- */ -#include +#include #include -void* operator new[](size_t sz) -{ - if (sz == 0) - ++sz; +void* operator new[](size_t sz) { + if (sz == 0) ++sz; - return HCore::ke_new_ke_heap(sz, true, false); + return HCore::ke_new_ke_heap(sz, true, false); } -void* operator new(size_t sz) -{ - if (sz == 0) - ++sz; +void* operator new(size_t sz) { + if (sz == 0) ++sz; - return HCore::ke_new_ke_heap(sz, true, false); + return HCore::ke_new_ke_heap(sz, true, false); } -void operator delete[](void* ptr) -{ - if (ptr == nullptr) - return; +void operator delete[](void* ptr) { + if (ptr == nullptr) return; - HCore::ke_delete_ke_heap(ptr); + HCore::ke_delete_ke_heap(ptr); } -void operator delete(void* ptr) -{ - if (ptr == nullptr) - return; +void operator delete(void* ptr) { + if (ptr == nullptr) return; - HCore::ke_delete_ke_heap(ptr); + HCore::ke_delete_ke_heap(ptr); } -void operator delete(void* ptr, size_t sz) -{ - if (ptr == nullptr) - return; +void operator delete(void* ptr, size_t sz) { + if (ptr == nullptr) return; - (void)sz; + HCORE_UNUSED(sz); - HCore::ke_delete_ke_heap(ptr); + HCore::ke_delete_ke_heap(ptr); } - diff --git a/Private/Source/PEFCodeManager.cxx b/Private/Source/PEFCodeManager.cxx index ec9525dc..bd529dca 100644 --- a/Private/Source/PEFCodeManager.cxx +++ b/Private/Source/PEFCodeManager.cxx @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/Private/Source/PageManager.cxx b/Private/Source/PageManager.cxx index 843aa66c..6cedd5b6 100644 --- a/Private/Source/PageManager.cxx +++ b/Private/Source/PageManager.cxx @@ -37,21 +37,27 @@ PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, } PTEWrapper::~PTEWrapper() { - PTE *raw = reinterpret_cast(m_VirtAddr); + PDE* cr3 = (PDE*)hal_read_cr3(); + + PTE* raw = (PTE*)&cr3->Pte[(this->m_VirtAddr % kPTESize)]; raw->Present = false; raw->Rw = false; } -void PTEWrapper::FlushTLB(Ref &pm) { - PTE* ptIndex = (PTE*)((m_VirtAddr >> 12) & 0x1FF); - ptIndex->Wt = m_Wt; - ptIndex->Rw = m_Rw; - ptIndex->Cache = m_Cache; - ptIndex->Present = m_Present; - ptIndex->ExecDisable = m_ExecDisable; +void PTEWrapper::Flush() { + PDE* cr3 = (PDE*)hal_read_cr3(); + + kcout << "CR3: " << hex_number((UIntPtr)cr3) << endl; + kcout << "Index: " << hex_number((this->m_VirtAddr % kPTESize)) << endl; - pm.Leak().FlushTLB((UIntPtr)ptIndex); + cr3->Pte[(this->m_VirtAddr % kPTESize)].Wt = m_Wt; + cr3->Pte[(this->m_VirtAddr % kPTESize)].Rw = m_Rw; + cr3->Pte[(this->m_VirtAddr % kPTESize)].Cache = m_Cache; + cr3->Pte[(this->m_VirtAddr % kPTESize)].Present = m_Present; + cr3->Pte[(this->m_VirtAddr % kPTESize)].ExecDisable = m_ExecDisable; + + kcout << "Wrote PTE to PDE: " << hex_number((UIntPtr)cr3) << endl; } void PageManager::FlushTLB(UIntPtr VirtAddr) { @@ -69,24 +75,19 @@ bool PTEWrapper::Reclaim() { return false; } -PTEWrapper *PageManager::Request(Boolean Rw, Boolean User, +PTEWrapper PageManager::Request(Boolean Rw, Boolean User, Boolean ExecDisable) { // Store PTE wrapper right after PTE. - PTEWrapper *PageTableEntry = reinterpret_cast( - HCore::HAL::hal_alloc_page(sizeof(PTEWrapper), Rw, User) + sizeof(PTE)); + VoidPtr ptr = reinterpret_cast( + HCore::HAL::hal_alloc_page(sizeof(PTEWrapper), Rw, User)); - PageTableEntry->NoExecute(ExecDisable); - *PageTableEntry = PTEWrapper{Rw, User, ExecDisable, - reinterpret_cast(PageTableEntry)}; - return PageTableEntry; + return PTEWrapper{Rw, User, ExecDisable, (UIntPtr)ptr}; } bool PageManager::Free(Ref &wrapper) { if (wrapper) { if (!Detail::page_disable(wrapper->VirtualAddress())) return false; - - this->FlushTLB(wrapper->VirtualAddress()); return true; } diff --git a/Private/Source/Pmm.cxx b/Private/Source/Pmm.cxx index 6ac8c7d2..9112b3d9 100644 --- a/Private/Source/Pmm.cxx +++ b/Private/Source/Pmm.cxx @@ -13,16 +13,12 @@ Pmm::Pmm() : m_PageManager() { kcout << "[PMM] Allocate PageMemoryManager"; } Pmm::~Pmm() = default; /* If this returns Null pointer, enter emergency mode */ -Ref Pmm::RequestPage(Boolean user, Boolean readWrite) { - PTEWrapper *pt = m_PageManager.Leak().Request(user, readWrite, false); - - if (pt) { - pt->m_Present = true; - pt->FlushTLB(m_PageManager); +Ref Pmm::RequestPage(Boolean user, Boolean readWrite) { + PTEWrapper pt = m_PageManager.Leak().Request(user, readWrite, false); + if (pt.m_Present) { kcout << "[PMM]: Allocation was successful."; - - return Ref(pt); + return Ref(pt); } kcout << "[PMM]: Allocation failure."; @@ -30,42 +26,43 @@ Ref Pmm::RequestPage(Boolean user, Boolean readWrite) { return {}; } -Boolean Pmm::FreePage(Ref PageRef) { +Boolean Pmm::FreePage(Ref PageRef) { if (!PageRef) return false; - PageRef->m_Present = false; + PageRef.Leak().m_Present = false; + PageRef.Leak().Flush(); return true; } -Boolean Pmm::TogglePresent(Ref PageRef, Boolean Enable) { +Boolean Pmm::TogglePresent(Ref PageRef, Boolean Enable) { if (!PageRef) return false; - PageRef->m_Present = Enable; + PageRef.Leak().m_Present = Enable; return true; } -Boolean Pmm::ToggleUser(Ref PageRef, Boolean Enable) { +Boolean Pmm::ToggleUser(Ref PageRef, Boolean Enable) { if (!PageRef) return false; - PageRef->m_Rw = Enable; + PageRef.Leak().m_Rw = Enable; return true; } -Boolean Pmm::ToggleRw(Ref PageRef, Boolean Enable) { +Boolean Pmm::ToggleRw(Ref PageRef, Boolean Enable) { if (!PageRef) return false; - PageRef->m_Rw = Enable; + PageRef.Leak().m_Rw = Enable; return true; } -Boolean Pmm::ToggleShare(Ref PageRef, Boolean Enable) { +Boolean Pmm::ToggleShare(Ref PageRef, Boolean Enable) { if (!PageRef) return false; - PageRef->m_Shareable = Enable; + PageRef.Leak().m_Shareable = Enable; return true; } diff --git a/Private/Source/ProcessScheduler.cxx b/Private/Source/ProcessScheduler.cxx index a4f8dd2f..3432fe70 100644 --- a/Private/Source/ProcessScheduler.cxx +++ b/Private/Source/ProcessScheduler.cxx @@ -11,7 +11,7 @@ #include #include -#include +#include #include ///! bugs = 0 @@ -68,7 +68,7 @@ bool rt_in_pool_region(VoidPtr pool_ptr, VoidPtr pool, const SizeT &sz) { Char *_pool_ptr = (Char *)pool_ptr; Char *_pool = (Char *)pool; - for (SizeT index = sz; _pool[sz] != 0x55; --index) { + for (SizeT index = sz; _pool[sz] != kUserHeapMag; --index) { if (&_pool[index] > &_pool_ptr[sz]) continue; if (_pool[index] == _pool_ptr[index]) return true; @@ -151,7 +151,7 @@ SizeT ProcessManager::Add(Ref &process) { kcout << "ProcessManager::Add(Ref& process)\r\n"; - process.Leak().HeapPtr = rt_new_heap(kPoolUser | kPoolRw); + process.Leak().HeapPtr = rt_new_heap(kUserHeapUser | kUserHeapRw); process.Leak().ProcessId = mTeam.AsArray().Count(); process.Leak().HeapCursor = process.Leak().HeapPtr; diff --git a/Private/Source/UserHeap.cxx b/Private/Source/UserHeap.cxx index beda5c65..83d40845 100644 --- a/Private/Source/UserHeap.cxx +++ b/Private/Source/UserHeap.cxx @@ -5,7 +5,7 @@ ------------------------------------------- */ #include -#include +#include #define kHeapHeaderPaddingSz 16 @@ -37,7 +37,7 @@ class HeapManager final { STATIC SizeT& Count() { return s_NumPools; } STATIC Ref& Leak() { return s_Pmm; } STATIC Boolean& IsEnabled() { return s_PoolsAreEnabled; } - STATIC Array, kPoolMaxSz>& The() { return s_Pool; } + STATIC Array, kUserHeapMaxSz>& The() { return s_Pool; } private: STATIC Size s_NumPools; @@ -45,7 +45,7 @@ class HeapManager final { private: STATIC Boolean s_PoolsAreEnabled; - STATIC Array, kPoolMaxSz> s_Pool; + STATIC Array, kUserHeapMaxSz> s_Pool; }; //! declare fields @@ -53,7 +53,7 @@ class HeapManager final { SizeT HeapManager::s_NumPools = 0UL; Ref HeapManager::s_Pmm; Boolean HeapManager::s_PoolsAreEnabled = true; -Array, kPoolMaxSz> HeapManager::s_Pool; +Array, kUserHeapMaxSz> HeapManager::s_Pool; STATIC VoidPtr ke_find_unused_heap(Int flags); STATIC Void ke_free_heap_internal(VoidPtr vaddr); @@ -61,9 +61,9 @@ STATIC VoidPtr ke_make_heap(VoidPtr vaddr, Int flags); STATIC Boolean ke_check_and_free_heap(const SizeT& index, VoidPtr ptr); STATIC VoidPtr ke_find_unused_heap(Int flags) { - for (SizeT index = 0; index < kPoolMaxSz; ++index) { + for (SizeT index = 0; index < kUserHeapMaxSz; ++index) { if (HeapManager::The()[index] && - !HeapManager::The()[index].Leak().Leak().Leak()->Present()) { + !HeapManager::The()[index].Leak().Leak().Leak().Present()) { HeapManager::Leak().Leak().TogglePresent( HeapManager::The()[index].Leak().Leak(), true); kcout << "[ke_find_unused_heap] Done, trying now to make a pool\r\n"; @@ -72,7 +72,7 @@ STATIC VoidPtr ke_find_unused_heap(Int flags) { .Leak() .Leak() .Leak() - ->VirtualAddress(), + .VirtualAddress(), flags); } } @@ -90,7 +90,7 @@ STATIC VoidPtr ke_make_heap(VoidPtr virtualAddress, Int flags) { } poolHdr->fFlags = flags; - poolHdr->fMagic = kPoolMag; + poolHdr->fMagic = kUserHeapMag; poolHdr->fFree = false; kcout << "[ke_make_heap] New allocation has been done.\n"; @@ -106,7 +106,7 @@ STATIC Void ke_free_heap_internal(VoidPtr virtualAddress) { HeapHeader* poolHdr = reinterpret_cast( reinterpret_cast(virtualAddress) - sizeof(HeapHeader)); - if (poolHdr->fMagic == kPoolMag) { + if (poolHdr->fMagic == kUserHeapMag) { poolHdr->fFree = false; poolHdr->fFlags = 0; @@ -126,7 +126,7 @@ STATIC Boolean ke_check_and_free_heap(const SizeT& index, VoidPtr ptr) { // ErrorOr<>::operator Boolean /// if (address matches) /// -> Free heap. - if (HeapManager::The()[index].Leak().Leak().Leak()->VirtualAddress() == + if (HeapManager::The()[index].Leak().Leak().Leak().VirtualAddress() == (UIntPtr)ptr) { HeapManager::Leak().Leak().FreePage( HeapManager::The()[index].Leak().Leak()); @@ -149,13 +149,13 @@ STATIC Boolean ke_check_and_free_heap(const SizeT& index, VoidPtr ptr) { VoidPtr rt_new_heap(Int32 flags) { if (!HeapManager::IsEnabled()) return nullptr; - if (HeapManager::Count() > kPoolMaxSz) return nullptr; + if (HeapManager::Count() > kUserHeapMaxSz) return nullptr; if (VoidPtr ret = ke_find_unused_heap(flags)) return ret; // this wasn't set to true - auto ref_page = HeapManager::Leak().Leak().RequestPage(((flags & kPoolUser)), - (flags & kPoolRw)); + auto ref_page = HeapManager::Leak().Leak().RequestPage(((flags & kUserHeapUser)), + (flags & kUserHeapRw)); if (ref_page) { ///! reserve page. @@ -166,7 +166,7 @@ VoidPtr rt_new_heap(Int32 flags) { // finally make the pool address. return ke_make_heap( - reinterpret_cast(ref_page.Leak()->VirtualAddress()), flags); + reinterpret_cast(ref_page.Leak().VirtualAddress()), flags); } return nullptr; @@ -183,7 +183,7 @@ Int32 rt_free_heap(VoidPtr ptr) { if (ke_check_and_free_heap(base, ptr)) return 0; - for (SizeT index = 0; index < kPoolMaxSz; ++index) { + for (SizeT index = 0; index < kUserHeapMaxSz; ++index) { if (ke_check_and_free_heap(index, ptr)) return 0; --base; -- cgit v1.2.3