summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit/ARM64/HalPagingMgr.cc
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-08-16 19:56:21 +0200
committerGitHub <noreply@github.com>2025-08-16 19:56:21 +0200
commit1a32b9307357ac0fc9095e853b2b6d94f9fe62bb (patch)
treef41f723659c8926e38182fbe062746d821ab487e /dev/kernel/HALKit/ARM64/HalPagingMgr.cc
parenteb9df5eea339812513c25a8d3b2eeb03c633e7ac (diff)
parentb301047903b79560dce69085fc271a653a1eb4b6 (diff)
Merge pull request #55 from nekernel-org/dev
v0.0.4
Diffstat (limited to 'dev/kernel/HALKit/ARM64/HalPagingMgr.cc')
-rw-r--r--dev/kernel/HALKit/ARM64/HalPagingMgr.cc66
1 files changed, 62 insertions, 4 deletions
diff --git a/dev/kernel/HALKit/ARM64/HalPagingMgr.cc b/dev/kernel/HALKit/ARM64/HalPagingMgr.cc
index faad6778..b7b0c10e 100644
--- a/dev/kernel/HALKit/ARM64/HalPagingMgr.cc
+++ b/dev/kernel/HALKit/ARM64/HalPagingMgr.cc
@@ -13,16 +13,74 @@
namespace Kernel::HAL {
typedef UInt32 PageTableIndex;
+EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address) {
+ if (!virtual_address) return 0;
+
+ UInt64 ttbr0_val = 0;
+
+ asm volatile("mrs %0, ttbr0_el1" : "=r"(ttbr0_val));
+ volatile UInt64* l1_table = reinterpret_cast<volatile UInt64*>(ttbr0_val);
+
+ UInt64 l1_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 39) & 0x1FF;
+ UInt64 l2_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 30) & 0x1FF;
+ UInt64 l3_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 21) & 0x1FF;
+
+ if (!l1_table[l1_idx]) return 0;
+
+ volatile UInt64* l2_table = reinterpret_cast<volatile UInt64*>(l1_table[l1_idx] & ~0xFFFUL);
+
+ if (!l2_table[l2_idx]) return 0;
+
+ volatile UInt64* l3_table = reinterpret_cast<volatile UInt64*>(l2_table[l2_idx] & ~0xFFFUL);
+
+ if (!l3_table[l3_idx]) return 0;
+
+ return (l3_table[l3_idx] & ~0xFFFUL);
+}
+
/// @brief Maps or allocates a page from virtual_address.
/// @param virtual_address a valid virtual address.
/// @param phys_addr point to physical address.
/// @param flags the flags to put on the page.
/// @return Status code of page manipulation process.
-EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags) {
- if (!virtual_address || !flags) return kErrorInvalidData;
+EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags,
+ UInt32 level) {
+ if (!virtual_address || !flags || !physical_address) return kErrorInvalidData;
+
+ UInt64 ttbr0_val = 0;
+
+ asm volatile("mrs %0, ttbr0_el1" : "=r"(ttbr0_val));
+ volatile UInt64* l1_table = reinterpret_cast<volatile UInt64*>(ttbr0_val);
+
+ UInt64 l1_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 39) & 0x1FF;
+ UInt64 l2_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 30) & 0x1FF;
+ UInt64 l3_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 21) & 0x1FF;
+
+ if (!l1_table[l1_idx]) return kErrorInvalidData;
+
+ volatile UInt64* l2_table = reinterpret_cast<volatile UInt64*>(l1_table[l1_idx] & ~0xFFFUL);
+
+ if (!l2_table[l2_idx]) return kErrorInvalidData;
+
+ volatile UInt64* l3_table = reinterpret_cast<volatile UInt64*>(l2_table[l2_idx] & ~0xFFFUL);
+
+ l3_table[l3_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags;
- NE_UNUSED(physical_address);
+ switch (level) {
+ case 2: {
+ l3_table[l3_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags;
+ return kErrorSuccess;
+ }
+ case 1: {
+ l1_table[l1_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags;
+ return kErrorSuccess;
+ }
+ case 0: {
+ l1_table[l1_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags;
+ return kErrorSuccess;
+ }
+ }
- return kErrorSuccess;
+ return kErrorInvalidData;
}
} // namespace Kernel::HAL