diff options
Diffstat (limited to 'dev')
| -rw-r--r-- | dev/kernel/DmaKit/DmaPool.h | 19 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc | 161 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/HalKernelPanic.cc | 4 |
3 files changed, 178 insertions, 6 deletions
diff --git a/dev/kernel/DmaKit/DmaPool.h b/dev/kernel/DmaKit/DmaPool.h index 9decb3f1..d4bec398 100644 --- a/dev/kernel/DmaKit/DmaPool.h +++ b/dev/kernel/DmaKit/DmaPool.h @@ -2,8 +2,8 @@ Copyright (C) 2025, Amlal El Mahrouss , all rights reserved. - File: FileMgr.h - Purpose: Kernel file manager. + File: DmaPool.h + Purpose: Dma Pool Manager. ------------------------------------------- */ @@ -15,6 +15,13 @@ #ifdef __NE_AMD64__ #define kNeDMAPoolStart (0x1000000) #define kNeDMAPoolSize (0x1000000) +#elif defined(__NE_ARM64__) +/// @todo what reference offset shall we use? +#define kNeDMAPoolStart (0x1000000) +#define kNeDMAPoolSize (0x1000000) +#endif + +#define kNeDMABestAlign __BIGGEST_ALIGNMENT__ namespace Kernel { /// @brief DMA pool base pointer, here we're sure that AHCI or whatever tricky standard sees it. @@ -31,6 +38,11 @@ inline VoidPtr rtl_dma_alloc(SizeT size, SizeT align) { return nullptr; } + /// Check alignement according to architecture. + if ((align % kNeDMABestAlign) != 0) { + return nullptr; + } + UIntPtr addr = (UIntPtr) kDmaPoolPtr; /// here we just align the address according to a `align` variable, i'd rather be a power of two @@ -84,5 +96,4 @@ inline Void rtl_dma_flush(VoidPtr ptr, SizeT size_buffer) { HAL::mm_memory_fence((VoidPtr) ((UInt8*) ptr + buf_idx)); } } -} // namespace Kernel -#endif
\ No newline at end of file +} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc b/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc new file mode 100644 index 00000000..61a82314 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc @@ -0,0 +1,161 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#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::UIntPtr rdx_kerncall_arg) { + hal_int_send_eoi(51); + + 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)((Kernel::VoidPtr) rdx_kerncall_arg); + } + } + } +} diff --git a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc index d70fef00..91b2fe8a 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc @@ -45,8 +45,8 @@ Void RecoveryFactory::Recover() noexcept { void ke_runtime_check(bool expr, const Char* file, const Char* line) { if (!expr) { - (Void)(kout << "FAILED: FILE: " << file << kendl); - (Void)(kout << "FAILED: LINE: " << line << kendl); + (Void)(kout << "Kernel_Panic_FILE: " << file << kendl); + (Void)(kout << "Kernel_Panic_LINE: " << line << kendl); ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed } |
