summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit/AMD64
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-05-16 16:51:06 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-05-16 16:51:06 +0200
commit65a97e32ef586e073988186f1f4932c0193b3409 (patch)
tree3a33ff438a42ef48ab74f23a90afadf08f1dcb3d /dev/kernel/HALKit/AMD64
parent8e63423ef656d1a403c959589ed19621281ebb0b (diff)
feat(kernel): Better UPS and interrupt system too.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/HALKit/AMD64')
-rw-r--r--dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc32
-rw-r--r--dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc54
-rw-r--r--dev/kernel/HALKit/AMD64/HalInterruptAPI.asm89
-rw-r--r--dev/kernel/HALKit/AMD64/HalKernelMain.cc2
4 files changed, 81 insertions, 96 deletions
diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
index f7aa2a70..89fe00b5 100644
--- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
+++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
@@ -81,30 +81,13 @@ struct LAPIC final {
///////////////////////////////////////////////////////////////////////////////////////
/***********************************************************************************/
-/// @brief Send IPI command to APIC.
-/// @param apic_id programmable interrupt controller id.
-/// @param vector vector interrupt.
-/// @param target target APIC adress.
-/// @return
-/***********************************************************************************/
-
-Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) {
- Kernel::ke_dma_write<UInt32>(target, APIC_ICR_HIGH, apic_id << 24);
- Kernel::ke_dma_write<UInt32>(target, APIC_ICR_LOW, 0x00000500 | 0x00004000 | 0x00000000);
-
- while (Kernel::ke_dma_read<UInt32>(target, APIC_ICR_LOW) & 0x1000) {
- ;
- }
-}
-
-/***********************************************************************************/
/// @brief Send end IPI for CPU.
/// @param apic_id
/// @param vector
/// @param target
/// @return
/***********************************************************************************/
-Void hal_send_sipi(UInt32 target, UInt32 apic_id, UInt8 vector) {
+Void hal_send_ipi_msg(UInt32 target, UInt32 apic_id, UInt8 vector) {
Kernel::ke_dma_write<UInt32>(target, APIC_ICR_HIGH, apic_id << 24);
Kernel::ke_dma_write<UInt32>(target, APIC_ICR_LOW, 0x00000600 | 0x00004000 | 0x00000000 | vector);
@@ -202,13 +185,10 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept {
controller.Write(LAPIC_REG_TIMER_LVT, 32 | (1 << 17));
controller.Write(LAPIC_REG_TIMER_INITCNT, 1000000);
- const UIntPtr trampoline_phys = 0x7c00;
+ UInt8* trampoline_phys = (UInt8*) 0x7c00;
- HAL::mm_map_page((VoidPtr)trampoline_phys, (VoidPtr)trampoline_phys, HAL::kMMFlagsWr | HAL::kMMFlagsPresent);
-
- const SizeT len = AP_BLOB_SIZE; /// AP blob size.
-
- rt_copy_memory(hal_ap_blob_start, reinterpret_cast<VoidPtr>(trampoline_phys), len);
+ *trampoline_phys = 0xcd;
+ *(trampoline_phys + 1) = 0x00;
volatile UInt8* entry_ptr = reinterpret_cast<volatile UInt8*>(kMADTBlock->List);
volatile UInt8* end_ptr = ((UInt8*) kMADTBlock) + kMADTBlock->Length;
@@ -229,9 +209,7 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept {
kout << "LAPIC type, also is on...\r";
- hal_send_start_ipi(kApicBaseAddress, entry_struct->ProcessorID);
- hal_send_sipi(kApicBaseAddress, entry_struct->ProcessorID, trampoline_phys >> 12);
-
+ hal_send_ipi_msg(kApicBaseAddress, entry_struct->ProcessorID, 0x7c);
} else {
kout << "LAPIC type, also is not on...\r";
}
diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
index d5a40390..f52a7167 100644
--- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
+++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
@@ -13,12 +13,31 @@ 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 >= 0x20 && vector <= 0x2F) {
+ if (vector >= 0x28) {
+ Kernel::HAL::rt_out8(0xA0, 0x20);
+ }
+ Kernel::HAL::rt_out8(0x20, 0x20);
+ }
+
+ kIsRunning = NO;
+}
+
/// @brief Handle GPF fault.
/// @param rsp
EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) {
+ hal_idt_send_eoi(13);
+
auto& process = Kernel::UserProcessScheduler::The().CurrentProcess();
- Kernel::kout << "Kernel: General Protection Fault.\r";
+ Kernel::kout << "Kernel: General Access Fault.\r";
process.Leak().Signal.SignalArg = rsp;
process.Leak().Signal.SignalID = SIGKILL;
@@ -26,8 +45,6 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) {
Kernel::kout << "Kernel: SIGKILL status.\r";
- process.Leak().Status = Kernel::ProcessStatusKind::kKilled;
-
process.Leak().Crash();
dbg_break_point();
@@ -36,6 +53,8 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) {
/// @brief Handle page fault.
/// @param rsp
EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) {
+ hal_idt_send_eoi(14);
+
auto& process = Kernel::UserProcessScheduler::The().CurrentProcess();
Kernel::kout << "Kernel: Page Fault.\r";
@@ -45,8 +64,6 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) {
process.Leak().Signal.SignalID = SIGKILL;
process.Leak().Signal.Status = process.Leak().Status;
- process.Leak().Status = Kernel::ProcessStatusKind::kKilled;
-
process.Leak().Crash();
dbg_break_point();
@@ -54,17 +71,24 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) {
/// @brief Handle scheduler interrupt.
EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) {
- ((volatile UInt32*) kApicBaseAddress)[0xB0] = 0;
+ hal_idt_send_eoi(32);
- Kernel::HAL::rt_out8(0x20, 0x20);
+ while (kIsRunning)
+ ;
+
+ kIsRunning = YES;
NE_UNUSED(rsp);
Kernel::UserProcessHelper::StartScheduling();
+
+ kIsRunning = NO;
}
/// @brief Handle math fault.
/// @param rsp
EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) {
+ hal_idt_send_eoi(8);
+
auto& process = Kernel::UserProcessScheduler::The().CurrentProcess();
Kernel::kout << "Kernel: Math error (division by zero?).\r";
@@ -75,8 +99,6 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) {
Kernel::kout << "Kernel: SIGKILL status.\r";
- process.Leak().Status = Kernel::ProcessStatusKind::kKilled;
-
process.Leak().Crash();
dbg_break_point();
@@ -85,6 +107,8 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) {
/// @brief Handle any generic fault.
/// @param rsp
EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) {
+ hal_idt_send_eoi(30);
+
auto& process = Kernel::UserProcessScheduler::The().CurrentProcess();
(Void)(Kernel::kout << "Kernel: Process RSP: " << Kernel::hex_number(rsp) << Kernel::kendl);
@@ -96,14 +120,14 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) {
Kernel::kout << "Kernel: SIGKILL status.\r";
- process.Leak().Status = Kernel::ProcessStatusKind::kKilled;
-
process.Leak().Crash();
dbg_break_point();
}
EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) {
+ hal_idt_send_eoi(3);
+
auto& process = Kernel::UserProcessScheduler::The().CurrentProcess();
(Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl);
@@ -125,6 +149,8 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) {
/// @brief Handle #UD fault.
/// @param rsp
EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) {
+ hal_idt_send_eoi(6);
+
NE_UNUSED(rsp);
auto& process = Kernel::UserProcessScheduler::The().CurrentProcess();
@@ -137,8 +163,6 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) {
Kernel::kout << "Kernel: SIGKILL status.\r";
- process.Leak().Status = Kernel::ProcessStatusKind::kKilled;
-
process.Leak().Crash();
dbg_break_point();
@@ -149,6 +173,8 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) {
/// @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()) {
Kernel::kout << "syscall: Enter Syscall.\r";
@@ -171,6 +197,8 @@ EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index,
/// @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()) {
Kernel::kout << "kerncall: Enter Kernel Call List.\r";
diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm
index fdd62e57..667d3c5b 100644
--- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm
+++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm
@@ -20,6 +20,8 @@ __NE_INT_%1:
std
+ add rsp, 8
+
o64 iret
%endmacro
@@ -30,6 +32,8 @@ __NE_INT_%1:
std
+ add rsp, 8
+
o64 iret
%endmacro
@@ -45,29 +49,24 @@ extern ke_io_write
extern idt_handle_ud
extern idt_handle_generic
extern idt_handle_breakpoint
+extern idt_handle_math
section .text
__NE_INT_0:
cld
-
- mov al, 0x20
- out 0x20, al
-
push rcx
call idt_handle_generic
pop rcx
std
+ add rsp, 8
+
o64 iret
__NE_INT_1:
cld
-
- mov al, 0x20
- out 0x20, al
-
push rcx
call idt_handle_generic
pop rcx
@@ -78,100 +77,87 @@ __NE_INT_1:
__NE_INT_2:
cld
-
- mov al, 0x20
- out 0x20, al
-
push rcx
call idt_handle_generic
pop rcx
std
+ add rsp, 8
+
o64 iret
;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched.
__NE_INT_3:
cld
-
- mov al, 0x20
- out 0x20, al
-
push rcx
call idt_handle_breakpoint
pop rcx
std
+ add rsp, 8
+
o64 iret
__NE_INT_4:
cld
- mov al, 0x20
- out 0x20, al
-
-
push rcx
call idt_handle_generic
pop rcx
std
+ add rsp, 8
+
o64 iret
__NE_INT_5:
cld
-
- mov al, 0x20
- out 0x20, al
-
std
+ add rsp, 8
+
o64 iret
;; Invalid opcode interrupt
__NE_INT_6:
cld
-
- mov al, 0x20
- out 0x20, al
-
push rcx
call idt_handle_ud
pop rcx
std
+ add rsp, 8
+
o64 iret
__NE_INT_7:
cld
-
- mov al, 0x20
- out 0x20, al
-
push rcx
call idt_handle_generic
pop rcx
std
+ add rsp, 8
+
o64 iret
;; Invalid opcode interrupt
__NE_INT_8:
cld
- mov al, 0x20
- out 0x20, al
-
push rcx
- call idt_handle_generic
+ call idt_handle_math
pop rcx
std
+ add rsp, 8
+
o64 iret
IntNormal 9
@@ -183,29 +169,26 @@ IntExp 12
__NE_INT_13:
cld
- mov al, 0x20
- out 0x20, al
-
push rcx
call idt_handle_gpf
pop rcx
std
+ add rsp, 8
+
o64 iret
__NE_INT_14:
cld
-
- mov al, 0x20
- out 0x20, al
-
push rcx
call idt_handle_pf
pop rcx
std
+ add rsp, 8
+
o64 iret
IntNormal 15
@@ -232,11 +215,17 @@ IntNormal 31
[extern kApicBaseAddress]
__NE_INT_32:
+ cld
+
push rax
mov rcx, rsp
call idt_handle_scheduler
pop rax
+ std
+
+ add rsp, 8
+
o64 iret
IntNormal 33
@@ -253,10 +242,6 @@ IntNormal 39
__NE_INT_40:
cld
- mov al, 0x20
- out 0xA0, al
- out 0x20, al
-
push rax
mov rcx, rsp
call rtl_rtl8139_interrupt_handler
@@ -264,6 +249,8 @@ __NE_INT_40:
std
+ add rsp, 8
+
o64 iret
IntNormal 41
@@ -283,10 +270,6 @@ IntNormal 49
__NE_INT_50:
cld
- mov al, 0x20
- out 0xA0, al
- out 0x20, al
-
push rax
mov rax, hal_system_call_enter
@@ -303,10 +286,6 @@ __NE_INT_50:
__NE_INT_51:
cld
- mov al, 0x20
- out 0xA0, al
- out 0x20, al
-
push rax
mov rax, hal_kernel_call_enter
diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc
index 158eaa85..00dafc7b 100644
--- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc
+++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc
@@ -111,7 +111,7 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept {
Kernel::rtl_create_user_process(rtl_ne_task, "SecSrv");
Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr);
-
+
Kernel::HAL::Register64 idt_reg;
idt_reg.Base = reinterpret_cast<Kernel::UIntPtr>(kInterruptVectorTable);