diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-05-29 10:51:53 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-29 10:51:53 +0200 |
| commit | 5c0bb7ee7b1b0fee02cc179fb21f4c57a61d6c2d (patch) | |
| tree | cb17577bcdc9714c97a84ce417a075117097f146 /dev/kernel/HALKit | |
| parent | d608230b1350b064ceb01e6572519b108f6139b0 (diff) | |
| parent | 3167f59dbb401d6a79b1524537e04218baf49ee3 (diff) | |
Merge pull request #32 from nekernel-org/dev
0.0.2e3
Diffstat (limited to 'dev/kernel/HALKit')
53 files changed, 799 insertions, 1102 deletions
diff --git a/dev/kernel/HALKit/AMD64/CPUID.h b/dev/kernel/HALKit/AMD64/CPUID.h index 8250dfad..cc3bd25e 100644 --- a/dev/kernel/HALKit/AMD64/CPUID.h +++ b/dev/kernel/HALKit/AMD64/CPUID.h @@ -13,7 +13,7 @@ #pragma once -#include <NewKit/Defines.h> +#include <NeKit/Defines.h> EXTERN_C { #include <cpuid.h> diff --git a/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc b/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc index f4dd1347..1d289db8 100644 --- a/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc +++ b/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc @@ -6,8 +6,8 @@ #include <ArchKit/ArchKit.h> #include <HALKit/AMD64/Processor.h> -#include <KernelKit/MemoryMgr.h> -#include <NewKit/KString.h> +#include <KernelKit/HeapMgr.h> +#include <NeKit/KString.h> #include <modules/ACPI/ACPIFactoryInterface.h> namespace Kernel { diff --git a/dev/kernel/HALKit/AMD64/HalAPICController.cc b/dev/kernel/HALKit/AMD64/HalAPICController.cc deleted file mode 100644 index 758e2f52..00000000 --- a/dev/kernel/HALKit/AMD64/HalAPICController.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#include <HALKit/AMD64/Processor.h> -#include <modules/ACPI/ACPIFactoryInterface.h> - -#define cIOAPICRegVal (4) -#define cIOAPICRegReg (0) - -namespace Kernel::HAL { -APICController::APICController(VoidPtr base) : fApic(base) {} - -/// @brief Read from APIC controller. -/// @param reg register. -UInt32 APICController::Read(UInt32 reg) noexcept { - MUST_PASS(this->fApic); - - UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; - io_apic[cIOAPICRegReg] = (reg & 0xFF); - - return io_apic[cIOAPICRegVal]; -} - -/// @brief Write to APIC controller. -/// @param reg register. -/// @param value value. -Void APICController::Write(UInt32 reg, UInt32 value) noexcept { - MUST_PASS(this->fApic); - - UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; - - io_apic[cIOAPICRegReg] = (reg & 0xFF); - io_apic[cIOAPICRegVal] = value; -} -} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc b/dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc new file mode 100644 index 00000000..6aba5b0e --- /dev/null +++ b/dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc @@ -0,0 +1,39 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <HALKit/AMD64/Processor.h> +#include <modules/ACPI/ACPIFactoryInterface.h> + +namespace Kernel::HAL { +/***********************************************************************************/ +/// Constructors. +/***********************************************************************************/ +LAPICDmaWrapper::LAPICDmaWrapper(VoidPtr base) : fApic(base) {} +LAPICDmaWrapper::~LAPICDmaWrapper() = default; + +/***********************************************************************************/ +/// @brief Read from APIC controller. +/// @param reg register. +/***********************************************************************************/ +UInt32 LAPICDmaWrapper::Read(UInt16 reg) noexcept { + MUST_PASS(this->fApic); + + UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; + return io_apic[reg]; +} + +/***********************************************************************************/ +/// @brief Write to APIC controller. +/// @param reg register. +/// @param value value. +/***********************************************************************************/ +Void LAPICDmaWrapper::Write(UInt16 reg, UInt32 value) noexcept { + MUST_PASS(this->fApic); + + UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; + io_apic[reg] = value; +} +} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index dd9a36ed..3e10d577 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -4,27 +4,34 @@ ------------------------------------------- */ +#define APIC_MAG "APIC" + +#define APIC_ICR_LOW 0x300 +#define APIC_ICR_HIGH 0x310 +#define APIC_SIPI_VEC 0x00500 +#define APIC_EIPI_VEC 0x00400 + +#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 LAPIC_REG_ENABLE 0x80 +#define LAPIC_REG_SPURIOUS 0xF0 + +#define APIC_BASE_MSR 0x1B +#define APIC_BASE_MSR_BSP 0x100 +#define APIC_BASE_MSR_ENABLE 0x800 + #include <ArchKit/ArchKit.h> #include <HALKit/AMD64/Processor.h> #include <KernelKit/BinaryMutex.h> #include <KernelKit/HardwareThreadScheduler.h> #include <KernelKit/ProcessScheduler.h> #include <KernelKit/Timer.h> -#include <NewKit/KernelPanic.h> +#include <NeKit/KernelPanic.h> #include <modules/ACPI/ACPIFactoryInterface.h> #include <modules/CoreGfx/TextGfx.h> -#define kAPIC_Signature "APIC" - -#define kAPIC_ICR_Low 0x300 -#define kAPIC_ICR_High 0x310 -#define kAPIC_SIPI_Vector 0x00500 -#define kAPIC_EIPI_Vector 0x00400 - -#define kAPIC_BASE_MSR 0x1B -#define kAPIC_BASE_MSR_BSP 0x100 -#define kAPIC_BASE_MSR_ENABLE 0x800 - /// @note: _hal_switch_context is internal /////////////////////////////////////////////////////////////////////////////////////// @@ -39,83 +46,39 @@ struct HAL_HARDWARE_THREAD; struct HAL_HARDWARE_THREAD final { HAL::StackFramePtr mFramePtr; - ProcessID mProcessID{0}; - UInt8 mCoreID{0}; + ProcessID mThreadID{0}; }; +EXTERN_C Void sched_jump_to_task(HAL::StackFramePtr stack_frame); + STATIC HAL_APIC_MADT* kMADTBlock = nullptr; STATIC Bool kSMPAware = false; STATIC Int64 kSMPCount = 0; -STATIC UIntPtr kApicBaseAddress = 0UL; +EXTERN_C UIntPtr kApicBaseAddress; + +STATIC Int32 kSMPInterrupt = 0; +STATIC UInt64 kAPICLocales[kMaxAPInsideSched] = {0}; +STATIC VoidPtr kRawMADT = nullptr; -STATIC Int32 kSMPInterrupt = 0; -STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0}; -STATIC VoidPtr kRawMADT = nullptr; +STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}}; /// @brief Multiple APIC Descriptor Table. struct HAL_APIC_MADT final SDT_OBJECT { UInt32 Address; // Madt address - UInt8 Flags; // Madt flags - - struct { - UInt8 Type; - UInt8 Len; - - union APIC { - struct IOAPIC { - UInt8 IoID; - UInt8 Zero; - UInt32 IoAddress; - UInt32 GISBase; - } IOAPIC; - - struct LAPIC_NMI { - UInt8 Source; - UInt8 IRQSource; - UInt32 GSI; - UInt16 Flags; - } LApicNMI; - - struct LAPIC { - UInt8 ProcessorID; - UInt16 Flags; - UInt8 LINT; - } LAPIC; - - struct LAPIC_OVERRIDE { - UInt16 Reserved; - UInt64 Address; - } LApicOverride; - - struct LAPIC_X2 { - UInt16 Reserved; - UInt32 x2APICID; - UInt32 Flags; - UInt32 AcpiID; - } LocalApicX2; - } Apic; - } List[1]; // Records List + UInt32 Flags; // Madt flags + UInt8 List[1]; // Records List }; -/////////////////////////////////////////////////////////////////////////////////////// - -/***********************************************************************************/ -/// @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, kAPIC_ICR_High, apic_id << 24); - Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_Low, 0x00000500 | 0x00004000 | 0x00000000); +struct LAPIC final { + UInt8 Type; + UInt8 Length; + UInt8 ProcessorID; + UInt8 APICID; + UInt32 Flags; +}; - while (Kernel::ke_dma_read<UInt32>(target, kAPIC_ICR_Low) & 0x1000) { - ; - } -} +/////////////////////////////////////////////////////////////////////////////////////// /***********************************************************************************/ /// @brief Send end IPI for CPU. @@ -124,36 +87,40 @@ Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) { /// @param target /// @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); +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); - 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); } } -STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}}; - -EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) { - const auto process_index = pid % kSchedProcessLimitPerTeam; +/***********************************************************************************/ +/// @brief Get current stack frame for a thread. +/// @param thrdid The thread ID. +/***********************************************************************************/ - return kHWThread[process_index].mFramePtr; +EXTERN_C HAL::StackFramePtr mp_get_current_task(ThreadID thrdid) { + if (thrdid > kSMPCount) return nullptr; + return kHWThread[thrdid].mFramePtr; } -EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) { - MUST_PASS(stack_frame); +/***********************************************************************************/ +/// @brief Register current stack frame for a thread. +/// @param stack_frame The current stack frame. +/// @param thrdid The thread ID. +/***********************************************************************************/ - const auto process_index = pid % kSchedProcessLimitPerTeam; +EXTERN_C BOOL mp_register_task(HAL::StackFramePtr stack_frame, ThreadID thrdid) { + if (thrdid > kSMPCount) return NO; + if (!stack_frame) return NO; - kHWThread[process_index].mFramePtr = stack_frame; - kHWThread[process_index].mProcessID = pid; + kHWThread[thrdid].mFramePtr = stack_frame; - kHWThread[process_index].mCoreID = kAPICLocales[0]; + HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); - hal_send_sipi(kApicBaseAddress, kHWThread[process_index].mCoreID, - (UInt8) (((UIntPtr) stack_frame->BP) >> 12)); + sched_jump_to_task(kHWThread[thrdid].mFramePtr); return YES; } @@ -162,24 +129,16 @@ EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) /// @brief Is the current config SMP aware? /// @return True if YES, False if not. /***********************************************************************************/ + Bool mp_is_smp(Void) noexcept { return kSMPAware; } /***********************************************************************************/ -/// @brief Assembly symbol to bootstrap AP. -/***********************************************************************************/ -EXTERN_C Char* hal_ap_blob_start; - -/***********************************************************************************/ -/// @brief Assembly symbol to bootstrap AP. -/***********************************************************************************/ -EXTERN_C Char* hal_ap_blob_end; - -/***********************************************************************************/ /// @brief Fetch and enable SMP scheduler. /// @param vendor_ptr SMP containing structure. /***********************************************************************************/ + Void mp_init_cores(VoidPtr vendor_ptr) noexcept { if (!vendor_ptr) return; @@ -188,51 +147,80 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { return; } - auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr); - kRawMADT = hw_and_pow_int.Find(kAPIC_Signature).Leak().Leak(); + PowerFactoryInterface hw_and_pow_int{vendor_ptr}; + auto pwr = hw_and_pow_int.Find(APIC_MAG); + + if (pwr.HasError()) { + kSMPAware = NO; + return; + } + + kRawMADT = pwr.Leak().Leak(); kMADTBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT); kSMPAware = NO; if (kMADTBlock) { - SizeT index = 1; - kSMPInterrupt = 0; kSMPCount = 0; - kout << "SMP: Starting APs...\r"; + UInt32 lo = 0U, hi = 0U; - kApicBaseAddress = kMADTBlock->Address; + hal_get_msr(APIC_BASE_MSR, &lo, &hi); - while (Yes) { - /// @note Anything bigger than x2APIC type doesn't exist. - if (kMADTBlock->List[index].Type > 9 || kSMPCount > kSchedProcessLimitPerTeam) break; + UInt64 apic_base = ((UInt64) hi << 32) | lo; - switch (kMADTBlock->List[index].Type) { - case 0x00: { - if (kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID < 1) break; + apic_base |= APIC_BASE_MSR_ENABLE; // Enable APIC. - kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID; - (Void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl); + lo = apic_base & 0xFFFFFFFF; + hi = apic_base >> 32; + hal_set_msr(APIC_BASE_MSR, lo, hi); + + kApicBaseAddress = apic_base & 0xFFFFF000; + + LAPICDmaWrapper controller{(VoidPtr) kApicBaseAddress}; + + controller.Write(LAPIC_REG_ENABLE, 0); + controller.Write(LAPIC_REG_SPURIOUS, 0x1FF); // Enable bit, spurious interrupt vector register. + controller.Write(LAPIC_REG_TIMER_DIV, 0b0011); + controller.Write(LAPIC_REG_TIMER_LVT, 0x20 | (1 << 17)); + controller.Write(LAPIC_REG_TIMER_INITCNT, 1000000); + + volatile UInt8* entry_ptr = reinterpret_cast<volatile UInt8*>(kMADTBlock->List); + volatile UInt8* end_ptr = ((UInt8*) kMADTBlock) + kMADTBlock->Length; + + while (entry_ptr < end_ptr) { + UInt8 type = *entry_ptr; + UInt8 length = *(entry_ptr + 1); + + // Avoid infinite loop on bad APIC tables. + if (length < 2) break; + + if (type == 0) { + volatile LAPIC* entry_struct = (volatile LAPIC*) entry_ptr; + + if (entry_struct->Flags & 0x1) { + kAPICLocales[kSMPCount] = entry_struct->ProcessorID; + kHWThread[kSMPCount].mThreadID = kAPICLocales[kSMPCount]; + ++kSMPCount; - break; + + kout << "Kind: LAPIC: ON\r"; + + // 0x7c00, as recommended by the Intel SDM. + hal_send_ipi_msg(kApicBaseAddress, entry_struct->ProcessorID, 0x7c); + } else { + kout << "Kind: LAPIC: OFF\r"; } - default: - break; + } else { + kout << "Kind: UNKNOWN\r"; } - ++index; + entry_ptr += length; } - (Void)(kout << "SMP: Number of APs: " << number(kSMPCount) << kendl); - - // Kernel is now SMP aware. - // That means that the scheduler is now available (on MP Kernels) - - kSMPAware = true; - - /// TODO: Notify Boot AP that it must start. + kSMPAware = kSMPCount > 1; } } } // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessorGNU.s b/dev/kernel/HALKit/AMD64/HalApplicationProcessorGNU.s deleted file mode 100644 index a8ad3b76..00000000 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessorGNU.s +++ /dev/null @@ -1,8 +0,0 @@ -.data - -.global hal_ap_blob_start /* Export the start symbol */ -.global hal_ap_blob_end /* Export the end symbol */ - -hal_ap_blob_start: - .incbin "HALKit/AMD64/HalApplicationProcessorStartup.bin" -hal_ap_blob_end: diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm b/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm deleted file mode 100644 index 09a59e4f..00000000 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm +++ /dev/null @@ -1,79 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * NeKernel -;; * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. -;; * -;; * 25/03/25: FIX: Fix warning regarding resb being used inside a non-bss area (using no-op instead). -;; * -;; * ======================================================== -;; */ - -[bits 16] -[org 0x7c000] - -hal_ap_start: - mov ax, 0x0 - mov ss, ax - mov esp, 0x7000 - - cli - mov eax, cr0 - or eax, 1 - mov cr0, eax - jmp .hal_ap_start_flush -.hal_ap_start_flush: - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - mov eax, cr4 - or eax, 1 << 5 - mov cr4, eax - - mov eax, cr3 - mov cr3, eax - - mov ecx, 0xC0000080 - rdmsr - or eax, 1 - wrmsr - - mov eax, cr0 - or eax, (1 << 31) - mov cr0, eax - - jmp 0x08:hal_ap_64bit_entry -hal_ap_end: - -hal_ap_length: - dq hal_ap_end - hal_ap_start - -[bits 64] - -hal_ap_64bit_entry: - mov ax, 0x23 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - mov rsp, [hal_ap_64bit_entry_stack_end] - - push 0x33 - push qword [hal_ap_64bit_entry_loop] - o64 pushf - push rsp - push 0x33 - - o64 iret - -hal_ap_64bit_entry_loop: - jmp $ - -hal_ap_64bit_entry_stack: - times 8196*2 nop -hal_ap_64bit_entry_stack_end:
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s b/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s new file mode 100644 index 00000000..903038ea --- /dev/null +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s @@ -0,0 +1,14 @@ +.text + +.global hal_ap_blob_start +.global hal_ap_blob_length + +hal_ap_blob_start: + cli + hlt + jmp hal_ap_blob_start + +.data + +hal_ap_blob_length: + .long 4 diff --git a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm index c1dfc66a..be150dde 100644 --- a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm @@ -56,6 +56,8 @@ extern hal_system_call_enter global mp_system_call_handler mp_system_call_handler: + push rbp + mov rbp, rsp push r8 push r9 @@ -77,6 +79,59 @@ mp_system_call_handler: pop r9 pop r8 - o64 sysret + pop rbp -[bits 16] + o64 iret + + +section .text + +global sched_jump_to_task + +sched_jump_to_task: + push rbp + mov rbp, rsp + + mov ax, 0x30 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov ax, 0x18 + ltr ax + + push 0x30 + mov rdx, [rcx + 0x08] + push rdx + o64 pushf + push 0x28 + mov rdx, [rcx + 0x00] + push rdx + + call sched_recover_registers + + o64 iret + +global sched_idle_task + +sched_idle_task: + jmp $ + ret + +sched_recover_registers: + 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] + + pop rbp + + ret
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalControlRegister.s b/dev/kernel/HALKit/AMD64/HalControlRegisterAPI.s index 631d1d55..631d1d55 100644 --- a/dev/kernel/HALKit/AMD64/HalControlRegister.s +++ b/dev/kernel/HALKit/AMD64/HalControlRegisterAPI.s diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc index 84c35615..01456ae5 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc @@ -6,108 +6,90 @@ #include <ArchKit/ArchKit.h> #include <KernelKit/ProcessScheduler.h> -#include <NewKit/KString.h> +#include <NeKit/KString.h> #include <SignalKit/Signals.h> -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) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); +EXTERN_C Kernel::UIntPtr kApicBaseAddress; - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) return; +STATIC BOOL kIsRunning = NO; - kIsScheduling = 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; - Kernel::kout << "Kernel: General Protection Fault.\r"; + 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; - - Kernel::kout << "Kernel: SIGKILL status.\r"; - - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - - process.Leak().Crash(); } /// @brief Handle page fault. /// @param rsp EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) return; - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + process.Leak().Crash(); - Kernel::kout << "Kernel: Page Fault.\r"; - Kernel::kout << "Kernel: SIGKILL\r"; + hal_idt_send_eoi(14); process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; process.Leak().Signal.Status = process.Leak().Status; - - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - - process.Leak().Crash(); -} - -namespace Kernel::Detail { -constexpr static Int32 kTimeoutCount = 100000UL; } /// @brief Handle scheduler interrupt. EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { NE_UNUSED(rsp); - static Kernel::Int64 try_count_before_brute = Kernel::Detail::kTimeoutCount; - - while (kIsScheduling) { - --try_count_before_brute; + hal_idt_send_eoi(32); - if (try_count_before_brute < 1) break; - } + while (kIsRunning) + ; - try_count_before_brute = Kernel::Detail::kTimeoutCount; - kIsScheduling = YES; + kIsRunning = YES; Kernel::UserProcessHelper::StartScheduling(); - kIsScheduling = NO; + kIsRunning = NO; } /// @brief Handle math fault. /// @param rsp EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) return; - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + process.Leak().Crash(); - Kernel::kout << "Kernel: Math error (division by zero?).\r"; + hal_idt_send_eoi(8); process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; process.Leak().Signal.Status = process.Leak().Status; - - Kernel::kout << "Kernel: SIGKILL status.\r"; - - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - - process.Leak().Crash(); } /// @brief Handle any generic fault. /// @param rsp EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) return; + auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + process.Leak().Crash(); - kIsScheduling = NO; + hal_idt_send_eoi(30); Kernel::kout << "Kernel: Generic Process Fault.\r"; @@ -116,57 +98,32 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { process.Leak().Signal.Status = process.Leak().Status; Kernel::kout << "Kernel: SIGKILL status.\r"; - - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - - process.Leak().Crash(); } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); + auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) { - Kernel::kout << "Kernel: SIGTRAP\r"; - - while (YES) - ; - } - - kIsScheduling = NO; - - (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); - Kernel::kout << "Kernel: SIGTRAP\r"; + hal_idt_send_eoi(3); process.Leak().Signal.SignalArg = rip; process.Leak().Signal.SignalID = SIGTRAP; process.Leak().Signal.Status = process.Leak().Status; - Kernel::kout << "Kernel: SIGTRAP status.\r"; - 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().CurrentProcess(); - - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) return; - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + process.Leak().Crash(); - Kernel::kout << "Kernel: Undefined Opcode.\r"; + hal_idt_send_eoi(6); process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; process.Leak().Signal.Status = process.Leak().Status; - - Kernel::kout << "Kernel: SIGKILL status.\r"; - - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - - process.Leak().Crash(); } /// @brief Enter syscall from assembly. @@ -174,20 +131,14 @@ 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) { - if (rcx_syscall_index < kSysCalls.Count()) { - Kernel::kout << "syscall: Enter Syscall.\r"; + 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); - } else { - Kernel::kout << "syscall: syscall isn't valid at all! (is nullptr)\r"; } - } else { - Kernel::kout << "syscall: syscall isn't hooked at all! (is set to false)\r"; } - - Kernel::kout << "syscall: Exit Syscall.\r"; } } @@ -196,19 +147,13 @@ 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) { - if (rcx_kerncall_index < kKernCalls.Count()) { - Kernel::kout << "kerncall: Enter Kernel Call List.\r"; + 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); - } else { - Kernel::kout << "kerncall: Kernel call isn't valid at all! (is nullptr)\r"; } - } else { - Kernel::kout << "kerncall: Kernel call isn't hooked at all! (is set to false)\r"; } - - Kernel::kout << "kerncall: Exit Kernel Call List.\r"; } } diff --git a/dev/kernel/HALKit/AMD64/HalCoreSystemCalls.cc b/dev/kernel/HALKit/AMD64/HalCoreSystemCalls.cc index 8581950f..11e773a8 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreSystemCalls.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreSystemCalls.cc @@ -3,3 +3,7 @@ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ + +#include <ArchKit/ArchKit.h> + +using namespace Kernel; diff --git a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc index 5d14f214..b0463eb5 100644 --- a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc +++ b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc @@ -6,8 +6,8 @@ #include <ArchKit/ArchKit.h> #include <KernelKit/DebugOutput.h> -#include <NewKit/New.h> -#include <NewKit/Utils.h> +#include <NeKit/New.h> +#include <NeKit/Utils.h> #include <modules/CoreGfx/CoreGfx.h> #include <modules/CoreGfx/TextGfx.h> diff --git a/dev/kernel/HALKit/AMD64/HalDebugPort.cc b/dev/kernel/HALKit/AMD64/HalDebugProtocol.cc index e7448aa3..8a1249ea 100644 --- a/dev/kernel/HALKit/AMD64/HalDebugPort.cc +++ b/dev/kernel/HALKit/AMD64/HalDebugProtocol.cc @@ -9,11 +9,8 @@ #include <ArchKit/ArchKit.h> #include <KernelKit/DebugOutput.h> +#include <NetworkKit/NetworkDevice.h> // after that we have start of additional data. -namespace Kernel { -void rt_debug_listen(DebuggerPortHeader* theHook) noexcept { - NE_UNUSED(theHook); -} -} // namespace Kernel +namespace Kernel {} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc index 2fb6ad4c..f9749946 100644 --- a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc +++ b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc @@ -8,56 +8,10 @@ #include <FSKit/NeFS.h> #include <HALKit/AMD64/Processor.h> -#define kPITDefaultTicks (1000U) - namespace Kernel::HAL { namespace Detail { STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64 kInterruptVectorTable[kKernelIdtSize] = {}; - - STATIC ATTRIBUTE(unused) void hal_set_irq_mask(UInt8 irql) [[maybe_unused]] { - UInt16 port; - UInt8 value; - - if (irql < 8) { - port = kPICData; - } else { - port = kPIC2Data; - irql -= 8; - } - - value = rt_in8(port) | (1 << irql); - rt_out8(port, value); - } - - STATIC void hal_clear_irq_mask(UInt8 irql) [[maybe_unused]] { - UInt16 port; - UInt8 value; - - if (irql < 8) { - port = kPICData; - } else { - port = kPIC2Data; - irql -= 8; - } - - value = rt_in8(port) & ~(1 << irql); - rt_out8(port, value); - } - - STATIC Void hal_enable_pit(UInt16 ticks) noexcept { - if (ticks == 0) ticks = kPITDefaultTicks; - - // Configure PIT to receieve scheduler interrupts. - - UInt16 kPITCommDivisor = kPITFrequency / ticks; // 100 Hz. - - HAL::rt_out8(kPITControlPort, 0x36); // Command to PIT - HAL::rt_out8(kPITChannel0Port, kPITCommDivisor & 0xFF); // Send low byte - HAL::rt_out8(kPITChannel0Port, (kPITCommDivisor >> 8) & 0xFF); // Send high byte - - hal_clear_irq_mask(32); - } } // namespace Detail /// @brief Loads the provided Global Descriptor Table. @@ -70,11 +24,10 @@ Void GDTLoader::Load(Register64& gdt) { } Void IDTLoader::Load(Register64& idt) { +#ifndef __NE_MODULAR_KERNEL_COMPONENTS__ rt_cli(); - const Int16 kPITTickForScheduler = kPITDefaultTicks; - - volatile ::Kernel::UIntPtr** ptr_ivt = (volatile ::Kernel::UIntPtr**) idt.Base; + volatile UIntPtr** ptr_ivt = (volatile UIntPtr**) idt.Base; for (SizeT idt_indx = 0; idt_indx < kKernelIdtSize; ++idt_indx) { Detail::kInterruptVectorTable[idt_indx].Selector = kIDTSelector; @@ -92,13 +45,11 @@ Void IDTLoader::Load(Register64& idt) { idt.Base = (UIntPtr) &Detail::kInterruptVectorTable[0]; idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) * (kKernelIdtSize); - Detail::hal_enable_pit(kPITTickForScheduler); - -#ifndef __NE_MODULAR_KERNEL_COMPONENTS__ hal_load_idt(idt); + rt_sti(); #endif // __NE_MODULAR_KERNEL_COMPONENTS__ - rt_sti(); + return; } /// @brief Loads the Global Descriptor Table into the CPU. diff --git a/dev/kernel/HALKit/AMD64/HalBootHeader.asm b/dev/kernel/HALKit/AMD64/HalHandoverStub.asm index 21f8621b..a337a223 100644 --- a/dev/kernel/HALKit/AMD64/HalBootHeader.asm +++ b/dev/kernel/HALKit/AMD64/HalHandoverStub.asm @@ -4,8 +4,6 @@ ;; * NeKernel ;; * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ;; * -;; * 25/03/25: Rename HalBootHeader.asm to HalBootHeader.asm, expose struct symbols; remove unused external symbol. -;; * ;; * ======================================================== ;; */ diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index cc34b99f..a0ff40dc 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -30,6 +30,8 @@ __NE_INT_%1: std + add rsp, 8 + o64 iret %endmacro @@ -45,15 +47,12 @@ 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 @@ -64,10 +63,6 @@ __NE_INT_0: __NE_INT_1: cld - - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_generic pop rcx @@ -78,10 +73,6 @@ __NE_INT_1: __NE_INT_2: cld - - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_generic pop rcx @@ -93,12 +84,8 @@ __NE_INT_2: ;; @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_generic + call idt_handle_breakpoint pop rcx std @@ -108,10 +95,6 @@ __NE_INT_3: __NE_INT_4: cld - mov al, 0x20 - out 0x20, al - - push rcx call idt_handle_generic pop rcx @@ -122,10 +105,6 @@ __NE_INT_4: __NE_INT_5: cld - - mov al, 0x20 - out 0x20, al - std o64 iret @@ -133,12 +112,8 @@ __NE_INT_5: ;; Invalid opcode interrupt __NE_INT_6: cld - - mov al, 0x20 - out 0x20, al - push rcx - call idt_handle_generic + call idt_handle_ud pop rcx std @@ -147,10 +122,6 @@ __NE_INT_6: __NE_INT_7: cld - - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_generic pop rcx @@ -163,12 +134,8 @@ __NE_INT_7: __NE_INT_8: cld - mov al, 0x20 - out 0xA0, al - out 0x20, al - push rcx - call idt_handle_generic + call idt_handle_math pop rcx std @@ -184,25 +151,18 @@ IntExp 12 __NE_INT_13: cld - mov al, 0x20 - out 0xA0, al - 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 0xA0, al - out 0x20, al - push rcx call idt_handle_pf pop rcx @@ -232,14 +192,11 @@ IntExp 30 IntNormal 31 [extern idt_handle_scheduler] +[extern kApicBaseAddress] __NE_INT_32: cld - mov al, 0x20 - out 0xA0, al - out 0x20, al - push rax mov rcx, rsp call idt_handle_scheduler @@ -257,7 +214,20 @@ IntNormal 36 IntNormal 37 IntNormal 38 IntNormal 39 -IntNormal 40 + +[extern rtl_rtl8139_interrupt_handler] + +__NE_INT_40: + cld + + push rax + mov rcx, rsp + call rtl_rtl8139_interrupt_handler + pop rax + + std + + o64 iret IntNormal 41 @@ -276,15 +246,13 @@ IntNormal 49 __NE_INT_50: cld - mov al, 0x20 - out 0xA0, al - out 0x20, al - push rax mov rax, hal_system_call_enter mov rcx, r8 mov rdx, r9 + mov r8, r10 + mov r9, r11 call rax pop rax @@ -296,15 +264,13 @@ __NE_INT_50: __NE_INT_51: cld - mov al, 0x20 - out 0xA0, al - out 0x20, al - push rax mov rax, hal_kernel_call_enter mov rcx, r8 mov rdx, r9 + mov r8, r10 + mov r9, r11 call rax pop rax @@ -399,3 +365,6 @@ kInterruptVectorTable: dq __NE_INT_%+i %assign i i+1 %endrep + +kApicBaseAddress: + dq 0
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 2747439a..446a1e85 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -14,26 +14,24 @@ #include <KernelKit/Timer.h> #include <NetworkKit/IPC.h> #include <StorageKit/AHCI.h> +#include <generic_kits/BenchKit/X64Chrono.h> #include <modules/ACPI/ACPIFactoryInterface.h> #include <modules/CoreGfx/TextGfx.h> #ifndef __NE_MODULAR_KERNEL_COMPONENTS__ EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; -STATIC Kernel::Void hal_pre_init_scheduler() noexcept { - for (Kernel::SizeT i = 0U; - i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i) { - Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::USER_PROCESS(); - } -} - /// @brief Kernel init function. /// @param handover_hdr Handover boot header. EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { + using namespace Kernel; + if (handover_hdr->f_Magic != kHandoverMagic && handover_hdr->f_Version != kHandoverVersion) { return kEfiFail; } + HAL::rt_sti(); + kHandoverHeader = handover_hdr; FB::fb_clear_video(); @@ -43,26 +41,31 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey, handover_hdr->f_HardwareTables.f_ImageHandle); - kKernelCR3 = kHandoverHeader->f_PageStart; + kKernelVM = kHandoverHeader->f_PageStart; - hal_write_cr3(kKernelCR3); + hal_write_cr3(kKernelVM); /************************************** */ /* INITIALIZE BIT MAP. */ /************************************** */ - kKernelBitMpSize = kHandoverHeader->f_BitMapSize; - kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>( - reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart)); + kKernelBitMpSize = kHandoverHeader->f_BitMapSize; + kKernelBitMpStart = + reinterpret_cast<VoidPtr>(reinterpret_cast<UIntPtr>(kHandoverHeader->f_BitMapStart)); /************************************** */ /* INITIALIZE GDT AND SEGMENTS. */ /************************************** */ - STATIC CONST auto kGDTEntriesCount = 6; + STATIC CONST auto kGDTEntriesCount = 8; + + STATIC HAL::Detail::NE_TSS kKernelTSS{}; - /* GDT, mostly descriptors for user and kernel segments. */ - STATIC Kernel::HAL::Detail::NE_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = { + kKernelTSS.fRsp0 = (UInt64) kHandoverHeader->f_StackTop; + kKernelTSS.fIopb = sizeof(HAL::Detail::NE_TSS); + + /* The GDT, mostly descriptors for user and kernel segments. */ + STATIC HAL::Detail::NE_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = { {.fLimitLow = 0, .fBaseLow = 0, .fBaseMid = 0, @@ -81,6 +84,8 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { .fAccessByte = 0x92, .fFlags = 0xCF, .fBaseHigh = 0}, // Kernel data + {}, // TSS data low + {}, // TSS data high {.fLimitLow = 0x0, .fBaseLow = 0, .fBaseMid = 0, @@ -95,63 +100,70 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { .fBaseHigh = 0}, // User data }; + kGDTArray[3].fLimitLow = sizeof(HAL::Detail::NE_TSS) - 1; + kGDTArray[3].fBaseLow = ((UIntPtr) &kKernelTSS) & 0xFFFF; + kGDTArray[3].fBaseMid = (((UIntPtr) &kKernelTSS) >> 16) & 0xFF; + kGDTArray[3].fAccessByte = 0x89; // Present, type 9 = 64-bit available TSS + kGDTArray[3].fFlags = 0x20 | ((((UIntPtr) &kKernelTSS) >> 24) & 0x0F); + kGDTArray[3].fBaseHigh = (((UIntPtr) &kKernelTSS) >> 24) & 0xFF; + + kGDTArray[4].fLimitLow = ((UIntPtr) &kKernelTSS >> 32) & 0xFFFF; + kGDTArray[4].fBaseLow = 0; + kGDTArray[4].fBaseMid = 0; + kGDTArray[4].fAccessByte = 0; + kGDTArray[4].fFlags = 0; + kGDTArray[4].fBaseHigh = 0; + // Load memory descriptors. - Kernel::HAL::Register64 gdt_reg; + HAL::Register64 gdt_reg; - gdt_reg.Base = reinterpret_cast<Kernel::UIntPtr>(kGDTArray); - gdt_reg.Limit = (sizeof(Kernel::HAL::Detail::NE_GDT_ENTRY) * kGDTEntriesCount) - 1; + gdt_reg.Base = reinterpret_cast<UIntPtr>(kGDTArray); + gdt_reg.Limit = (sizeof(HAL::Detail::NE_GDT_ENTRY) * kGDTEntriesCount) - 1; //! GDT will load hal_read_init after it successfully loads the segments. - Kernel::HAL::GDTLoader gdt_loader; + HAL::GDTLoader gdt_loader; gdt_loader.Load(gdt_reg); return kEfiFail; } EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { - hal_pre_init_scheduler(); - -#ifdef __FSKIT_INCLUDES_HEFS__ - Kernel::HeFS::fs_init_hefs(); -#elif defined(__FSKIT_INCLUDES_NEFS__) - Kernel::NeFS::fs_init_nefs(); -#endif + using namespace Kernel; - Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - - Kernel::HAL::Register64 idt_reg; - idt_reg.Base = (Kernel::UIntPtr) kInterruptVectorTable; - - Kernel::HAL::IDTLoader idt_loader; - - idt_loader.Load(idt_reg); - - /// after the scheduler runs, we must look over teams, every 5000s in order to schedule every - /// process according to their affinity fairly. + for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { + HardwareThreadScheduler::The()[index].Leak()->Kind() = ThreadKind::kAPStandard; + HardwareThreadScheduler::The()[index].Leak()->ID() = index; + HardwareThreadScheduler::The()[index].Leak()->Busy(NO); + } - auto constexpr kSchedTeamSwitchMS = 5U; /// @brief Team switch time in milliseconds. + for (SizeT index = 0UL; index < UserProcessScheduler::The().TheCurrentTeam().AsArray().Count(); + ++index) { + UserProcessScheduler::The().TheCurrentTeam().AsArray()[index].Status = + ProcessStatusKind::kInvalid; + } - Kernel::HardwareTimer timer(rtl_milliseconds(kSchedTeamSwitchMS)); + rtl_create_user_process(sched_idle_task, "MgmtSrv"); //! Mgmt command server. + rtl_create_user_process(sched_idle_task, "LaunchSrv"); //! launchd + rtl_create_user_process(sched_idle_task, "SecSrv"); //! Login Server - STATIC Kernel::Array<UserProcessTeam, kSchedTeamCount> kTeams; + HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - static SizeT team_index = 0U; +#ifdef __FSKIT_INCLUDES_HEFS__ + HeFS::fs_init_hefs(); +#endif - /// @brief This just loops over the teams and switches between them. - /// @details Not even round-robin, just a simple loop in this boot core we're at. - while (YES) { - if (team_index > (kSchedTeamCount - 1)) { - team_index = 0U; - } +#ifdef __FSKIT_INCLUDES_NEFS__ + NeFS::fs_init_nefs(); +#endif - kTeams[team_index].Id() = team_index; + HAL::Register64 idt_reg; + idt_reg.Base = reinterpret_cast<UIntPtr>(kInterruptVectorTable); - while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index])) - ; + HAL::IDTLoader idt_loader; - timer.Wait(); + idt_loader.Load(idt_reg); - ++team_index; - } + while (YES) + ; } #endif // ifndef __NE_MODULAR_KERNEL_COMPONENTS__ diff --git a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc index 7ec235bd..374c7302 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc @@ -9,9 +9,9 @@ #include <KernelKit/DebugOutput.h> #include <KernelKit/FileMgr.h> #include <KernelKit/Timer.h> -#include <NewKit/KString.h> -#include <NewKit/KernelPanic.h> -#include <NewKit/Utils.h> +#include <NeKit/KString.h> +#include <NeKit/KernelPanic.h> +#include <NeKit/Utils.h> #include <modules/CoreGfx/CoreGfx.h> #include <modules/CoreGfx/TextGfx.h> @@ -31,6 +31,7 @@ class RecoveryFactory final { /***********************************************************************************/ Void ke_panic(const Kernel::Int32& id, const Char* message) { (Void)(kout << "*** STOP ***\r"); + (Void)(kout << "Kernel_Panic_MSG: " << message << kendl); (Void)(kout << "Kernel_Panic_ID: " << hex_number(id) << kendl); (Void)(kout << "Kernel_Panic_CR2: " << hex_number((UIntPtr) hal_read_cr2()) << kendl); @@ -46,8 +47,10 @@ Void RecoveryFactory::Recover() noexcept { void ke_runtime_check(bool expr, const Char* file, const Char* line) { if (!expr) { - (Void)(kout << "Kernel_Panic_File: " << file << kendl); - (Void)(kout << "Kernel_Panic_Line: " << line << kendl); + (Void)(kout << "*** CHECK ***\r"); + + (Void)(kout << "Kernel_Panic_FILE: " << file << kendl); + (Void)(kout << "Kernel_Panic_LINE: " << line << kendl); ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed } diff --git a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc b/dev/kernel/HALKit/AMD64/HalPagingMgr.cc index 4681b5e5..048cb7c2 100644 --- a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalPagingMgr.cc @@ -57,7 +57,7 @@ STATIC Void mmi_page_status(Detail::PTE* pte) { /// @param virt a valid virtual address. /// @return Physical address. /***********************************************************************************/ -UIntPtr mm_get_phys_address(VoidPtr virt) { +EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virt) { const UInt64 kVMAddr = (UInt64) virt; const UInt64 kMask9Bits = 0x1FFULL; const UInt64 kPageOffsetMask = 0xFFFULL; @@ -102,7 +102,7 @@ UIntPtr mm_get_phys_address(VoidPtr virt) { /// @brief clflush+mfence helper function. /***********************************************************************************/ EXTERN_C Int32 mm_memory_fence(VoidPtr virtual_address) { - if (!virtual_address || !mm_get_phys_address(virtual_address)) return kErrorInvalidData; + if (!virtual_address || !mm_get_page_addr(virtual_address)) return kErrorInvalidData; asm volatile("clflush (%0)" : : "r"(virtual_address) : "memory"); asm volatile("mfence" ::: "memory"); diff --git a/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc b/dev/kernel/HALKit/AMD64/HalProcessor.cc index 66f27c24..6ebbea08 100644 --- a/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalProcessor.cc @@ -16,6 +16,20 @@ */ namespace Kernel::HAL { +inline Bool hal_has_msr() noexcept { + static UInt32 eax, unused, edx; // eax, edx + + __get_cpuid(1, &eax, &unused, &unused, &edx); + + // edx returns the flag for MSR (which is 1 shifted to 5.) + return edx & (1 << 5); +} + +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/HalSchedulerCorePrimitives.cc index 8f7ffdaf..0c468e14 100644 --- a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitives.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/HalTimerAMD64.cc b/dev/kernel/HALKit/AMD64/HalTimer.cc index 79165289..13573880 100644 --- a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalTimer.cc @@ -17,6 +17,8 @@ // timer slot 0
+#define kHPETSignature ("HPET")
+
#define kHPETCounterRegValue (0x00)
#define kHPETConfigRegValue (0x20)
#define kHPETCompRegValue (0x24)
@@ -46,7 +48,7 @@ using namespace Kernel; HardwareTimer::HardwareTimer(UInt64 ms) : fWaitFor(ms) {
auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr);
- auto hpet = (Detail::HPET_BLOCK*) power.Find("HPET").Leak().Leak();
+ auto hpet = (Detail::HPET_BLOCK*) power.Find(kHPETSignature).Leak().Leak();
MUST_PASS(hpet);
fDigitalTimer = (UInt8*) hpet->address.Address;
diff --git a/dev/kernel/HALKit/AMD64/HalUtilsAPI.asm b/dev/kernel/HALKit/AMD64/HalUtilsAPI.asm index ab639992..11336229 100644 --- a/dev/kernel/HALKit/AMD64/HalUtilsAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalUtilsAPI.asm @@ -22,5 +22,3 @@ rt_install_tib: ret ;; //////////////////////////////////////////////////// ;; - -[extern kApicMadtAddressesCount] diff --git a/dev/kernel/HALKit/AMD64/Hypervisor.h b/dev/kernel/HALKit/AMD64/Hypervisor.h index df88b02b..5702c8e2 100644 --- a/dev/kernel/HALKit/AMD64/Hypervisor.h +++ b/dev/kernel/HALKit/AMD64/Hypervisor.h @@ -6,7 +6,7 @@ #pragma once -#include <NewKit/Defines.h> +#include <NeKit/Defines.h> namespace Kernel { MAKE_STRING_ENUM(HYPERVISOR) diff --git a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc new file mode 100644 index 00000000..3ccbfa24 --- /dev/null +++ b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc @@ -0,0 +1,114 @@ +/* ------------------------------------------- + +Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <DmaKit/DmaPool.h> +#include <HALKit/AMD64/Processor.h> +#include <modules/ACPI/ACPIFactoryInterface.h> + +using namespace Kernel; +using namespace Kernel::HAL; + +STATIC UInt16 kRTLIOBase = 0xFFFF; + +STATIC BOOL kTXEnabled = NO; + +STATIC UInt32 kRXOffset = 0UL; + +STATIC constexpr CONST UInt32 kRXBufferSize = 8192 + 16 + 1500; + +STATIC UInt8* kRXUpperLayer = nullptr; +STATIC UInt8* kRXBuffer = nullptr; + +/***********************************************************************************/ +///@brief RTL8139 Init routine. +/***********************************************************************************/ + +EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept { + if (kTXEnabled) return; + + kRTLIOBase = io_base; + + MUST_PASS(io_base != 0xFFFF); + + kRXBuffer = reinterpret_cast<UInt8*>(rtl_dma_alloc(sizeof(UInt8) * kRXBufferSize, 0)); + + MUST_PASS(kRXBuffer); + + /// Reset first. + + rt_out8(io_base + 0x37, 0x10); + + UInt16 timeout = 0U; + + while (rt_in8(io_base + 0x37) & 0x10) { + ++timeout; + if (timeout > 0x1000) break; + } + + if (timeout <= 0x1000) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "RTL8139: Reset failed"); + return; + } + + rt_out32(io_base + 0x30, (UInt32) (UIntPtr) kRXBuffer); + + rt_out8(io_base + 0x37, 0x0C); + + rt_out32(io_base + 0x44, 0xF | (1 << 7)); + + rt_out16(io_base + 0x3C, 0x0005); + + kTXEnabled = YES; +} + +/***********************************************************************************/ +/// @brief RTL8139 I/O interrupt handler. +/// @note This function is called when the device interrupts to retrieve network data. +/***********************************************************************************/ + +EXTERN_C void rtl_rtl8139_interrupt_handler() { + if (kRTLIOBase == 0xFFFF) return; + + UInt16 status = rt_in16(kRTLIOBase + 0x3E); + rt_out16(kRTLIOBase + 0x3E, status); + + if (status & 0x01) { + // While we receive data. + while ((rt_in8(kRTLIOBase + 0x37) & 0x01) == 0) { + // We grab an offset from the RX buffer. + UInt32 offset = kRXOffset % kRXBufferSize; + + // If the offset is too high, we reset it. + if (offset >= (kRXBufferSize - 16)) { + kRXOffset = 0UL; + offset = 0UL; + } + + volatile UInt8* packet = kRXBuffer + offset + 4; + UInt16 len = *(UInt16*) (kRXBuffer + offset + 2); + + kRXUpperLayer[(offset + 4)] = *packet; + kRXOffset += (len + 4); + + rt_out16(kRTLIOBase + 0x38, (UInt16) (kRXOffset - 16)); + } + } + + if (!(status & 0x04)) { + err_global_get() = kErrorNoNetwork; + } +} + +/***********************************************************************************/ +/// @brief RTL8139 get upper layer function +/// @return the upper layer. +/// @retval nullptr if no upper layer is set. +/// @retval pointer to the upper layer if set. +/***********************************************************************************/ + +EXTERN_C UInt8* rtl_rtl8139_get_upper_layer() { + return kRXUpperLayer; +}
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Paging.h b/dev/kernel/HALKit/AMD64/Paging.h index cfba232c..079acde4 100644 --- a/dev/kernel/HALKit/AMD64/Paging.h +++ b/dev/kernel/HALKit/AMD64/Paging.h @@ -6,13 +6,15 @@ #pragma once +#ifdef __NE_AMD64__ + /** --------------------------------------------------- * THIS FILE CONTAINS CODE FOR X86_64 PAGING. ------------------------------------------------------- */ -#include <NewKit/Defines.h> +#include <NeKit/Defines.h> #ifndef kPageMax #define kPageMax (0x200) @@ -63,6 +65,27 @@ auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; } // namespace Kernel::HAL namespace Kernel { -typedef VoidPtr PTE; -typedef VoidPtr PDE; +struct PTE { + UInt64 Present : 1; + UInt64 Wr : 1; + UInt64 User : 1; + UInt64 Pwt : 1; // Page-level Write-Through + UInt64 Pcd : 1; // Page-level Cache Disable + UInt64 Accessed : 1; + UInt64 Dirty : 1; + UInt64 Pat : 1; // Page Attribute Table (or PS for PDE) + UInt64 Global : 1; + UInt64 Ignored1 : 3; // Available to software + UInt64 PhysicalAddress : 40; // Physical page frame address (bits 12–51) + UInt64 Ignored2 : 7; // More software bits / reserved + UInt64 ProtectionKey : 4; // Optional (if PKU enabled) + UInt64 Reserved : 1; // Usually reserved + UInt64 Nx : 1; // No Execute +}; + +struct PDE { + ATTRIBUTE(aligned(kib_cast(4))) PTE fPTE[512]; +}; } // namespace Kernel + +#endif // __NE_AMD64__
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index e1ce8718..80dc7a1d 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -13,11 +13,15 @@ #pragma once +#ifdef __NE_AMD64__ + #include <FirmwareKit/Handover.h> #include <HALKit/AMD64/Paging.h> -#include <NewKit/Array.h> -#include <NewKit/Defines.h> -#include <NewKit/Utils.h> +#include <NeKit/Array.h> +#include <NeKit/Defines.h> +#include <NeKit/Utils.h> + +#include <HALKit/AMD64/CPUID.h> #define kPITControlPort (0x43) #define kPITChannel0Port (0x40) @@ -28,7 +32,8 @@ #define kPIC2Command (0xA0) #define kPIC2Data (0xA1) -#include <HALKit/AMD64/CPUID.h> +#define kIOAPICRegVal (4) +#define kIOAPICRegReg (0) #define rtl_nop_op() asm volatile("nop") @@ -70,7 +75,7 @@ enum { kMMFlagsNX = 1 << 4, kMMFlagsPCD = 1 << 5, kMMFlagsPwt = 1 << 6, - kMMFlagsCount = 4, + kMMFlagsCount = 6, }; struct PACKED Register64 final { @@ -83,18 +88,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; @@ -170,16 +174,7 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept; /// @retval true it does exists. /// @retval false it doesn't. /***********************************************************************************/ -inline Bool hal_has_msr() noexcept { - static UInt32 eax, unused, edx; // eax, edx - - __get_cpuid(1, &eax, &unused, &unused, &edx); - - // edx returns the flag for MSR (which is 1 shifted to 5.) - return edx & (1 << 5); -} - -UIntPtr mm_get_phys_address(VoidPtr virtual_address); +Bool hal_has_msr() noexcept; /***********************************************************************************/ /// @brief Get Model specific register inside core. @@ -187,13 +182,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 @@ -236,16 +225,16 @@ namespace Detail { }; } // namespace Detail -class APICController final { +class LAPICDmaWrapper final { public: - explicit APICController(VoidPtr base); - ~APICController() = default; + explicit LAPICDmaWrapper(VoidPtr base); + ~LAPICDmaWrapper(); - NE_COPY_DEFAULT(APICController) + NE_COPY_DEFAULT(LAPICDmaWrapper) public: - UInt32 Read(UInt32 reg) noexcept; - Void Write(UInt32 reg, UInt32 value) noexcept; + UInt32 Read(UInt16 reg) noexcept; + Void Write(UInt16 reg, UInt32 value) noexcept; private: VoidPtr fApic{nullptr}; @@ -273,6 +262,8 @@ EXTERN_C Void rt_sti(); EXTERN_C Void rt_cld(); EXTERN_C Void rt_std(); +EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address); + EXTERN_C Int32 mm_memory_fence(VoidPtr virtual_address); } // namespace Kernel::HAL @@ -287,4 +278,4 @@ EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_gdt(Kernel::HAL::Register64 ptr) inline Kernel::VoidPtr kKernelBitMpStart = nullptr; inline Kernel::UIntPtr kKernelBitMpSize = 0UL; -inline Kernel::VoidPtr kKernelCR3 = nullptr;
\ No newline at end of file +#endif // __NE_AMD64__ */
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index 21483560..b30bfc32 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -15,6 +15,7 @@ * */ +#include <DmaKit/DmaPool.h> #include <FirmwareKit/EPM.h> #include <KernelKit/DeviceMgr.h> #include <KernelKit/DriveMgr.h> @@ -23,9 +24,8 @@ #include <KernelKit/PCI/Iterator.h> #include <KernelKit/ProcessScheduler.h> #include <KernelKit/Timer.h> -#include <NewKit/Utils.h> +#include <NeKit/Utils.h> #include <StorageKit/AHCI.h> -#include <StorageKit/DmaPool.h> #include <modules/AHCI/AHCI.h> #include <modules/ATA/ATA.h> @@ -54,7 +54,6 @@ using namespace Kernel; -STATIC HardwareTimer kSATATimer(rtl_milliseconds(5)); STATIC PCI::Device kSATADev; STATIC HbaMemRef kSATAHba; STATIC Lba kSATASectorCount = 0UL; @@ -360,7 +359,7 @@ STATIC Bool drv_init_command_structures_ahci() { return NO; } - UIntPtr clb_phys = HAL::mm_get_phys_address(clb_mem); + UIntPtr clb_phys = HAL::mm_get_page_addr(clb_mem); kSATAHba->Ports[kSATAIndex].Clb = (UInt32) (clb_phys & 0xFFFFFFFF); kSATAHba->Ports[kSATAIndex].Clbu = (UInt32) (clb_phys >> 32); @@ -380,7 +379,7 @@ STATIC Bool drv_init_command_structures_ahci() { return NO; } - UIntPtr ct_phys = HAL::mm_get_phys_address(ct_mem); + UIntPtr ct_phys = HAL::mm_get_page_addr(ct_mem); header[i].Ctba = (UInt32) (ct_phys & 0xFFFFFFFF); header[i].Ctbau = (UInt32) (ct_phys >> 32); diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic+Next.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic+Next.cc deleted file mode 100644 index dd6b9aea..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic+Next.cc +++ /dev/null @@ -1,280 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -/** - * @file PIO+Generic.cc - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief ATA driver (PIO mode). - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Amlal El Mahrouss - * - */ - -#if 0 - -#include <ArchKit/ArchKit.h> -#include <KernelKit/DriveMgr.h> -#include <StorageKit/ATA.h> -#include <modules/ATA/ATA.h> - -using namespace Kernel; -using namespace Kernel::HAL; - -/// BUGS: 0 - -#define kATADataLen 256 - -STATIC Boolean kATADetected = false; -STATIC UInt16 kATAIdentifyData[kATADataLen] = {0}; -STATIC Char kATADiskModel[50] = {"GENERIC PIO"}; - -static Boolean drv_pio_std_wait_io(UInt16 IO) { - for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto stat_rdy = rt_in8(IO + ATA_REG_STATUS); - - if ((stat_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - stat_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (stat_rdy & ATA_SR_ERR) return false; - - if (!(stat_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; - - return true; -} - -STATIC Void drv_pio_std_select(UInt16 Bus) { - if (Bus == ATA_PRIMARY_IO) - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); - else - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); -} - -Boolean drv_pio_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { - UInt16 IO = Bus; - - NE_UNUSED(Drive); - - drv_pio_std_select(IO); - - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); - - // identify until it's good. -ATAInit_Retry: - auto stat_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (stat_rdy & ATA_SR_ERR) { - return false; - } - - if ((stat_rdy & ATA_SR_BSY)) goto ATAInit_Retry; - - OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - - drv_pio_std_select(IO); - - rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); - - - /// fetch serial info - /// model, speed, number of sectors... - - for (SizeT i = 0ul; i < kATADataLen; ++i) { - kATAIdentifyData[i] = rt_in16(OutBus + ATA_REG_DATA); - } - - for (Int32 i = 0; i < 20; i++) { - kATADiskModel[i * 2] = (kATAIdentifyData[27 + i] >> 8) & 0xFF; - kATADiskModel[i * 2 + 1] = kATAIdentifyData[27 + i] & 0xFF; - } - - kATADiskModel[40] = '\0'; - - (Void)(kout << "Drive Model: " << kATADiskModel << kendl); - - return true; -} - -Void drv_pio_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - drv_pio_std_wait_io(IO); - drv_pio_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); - - for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { - drv_pio_std_wait_io(IO); - - auto in = rt_in16(IO + ATA_REG_DATA); - - Buf[IndexOff] = in & 0xFF; - Buf[IndexOff + 1] = (in >> 8) & 0xFF; - } -} - -Void drv_pio_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - drv_pio_std_wait_io(IO); - drv_pio_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); - - for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { - drv_pio_std_wait_io(IO); - - UInt8 low = (UInt8)Buf[IndexOff]; - UInt8 high = (IndexOff + 1 < Size) ? (UInt8)Buf[IndexOff + 1] : 0; - UInt16 packed = (high << 8) | low; - - rt_out16(IO + ATA_REG_DATA, packed); - } -} - -/// @brief is ATA detected? -Boolean drv_pio_std_detected(Void) { - return kATADetected; -} - -/*** - @brief Getter, gets the number of sectors inside the drive. - */ -SizeT drv_pio_get_sector_count() { - return (kATAIdentifyData[61] << 16) | kATAIdentifyData[60]; -} - -/// @brief Get the drive size. -SizeT drv_pio_get_size() { - return (drv_pio_get_sector_count()) * kATASectorSize; -} - -namespace Kernel { -/// @brief Initialize an PIO device (StorageKit function) -/// @param is_master is the current PIO master? -/// @return [io:master] for PIO device. -BOOL sk_init_ata_device(BOOL is_master, UInt16& io, UInt8& master) { - return drv_pio_std_init(ATA_SECONDARY_IO, is_master, io, master); -} - -/// @brief Implementation details namespace. -namespace Detail { - /// @brief Read PIO device. - /// @param self device - /// @param mnt mounted disk. - STATIC Void sk_io_read_pio(IDeviceObject<MountpointInterface*>* self, MountpointInterface* mnt) { - ATADeviceInterface* dev = (ATADeviceInterface*) self; - - err_global_get() = kErrorDisk; - - if (!dev) return; - - auto disk = mnt->GetAddressOf(dev->GetIndex()); - - if (!disk) return; - - err_global_get() = kErrorSuccess; - - drv_pio_std_read(disk->fPacket.fPacketLba, dev->GetIO(), dev->GetMaster(), - (Char*) disk->fPacket.fPacketContent, kATASectorSize, - disk->fPacket.fPacketSize); - } - - /// @brief Write PIO device. - /// @param self device - /// @param mnt mounted disk. - STATIC Void sk_io_write_pio(IDeviceObject<MountpointInterface*>* self, MountpointInterface* mnt) { - ATADeviceInterface* dev = (ATADeviceInterface*) self; - - err_global_get() = kErrorDisk; - - if (!dev) return; - - auto disk = mnt->GetAddressOf(dev->GetIndex()); - - if (!disk) return; - - err_global_get() = kErrorSuccess; - - drv_pio_std_write(disk->fPacket.fPacketLba, dev->GetIO(), dev->GetMaster(), - (Char*) disk->fPacket.fPacketContent, kATASectorSize, - disk->fPacket.fPacketSize); - } -} // namespace Detail - -/// @brief Acquires a new PIO device with drv_index in mind. -/// @param drv_index The drive index to assign. -/// @return A wrapped device interface if successful, or error code. -ErrorOr<ATADeviceInterface> sk_acquire_ata_device(Int32 drv_index) { - /// here we don't check if we probed ATA, since we'd need to grab IO after that. - ATADeviceInterface device(Detail::sk_io_read_pio, Detail::sk_io_write_pio); - - device.SetIndex(drv_index); - - return ErrorOr<ATADeviceInterface>(device); -} -} // namespace Kernel - -#ifdef __ATA_PIO__ - -Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - drv_pio_std_read(Lba, IO, Master, Buf, SectorSz, Size); -} - -Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - drv_pio_std_write(Lba, IO, Master, Buf, SectorSz, Size); -} - -SizeT drv_std_get_size() { - return drv_pio_get_size(); -} - -SizeT drv_std_get_sector_count() { - return drv_pio_get_sector_count(); -} - -Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { - return drv_pio_std_init(Bus, Drive, OutBus, OutMaster); -} - -#endif - -#endif
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc index aec21ee4..99e1c619 100644 --- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc @@ -49,7 +49,7 @@ ATAWaitForIO_Retry2: return true; } -static Void drv_pio_std_select(UInt16 Bus) { +STATIC Void drv_pio_std_select(UInt16 Bus) { if (Bus == ATA_PRIMARY_IO) rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); else @@ -79,15 +79,18 @@ ATAInit_Retry: OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + drv_pio_std_select(IO); + rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - drv_pio_std_wait_io(IO); + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) + ; /// fetch serial info /// model, speed, number of sectors... for (SizeT i = 0ul; i < kATADataLen; ++i) { - kATAIdentifyData[i] = HAL::rt_in16(OutBus + ATA_REG_DATA); + kATAIdentifyData[i] = rt_in16(OutBus + ATA_REG_DATA); } for (Int32 i = 0; i < 20; i++) { @@ -99,10 +102,6 @@ ATAInit_Retry: (Void)(kout << "Drive Model: " << kATADiskModel << kendl); - // Why? the current disk driver writes whole word instead of a single byte (expected btw) so i'm - // planning to finish +Next drivers for 0.0.3 - ke_panic(RUNTIME_CHECK_INVALID, "PIO driver is currently being reworked."); - return true; } @@ -125,9 +124,16 @@ Void drv_pio_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT Sect rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) + ; + + for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { drv_pio_std_wait_io(IO); - Buf[IndexOff] = HAL::rt_in16(IO + ATA_REG_DATA); + + auto in = rt_in16(IO + ATA_REG_DATA); + + Buf[IndexOff] = in & 0xFF; + Buf[IndexOff + 1] = (in >> 8) & 0xFF; } } @@ -150,9 +156,17 @@ Void drv_pio_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT Sec rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) + ; + + for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { drv_pio_std_wait_io(IO); - rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); + + UInt8 low = (UInt8) Buf[IndexOff]; + UInt8 high = (IndexOff + 1 < Size) ? (UInt8) Buf[IndexOff + 1] : 0; + UInt16 packed = (high << 8) | low; + + rt_out16(IO + ATA_REG_DATA, packed); } } diff --git a/dev/kernel/HALKit/AMD64/make_ap_blob.sh b/dev/kernel/HALKit/AMD64/make_ap_blob.sh deleted file mode 100755 index 3f079187..00000000 --- a/dev/kernel/HALKit/AMD64/make_ap_blob.sh +++ /dev/null @@ -1,3 +0,0 @@ -# !/bin/sh - -nasm -f bin HalApplicationProcessorStartup.asm -o HalApplicationProcessorStartup.bin
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h index f48c1483..3d472bf0 100644 --- a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h +++ b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h @@ -7,12 +7,13 @@ #pragma once #include <HALKit/ARM64/Processor.h> -#include <NewKit/Defines.h> +#include <NeKit/Defines.h> /************************************************** */ -/* INITIALIZE THE GIC ON CPU. */ +/* INITIALIZE THE GIC ON THE CURRENT CORE. */ +/* WITH AN EXECUTION LEVEL IN MIND. */ /************************************************** */ namespace Kernel { -BOOL mp_initialize_gic(Kernel::Void); +Void mp_init_cores(Void) noexcept; }
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc b/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc index 31f5a4f2..dc883239 100644 --- a/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc +++ b/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc @@ -5,8 +5,8 @@ ------------------------------------------- */ #include <ArchKit/ArchKit.h> -#include <KernelKit/MemoryMgr.h> -#include <NewKit/KString.h> +#include <KernelKit/HeapMgr.h> +#include <NeKit/KString.h> #include <modules/ACPI/ACPIFactoryInterface.h> #include <modules/APM/APM.h> diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc index 7e55aa07..02f09e23 100644 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -4,89 +4,80 @@ ------------------------------------------- */
+#define GICD_BASE 0x08000000
+#define GICC_BASE 0x08010000
+
+#define GICD_CTLR 0x000
+#define GICD_ISENABLER 0x100
+#define GICD_ICENABLER 0x180
+#define GICD_ISPENDR 0x200
+#define GICD_ICPENDR 0x280
+#define GICD_IPRIORITYR 0x400
+#define GICD_ITARGETSR 0x800
+#define GICD_ICFGR 0xC00
+
+#define GICC_CTLR 0x000
+#define GICC_PMR 0x004
+#define GICC_IAR 0x00C
+#define GICC_EOIR 0x010
+
#include <HALKit/ARM64/ApplicationProcessor.h>
#include <HALKit/ARM64/Processor.h>
#include <KernelKit/DebugOutput.h>
+#include <KernelKit/HardwareThreadScheduler.h>
#include <KernelKit/ProcessScheduler.h>
-
-#define GICD_BASE 0x08000000 // Distributor base address
-#define GICC_BASE 0x08010000 // CPU interface base address
-
-#define GICD_CTLR 0x000 // Distributor Control Register
-#define GICD_ISENABLER 0x100 // Interrupt Set-Enable Registers
-#define GICD_ICENABLER 0x180 // Interrupt Clear-Enable Registers
-#define GICD_ISPENDR 0x200 // Interrupt Set-Pending Registers
-#define GICD_ICPENDR 0x280 // Interrupt Clear-Pending Registers
-#define GICD_IPRIORITYR 0x400 // Interrupt Priority Registers
-#define GICD_ITARGETSR 0x800 // Interrupt Processor Targets Registers
-#define GICD_ICFGR 0xC00 // Interrupt Configuration Registers
-
-#define GICC_CTLR 0x000 // CPU Interface Control Register
-#define GICC_PMR 0x004 // Interrupt Priority Mask Register
-#define GICC_IAR 0x00C // Interrupt Acknowledge Register
-#define GICC_EOIR 0x010 // End of Interrupt Register
+#include <KernelKit/Timer.h>
// ================================================================= //
namespace Kernel {
-struct PROCESS_CONTROL_BLOCK final {
- HAL::StackFramePtr mFrame;
+struct HAL_HARDWARE_THREAD final {
+ HAL::StackFramePtr mFramePtr;
+ ProcessID mThreadID{0};
};
-STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0};
+STATIC HAL_HARDWARE_THREAD kHWThread[kMaxAPInsideSched] = {{nullptr}};
namespace Detail {
STATIC BOOL kGICEnabled = NO;
- STATIC void mp_hang_fn(void) {
- while (YES)
- ;
-
- dbg_break_point();
- }
-
- Void mp_setup_gic_el0(Void) {
- // enable distributor.
+ /***********************************************************************************/
+ /// @brief Enables the GIC with EL0 configuration.
+ /// @internal
+ /***********************************************************************************/
+ STATIC Void mp_setup_gic_el0(Void) {
ke_dma_write<UInt32>(GICD_BASE, GICD_CTLR, YES);
UInt32 gicc_ctlr = ke_dma_read<UInt32>(GICC_BASE, GICC_CTLR);
- const auto kEnableSignalInt = YES;
+ const UInt8 kEnableSignalInt = 0x1;
- gicc_ctlr |= kEnableSignalInt; // Enable signaling of interrupts
- gicc_ctlr |= (kEnableSignalInt << 1); // Allow Group 1 interrupts in EL0
+ gicc_ctlr |= kEnableSignalInt;
+ gicc_ctlr |= (kEnableSignalInt << 0x1);
ke_dma_write<UInt32>(GICC_BASE, GICC_CTLR, gicc_ctlr);
- // Set priority mask (accept all priorities)
ke_dma_write<UInt32>(GICC_BASE, GICC_PMR, 0xFF);
UInt32 icfgr = ke_dma_read<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4);
- icfgr |= (0x2 << ((32 % 16) * 2)); // Edge-triggered
- ke_dma_write<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr);
+ icfgr |= (0x2 << ((32 % 16) * 2));
- // Target interrupt 32 to CPU 1
+ ke_dma_write<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr);
ke_dma_write<UInt32>(GICD_BASE, GICD_ITARGETSR + (0x20 / 0x04) * 4, 0x2 << ((32 % 4) * 8));
-
- // Set interrupt 32 priority to lowest (0xFF)
ke_dma_write<UInt32>(GICD_BASE, GICD_IPRIORITYR + (0x20 / 0x04) * 4, 0xFF << ((32 % 4) * 8));
-
- // Enable interrupt 32 for AP.
ke_dma_write<UInt32>(GICD_BASE, GICD_ISENABLER + 4, 0x01);
}
- BOOL mp_handle_gic_interrupt_el0(Void) {
- // Read the interrupt ID
+ EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void) {
UInt32 interrupt_id = ke_dma_read<UInt32>(GICC_BASE, GICC_IAR);
- // Check if it's a valid interrupt (not spurious)
if ((interrupt_id & 0x3FF) < 1020) {
auto interrupt = interrupt_id & 0x3FF;
const UInt16 kInterruptScheduler = 0x20;
- (Void)(kout << "Handling interrupt for AP: " << interrupt << kendl);
+ (Void)(kout << "SMP: AP: " << hex_number(interrupt) << kendl);
switch (interrupt) {
case kInterruptScheduler: {
@@ -103,31 +94,47 @@ namespace Detail { return YES;
}
- // spurious interrupt
return NO;
}
} // namespace Detail
-EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID pid) {
- return kProcessBlocks[pid % kSchedProcessLimitPerTeam].mFrame;
+/***********************************************************************************/
+/// @brief Get current stack frame for a thread.
+/// @param thrdid The thread ID.
+/***********************************************************************************/
+
+EXTERN_C HAL::StackFramePtr mp_get_current_task(ProcessID thrdid) {
+ return kHWThread[thrdid].mFramePtr;
}
-EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) {
- MUST_PASS(stack_frame);
+/***********************************************************************************/
+/// @brief Register current stack frame for a thread.
+/// @param stack_frame The current stack frame.
+/// @param thrdid The thread ID.
+/***********************************************************************************/
- const auto process_index = pid % kSchedProcessLimitPerTeam;
+EXTERN_C Bool mp_register_task(HAL::StackFramePtr stack_frame, ProcessID thrdid) {
+ MUST_PASS(Detail::kGICEnabled);
- kProcessBlocks[process_index].mFrame = stack_frame;
+ if (!stack_frame) return NO;
+ if (thrdid > kMaxAPInsideSched) return NO;
+
+ const auto process_index = thrdid;
+
+ kHWThread[process_index].mFramePtr = stack_frame;
+ kHWThread[process_index].mThreadID = thrdid;
return YES;
}
-BOOL mp_initialize_gic(Void) {
+/***********************************************************************************/
+/// @brief Initialize the Global Interrupt Controller.
+/// @internal
+/***********************************************************************************/
+Void mp_init_cores(Void) noexcept {
if (!Detail::kGICEnabled) {
Detail::kGICEnabled = YES;
Detail::mp_setup_gic_el0();
}
-
- return Detail::kGICEnabled;
}
} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s b/dev/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s new file mode 100644 index 00000000..dca52571 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s @@ -0,0 +1,12 @@ +.text + +.global hal_ap_blob_start +.global hal_ap_blob_length + +hal_ap_blob_start: + ret + +.data + +hal_ap_blob_length: + .long 4 diff --git a/dev/kernel/HALKit/ARM64/HalFlushTLB.S b/dev/kernel/HALKit/ARM64/HalCommonAPI.s index e76b6e3f..e76b6e3f 100644 --- a/dev/kernel/HALKit/ARM64/HalFlushTLB.S +++ b/dev/kernel/HALKit/ARM64/HalCommonAPI.s diff --git a/dev/kernel/HALKit/ARM64/HalDebugOutput.cc b/dev/kernel/HALKit/ARM64/HalDebugOutput.cc index 7ec90c6e..3c518e2f 100644 --- a/dev/kernel/HALKit/ARM64/HalDebugOutput.cc +++ b/dev/kernel/HALKit/ARM64/HalDebugOutput.cc @@ -6,8 +6,8 @@ #include <ArchKit/ArchKit.h> #include <KernelKit/DebugOutput.h> -#include <NewKit/New.h> -#include <NewKit/Utils.h> +#include <NeKit/New.h> +#include <NeKit/Utils.h> namespace Kernel { EXTERN_C void ke_io_write(IDeviceObject<const Char*>* self, const Char* bytes) { diff --git a/dev/kernel/HALKit/ARM64/HalInterruptAPI.s b/dev/kernel/HALKit/ARM64/HalInterruptAPI.s new file mode 100644 index 00000000..cafebb7d --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalInterruptAPI.s @@ -0,0 +1,3 @@ +/* (c) 2024-2025 Amlal El Mahrouss */ + +.text diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc index bf5849ef..20bd3d8a 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc @@ -7,20 +7,23 @@ #include <ArchKit/ArchKit.h> #include <CFKit/Property.h> #include <FirmwareKit/Handover.h> +#include <HALKit/ARM64/ApplicationProcessor.h> #include <HALKit/ARM64/Processor.h> #include <KernelKit/CodeMgr.h> #include <KernelKit/FileMgr.h> -#include <KernelKit/MemoryMgr.h> +#include <KernelKit/HardwareThreadScheduler.h> +#include <KernelKit/HeapMgr.h> #include <KernelKit/PEFCodeMgr.h> #include <KernelKit/ProcessScheduler.h> +#include <NeKit/Json.h> #include <NetworkKit/IPC.h> -#include <NewKit/Json.h> #include <modules/ACPI/ACPIFactoryInterface.h> #include <modules/CoreGfx/CoreGfx.h> -#include <HALKit/ARM64/ApplicationProcessor.h> - +#ifndef __NE_MODULAR_KERNEL_COMPONENTS__ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { + using namespace Kernel; + /************************************************** */ /* INITIALIZE AND VALIDATE HEADER. */ /************************************************** */ @@ -32,6 +35,15 @@ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { return; } + FB::fb_clear_video(); + +#ifdef __NE_ARM64_EFI__ + fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]); + + Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey, + handover_hdr->f_HardwareTables.f_ImageHandle); +#endif + /************************************** */ /* INITIALIZE BIT MAP. */ /************************************** */ @@ -42,31 +54,24 @@ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { /// @note do initialize the interrupts after it. - Kernel::mp_initialize_gic(); - - /// after the scheduler runs, we must look over teams, every 5000s in order to schedule every - /// process according to their affinity fairly. - - auto constexpr kSchedTeamSwitchMS = 5U; /// @brief Team switch time in milliseconds. - - Kernel::HardwareTimer timer(rtl_milliseconds(kSchedTeamSwitchMS)); - - STATIC Kernel::Array<UserProcessTeam, kSchedTeamCount> kTeams; - - SizeT team_index = 0U; + for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { + HardwareThreadScheduler::The()[index].Leak()->Kind() = ThreadKind::kAPStandard; + HardwareThreadScheduler::The()[index].Leak()->Busy(NO); + } - /// @brief This just loops over the teams and switches between them. - /// @details Not even round-robin, just a simple loop in this boot core we're at. - while (YES) { - if (team_index > (kSchedTeamCount - 1)) { - team_index = 0U; - } + for (SizeT index = 0UL; index < UserProcessScheduler::The().TheCurrentTeam().AsArray().Count(); + ++index) { + UserProcessScheduler::The().TheCurrentTeam().AsArray()[index].Status = + ProcessStatusKind::kInvalid; + } - while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index])) - ; + rtl_create_user_process(sched_idle_task, "MgmtSrv"); //! Mgmt command server. + rtl_create_user_process(sched_idle_task, "LaunchSrv"); //! launchd + rtl_create_user_process(sched_idle_task, "SecSrv"); //! Login Server - timer.Wait(); + Kernel::mp_init_cores(); - ++team_index; - } + while (YES) + ; } +#endif
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc index c3d3175c..5feb6c75 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc @@ -9,9 +9,9 @@ #include <KernelKit/DebugOutput.h> #include <KernelKit/FileMgr.h> #include <KernelKit/Timer.h> -#include <NewKit/KString.h> -#include <NewKit/KernelPanic.h> -#include <NewKit/Utils.h> +#include <NeKit/KString.h> +#include <NeKit/KernelPanic.h> +#include <NeKit/Utils.h> #include <modules/CoreGfx/CoreGfx.h> #include <modules/CoreGfx/TextGfx.h> diff --git a/dev/kernel/HALKit/ARM64/HalPagingMgr.cc b/dev/kernel/HALKit/ARM64/HalPagingMgr.cc new file mode 100644 index 00000000..faad6778 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalPagingMgr.cc @@ -0,0 +1,28 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + + File: HalPagingMgr.cc + Purpose: Platform Paging Manager. + +------------------------------------------- */ + +#include <HALKit/ARM64/Paging.h> +#include <HALKit/ARM64/Processor.h> + +namespace Kernel::HAL { +typedef UInt32 PageTableIndex; + +/// @brief Maps or allocates a page from virtual_address. +/// @param virtual_address a valid virtual address. +/// @param phys_addr point to physical address. +/// @param flags the flags to put on the page. +/// @return Status code of page manipulation process. +EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags) { + if (!virtual_address || !flags) return kErrorInvalidData; + + NE_UNUSED(physical_address); + + return kErrorSuccess; +} +} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc b/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc deleted file mode 100644 index e0b67489..00000000 --- a/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - - File: HalPagingMgr.cc - Purpose: Platform Paging Manager. - -------------------------------------------- */ - -#include <HALKit/ARM64/Paging.h> -#include <HALKit/ARM64/Processor.h> - -namespace Kernel::HAL { -typedef UInt32 PageTableIndex; - -/// \brief Page store type. -struct NE_PAGE_STORE final { - struct { - PDE* fPde{nullptr}; - PTE* fPte{nullptr}; - VoidPtr fVAddr{nullptr}; - } fInternalStore; - - Bool fStoreOp{No}; // Store operation in progress. - - static NE_PAGE_STORE& The() { - static NE_PAGE_STORE the; - return the; - } -}; - -/// \brief Retrieve the page status of a PTE. -STATIC Void mmi_page_status(PTE* pte) { - NE_UNUSED(pte); -} - -STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry); - -/// @brief Maps or allocates a page from virtual_address. -/// @param virtual_address a valid virtual address. -/// @param phys_addr point to physical address. -/// @param flags the flags to put on the page. -/// @return Status code of page manipulation process. -EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags) { - if (!virtual_address || !flags) return kErrorSuccess; - - NE_PAGE_STORE& page_store = NE_PAGE_STORE::The(); - - while (page_store.fStoreOp) - ; - - page_store.fStoreOp = Yes; - - if (page_store.fInternalStore.fVAddr == virtual_address) { - page_store.fStoreOp = No; - return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags, - page_store.fInternalStore.fPte); - } - - return kErrorSuccess; -} - -/// @brief Maps flags for a specific pte. -/// @internal Internal function. -STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry) { - NE_PAGE_STORE& page_store = NE_PAGE_STORE::The(); - - // Update internal store, and tlbi the virtual address. - - page_store.fInternalStore.fPde = nullptr; - page_store.fInternalStore.fPte = pt_entry; - page_store.fInternalStore.fVAddr = virtual_address; - - page_store.fStoreOp = No; - - return kErrorSuccess; -} -} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCore.cc index b3f1b62a..b3f1b62a 100644 --- a/dev/kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalSchedulerCore.cc diff --git a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc index a8f0b1e1..ee286639 100644 --- a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.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/HalTimerARM64.cc b/dev/kernel/HALKit/ARM64/HalTimer.cc index 32f64aec..2a595f11 100644 --- a/dev/kernel/HALKit/ARM64/HalTimerARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalTimer.cc @@ -12,3 +12,4 @@ ------------------------------------------- */ #include <ArchKit/ArchKit.h> +#include <KernelKit/Timer.h>
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/Paging.h b/dev/kernel/HALKit/ARM64/Paging.h index 2eb02bc1..5001871b 100644 --- a/dev/kernel/HALKit/ARM64/Paging.h +++ b/dev/kernel/HALKit/ARM64/Paging.h @@ -12,7 +12,9 @@ ------------------------------------------------------- */ -#include <NewKit/Defines.h> +#ifdef __NE_ARM64__ + +#include <NeKit/Defines.h> #ifndef kPageMax #define kPageMax (0x200) @@ -101,3 +103,5 @@ typedef HAL::PDE_4KB PDE; } // namespace Kernel EXTERN_C void hal_flush_tlb(); + +#endif // __NE_ARM64__
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index 1d9d2af2..068b798d 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -6,12 +6,14 @@ #pragma once +#ifdef __NE_ARM64__ + #include <FirmwareKit/Handover.h> -#include <NewKit/Array.h> -#include <NewKit/Defines.h> -#include <NewKit/Utils.h> +#include <NeKit/Array.h> +#include <NeKit/Defines.h> +#include <NeKit/Utils.h> -#define kCPUBackendName "ARMv8" +#define kCPUBackendName "aarch64" namespace Kernel::HAL { struct PACKED Register64 final { @@ -21,11 +23,11 @@ struct PACKED Register64 final { /// @brief Memory Manager mapping flags. enum { - kMMFlagsPresent = 1 << 0, - kMMFlagsWr = 1 << 1, - kMMFlagsUser = 1 << 2, - kMMFlagsNX = 1 << 3, - kMMFlagsPCD = 1 << 4, + kMMFlagsInvalid = 1 << 0, + kMMFlagsPresent = 1 << 1, + kMMFlagsWr = 1 << 2, + kMMFlagsUser = 1 << 3, + kMMFlagsNX = 1 << 4, kMMFlagsCount = 4, }; @@ -36,23 +38,23 @@ enum { /// @return Status code of page manip. EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags); -EXTERN_C UIntPtr mm_get_phys_address(VoidPtr virtual_address); +EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address); 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; @@ -62,16 +64,6 @@ inline Void rt_halt() noexcept { } } -template <typename DataKind> -inline void hal_dma_write(UIntPtr address, DataKind value) { - *reinterpret_cast<volatile DataKind*>(address) = value; -} - -template <typename DataKind> -inline DataKind hal_dma_read(UIntPtr address) { - return *reinterpret_cast<volatile DataKind*>(address); -} - inline Void hal_wfi(Void) { asm volatile("wfi"); } @@ -80,6 +72,6 @@ inline Void hal_wfi(Void) { inline Kernel::VoidPtr kKernelBitMpStart = nullptr; inline Kernel::UIntPtr kKernelBitMpSize = 0UL; -inline Kernel::VoidPtr kKernelPhysicalStart = nullptr; - #include <HALKit/ARM64/Paging.h> + +#endif // __NE_ARM64__
\ No newline at end of file diff --git a/dev/kernel/HALKit/POWER/AP.h b/dev/kernel/HALKit/POWER/AP.h index f938d6a1..92007da3 100644 --- a/dev/kernel/HALKit/POWER/AP.h +++ b/dev/kernel/HALKit/POWER/AP.h @@ -13,7 +13,7 @@ #pragma once -#include <NewKit/Defines.h> +#include <NeKit/Defines.h> namespace Kernel { struct HAL_HARDWARE_THREAD; 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..8b75bcc8 100644 --- a/dev/kernel/HALKit/POWER/Processor.h +++ b/dev/kernel/HALKit/POWER/Processor.h @@ -8,8 +8,8 @@ #pragma once -#include <NewKit/Defines.h> -#include <NewKit/Utils.h> +#include <NeKit/Defines.h> +#include <NeKit/Utils.h> #define rtl_nop_op() asm volatile("mr 0, 0") #define kHalPPCAlignment __attribute__((aligned(4))) @@ -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/AP.h b/dev/kernel/HALKit/RISCV/AP.h index 0e94fd97..79b0d038 100644 --- a/dev/kernel/HALKit/RISCV/AP.h +++ b/dev/kernel/HALKit/RISCV/AP.h @@ -13,7 +13,7 @@ #pragma once -#include <NewKit/Defines.h> +#include <NeKit/Defines.h> namespace Kernel { typedef Int64 hal_ap_kind; 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.
|
