summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit/ARM64
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
parenteb9df5eea339812513c25a8d3b2eeb03c633e7ac (diff)
parentb301047903b79560dce69085fc271a653a1eb4b6 (diff)
Merge pull request #55 from nekernel-org/dev
v0.0.4
Diffstat (limited to 'dev/kernel/HALKit/ARM64')
-rw-r--r--dev/kernel/HALKit/ARM64/APM/APM+IO.cc2
-rw-r--r--dev/kernel/HALKit/ARM64/CxxAbi.cc87
-rw-r--r--dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc17
-rw-r--r--dev/kernel/HALKit/ARM64/HalKernelMain.cc3
-rw-r--r--dev/kernel/HALKit/ARM64/HalPagingMgr.cc66
-rw-r--r--dev/kernel/HALKit/ARM64/Paging.h6
-rw-r--r--dev/kernel/HALKit/ARM64/Processor.h3
7 files changed, 164 insertions, 20 deletions
diff --git a/dev/kernel/HALKit/ARM64/APM/APM+IO.cc b/dev/kernel/HALKit/ARM64/APM/APM+IO.cc
index e58fb782..17a60515 100644
--- a/dev/kernel/HALKit/ARM64/APM/APM+IO.cc
+++ b/dev/kernel/HALKit/ARM64/APM/APM+IO.cc
@@ -9,7 +9,7 @@
using namespace Kernel;
-/// @brief Send APM command to it's IO space.
+/// @brief Send APM command to its IO space.
/// @param base_dma the IO base port.
/// @param cmd the command.
/// @return status code.
diff --git a/dev/kernel/HALKit/ARM64/CxxAbi.cc b/dev/kernel/HALKit/ARM64/CxxAbi.cc
new file mode 100644
index 00000000..964fc2f4
--- /dev/null
+++ b/dev/kernel/HALKit/ARM64/CxxAbi.cc
@@ -0,0 +1,87 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/KPC.h>
+#include <NeKit/CxxAbi.h>
+
+atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors];
+
+uarch_t __atexit_func_count;
+
+/// @brief dynamic shared object Handle.
+Kernel::UIntPtr __dso_handle;
+
+EXTERN_C void __chkstk(void) {}
+
+EXTERN_C int atexit(void (*f)(), void* arg, void* dso) {
+ if (__atexit_func_count >= kAtExitMacDestructors) return 1;
+
+ __atexit_funcs[__atexit_func_count].destructor_func = f;
+ __atexit_funcs[__atexit_func_count].obj_ptr = arg;
+ __atexit_funcs[__atexit_func_count].dso_handle = dso;
+
+ __atexit_func_count++;
+
+ return 0;
+}
+
+EXTERN_C void __cxa_finalize(void* f) {
+ uarch_t i = __atexit_func_count;
+ if (!f) {
+ while (i--) {
+ if (__atexit_funcs[i].destructor_func) {
+ (*__atexit_funcs[i].destructor_func)();
+ __atexit_funcs[i].destructor_func = 0;
+ };
+ }
+
+ return;
+ }
+
+ while (i--) {
+ if (__atexit_funcs[i].destructor_func) {
+ (*__atexit_funcs[i].destructor_func)();
+ __atexit_funcs[i].destructor_func = 0;
+ };
+ }
+}
+
+namespace cxxabiv1 {
+EXTERN_C int __cxa_guard_acquire(__guard* g) {
+ (void) g;
+ return 0;
+}
+
+EXTERN_C int __cxa_guard_release(__guard* g) {
+ *(char*) g = 1;
+ return 0;
+}
+
+EXTERN_C void __cxa_guard_abort(__guard* g) {
+ (void) g;
+}
+} // namespace cxxabiv1
+
+EXTERN_C Kernel::Void _purecall(void* self) {
+ (Kernel::Void)(Kernel::kout << "object: "
+ << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self)));
+ (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r");
+}
+
+EXTERN_C Kernel::Void _Init_thread_footer(Kernel::Int* thread_obj) {
+ NE_UNUSED(thread_obj);
+}
+
+EXTERN_C Kernel::Void _Init_thread_epoch(Kernel::Void) {
+ NE_UNUSED(0);
+}
+
+EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj) {
+ NE_UNUSED(0);
+}
+
+EXTERN_C Kernel::Int _tls_index = 0UL;
diff --git a/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc b/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc
index 61a82314..63a42de8 100644
--- a/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc
+++ b/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc
@@ -11,16 +11,16 @@
#include <SignalKit/Signals.h>
EXTERN_C Kernel::Void int_handle_breakpoint(Kernel::UIntPtr rip);
- EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void);
+EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void);
-EXTERN_C BOOL kEndOfInterrupt;
+EXTERN_C BOOL kEndOfInterrupt;
EXTERN_C UInt8 kEndOfInterruptVector;
STATIC BOOL kIsRunning = NO;
/// @note This is managed by the system software.
STATIC void hal_int_send_eoi(UInt8 vector) {
- kEndOfInterrupt = YES;
+ kEndOfInterrupt = YES;
kEndOfInterruptVector = vector;
}
@@ -56,8 +56,7 @@ EXTERN_C void int_handle_scheduler(Kernel::UIntPtr rsp) {
hal_int_send_eoi(32);
- while (kIsRunning)
- ;
+ while (kIsRunning);
kIsRunning = YES;
@@ -143,10 +142,8 @@ EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_hash,
/// @brief Enter Kernel call from assembly (libDDK only).
/// @param stack the stack pushed from assembly routine.
/// @return nothing.
-EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash,
- Kernel::UIntPtr rdx_kerncall_arg) {
- hal_int_send_eoi(51);
-
+EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, Kernel::SizeT cnt,
+ Kernel::UIntPtr arg, Kernel::SizeT sz) {
if (!Kernel::kRootUser) return;
if (Kernel::kCurrentUser != Kernel::kRootUser) return;
if (!Kernel::kCurrentUser->IsSuperUser()) return;
@@ -154,7 +151,7 @@ EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash,
for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) {
if (kKernCalls[i].fHooked && rcx_hash == kKernCalls[rcx_hash].fHash) {
if (kKernCalls[i].fProc) {
- (kKernCalls[i].fProc)((Kernel::VoidPtr) rdx_kerncall_arg);
+ (kKernCalls[i].fProc)(cnt, (Kernel::VoidPtr) arg, sz);
}
}
}
diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc
index 20bd3d8a..d8e6843b 100644
--- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc
+++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc
@@ -71,7 +71,6 @@ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
Kernel::mp_init_cores();
- while (YES)
- ;
+ while (YES);
}
#endif \ No newline at end of file
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
diff --git a/dev/kernel/HALKit/ARM64/Paging.h b/dev/kernel/HALKit/ARM64/Paging.h
index 5001871b..be9fb116 100644
--- a/dev/kernel/HALKit/ARM64/Paging.h
+++ b/dev/kernel/HALKit/ARM64/Paging.h
@@ -86,14 +86,16 @@ namespace Detail {
PageEnable = 31,
};
- inline UInt8 control_register_cast(ControlRegisterBits reg) { return static_cast<UInt8>(reg); }
+ inline UInt8 control_register_cast(ControlRegisterBits reg) {
+ return static_cast<UInt8>(reg);
+ }
} // namespace Detail
struct PDE_4KB final {
PTE_4KB ALIGN(kPageAlign) fEntries[kPageMax];
};
-auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr;
+auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad = 0) -> VoidPtr;
auto mm_free_bitmap(VoidPtr page_ptr) -> Bool;
} // namespace Kernel::HAL
diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h
index 068b798d..68fe736c 100644
--- a/dev/kernel/HALKit/ARM64/Processor.h
+++ b/dev/kernel/HALKit/ARM64/Processor.h
@@ -36,7 +36,8 @@ enum {
/// @param phys_addr point to physical address.
/// @param flags the flags to put on the page.
/// @return Status code of page manip.
-EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags);
+EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags,
+ UInt32 level = 2);
EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address);