summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-05-25 09:56:46 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-05-25 09:56:46 +0200
commit5b30cacacf0f0ca6fb06bb34389f04b05ceb2b15 (patch)
tree85c1fb5b167d3089483affe7060155a7d148d641 /dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc
parentef3e3db6fafb43afd3e254b17c7169c603cdf416 (diff)
kernel!: lots of changes, see commit details.
refactor(hal): unify file naming and drop redundant architecture suffixes feat(build): rename kernel and bootloader to 'ne_kernel' and 'ne_bootz' refactor(memory): replace mm_get_phys_address with mm_get_page_addr feat(bitmap): track bitmap allocator usage and add out-of-memory error fix(heap): correct heap magic naming and alignment logic chore(fs): downgrade HeFS disk size check to warning chore(tools): clean up formatting in 'ping' and 'manual' docs(design): update OS_DESIGN.drawio to reflect Hypr86 and new layout Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc')
-rw-r--r--dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc159
1 files changed, 159 insertions, 0 deletions
diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc
new file mode 100644
index 00000000..01456ae5
--- /dev/null
+++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc
@@ -0,0 +1,159 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/ProcessScheduler.h>
+#include <NeKit/KString.h>
+#include <SignalKit/Signals.h>
+
+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();
+ process.Leak().Crash();
+
+ hal_idt_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 idt_handle_pf(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_idt_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 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();
+ process.Leak().Crash();
+
+ hal_idt_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 idt_handle_generic(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_idt_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 idt_handle_breakpoint(Kernel::UIntPtr rip) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+
+ hal_idt_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 idt_handle_ud(Kernel::UIntPtr rsp) {
+ auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess();
+ process.Leak().Crash();
+
+ hal_idt_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.
+/// @param stack the stack pushed from assembly routine.
+/// @return nothing.
+EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index,
+ Kernel::UIntPtr rdx_syscall_struct) {
+ hal_idt_send_eoi(50);
+
+ if (rcx_syscall_index < kSysCalls.Count()) {
+ if (kSysCalls[rcx_syscall_index].fHooked) {
+ if (kSysCalls[rcx_syscall_index].fProc) {
+ (kSysCalls[rcx_syscall_index].fProc)((Kernel::VoidPtr) rdx_syscall_struct);
+ }
+ }
+ }
+}
+
+/// @brief Enter Kernel call from assembly (DDK only).
+/// @param stack the stack pushed from assembly routine.
+/// @return nothing.
+EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_kerncall_index,
+ Kernel::UIntPtr rdx_kerncall_struct) {
+ hal_idt_send_eoi(51);
+
+ if (rcx_kerncall_index < kKernCalls.Count()) {
+ if (kKernCalls[rcx_kerncall_index].fHooked) {
+ if (kKernCalls[rcx_kerncall_index].fProc) {
+ (kKernCalls[rcx_kerncall_index].fProc)((Kernel::VoidPtr) rdx_kerncall_struct);
+ }
+ }
+ }
+}