diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-05-15 18:42:59 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-05-15 18:42:59 +0200 |
| commit | d126ebf73370fbc64913aa6ff19db56a39f625b2 (patch) | |
| tree | db66ede0635b1a6a5f13b8f7e161b68ed631226b /dev/kernel/HALKit | |
| parent | 6a30f42d5dcd0f944262147b2806db6c14fe7ffc (diff) | |
feat(kernel): pushing the fixes regarding the scheduler, and working on
making the LAPIC work correctly.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/HALKit')
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 69 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalCommonAPI.asm | 30 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 12 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 15 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalKernelMain.cc | 31 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc | 5 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Processor.h | 31 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/Processor.h | 22 | ||||
| -rw-r--r-- | dev/kernel/HALKit/POWER/HalApplicationProcessor.cc | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/POWER/Processor.h | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc | 2 |
13 files changed, 127 insertions, 98 deletions
diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index 84c52768..d049a74d 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -14,16 +14,21 @@ #include <modules/ACPI/ACPIFactoryInterface.h> #include <modules/CoreGfx/TextGfx.h> -#define kAPIC_Signature "APIC" +#define APIC_Signature "APIC" -#define kAPIC_ICR_Low 0x300 -#define kAPIC_ICR_High 0x310 -#define kAPIC_SIPI_Vector 0x00500 -#define kAPIC_EIPI_Vector 0x00400 +#define APIC_ICR_Low 0x300 +#define APIC_ICR_High 0x310 +#define APIC_SIPI_Vector 0x00500 +#define APIC_EIPI_Vector 0x00400 -#define kAPIC_BASE_MSR 0x1B -#define kAPIC_BASE_MSR_BSP 0x100 -#define kAPIC_BASE_MSR_ENABLE 0x800 +#define LAPIC_REG_TIMER_LVT 0x320 +#define LAPIC_REG_TIMER_INITCNT 0x380 +#define LAPIC_REG_TIMER_CURRCNT 0x390 +#define LAPIC_REG_TIMER_DIV 0x3E0 + +#define APIC_BASE_MSR 0x1B +#define APIC_BASE_MSR_BSP 0x100 +#define APIC_BASE_MSR_ENABLE 0x800 /// @note: _hal_switch_context is internal @@ -47,7 +52,7 @@ STATIC HAL_APIC_MADT* kMADTBlock = nullptr; STATIC Bool kSMPAware = false; STATIC Int64 kSMPCount = 0; -STATIC UIntPtr kApicBaseAddress = 0UL; +EXTERN_C UIntPtr kApicBaseAddress = 0UL; STATIC Int32 kSMPInterrupt = 0; STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0}; @@ -109,10 +114,10 @@ struct HAL_APIC_MADT final SDT_OBJECT { /***********************************************************************************/ Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) { - Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_High, apic_id << 24); - Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_Low, 0x00000500 | 0x00004000 | 0x00000000); + 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, kAPIC_ICR_Low) & 0x1000) { + while (Kernel::ke_dma_read<UInt32>(target, APIC_ICR_Low) & 0x1000) { ; } } @@ -125,11 +130,10 @@ Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) { /// @return /***********************************************************************************/ Void hal_send_sipi(UInt32 target, UInt32 apic_id, UInt8 vector) { - Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_High, apic_id << 24); - Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_Low, - 0x00000600 | 0x00004000 | 0x00000000 | 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); - while (Kernel::ke_dma_read<UInt32>(target, kAPIC_ICR_Low) & 0x1000) { + while (Kernel::ke_dma_read<UInt32>(target, APIC_ICR_Low) & 0x1000) { NE_UNUSED(0); } } @@ -192,7 +196,7 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { } auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr); - kRawMADT = hw_and_pow_int.Find(kAPIC_Signature).Leak().Leak(); + kRawMADT = hw_and_pow_int.Find(APIC_Signature).Leak().Leak(); kMADTBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT); kSMPAware = NO; @@ -203,7 +207,31 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { kSMPInterrupt = 0; kSMPCount = 0; - kApicBaseAddress = kMADTBlock->Address; + UInt32 lo = 0, hi = 0; + hal_get_msr(0x1B, &lo, &hi); + UInt64 apic_base = ((UInt64) hi << 32) | lo; + + apic_base |= 0x800; // enable bit + + lo = apic_base & 0xFFFFFFFF; + hi = apic_base >> 32; + + hal_set_msr(0x1B, lo, hi); + + kApicBaseAddress = apic_base & 0xFFFFF000; + + // Allow LAPIC to forward interrupts (TPR = 0) + *(volatile UInt32*) (kApicBaseAddress + 0x80) = 0; + + // Set Spurious Interrupt Vector and enable LAPIC (bit 8) + *(volatile UInt32*) (kApicBaseAddress + 0xF0) = 0x1FF; // vector = 0xFF, enable bit = 1 << 8 + + // LAPIC timer setup + *(volatile UInt32*) (kApicBaseAddress + LAPIC_REG_TIMER_DIV) = 0b0011; // Divide by 16 + *(volatile UInt32*) (kApicBaseAddress + LAPIC_REG_TIMER_LVT) = + 32 | (1 << 17); // Vector 32, periodic + *(volatile UInt32*) (kApicBaseAddress + LAPIC_REG_TIMER_INITCNT) = + 1000000; // Init count (e.g., ~100Hz) constexpr const auto kSMPCountMax = kMaxAPInsideSched; @@ -224,10 +252,7 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { ++index; } - // Kernel is now SMP aware. - // That means that the scheduler is now available (on MP Kernels) - - kSMPAware = true; + kSMPAware = kSMPCount > 1; } } } // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm index c1dfc66a..432f79d3 100644 --- a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm @@ -79,4 +79,32 @@ mp_system_call_handler: o64 sysret -[bits 16] + +section .text + +global sched_jump_to_task + +;; Jump to the task from its stack frame. +sched_jump_to_task: + push rbp + mov rbp, rsp + + mov r8, [rcx + 0x10] + mov r9, [rcx + 0x18] + mov r10, [rcx + 0x20] + mov r11, [rcx + 0x28] + mov r12, [rcx + 0x30] + mov r13, [rcx + 0x38] + mov r14, [rcx + 0x40] + mov r15, [rcx + 0x48] + + mov rax, [rcx + 0x00] + mov rsp, [rcx + 0x08] ; SP + + jmp rax + +global rtl_ne_task + +rtl_ne_task: + jmp $ + ret
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 1e513e3f..2c2bf5ff 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -11,6 +11,8 @@ STATIC BOOL kIsScheduling = NO; +EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip); + /// @brief Handle GPF fault. /// @param rsp EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) { @@ -104,16 +106,6 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) { - (Void)(Kernel::kout << "Kernel: Kernel RIP: " << Kernel::hex_number(rip) << Kernel::kendl); - Kernel::kout << "Kernel: SIGTRAP\r"; - - kIsScheduling = NO; - - while (YES) - ; - } - kIsScheduling = NO; (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index 0634b0ea..60a20b77 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -232,17 +232,15 @@ IntExp 30 IntNormal 31 [extern idt_handle_scheduler] +[extern kApicBaseAddress] __NE_INT_32: - cld - push rax mov rcx, rsp call idt_handle_scheduler pop rax - mov al, 0x20 - out 0x20, al + mov dword [kApicBaseAddress+0xB0], 0 o64 iret @@ -413,12 +411,3 @@ kInterruptVectorTable: dq __NE_INT_%+i %assign i i+1 %endrep - -section .text - -global sched_jump_to_task - -;; Jump to the task from its stack frame. -sched_jump_to_task: - mov rsp, rcx - ret
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index b0ac076d..a535b4ac 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -103,14 +103,22 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { return kEfiFail; } -EXTERN_C Kernel::Void rtl_ne_task(Kernel::Void) { - kout << "Hello, world!\r"; - dbg_break_point(); -} - -EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp); +EXTERN_C void rtl_ne_task(void); EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { + Kernel::rtl_create_user_process(rtl_ne_task, "NeTask"); + Kernel::rtl_create_user_process(rtl_ne_task, "NeTask#2"); + Kernel::rtl_create_user_process(rtl_ne_task, "NeTask#3"); + + Kernel::HAL::Register64 idt_reg; + idt_reg.Base = reinterpret_cast<Kernel::UIntPtr>(kInterruptVectorTable); + + Kernel::HAL::IDTLoader idt_loader; + + idt_loader.Load(idt_reg); + + Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); + #ifdef __FSKIT_INCLUDES_HEFS__ if (!Kernel::HeFS::fs_init_hefs()) { // Fallback to NeFS, if HeFS doesn't work here. @@ -123,17 +131,6 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { } #endif - Kernel::rtl_create_user_process(rtl_ne_task, "NeTask"); - - Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - - Kernel::HAL::Register64 idt_reg; - idt_reg.Base = reinterpret_cast<Kernel::UIntPtr>(kInterruptVectorTable); - - Kernel::HAL::IDTLoader idt_loader; - - idt_loader.Load(idt_reg); - while (YES) ; } diff --git a/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc b/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc index 66f27c24..2fc18e2f 100644 --- a/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc @@ -16,6 +16,11 @@ */ namespace Kernel::HAL { +Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept { + if (!lo || !hi) return; + asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); +} + Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept { asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr)); } diff --git a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc index 8f7ffdaf..0c468e14 100644 --- a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc @@ -25,7 +25,7 @@ EXTERN_C Void __zka_pure_call(USER_PROCESS* process) { EXTERN_C Bool hal_check_stack(HAL::StackFramePtr stack_ptr) { if (!stack_ptr) return No; - return stack_ptr->SP != 0 && stack_ptr->BP != 0; + return stack_ptr->SP != 0 && stack_ptr->IP != 0; } /// @brief Wakes up thread. diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index e1ce8718..1b2e35f7 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -83,18 +83,17 @@ using Reg = RawRegister; using InterruptId = UInt16; /* For each element in the IVT */ /// @brief Stack frame (as retrieved from assembly.) -struct PACKED StackFrame final { - RawRegister R8{0}; - RawRegister R9{0}; - RawRegister R10{0}; - RawRegister FS{0}; - RawRegister R12{0}; - RawRegister R13{0}; - RawRegister R14{0}; - RawRegister R15{0}; - RawRegister GS{0}; - RawRegister SP{0}; - RawRegister BP{0}; +struct PACKED StackFrame { + Reg IP; + Reg SP; + Reg R8; + Reg R9; + Reg R10; + Reg R11; + Reg R12; + Reg R13; + Reg R14; + Reg R15; }; typedef StackFrame* StackFramePtr; @@ -187,13 +186,7 @@ UIntPtr mm_get_phys_address(VoidPtr virtual_address); /// @param lo low byte /// @param hi high byte /***********************************************************************************/ -inline UInt32 hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept { - if (!lo || !hi) return 0; - - asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); - - return *lo + *hi; -} +Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept; /// @brief Set Model-specific register. /// @param msr MSR diff --git a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc index a8f0b1e1..ee286639 100644 --- a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc @@ -25,6 +25,6 @@ EXTERN_C Void __zka_pure_call(USER_PROCESS* process) { EXTERN_C Bool hal_check_stack(HAL::StackFramePtr stack_ptr) {
if (!stack_ptr) return No;
- return stack_ptr->SP != 0 && stack_ptr->BP != 0;
+ return stack_ptr->SP != 0 && stack_ptr->IP != 0;
}
} // namespace Kernel
diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index 1d9d2af2..9f16d8f5 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -42,17 +42,17 @@ typedef UIntPtr Reg; typedef Register64 Register; /// @note let's keep the same name as AMD64 HAL. -struct PACKED StackFrame final { - Reg R8{0}; - Reg R9{0}; - Reg R10{0}; - Reg R11{0}; - Reg R12{0}; - Reg R13{0}; - Reg R14{0}; - Reg R15{0}; - Reg SP{0}; - Reg BP{0}; +struct PACKED StackFrame { + Reg IP; + Reg SP; + Reg R8; + Reg R9; + Reg R10; + Reg R11; + Reg R12; + Reg R13; + Reg R14; + Reg R15; }; typedef StackFrame* StackFramePtr; diff --git a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc index 617b3dda..daa26e53 100644 --- a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc @@ -22,7 +22,7 @@ void mp_wakeup_thread(HAL::StackFramePtr stack) { if (!stack) return; hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15), - reinterpret_cast<VoidPtr>(stack->BP)); + reinterpret_cast<VoidPtr>(stack->IP)); } /// @brief makes thread sleep. diff --git a/dev/kernel/HALKit/POWER/Processor.h b/dev/kernel/HALKit/POWER/Processor.h index 850b636d..d50c4ff2 100644 --- a/dev/kernel/HALKit/POWER/Processor.h +++ b/dev/kernel/HALKit/POWER/Processor.h @@ -28,7 +28,7 @@ struct PACKED StackFrame final { Reg R14{0}; Reg R15{0}; Reg SP{0}; - Reg BP{0}; + Reg IP{0}; }; typedef StackFrame* StackFramePtr; diff --git a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc index 80162b81..31d4a62e 100644 --- a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc @@ -25,7 +25,7 @@ void mp_wakeup_thread(HAL::StackFramePtr stack) { if (!stack) return;
hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15),
- reinterpret_cast<VoidPtr>(stack->BP));
+ reinterpret_cast<VoidPtr>(stack->IP));
}
/// @brief makes thread sleep.
|
