summaryrefslogtreecommitdiffhomepage
path: root/dev/zka/src/BitMapMgr.cc
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-10-21 20:23:36 +0200
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-10-21 20:23:36 +0200
commitd48cbe75ef29a9c67c9d176bf58e56ea6448fb9e (patch)
tree89cbd6b7e23802f92bf3158868f4dc33c088e516 /dev/zka/src/BitMapMgr.cc
parent21b3da78f806d6765f9dffa6a84c21346f171cee (diff)
IMP: Major refactor of header and source files extensions.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/zka/src/BitMapMgr.cc')
-rw-r--r--dev/zka/src/BitMapMgr.cc203
1 files changed, 203 insertions, 0 deletions
diff --git a/dev/zka/src/BitMapMgr.cc b/dev/zka/src/BitMapMgr.cc
new file mode 100644
index 00000000..e97c9bfa
--- /dev/null
+++ b/dev/zka/src/BitMapMgr.cc
@@ -0,0 +1,203 @@
+/* -------------------------------------------
+
+ Copyright ZKA Web Services Co.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+
+#define kBitMapMagic (0x10210)
+
+#ifdef __ZKA_AMD64__
+#include <HALKit/AMD64/Paging.h>
+#elif defined(__ZKA_ARM64__)
+#include <HALKit/ARM64/Paging.h>
+#endif
+
+#include <NewKit/Defines.h>
+#include <NewKit/Stop.h>
+
+#define cBitMapMagIdx (0)
+#define cBitMapSizeIdx (1)
+#define cBitMapUsedIdx (2)
+
+namespace Kernel
+{
+ namespace HAL
+ {
+ namespace Detail
+ {
+ /// \brief Proxy Interface to allocate a bitmap.
+ class IBitMapAllocator final
+ {
+ public:
+ explicit IBitMapAllocator() = default;
+ ~IBitMapAllocator() = default;
+
+ ZKA_COPY_DELETE(IBitMapAllocator);
+
+ auto IsBitMap(VoidPtr page_ptr) -> Bool
+ {
+ if (!page_ptr)
+ return No;
+
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr);
+
+ if (!ptr_bit_set[cBitMapMagIdx] ||
+ ptr_bit_set[cBitMapMagIdx] != kBitMapMagic)
+ return No;
+
+ return Yes;
+ }
+
+ auto FreeBitMap(VoidPtr page_ptr) -> Bool
+ {
+ if (this->IsBitMap(page_ptr) == No)
+ return No;
+
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr);
+
+ ptr_bit_set[cBitMapMagIdx] = kBitMapMagic;
+ ptr_bit_set[cBitMapUsedIdx] = No;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ mm_map_page(ptr_bit_set, ~eFlagsPresent);
+ mm_map_page(ptr_bit_set, ~eFlagsWr);
+ mm_map_page(ptr_bit_set, ~eFlagsUser);
+
+ return Yes;
+ }
+
+ UInt32 MakeFlags(Bool wr, Bool user)
+ {
+
+ UInt32 flags = eFlagsPresent;
+
+ if (wr)
+ flags |= eFlagsWr;
+
+ if (user)
+ flags |= eFlagsUser;
+
+ return flags;
+ }
+
+ /// @brief Iterate over availables pages for a free one.
+ /// @return The new address which was found.
+ auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user) -> VoidPtr
+ {
+ VoidPtr base = reinterpret_cast<VoidPtr>(((UIntPtr)base_ptr) + kPageSize);
+
+ while (base && size)
+ {
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base);
+
+ if (ptr_bit_set[cBitMapMagIdx] == kBitMapMagic &&
+ ptr_bit_set[cBitMapSizeIdx] <= size)
+ {
+ if (ptr_bit_set[cBitMapUsedIdx] == No)
+ {
+ ptr_bit_set[cBitMapSizeIdx] = size;
+ ptr_bit_set[cBitMapUsedIdx] = Yes;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ UInt32 flags = this->MakeFlags(wr, user);
+ mm_map_page(ptr_bit_set, flags);
+
+ return (VoidPtr)ptr_bit_set;
+ }
+ }
+ else if (ptr_bit_set[cBitMapMagIdx] != kBitMapMagic)
+ {
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base_ptr);
+
+ ptr_bit_set[cBitMapMagIdx] = kBitMapMagic;
+ ptr_bit_set[cBitMapSizeIdx] = size;
+ ptr_bit_set[cBitMapUsedIdx] = Yes;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ UInt32 flags = this->MakeFlags(wr, user);
+ mm_map_page(ptr_bit_set, flags);
+
+ return (VoidPtr)ptr_bit_set;
+ }
+
+ base = reinterpret_cast<VoidPtr>(reinterpret_cast<UIntPtr>(base_ptr) + (ptr_bit_set[0] != kBitMapMagic ? size : ptr_bit_set[1]));
+
+ if ((UIntPtr)base_ptr < (reinterpret_cast<UIntPtr>(base) + kHandoverHeader->f_BitMapSize))
+ return nullptr;
+ }
+
+ return nullptr;
+ }
+
+ /// @brief Print Bitmap status
+ auto GetBitMapStatus(UIntPtr* ptr_bit_set) -> Void
+ {
+ if (!this->IsBitMap(ptr_bit_set))
+ {
+ kcout << "Not a BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl;
+ return;
+ }
+
+ kcout << "Magic Number: " << hex_number(ptr_bit_set[cBitMapMagIdx]) << endl;
+ kcout << "Is Allocated: " << (ptr_bit_set[cBitMapUsedIdx] ? "Yes" : "No") << endl;
+ kcout << "Size of BitMap (B): " << number(ptr_bit_set[cBitMapSizeIdx]) << endl;
+ kcout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[cBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[cBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[cBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[cBitMapSizeIdx])) << endl;
+ kcout << "Address Of BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl;
+ }
+ };
+ } // namespace Detail
+
+ /// @brief Allocate a new page to be used by the OS.
+ /// @param wr read/write bit.
+ /// @param user user bit.
+ /// @return a new bitmap allocated pointer.
+ auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr
+ {
+ VoidPtr ptr_new = nullptr;
+ Detail::IBitMapAllocator traits;
+
+ ptr_new = traits.FindBitMap(kKernelBitMpStart, size, wr, user);
+
+ if (!ptr_new)
+ {
+ return nullptr;
+ }
+
+ if (wr)
+ mm_map_page(ptr_new, eFlagsWr | eFlagsPresent);
+ else if (user && wr)
+ mm_map_page(ptr_new, eFlagsUser | eFlagsWr | eFlagsPresent);
+ else if (user)
+ mm_map_page(ptr_new, eFlagsUser | eFlagsPresent);
+ else
+ mm_map_page(ptr_new, eFlagsPresent);
+
+ return (UIntPtr*)ptr_new;
+ }
+
+ /// @brief Free Bitmap, and mark it a absent in page terms.
+ auto mm_free_bitmap(VoidPtr page_ptr) -> Bool
+ {
+ if (!page_ptr)
+ return No;
+
+ Detail::IBitMapAllocator traits;
+ Bool ret = traits.FreeBitMap(page_ptr);
+
+ if (ret)
+ {
+ mm_map_page(page_ptr, ~eFlagsPresent);
+ }
+
+ return ret;
+ }
+ } // namespace HAL
+} // namespace Kernel