From f0acad6f3206079d804b2f59aace0dc32dbeb6dc Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 19 Feb 2026 08:14:48 +0100 Subject: kernel: lots of tweaks and improvements, WIP: ASN, FileMgr support for OpenHeFS. Signed-off-by: Amlal El Mahrouss --- src/kernel/HALKit/ARM64/APM/APM+IO.cc | 33 ----- src/kernel/HALKit/ARM64/APM/APM+IO.cpp | 33 +++++ src/kernel/HALKit/ARM64/CxxAbi.cc | 85 ----------- src/kernel/HALKit/ARM64/CxxAbi.cpp | 85 +++++++++++ src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc | 24 ---- .../HALKit/ARM64/HalACPIFactoryInterface.cpp | 24 ++++ src/kernel/HALKit/ARM64/HalApplicationProcessor.cc | 138 ------------------ .../HALKit/ARM64/HalApplicationProcessor.cpp | 138 ++++++++++++++++++ src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc | 156 --------------------- .../HALKit/ARM64/HalCoreInterruptHandler.cpp | 156 +++++++++++++++++++++ src/kernel/HALKit/ARM64/HalDebugOutput.cc | 69 --------- src/kernel/HALKit/ARM64/HalDebugOutput.cpp | 69 +++++++++ src/kernel/HALKit/ARM64/HalKernelMain.cc | 60 -------- src/kernel/HALKit/ARM64/HalKernelMain.cpp | 60 ++++++++ src/kernel/HALKit/ARM64/HalKernelPanic.cc | 52 ------- src/kernel/HALKit/ARM64/HalKernelPanic.cpp | 52 +++++++ src/kernel/HALKit/ARM64/HalPagingMgr.cc | 81 ----------- src/kernel/HALKit/ARM64/HalPagingMgr.cpp | 81 +++++++++++ src/kernel/HALKit/ARM64/HalSchedulerCore.cc | 19 --- src/kernel/HALKit/ARM64/HalSchedulerCore.cpp | 19 +++ .../HALKit/ARM64/HalSchedulerCorePrimitives.cc | 28 ---- .../HALKit/ARM64/HalSchedulerCorePrimitives.cpp | 28 ++++ src/kernel/HALKit/ARM64/HalTimer.cc | 6 - src/kernel/HALKit/ARM64/HalTimer.cpp | 6 + src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc | 11 -- src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cpp | 11 ++ src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc | 3 - src/kernel/HALKit/ARM64/Storage/UFS+Generic.cpp | 3 + 28 files changed, 765 insertions(+), 765 deletions(-) delete mode 100644 src/kernel/HALKit/ARM64/APM/APM+IO.cc create mode 100644 src/kernel/HALKit/ARM64/APM/APM+IO.cpp delete mode 100644 src/kernel/HALKit/ARM64/CxxAbi.cc create mode 100644 src/kernel/HALKit/ARM64/CxxAbi.cpp delete mode 100644 src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc create mode 100644 src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cpp delete mode 100644 src/kernel/HALKit/ARM64/HalApplicationProcessor.cc create mode 100644 src/kernel/HALKit/ARM64/HalApplicationProcessor.cpp delete mode 100644 src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc create mode 100644 src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cpp delete mode 100644 src/kernel/HALKit/ARM64/HalDebugOutput.cc create mode 100644 src/kernel/HALKit/ARM64/HalDebugOutput.cpp delete mode 100644 src/kernel/HALKit/ARM64/HalKernelMain.cc create mode 100644 src/kernel/HALKit/ARM64/HalKernelMain.cpp delete mode 100644 src/kernel/HALKit/ARM64/HalKernelPanic.cc create mode 100644 src/kernel/HALKit/ARM64/HalKernelPanic.cpp delete mode 100644 src/kernel/HALKit/ARM64/HalPagingMgr.cc create mode 100644 src/kernel/HALKit/ARM64/HalPagingMgr.cpp delete mode 100644 src/kernel/HALKit/ARM64/HalSchedulerCore.cc create mode 100644 src/kernel/HALKit/ARM64/HalSchedulerCore.cpp delete mode 100644 src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc create mode 100644 src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cpp delete mode 100644 src/kernel/HALKit/ARM64/HalTimer.cc create mode 100644 src/kernel/HALKit/ARM64/HalTimer.cpp delete mode 100644 src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc create mode 100644 src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cpp delete mode 100644 src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc create mode 100644 src/kernel/HALKit/ARM64/Storage/UFS+Generic.cpp (limited to 'src/kernel/HALKit/ARM64') diff --git a/src/kernel/HALKit/ARM64/APM/APM+IO.cc b/src/kernel/HALKit/ARM64/APM/APM+IO.cc deleted file mode 100644 index 91b8255e..00000000 --- a/src/kernel/HALKit/ARM64/APM/APM+IO.cc +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include -#include - -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/APM/APM+IO.cpp b/src/kernel/HALKit/ARM64/APM/APM+IO.cpp new file mode 100644 index 00000000..91b8255e --- /dev/null +++ b/src/kernel/HALKit/ARM64/APM/APM+IO.cpp @@ -0,0 +1,33 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include +#include + +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/CxxAbi.cc b/src/kernel/HALKit/ARM64/CxxAbi.cc deleted file mode 100644 index 7b19aa71..00000000 --- a/src/kernel/HALKit/ARM64/CxxAbi.cc +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include -#include -#include - -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(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/CxxAbi.cpp b/src/kernel/HALKit/ARM64/CxxAbi.cpp new file mode 100644 index 00000000..7b19aa71 --- /dev/null +++ b/src/kernel/HALKit/ARM64/CxxAbi.cpp @@ -0,0 +1,85 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include +#include +#include + +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(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 deleted file mode 100644 index 544d1ee1..00000000 --- a/src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include -#include -#include -#include -#include - -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/HalACPIFactoryInterface.cpp b/src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cpp new file mode 100644 index 00000000..544d1ee1 --- /dev/null +++ b/src/kernel/HALKit/ARM64/HalACPIFactoryInterface.cpp @@ -0,0 +1,24 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include +#include +#include +#include +#include + +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 deleted file mode 100644 index 33921a56..00000000 --- a/src/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#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 -#include -#include -#include -#include -#include - -// ================================================================= // - -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(GICD_BASE, GICD_CTLR, YES); - - UInt32 gicc_ctlr = ke_dma_read(GICC_BASE, GICC_CTLR); - - const UInt8 kEnableSignalInt = 0x1; - - gicc_ctlr |= kEnableSignalInt; - gicc_ctlr |= (kEnableSignalInt << 0x1); - - ke_dma_write(GICC_BASE, GICC_CTLR, gicc_ctlr); - - ke_dma_write(GICC_BASE, GICC_PMR, 0xFF); - - UInt32 icfgr = ke_dma_read(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4); - - icfgr |= (0x2 << ((32 % 16) * 2)); - - ke_dma_write(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr); - ke_dma_write(GICD_BASE, GICD_ITARGETSR + (0x20 / 0x04) * 4, 0x2 << ((32 % 4) * 8)); - ke_dma_write(GICD_BASE, GICD_IPRIORITYR + (0x20 / 0x04) * 4, 0xFF << ((32 % 4) * 8)); - ke_dma_write(GICD_BASE, GICD_ISENABLER + 4, 0x01); - } - - EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void) { - UInt32 interrupt_id = ke_dma_read(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(GICC_BASE, GICC_EOIR, interrupt_id); - UserProcessHelper::StartScheduling(); - break; - } - default: { - ke_dma_write(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) { - 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/HalApplicationProcessor.cpp b/src/kernel/HALKit/ARM64/HalApplicationProcessor.cpp new file mode 100644 index 00000000..33921a56 --- /dev/null +++ b/src/kernel/HALKit/ARM64/HalApplicationProcessor.cpp @@ -0,0 +1,138 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#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 +#include +#include +#include +#include +#include + +// ================================================================= // + +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(GICD_BASE, GICD_CTLR, YES); + + UInt32 gicc_ctlr = ke_dma_read(GICC_BASE, GICC_CTLR); + + const UInt8 kEnableSignalInt = 0x1; + + gicc_ctlr |= kEnableSignalInt; + gicc_ctlr |= (kEnableSignalInt << 0x1); + + ke_dma_write(GICC_BASE, GICC_CTLR, gicc_ctlr); + + ke_dma_write(GICC_BASE, GICC_PMR, 0xFF); + + UInt32 icfgr = ke_dma_read(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4); + + icfgr |= (0x2 << ((32 % 16) * 2)); + + ke_dma_write(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr); + ke_dma_write(GICD_BASE, GICD_ITARGETSR + (0x20 / 0x04) * 4, 0x2 << ((32 % 4) * 8)); + ke_dma_write(GICD_BASE, GICD_IPRIORITYR + (0x20 / 0x04) * 4, 0xFF << ((32 % 4) * 8)); + ke_dma_write(GICD_BASE, GICD_ISENABLER + 4, 0x01); + } + + EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void) { + UInt32 interrupt_id = ke_dma_read(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(GICC_BASE, GICC_EOIR, interrupt_id); + UserProcessHelper::StartScheduling(); + break; + } + default: { + ke_dma_write(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) { + 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/HalCoreInterruptHandler.cc b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc deleted file mode 100644 index f0085e13..00000000 --- a/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include -#include -#include -#include -#include - -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.Crash(); - - hal_int_send_eoi(13); - - process.Signal.SignalArg = rsp; - process.Signal.SignalID = SIGKILL; - process.Signal.Status = process.Status; -} - -/// @brief Handle page fault. -/// @param rsp -EXTERN_C void int_handle_pf(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Crash(); - - hal_int_send_eoi(14); - - process.Signal.SignalArg = rsp; - process.Signal.SignalID = SIGKILL; - process.Signal.Status = process.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.Crash(); - - hal_int_send_eoi(8); - - process.Signal.SignalArg = rsp; - process.Signal.SignalID = SIGKILL; - process.Signal.Status = process.Status; -} - -/// @brief Handle any generic fault. -/// @param rsp -EXTERN_C void int_handle_generic(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Crash(); - - hal_int_send_eoi(30); - - Kernel::kout << "Kernel: Generic Process Fault.\r"; - - process.Signal.SignalArg = rsp; - process.Signal.SignalID = SIGKILL; - process.Signal.Status = process.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.Signal.SignalArg = rip; - process.Signal.SignalID = SIGTRAP; - - process.Signal.Status = process.Status; - - process.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.Crash(); - - hal_int_send_eoi(6); - - process.Signal.SignalArg = rsp; - process.Signal.SignalID = SIGKILL; - process.Signal.Status = process.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/HalCoreInterruptHandler.cpp b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cpp new file mode 100644 index 00000000..f0085e13 --- /dev/null +++ b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cpp @@ -0,0 +1,156 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include +#include +#include +#include +#include + +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.Crash(); + + hal_int_send_eoi(13); + + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.Status; +} + +/// @brief Handle page fault. +/// @param rsp +EXTERN_C void int_handle_pf(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + process.Crash(); + + hal_int_send_eoi(14); + + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.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.Crash(); + + hal_int_send_eoi(8); + + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.Status; +} + +/// @brief Handle any generic fault. +/// @param rsp +EXTERN_C void int_handle_generic(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + process.Crash(); + + hal_int_send_eoi(30); + + Kernel::kout << "Kernel: Generic Process Fault.\r"; + + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.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.Signal.SignalArg = rip; + process.Signal.SignalID = SIGTRAP; + + process.Signal.Status = process.Status; + + process.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.Crash(); + + hal_int_send_eoi(6); + + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.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 deleted file mode 100644 index 4e47d38e..00000000 --- a/src/kernel/HALKit/ARM64/HalDebugOutput.cc +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include -#include -#include -#include - -namespace Kernel { -EXTERN_C void ke_io_write(IDevice* 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(IDevice* 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() { - TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); - return out; -} - -} // namespace Kernel diff --git a/src/kernel/HALKit/ARM64/HalDebugOutput.cpp b/src/kernel/HALKit/ARM64/HalDebugOutput.cpp new file mode 100644 index 00000000..4e47d38e --- /dev/null +++ b/src/kernel/HALKit/ARM64/HalDebugOutput.cpp @@ -0,0 +1,69 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include +#include +#include +#include + +namespace Kernel { +EXTERN_C void ke_io_write(IDevice* 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(IDevice* 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() { + TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); + return out; +} + +} // namespace Kernel diff --git a/src/kernel/HALKit/ARM64/HalKernelMain.cc b/src/kernel/HALKit/ARM64/HalKernelMain.cc deleted file mode 100644 index 3a6e4085..00000000 --- a/src/kernel/HALKit/ARM64/HalKernelMain.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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( - reinterpret_cast(kHandoverHeader->f_BitMapStart)); - - /// @note do initialize the interrupts after it. - - Kernel::mp_init_cores(); - - while (YES); -} -#endif diff --git a/src/kernel/HALKit/ARM64/HalKernelMain.cpp b/src/kernel/HALKit/ARM64/HalKernelMain.cpp new file mode 100644 index 00000000..3a6e4085 --- /dev/null +++ b/src/kernel/HALKit/ARM64/HalKernelMain.cpp @@ -0,0 +1,60 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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( + reinterpret_cast(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 deleted file mode 100644 index 59397611..00000000 --- a/src/kernel/HALKit/ARM64/HalKernelPanic.cc +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* 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(); -}; - -/***********************************************************************************/ -/// @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() { - 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/HalKernelPanic.cpp b/src/kernel/HALKit/ARM64/HalKernelPanic.cpp new file mode 100644 index 00000000..59397611 --- /dev/null +++ b/src/kernel/HALKit/ARM64/HalKernelPanic.cpp @@ -0,0 +1,52 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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(); +}; + +/***********************************************************************************/ +/// @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() { + 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 deleted file mode 100644 index 0fe4d759..00000000 --- a/src/kernel/HALKit/ARM64/HalPagingMgr.cc +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include -#include - -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(ttbr0_val); - - UInt64 l1_idx = (reinterpret_cast(virtual_address) >> 39) & 0x1FF; - UInt64 l2_idx = (reinterpret_cast(virtual_address) >> 30) & 0x1FF; - UInt64 l3_idx = (reinterpret_cast(virtual_address) >> 21) & 0x1FF; - - if (!l1_table[l1_idx]) return 0; - - volatile UInt64* l2_table = reinterpret_cast(l1_table[l1_idx] & ~0xFFFUL); - - if (!l2_table[l2_idx]) return 0; - - volatile UInt64* l3_table = reinterpret_cast(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(ttbr0_val); - - UInt64 l1_idx = (reinterpret_cast(virtual_address) >> 39) & 0x1FF; - UInt64 l2_idx = (reinterpret_cast(virtual_address) >> 30) & 0x1FF; - UInt64 l3_idx = (reinterpret_cast(virtual_address) >> 21) & 0x1FF; - - if (!l1_table[l1_idx]) return kErrorInvalidData; - - volatile UInt64* l2_table = reinterpret_cast(l1_table[l1_idx] & ~0xFFFUL); - - if (!l2_table[l2_idx]) return kErrorInvalidData; - - volatile UInt64* l3_table = reinterpret_cast(l2_table[l2_idx] & ~0xFFFUL); - - l3_table[l3_idx] = (reinterpret_cast(physical_address) & ~0xFFFUL) | flags; - - switch (level) { - case 2: { - l3_table[l3_idx] = (reinterpret_cast(physical_address) & ~0xFFFUL) | flags; - return kErrorSuccess; - } - case 1: { - l1_table[l1_idx] = (reinterpret_cast(physical_address) & ~0xFFFUL) | flags; - return kErrorSuccess; - } - case 0: { - l1_table[l1_idx] = (reinterpret_cast(physical_address) & ~0xFFFUL) | flags; - return kErrorSuccess; - } - } - - return kErrorInvalidData; -} -} // namespace Kernel::HAL diff --git a/src/kernel/HALKit/ARM64/HalPagingMgr.cpp b/src/kernel/HALKit/ARM64/HalPagingMgr.cpp new file mode 100644 index 00000000..0fe4d759 --- /dev/null +++ b/src/kernel/HALKit/ARM64/HalPagingMgr.cpp @@ -0,0 +1,81 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include +#include + +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(ttbr0_val); + + UInt64 l1_idx = (reinterpret_cast(virtual_address) >> 39) & 0x1FF; + UInt64 l2_idx = (reinterpret_cast(virtual_address) >> 30) & 0x1FF; + UInt64 l3_idx = (reinterpret_cast(virtual_address) >> 21) & 0x1FF; + + if (!l1_table[l1_idx]) return 0; + + volatile UInt64* l2_table = reinterpret_cast(l1_table[l1_idx] & ~0xFFFUL); + + if (!l2_table[l2_idx]) return 0; + + volatile UInt64* l3_table = reinterpret_cast(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(ttbr0_val); + + UInt64 l1_idx = (reinterpret_cast(virtual_address) >> 39) & 0x1FF; + UInt64 l2_idx = (reinterpret_cast(virtual_address) >> 30) & 0x1FF; + UInt64 l3_idx = (reinterpret_cast(virtual_address) >> 21) & 0x1FF; + + if (!l1_table[l1_idx]) return kErrorInvalidData; + + volatile UInt64* l2_table = reinterpret_cast(l1_table[l1_idx] & ~0xFFFUL); + + if (!l2_table[l2_idx]) return kErrorInvalidData; + + volatile UInt64* l3_table = reinterpret_cast(l2_table[l2_idx] & ~0xFFFUL); + + l3_table[l3_idx] = (reinterpret_cast(physical_address) & ~0xFFFUL) | flags; + + switch (level) { + case 2: { + l3_table[l3_idx] = (reinterpret_cast(physical_address) & ~0xFFFUL) | flags; + return kErrorSuccess; + } + case 1: { + l1_table[l1_idx] = (reinterpret_cast(physical_address) & ~0xFFFUL) | flags; + return kErrorSuccess; + } + case 0: { + l1_table[l1_idx] = (reinterpret_cast(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 deleted file mode 100644 index ecf666e8..00000000 --- a/src/kernel/HALKit/ARM64/HalSchedulerCore.cc +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include - -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/HalSchedulerCore.cpp b/src/kernel/HALKit/ARM64/HalSchedulerCore.cpp new file mode 100644 index 00000000..ecf666e8 --- /dev/null +++ b/src/kernel/HALKit/ARM64/HalSchedulerCore.cpp @@ -0,0 +1,19 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include + +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 deleted file mode 100644 index 960dbc6d..00000000 --- a/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include -#include - -namespace Kernel { -/***********************************************************************************/ -/// @brief Unimplemented function (crashes by default) -/// @param process The process handle. -/***********************************************************************************/ - -EXTERN_C Void __ne_pure_call(UserProcess* 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/HalSchedulerCorePrimitives.cpp b/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cpp new file mode 100644 index 00000000..960dbc6d --- /dev/null +++ b/src/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cpp @@ -0,0 +1,28 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include +#include + +namespace Kernel { +/***********************************************************************************/ +/// @brief Unimplemented function (crashes by default) +/// @param process The process handle. +/***********************************************************************************/ + +EXTERN_C Void __ne_pure_call(UserProcess* 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 deleted file mode 100644 index 3084838d..00000000 --- a/src/kernel/HALKit/ARM64/HalTimer.cc +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include -#include \ No newline at end of file diff --git a/src/kernel/HALKit/ARM64/HalTimer.cpp b/src/kernel/HALKit/ARM64/HalTimer.cpp new file mode 100644 index 00000000..3084838d --- /dev/null +++ b/src/kernel/HALKit/ARM64/HalTimer.cpp @@ -0,0 +1,6 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include +#include \ 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 deleted file mode 100644 index f73946d7..00000000 --- a/src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel - -#include - -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/SCSI+Generic.cpp b/src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cpp new file mode 100644 index 00000000..f73946d7 --- /dev/null +++ b/src/kernel/HALKit/ARM64/Storage/SCSI+Generic.cpp @@ -0,0 +1,11 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel + +#include + +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 deleted file mode 100644 index ba8d285b..00000000 --- a/src/kernel/HALKit/ARM64/Storage/UFS+Generic.cc +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/nekernel-org/nekernel diff --git a/src/kernel/HALKit/ARM64/Storage/UFS+Generic.cpp b/src/kernel/HALKit/ARM64/Storage/UFS+Generic.cpp new file mode 100644 index 00000000..ba8d285b --- /dev/null +++ b/src/kernel/HALKit/ARM64/Storage/UFS+Generic.cpp @@ -0,0 +1,3 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/nekernel-org/nekernel -- cgit v1.2.3