summaryrefslogtreecommitdiffhomepage
path: root/src/kernel/HALKit/ARM64
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-11-23 21:06:27 -0500
committerGitHub <noreply@github.com>2025-11-23 21:06:27 -0500
commit23040fad647634c08697451fc22ee2ca999629c8 (patch)
tree72888f88c7728c82f3f6df1f4f70591de15eab36 /src/kernel/HALKit/ARM64
parente5cc7351f0577b54c528fb827a7c7e6306c3e843 (diff)
parent83d870e58457a1d335a1d9b9966a6a1887cc297b (diff)
Merge pull request #81 from nekernel-org/dev
feat! breaking changes on kernel sources.
Diffstat (limited to 'src/kernel/HALKit/ARM64')
-rw-r--r--src/kernel/HALKit/ARM64/APM/APM+IO.cc35
-rw-r--r--src/kernel/HALKit/ARM64/ApplicationProcessor.h19
-rw-r--r--src/kernel/HALKit/ARM64/CxxAbi.cc87
-rw-r--r--src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc26
-rw-r--r--src/kernel/HALKit/ARM64/HalApplicationProcessor.cc140
-rw-r--r--src/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s12
-rw-r--r--src/kernel/HALKit/ARM64/HalCommonAPI.s9
-rw-r--r--src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc159
-rw-r--r--src/kernel/HALKit/ARM64/HalDebugOutput.cc71
-rw-r--r--src/kernel/HALKit/ARM64/HalHandoverStub.s19
-rw-r--r--src/kernel/HALKit/ARM64/HalInterruptAPI.s3
-rw-r--r--src/kernel/HALKit/ARM64/HalKernelMain.cc63
-rw-r--r--src/kernel/HALKit/ARM64/HalKernelPanic.cc54
-rw-r--r--src/kernel/HALKit/ARM64/HalPagingMgr.cc86
-rw-r--r--src/kernel/HALKit/ARM64/HalSchedulerCore.cc21
-rw-r--r--src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc30
-rw-r--r--src/kernel/HALKit/ARM64/HalTimer.cc15
-rw-r--r--src/kernel/HALKit/ARM64/Paging.h107
-rw-r--r--src/kernel/HALKit/ARM64/Processor.h78
-rw-r--r--src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc13
-rw-r--r--src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc8
21 files changed, 1055 insertions, 0 deletions
diff --git a/src/kernel/HALKit/ARM64/APM/APM+IO.cc b/src/kernel/HALKit/ARM64/APM/APM+IO.cc
new file mode 100644
index 00000000..c4d0154b
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/APM/APM+IO.cc
@@ -0,0 +1,35 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/KPC.h>
+#include <modules/APM/APM.h>
+
+using namespace Kernel;
+
+/// @brief Send APM command to its IO space.
+/// @param base_dma the IO base port.
+/// @param cmd the command.
+/// @return status code.
+EXTERN_C Int32 apm_send_io_command(UInt16 cmd) {
+ switch (cmd) {
+ case kAPMPowerCommandReboot: {
+ asm volatile(
+ "ldr x0, =0x84000004\n"
+ "svc #0\n");
+
+ return kErrorSuccess;
+ }
+ case kAPMPowerCommandShutdown: {
+ asm volatile(
+ "ldr x0, =0x84000008\n"
+ "svc #0\n");
+
+ return kErrorSuccess;
+ }
+ default:
+ return kErrorInvalidData;
+ }
+}
diff --git a/src/kernel/HALKit/ARM64/ApplicationProcessor.h b/src/kernel/HALKit/ARM64/ApplicationProcessor.h
new file mode 100644
index 00000000..208bf82e
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/ApplicationProcessor.h
@@ -0,0 +1,19 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#include <HALKit/ARM64/Processor.h>
+#include <NeKit/Defines.h>
+
+/************************************************** */
+/* INITIALIZE THE GIC ON THE CURRENT CORE. */
+/* WITH AN EXECUTION LEVEL IN MIND. */
+/************************************************** */
+
+namespace Kernel {
+Void mp_init_cores(Void) noexcept;
+} \ No newline at end of file
diff --git a/src/kernel/HALKit/ARM64/CxxAbi.cc b/src/kernel/HALKit/ARM64/CxxAbi.cc
new file mode 100644
index 00000000..7b4eca20
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/CxxAbi.cc
@@ -0,0 +1,87 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#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/src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc b/src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc
new file mode 100644
index 00000000..9a8661cd
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc
@@ -0,0 +1,26 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/HeapMgr.h>
+#include <NeKit/KString.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+#include <modules/APM/APM.h>
+
+namespace Kernel {
+ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) : fRsdp(rsp_ptr), fEntries(0) {}
+
+BOOL ACPIFactoryInterface::Shutdown() {
+ apm_send_io_command(kAPMPowerCommandShutdown);
+ return NO;
+}
+
+/// @brief Reboot machine in either ACPI or by triple faulting.
+/// @return nothing it's a reboot.
+Void ACPIFactoryInterface::Reboot() {
+ apm_send_io_command(kAPMPowerCommandReboot);
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/src/kernel/HALKit/ARM64/HalApplicationProcessor.cc
new file mode 100644
index 00000000..2a3c73e5
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalApplicationProcessor.cc
@@ -0,0 +1,140 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#define GICD_BASE 0x08000000
+#define GICC_BASE 0x08010000
+
+#define GICD_CTLR 0x000
+#define GICD_ISENABLER 0x100
+#define GICD_ICENABLER 0x180
+#define GICD_ISPENDR 0x200
+#define GICD_ICPENDR 0x280
+#define GICD_IPRIORITYR 0x400
+#define GICD_ITARGETSR 0x800
+#define GICD_ICFGR 0xC00
+
+#define GICC_CTLR 0x000
+#define GICC_PMR 0x004
+#define GICC_IAR 0x00C
+#define GICC_EOIR 0x010
+
+#include <HALKit/ARM64/ApplicationProcessor.h>
+#include <HALKit/ARM64/Processor.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/Timer.h>
+
+// ================================================================= //
+
+namespace Kernel {
+struct HAL_HARDWARE_THREAD final {
+ HAL::StackFramePtr mFramePtr;
+ ProcessID mThreadID{0};
+};
+
+STATIC HAL_HARDWARE_THREAD kHWThread[kMaxAPInsideSched] = {{nullptr}};
+
+namespace Detail {
+ STATIC BOOL kGICEnabled = NO;
+
+ /***********************************************************************************/
+ /// @brief Enables the GIC with EL0 configuration.
+ /// @internal
+ /***********************************************************************************/
+ STATIC Void mp_setup_gic_el0(Void) {
+ ke_dma_write<UInt32>(GICD_BASE, GICD_CTLR, YES);
+
+ UInt32 gicc_ctlr = ke_dma_read<UInt32>(GICC_BASE, GICC_CTLR);
+
+ const UInt8 kEnableSignalInt = 0x1;
+
+ gicc_ctlr |= kEnableSignalInt;
+ gicc_ctlr |= (kEnableSignalInt << 0x1);
+
+ ke_dma_write<UInt32>(GICC_BASE, GICC_CTLR, gicc_ctlr);
+
+ ke_dma_write<UInt32>(GICC_BASE, GICC_PMR, 0xFF);
+
+ UInt32 icfgr = ke_dma_read<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4);
+
+ icfgr |= (0x2 << ((32 % 16) * 2));
+
+ ke_dma_write<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr);
+ ke_dma_write<UInt32>(GICD_BASE, GICD_ITARGETSR + (0x20 / 0x04) * 4, 0x2 << ((32 % 4) * 8));
+ ke_dma_write<UInt32>(GICD_BASE, GICD_IPRIORITYR + (0x20 / 0x04) * 4, 0xFF << ((32 % 4) * 8));
+ ke_dma_write<UInt32>(GICD_BASE, GICD_ISENABLER + 4, 0x01);
+ }
+
+ EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void) {
+ UInt32 interrupt_id = ke_dma_read<UInt32>(GICC_BASE, GICC_IAR);
+
+ if ((interrupt_id & 0x3FF) < 1020) {
+ auto interrupt = interrupt_id & 0x3FF;
+
+ const UInt16 kInterruptScheduler = 0x20;
+
+ (Void)(kout << "SMP: AP: " << hex_number(interrupt) << kendl);
+
+ switch (interrupt) {
+ case kInterruptScheduler: {
+ ke_dma_write<UInt32>(GICC_BASE, GICC_EOIR, interrupt_id);
+ UserProcessHelper::StartScheduling();
+ break;
+ }
+ default: {
+ ke_dma_write<UInt32>(GICC_BASE, GICC_EOIR, interrupt_id);
+ break;
+ }
+ }
+
+ return YES;
+ }
+
+ return NO;
+ }
+} // namespace Detail
+
+/***********************************************************************************/
+/// @brief Get current stack frame for a thread.
+/// @param thrdid The thread ID.
+/***********************************************************************************/
+
+EXTERN_C HAL::StackFramePtr mp_get_current_task(ProcessID thrdid) {
+ return kHWThread[thrdid].mFramePtr;
+}
+
+/***********************************************************************************/
+/// @brief Register current stack frame for a thread.
+/// @param stack_frame The current stack frame.
+/// @param thrdid The thread ID.
+/***********************************************************************************/
+
+EXTERN_C Bool mp_register_task(HAL::StackFramePtr stack_frame, ProcessID thrdid) {
+ MUST_PASS(Detail::kGICEnabled);
+
+ if (!stack_frame) return NO;
+ if (thrdid > kMaxAPInsideSched) return NO;
+
+ const auto process_index = thrdid;
+
+ kHWThread[process_index].mFramePtr = stack_frame;
+ kHWThread[process_index].mThreadID = thrdid;
+
+ return YES;
+}
+
+/***********************************************************************************/
+/// @brief Initialize the Global Interrupt Controller.
+/// @internal
+/***********************************************************************************/
+Void mp_init_cores(Void) noexcept {
+ if (!Detail::kGICEnabled) {
+ Detail::kGICEnabled = YES;
+ Detail::mp_setup_gic_el0();
+ }
+}
+} // namespace Kernel \ No newline at end of file
diff --git a/src/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s b/src/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s
new file mode 100644
index 00000000..dca52571
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s
@@ -0,0 +1,12 @@
+.text
+
+.global hal_ap_blob_start
+.global hal_ap_blob_length
+
+hal_ap_blob_start:
+ ret
+
+.data
+
+hal_ap_blob_length:
+ .long 4
diff --git a/src/kernel/HALKit/ARM64/HalCommonAPI.s b/src/kernel/HALKit/ARM64/HalCommonAPI.s
new file mode 100644
index 00000000..f0c69368
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalCommonAPI.s
@@ -0,0 +1,9 @@
+/* (c) 2024-2025 Amlal El Mahrouss */
+
+.text
+
+.global hal_flush_tlb
+
+hal_flush_tlb:
+ tlbi vmalle1
+ ret
diff --git a/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc
new file mode 100644
index 00000000..b89f68bd
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc
@@ -0,0 +1,159 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <KernelKit/UserMgr.h>
+#include <NeKit/KString.h>
+#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 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;
+ kEndOfInterruptVector = vector;
+}
+
+/// @brief Handle GPF fault.
+/// @param rsp
+EXTERN_C Kernel::Void int_handle_gpf(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_int_send_eoi(13);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Handle page fault.
+/// @param rsp
+EXTERN_C void int_handle_pf(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_int_send_eoi(14);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Handle scheduler interrupt.
+EXTERN_C void int_handle_scheduler(Kernel::UIntPtr rsp) {
+ NE_UNUSED(rsp);
+
+ hal_int_send_eoi(32);
+
+ while (kIsRunning)
+ ;
+
+ kIsRunning = YES;
+
+ mp_handle_gic_interrupt_el0();
+
+ kIsRunning = NO;
+}
+
+/// @brief Handle math fault.
+/// @param rsp
+EXTERN_C void int_handle_math(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_int_send_eoi(8);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Handle any generic fault.
+/// @param rsp
+EXTERN_C void int_handle_generic(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_int_send_eoi(30);
+
+ Kernel::kout << "Kernel: Generic Process Fault.\r";
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+
+ Kernel::kout << "Kernel: SIGKILL status.\r";
+}
+
+EXTERN_C Kernel::Void int_handle_breakpoint(Kernel::UIntPtr rip) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+
+ hal_int_send_eoi(3);
+
+ process.Leak().Signal.SignalArg = rip;
+ process.Leak().Signal.SignalID = SIGTRAP;
+
+ process.Leak().Signal.Status = process.Leak().Status;
+
+ process.Leak().Status = Kernel::ProcessStatusKind::kFrozen;
+}
+
+/// @brief Handle #UD fault.
+/// @param rsp
+EXTERN_C void int_handle_ud(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_int_send_eoi(6);
+
+ process.Leak().Signal.SignalArg = rsp;
+ process.Leak().Signal.SignalID = SIGKILL;
+ process.Leak().Signal.Status = process.Leak().Status;
+}
+
+/// @brief Enter syscall from assembly (libSystem only)
+/// @param stack the stack pushed from assembly routine.
+/// @return nothing.
+EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_hash,
+ Kernel::UIntPtr rdx_syscall_arg) {
+ hal_int_send_eoi(50);
+
+ if (!Kernel::kCurrentUser) return;
+
+ for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) {
+ if (kSysCalls[i].fHooked && rcx_hash == kSysCalls[i].fHash) {
+ if (kSysCalls[i].fProc) {
+ (kSysCalls[i].fProc)((Kernel::VoidPtr) rdx_syscall_arg);
+ }
+ }
+ }
+}
+
+/// @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::SizeT cnt,
+ Kernel::UIntPtr arg, Kernel::SizeT sz) {
+ if (!Kernel::kRootUser) return;
+ if (Kernel::kCurrentUser != Kernel::kRootUser) return;
+ if (!Kernel::kCurrentUser->IsSuperUser()) return;
+
+ for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) {
+ if (kKernCalls[i].fHooked && rcx_hash == kKernCalls[rcx_hash].fHash) {
+ if (kKernCalls[i].fProc) {
+ (kKernCalls[i].fProc)(cnt, (Kernel::VoidPtr) arg, sz);
+ }
+ }
+ }
+}
diff --git a/src/kernel/HALKit/ARM64/HalDebugOutput.cc b/src/kernel/HALKit/ARM64/HalDebugOutput.cc
new file mode 100644
index 00000000..c0da9c3a
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalDebugOutput.cc
@@ -0,0 +1,71 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <NeKit/New.h>
+#include <NeKit/Utils.h>
+
+namespace Kernel {
+EXTERN_C void ke_io_write(DeviceInterface<const Char*>* self, const Char* bytes) {
+#ifdef __DEBUG__
+ if (*bytes == 0) return;
+
+ SizeT index = 0;
+ SizeT len = 0;
+
+ index = 0;
+ len = rt_string_len(bytes, 256U);
+
+ volatile UInt8* uart_ptr = (UInt8*) 0x09000000;
+
+ while (index < len) {
+ if (bytes[index] == '\r') *uart_ptr = '\r';
+
+ *uart_ptr = bytes[index] == '\r' ? '\n' : bytes[index];
+ ++index;
+ }
+#endif // __DEBUG__
+}
+
+TerminalDevice::~TerminalDevice() = default;
+
+EXTERN_C void ke_io_read(DeviceInterface<const Char*>* self, const Char* bytes) {
+#ifdef __DEBUG__
+ SizeT index = 0;
+
+ volatile UInt8* uart_ptr = (UInt8*) 0x09000000;
+
+ ///! TODO: Look on how to wait for the UART to complete.
+ while (Yes) {
+ auto in = *uart_ptr;
+
+ ///! If enter pressed then break.
+ if (in == 0xD) {
+ break;
+ }
+
+ if (in < '0' || in < 'A' || in < 'a') {
+ if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || in != ':') {
+ continue;
+ }
+ }
+
+ ((char*) bytes)[index] = in;
+
+ ++index;
+ }
+
+ ((char*) bytes)[index] = 0;
+#endif // __DEBUG__
+}
+
+TerminalDevice TerminalDevice::The() noexcept {
+ TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read);
+ return out;
+}
+
+} // namespace Kernel
diff --git a/src/kernel/HALKit/ARM64/HalHandoverStub.s b/src/kernel/HALKit/ARM64/HalHandoverStub.s
new file mode 100644
index 00000000..5d5647c4
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalHandoverStub.s
@@ -0,0 +1,19 @@
+;; /*
+;; * ========================================================
+;; *
+;; * NeKernel
+;; * Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+;; *
+;; * ========================================================
+;; */
+
+.section .ldr
+
+ ;; // MAGIC
+.quad 0xDAB4
+ ;; // VERSION (1.0.0)
+.word 100
+ ;; // CPU (ARM64)
+.word 0
+ ;; // TYPE (KERNEL)
+.word 122
diff --git a/src/kernel/HALKit/ARM64/HalInterruptAPI.s b/src/kernel/HALKit/ARM64/HalInterruptAPI.s
new file mode 100644
index 00000000..cafebb7d
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalInterruptAPI.s
@@ -0,0 +1,3 @@
+/* (c) 2024-2025 Amlal El Mahrouss */
+
+.text
diff --git a/src/kernel/HALKit/ARM64/HalKernelMain.cc b/src/kernel/HALKit/ARM64/HalKernelMain.cc
new file mode 100644
index 00000000..e36535c3
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalKernelMain.cc
@@ -0,0 +1,63 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <CFKit/Property.h>
+#include <FirmwareKit/Handover.h>
+#include <HALKit/ARM64/ApplicationProcessor.h>
+#include <HALKit/ARM64/Processor.h>
+#include <KernelKit/CodeMgr.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/HeapMgr.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/Json.h>
+#include <NetworkKit/IPC.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+#include <modules/CoreGfx/CoreGfx.h>
+
+#ifndef __NE_MODULAR_KERNEL_COMPONENTS__
+EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
+ using namespace Kernel;
+
+ /************************************************** */
+ /* INITIALIZE AND VALIDATE HEADER. */
+ /************************************************** */
+
+ kHandoverHeader = handover_hdr;
+
+ if (kHandoverHeader->f_Magic != kHandoverMagic &&
+ kHandoverHeader->f_Version != kHandoverVersion) {
+ return;
+ }
+
+#ifdef __NE_ARM64_EFI__
+ fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]);
+
+ Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey,
+ handover_hdr->f_HardwareTables.f_ImageHandle);
+#endif
+
+ FB::cg_clear_video();
+
+ /************************************** */
+ /* INITIALIZE BIT MAP. */
+ /************************************** */
+
+ kBitMapCursor = 0UL;
+ kKernelBitMpSize = kHandoverHeader->f_BitMapSize;
+ kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>(
+ reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart));
+
+ /// @note do initialize the interrupts after it.
+
+ Kernel::mp_init_cores();
+
+ while (YES)
+ ;
+}
+#endif
diff --git a/src/kernel/HALKit/ARM64/HalKernelPanic.cc b/src/kernel/HALKit/ARM64/HalKernelPanic.cc
new file mode 100644
index 00000000..6837ba1c
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalKernelPanic.cc
@@ -0,0 +1,54 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/Timer.h>
+#include <NeKit/KString.h>
+#include <NeKit/KernelPanic.h>
+#include <NeKit/Utils.h>
+#include <modules/CoreGfx/CoreGfx.h>
+#include <modules/CoreGfx/TextGfx.h>
+
+/* Each error code is attributed with an ID, which will prompt a string onto the
+ * screen. Wait for debugger... */
+
+namespace Kernel {
+/// @brief Dumping factory class.
+class RecoveryFactory final {
+ public:
+ STATIC Void Recover() noexcept;
+};
+
+/***********************************************************************************/
+/// @brief Stops execution of the kernel.
+/// @param id kernel stop ID.
+/***********************************************************************************/
+Void ke_panic(const Kernel::Int32& id, const Char* message) {
+ (Void)(kout << "*** STOP ***\r");
+ (Void)(kout << "Kernel_Panic_MSG: " << message << kendl);
+ (Void)(kout << "Kernel_Panic_ID: " << hex_number(id) << kendl);
+
+ RecoveryFactory::Recover();
+}
+
+Void RecoveryFactory::Recover() noexcept {
+ while (YES) {
+ HAL::rt_halt();
+ }
+}
+
+void ke_runtime_check(bool expr, const Char* file, const Char* line) {
+ if (!expr) {
+ (Void)(kout << "Kernel_Panic_FILE: " << file << kendl);
+ (Void)(kout << "Kernel_Panic_LINE: " << line << kendl);
+
+ ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed
+ }
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/ARM64/HalPagingMgr.cc b/src/kernel/HALKit/ARM64/HalPagingMgr.cc
new file mode 100644
index 00000000..d597ccce
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalPagingMgr.cc
@@ -0,0 +1,86 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: HalPagingMgr.cc
+ Purpose: Platform Paging Manager.
+
+======================================== */
+
+#include <HALKit/ARM64/Paging.h>
+#include <HALKit/ARM64/Processor.h>
+
+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,
+ 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;
+
+ 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 kErrorInvalidData;
+}
+} // namespace Kernel::HAL
diff --git a/src/kernel/HALKit/ARM64/HalSchedulerCore.cc b/src/kernel/HALKit/ARM64/HalSchedulerCore.cc
new file mode 100644
index 00000000..467547b0
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalSchedulerCore.cc
@@ -0,0 +1,21 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <KernelKit/ProcessScheduler.h>
+
+namespace Kernel {
+/// @brief Wakes up thread.
+/// Wakes up thread from the hang state.
+Void mp_wakeup_thread(HAL::StackFrame* stack) {
+ NE_UNUSED(stack);
+}
+
+/// @brief makes the thread sleep on a loop.
+/// hooks and hangs thread to prevent code from executing.
+Void mp_hang_thread(HAL::StackFrame* stack) {
+ NE_UNUSED(stack);
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc b/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc
new file mode 100644
index 00000000..b1728bac
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc
@@ -0,0 +1,30 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <HALKit/ARM64/Processor.h>
+#include <KernelKit/ProcessScheduler.h>
+
+namespace Kernel {
+/***********************************************************************************/
+/// @brief Unimplemented function (crashes by default)
+/// @param process The process handle.
+/***********************************************************************************/
+
+EXTERN_C Void __ne_pure_call(USER_PROCESS* process) {
+ if (process) process->Crash();
+}
+
+/***********************************************************************************/
+/// @brief Validate user stack.
+/// @param stack_ptr the frame pointer.
+/***********************************************************************************/
+
+EXTERN_C Bool hal_check_task(HAL::StackFramePtr stack_ptr) {
+ if (!stack_ptr) return No;
+
+ return stack_ptr->SP != 0 && stack_ptr->IP != 0;
+}
+} // namespace Kernel
diff --git a/src/kernel/HALKit/ARM64/HalTimer.cc b/src/kernel/HALKit/ARM64/HalTimer.cc
new file mode 100644
index 00000000..2f524a1b
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/HalTimer.cc
@@ -0,0 +1,15 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+ File: HalTimer.cc
+ Purpose: HAL timer
+
+ Revision History:
+
+ 07/07/24: Added file (amlel)
+
+======================================== */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Timer.h> \ No newline at end of file
diff --git a/src/kernel/HALKit/ARM64/Paging.h b/src/kernel/HALKit/ARM64/Paging.h
new file mode 100644
index 00000000..766210b3
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/Paging.h
@@ -0,0 +1,107 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+/** ---------------------------------------------------
+
+ * THIS FILE CONTAINS CODE FOR ARMV8 PAGING.
+
+------------======================================== */
+
+#ifdef __NE_ARM64__
+
+#include <NeKit/Defines.h>
+
+#ifndef kPageMax
+#define kPageMax (0x200)
+#endif //! kPageMax
+
+#ifndef kPageAlign
+#define kPageAlign (0x1000)
+#endif //! kPageAlign
+
+#ifndef kPageSize
+#define kPageSize (0x1000)
+#endif // !kPageSize
+
+//! short format address range
+
+#define c16KBPage 0b000
+#define c8KBPage 0b001
+#define c4KBPage 0b010
+#define c2KBPage 0b011
+#define c1KBPage 0b100
+#define c512BPage 0b101
+#define c256BPage 0b110
+#define c128BPage 0b111
+
+/// Long format address range
+
+#define cPageMAll \
+ { 0b000, 0b000 }
+#define cPageMToMax(M) \
+ { M, 0b000 }
+#define cPageMaxToM(M) \
+ { 0b000, M }
+#define cPageMToN(M, N) \
+ { M, N }
+
+namespace Kernel::HAL {
+struct PACKED PTE_4KB final {
+ UInt64 Valid : 1;
+ UInt64 Table : 1;
+ UInt64 AttrIndex : 3;
+ UInt64 NS : 1;
+ UInt64 AP : 2;
+ UInt64 SH : 2;
+ UInt64 AF : 1;
+ UInt64 NG : 1;
+ UInt64 Reserved1 : 1;
+ UInt64 Contiguous : 1;
+ UInt64 Dirty : 1;
+ UInt64 Reserved : 2;
+ UInt64 PhysicalAddress : 36;
+ UInt64 Reserved3 : 4;
+ UInt64 PXN : 1;
+ UInt64 XN : 1;
+ UInt64 Reserved4 : 9;
+};
+
+namespace Detail {
+ enum class ControlRegisterBits {
+ ProtectedModeEnable = 0,
+ MonitorCoProcessor = 1,
+ Emulation = 2,
+ TaskSwitched = 3,
+ ExtensionType = 4,
+ NumericError = 5,
+ WriteProtect = 16,
+ AlignementMask = 18,
+ NotWriteThrough = 29,
+ CacheDisable = 30,
+ PageEnable = 31,
+ };
+
+ 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, SizeT pad = 0) -> VoidPtr;
+auto mm_free_bitmap(VoidPtr page_ptr) -> Bool;
+} // namespace Kernel::HAL
+
+namespace Kernel {
+typedef HAL::PTE_4KB PTE;
+typedef HAL::PDE_4KB PDE;
+} // namespace Kernel
+
+EXTERN_C void hal_flush_tlb();
+
+#endif // __NE_ARM64__ \ No newline at end of file
diff --git a/src/kernel/HALKit/ARM64/Processor.h b/src/kernel/HALKit/ARM64/Processor.h
new file mode 100644
index 00000000..716d317b
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/Processor.h
@@ -0,0 +1,78 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#pragma once
+
+#ifdef __NE_ARM64__
+
+#include <FirmwareKit/Handover.h>
+#include <NeKit/Array.h>
+#include <NeKit/Defines.h>
+#include <NeKit/Utils.h>
+
+#define kCPUBackendName "aarch64"
+
+namespace Kernel::HAL {
+struct PACKED Register64 final {
+ UShort Limit;
+ UIntPtr Base;
+};
+
+/// @brief Memory Manager mapping flags.
+enum {
+ kMMFlagsInvalid = 1 << 0,
+ kMMFlagsPresent = 1 << 1,
+ kMMFlagsWr = 1 << 2,
+ kMMFlagsUser = 1 << 3,
+ kMMFlagsNX = 1 << 4,
+ kMMFlagsCount = 4,
+};
+
+/// @brief Set a PTE from pd_base.
+/// @param virt_addr 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 manip.
+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);
+
+typedef UIntPtr Reg;
+typedef Register64 Register;
+
+/// @note let's keep the same name as AMD64 HAL.
+struct PACKED StackFrame {
+ Reg IP;
+ Reg SP;
+ Reg R8;
+ Reg R9;
+ Reg R10;
+ Reg R11;
+ Reg R12;
+ Reg R13;
+ Reg R14;
+ Reg R15;
+};
+
+typedef StackFrame* StackFramePtr;
+
+inline Void rt_halt() noexcept {
+ while (Yes) {
+ }
+}
+
+inline Void hal_wfi(Void) {
+ asm volatile("wfi");
+}
+} // namespace Kernel::HAL
+
+inline Kernel::VoidPtr kKernelBitMpStart = nullptr;
+inline Kernel::UIntPtr kKernelBitMpSize = 0UL;
+
+#include <HALKit/ARM64/Paging.h>
+
+#endif // __NE_ARM64__ \ No newline at end of file
diff --git a/src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc b/src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc
new file mode 100644
index 00000000..0200ec5a
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc
@@ -0,0 +1,13 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+#include <modules/SCSI/SCSI.h>
+
+using namespace Kernel;
+
+///! @brief ATAPI SCSI packet.
+const ATTRIBUTE(unused) scsi_packet_type_12 kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0,
+ 0, 12, 0x40, 0, 0};
diff --git a/src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc b/src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc
new file mode 100644
index 00000000..9971b2a8
--- /dev/null
+++ b/src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc
@@ -0,0 +1,8 @@
+/* ========================================
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
+
+======================================== */
+
+/// @file UFS.cc
+/// @brief UFS Flash Memory support.