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 --- .../HALKit/AMD64/HalCoreInterruptHandler.cpp | 177 +++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cpp (limited to 'src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cpp') diff --git a/src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cpp b/src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cpp new file mode 100644 index 00000000..a171ac57 --- /dev/null +++ b/src/kernel/HALKit/AMD64/HalCoreInterruptHandler.cpp @@ -0,0 +1,177 @@ +// 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 + +EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip); +EXTERN_C Kernel::UIntPtr kApicBaseAddress; + +STATIC BOOL kIsRunning{NO}; + +/// @brief Notify APIC and PIC that we're done with the interrupt. +/// @note +static void hal_idt_send_eoi(UInt8 vector) { + ((volatile UInt32*) kApicBaseAddress)[0xB0 / 4] = 0; + + if (vector >= kPICCommand && vector <= 0x2F) { + if (vector >= 0x28) { + Kernel::HAL::rt_out8(kPIC2Command, kPICCommand); + } + Kernel::HAL::rt_out8(kPICCommand, kPICCommand); + } +} + +/// @brief Handle GPF fault. +/// @param rsp +EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + + if (process) process.Crash(); + + hal_idt_send_eoi(13); + + if (process) { + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.Status; + } +} + +/// @brief Handle page fault. +/// @param rsp +EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + + if (process) process.Crash(); + + hal_idt_send_eoi(14); + + if (process) { + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.Status; + } +} + +/// @brief Handle scheduler interrupt. +EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { + NE_UNUSED(rsp); + + hal_idt_send_eoi(32); + + while (kIsRunning); + + kIsRunning = YES; + + Kernel::UserProcessHelper::StartScheduling(); + + kIsRunning = NO; +} + +/// @brief Handle math fault. +/// @param rsp +EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + + if (process) process.Crash(); + + hal_idt_send_eoi(8); + + if (process) { + process.Signal.SignalArg = rsp; + process.Signal.SignalID = sig_generate_unique(); + process.Signal.Status = process.Status; + } +} + +/// @brief Handle any generic fault. +/// @param rsp +EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + + if (process) process.Crash(); + + hal_idt_send_eoi(30); + + Kernel::kout << "Kernel: Generic Process Fault.\r"; + + process.Signal.SignalArg = rsp; + process.Signal.SignalID = sig_generate_unique(); + ; + process.Signal.Status = process.Status; + + Kernel::kout << "Kernel: SIGKILL status.\r"; +} + +EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { + auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + + if (process) process.Crash(); + + hal_idt_send_eoi(3); + + process.Signal.SignalArg = rip; + process.Signal.SignalID = sig_generate_unique(); + + process.Signal.Status = process.Status; + + process.Status = Kernel::ProcessStatusKind::kFrozen; +} + +/// @brief Handle #UD fault. +/// @param rsp +EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + + if (process) process.Crash(); + + hal_idt_send_eoi(6); + + process.Signal.SignalArg = rsp; + process.Signal.SignalID = sig_generate_unique(); + 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_idt_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) { + hal_idt_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)(cnt, (Kernel::VoidPtr) arg, sz); + } + } + } +} -- cgit v1.2.3