From 6a30f42d5dcd0f944262147b2806db6c14fe7ffc Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 15 May 2025 13:56:17 +0200 Subject: feat(kernel): Finalizing the first version of the user scheduler. other: - Removed DmaPool into its own Kit. - ApplicationProcessor unit has been cleaned up. - Rename functions of MemoryMgr. - Use KIB instead of MIBs of stack. - Cleanup parts of the scheduler, and hw scheduler. - Use UD handler for INT 6. Signed-off-by: Amlal El Mahrouss --- dev/kernel/src/HardwareThreadScheduler.cc | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'dev/kernel/src/HardwareThreadScheduler.cc') diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index c49c3081..1df5ad7a 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -41,14 +41,14 @@ HardwareThread::~HardwareThread() = default; /***********************************************************************************/ //! @brief returns the id of the thread. /***********************************************************************************/ -const ThreadID& HardwareThread::ID() noexcept { +ThreadID& HardwareThread::ID() noexcept { return fID; } /***********************************************************************************/ //! @brief returns the kind of thread we have. /***********************************************************************************/ -const ThreadKind& HardwareThread::Kind() noexcept { +ThreadKind& HardwareThread::Kind() noexcept { return fKind; } @@ -104,16 +104,10 @@ Void HardwareThread::Wake(const bool wakeup) noexcept { /// @retval true stack was changed, code is running. /// @retval false stack is invalid, previous code is running. /***********************************************************************************/ -Bool HardwareThread::Switch(VoidPtr image_ptr, Ptr8 stack_ptr, HAL::StackFramePtr frame, - const ThreadID& pid) { - if (this->IsBusy()) return NO; - +Bool HardwareThread::Switch(HAL::StackFramePtr frame, const ThreadID& pid) { this->fStack = frame; this->fPID = pid; - this->fStack->BP = reinterpret_cast(image_ptr); - this->fStack->SP = reinterpret_cast(stack_ptr); - Bool ret = mp_register_process(fStack, this->fPID); if (ret) this->Busy(YES); -- cgit v1.2.3 From b55f22d6a4f85751e0054dbf17eefe438a21b048 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 15 May 2025 23:50:06 +0200 Subject: feat(kernel/sched): fixes and improvements on the scheduler's implementation. why? - The previous one wasn't entierly correct on some parts. Signed-off-by: Amlal El Mahrouss --- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 35 +++++++--------------- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 10 +++---- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 6 ++-- dev/kernel/KernelKit/CoreProcessScheduler.h | 4 +-- dev/kernel/src/HardwareThreadScheduler.cc | 2 ++ dev/kernel/src/UserProcessScheduler.cc | 18 ++++++----- 6 files changed, 33 insertions(+), 42 deletions(-) (limited to 'dev/kernel/src/HardwareThreadScheduler.cc') diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 2c2bf5ff..ff283141 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -9,16 +9,12 @@ #include #include -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(); - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: General Protection Fault.\r"; @@ -36,9 +32,7 @@ EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) { /// @brief Handle page fault. /// @param rsp EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: Page Fault.\r"; Kernel::kout << "Kernel: SIGKILL\r"; @@ -55,20 +49,13 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { /// @brief Handle scheduler interrupt. EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { NE_UNUSED(rsp); - - Kernel::kout << "Kernel: Scheduler interrupt.\r"; - - kIsScheduling = YES; Kernel::UserProcessHelper::StartScheduling(); - kIsScheduling = NO; } /// @brief Handle math fault. /// @param rsp EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: Math error (division by zero?).\r"; @@ -86,11 +73,10 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { /// @brief Handle any generic fault. /// @param rsp EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); - Kernel::kout << "Kernel: Generic Process Fault.\r"; + (Void)(Kernel::kout << "Kernel: Process RSP: " << Kernel::hex_number(rsp) << Kernel::kendl); + Kernel::kout << "Kernel: Access Process Fault.\r"; process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; @@ -104,11 +90,10 @@ 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(); - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); + Kernel::kout << "Kernel: SIGTRAP\r"; process.Leak().Signal.SignalArg = rip; @@ -124,9 +109,9 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { /// @brief Handle #UD fault. /// @param rsp EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); + NE_UNUSED(rsp); - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: Undefined Opcode.\r"; diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index 60a20b77..189b2976 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -164,7 +164,6 @@ __NE_INT_8: cld mov al, 0x20 - out 0xA0, al out 0x20, al push rcx @@ -185,7 +184,6 @@ __NE_INT_13: cld mov al, 0x20 - out 0xA0, al out 0x20, al push rcx @@ -200,7 +198,6 @@ __NE_INT_14: cld mov al, 0x20 - out 0xA0, al out 0x20, al push rcx @@ -235,13 +232,16 @@ IntNormal 31 [extern kApicBaseAddress] __NE_INT_32: + mov al, 0x20 + out 0x20, al + + mov dword [kApicBaseAddress+0xB0], 0 + push rax mov rcx, rsp call idt_handle_scheduler pop rax - mov dword [kApicBaseAddress+0xB0], 0 - o64 iret IntNormal 33 diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 722c9cb5..b7ff3038 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -106,9 +106,9 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { 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::rtl_create_user_process(rtl_ne_task, "MGMTCTL"); + Kernel::rtl_create_user_process(rtl_ne_task, "LAUNCHCTL"); + Kernel::rtl_create_user_process(rtl_ne_task, "SECURITYCTL"); Kernel::HAL::Register64 idt_reg; idt_reg.Base = reinterpret_cast(kInterruptVectorTable); diff --git a/dev/kernel/KernelKit/CoreProcessScheduler.h b/dev/kernel/KernelKit/CoreProcessScheduler.h index f9d11459..6cb17261 100644 --- a/dev/kernel/KernelKit/CoreProcessScheduler.h +++ b/dev/kernel/KernelKit/CoreProcessScheduler.h @@ -128,8 +128,8 @@ enum class ProcessStatusKind : Int32 { //! @brief Affinity is the amount of nano-seconds this process is going to run. /***********************************************************************************/ enum class AffinityKind : Int32 { - kRealTime = 500, - kVeryHigh = 250, + kRealTime = 50, + kVeryHigh = 150, kHigh = 200, kStandard = 1000, kLowUsage = 1500, diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index 1df5ad7a..6cb83b3d 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -105,6 +105,8 @@ Void HardwareThread::Wake(const bool wakeup) noexcept { /// @retval false stack is invalid, previous code is running. /***********************************************************************************/ Bool HardwareThread::Switch(HAL::StackFramePtr frame, const ThreadID& pid) { + if (this->IsBusy()) return NO; + this->fStack = frame; this->fPID = pid; diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 24869d63..fe1a95ae 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -491,7 +491,7 @@ SizeT UserProcessScheduler::Run() noexcept { continue; } - kout << process.Name << " is being scheduled to run...\r"; + kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled...\r"; this->CurrentProcess() = process; @@ -499,17 +499,21 @@ SizeT UserProcessScheduler::Run() noexcept { if (process.PTime < process.RTime) { if (process.RTime < (Int32) AffinityKind::kVeryHigh) - process.PTime = (Int32) AffinityKind::kLowUsage; + process.RTime = (Int32) AffinityKind::kLowUsage; else if (process.RTime < (Int32) AffinityKind::kHigh) - process.PTime = (Int32) AffinityKind::kStandard; + process.RTime = (Int32) AffinityKind::kStandard; else if (process.RTime < (Int32) AffinityKind::kStandard) - process.PTime = (Int32) AffinityKind::kHigh; + process.RTime = (Int32) AffinityKind::kHigh; + + process.PTime += process.RTime; process.RTime = 0UL; - } else { - ++process.RTime; + } + + if (!UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { + continue; } } else { - kout << process.Name << " won't be scheduled to run...\r"; + ++process.RTime; --process.PTime; } } -- cgit v1.2.3 From 0266d8058990a496b935abd76417abcfe4e9cffd Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 18 May 2025 15:15:52 +0200 Subject: dev(sched): Improvements and work in progress fixes. what? - The main algorithm got improved for real time tasks, and SMP usage. - The SMP usage was present before, I just reintroduced it after realizing that it won't scale well from what I have right now. - Also removed weird implementations quirks from previous sketch. - Such as the core 0 being reserved for the boot core. - Also moved FS init code after IDT initalization. - To avoid weird FS format behavior. - Wrap HPET signature in a macro. next? - Work on the HAL's userspace transition mechanism. Signed-off-by: Amlal El Mahrouss --- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 30 ++++++++++++++--- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 2 -- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 15 +++++---- dev/kernel/HALKit/AMD64/HalTimerAMD64.cc | 4 ++- dev/kernel/KernelKit/HardwareThreadScheduler.h | 10 +++--- dev/kernel/src/ACPIFactoryInterface.cc | 7 ++-- dev/kernel/src/HardwareThreadScheduler.cc | 8 ++--- dev/kernel/src/UserProcessScheduler.cc | 38 ++++++++++------------ 8 files changed, 64 insertions(+), 50 deletions(-) (limited to 'dev/kernel/src/HardwareThreadScheduler.cc') diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 7e2b8957..eac6c389 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -37,6 +37,9 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "General Access Fault."); + } if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -62,6 +65,10 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Access Fault."); + } + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -101,6 +108,9 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Math Fault."); + } if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -126,6 +136,10 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Generic Fault."); + } + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -146,10 +160,15 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { - hal_idt_send_eoi(3); - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + while (YES) + ; + } + + hal_idt_send_eoi(3); + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -167,8 +186,6 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { Kernel::kout << "Kernel: SIGTRAP status.\r"; process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; - - idt_handle_scheduler(rip); } /// @brief Handle #UD fault. @@ -180,6 +197,11 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + while (YES) + ; + } + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index 667d3c5b..a6b194d3 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -224,8 +224,6 @@ __NE_INT_32: std - add rsp, 8 - o64 iret IntNormal 33 diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 581af60a..f4585835 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -110,24 +110,25 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - Kernel::HAL::Register64 idt_reg; - idt_reg.Base = reinterpret_cast(kInterruptVectorTable); - - Kernel::HAL::IDTLoader idt_loader; - - idt_loader.Load(idt_reg); - #ifdef __FSKIT_INCLUDES_HEFS__ if (Kernel::HeFS::fs_init_hefs()) { goto hal_spin_kernel; } #endif + if (!Kernel::NeFS::fs_init_nefs()) { kout << "NeFS cannot be formated on the disk. Aborting\r"; dbg_break_point(); } hal_spin_kernel: + Kernel::HAL::Register64 idt_reg; + idt_reg.Base = reinterpret_cast(kInterruptVectorTable); + + Kernel::HAL::IDTLoader idt_loader; + + idt_loader.Load(idt_reg); + while (YES) ; } diff --git a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc index 79165289..13573880 100644 --- a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalTimerAMD64.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/KernelKit/HardwareThreadScheduler.h b/dev/kernel/KernelKit/HardwareThreadScheduler.h index dd8271eb..4a3220bd 100644 --- a/dev/kernel/KernelKit/HardwareThreadScheduler.h +++ b/dev/kernel/KernelKit/HardwareThreadScheduler.h @@ -24,11 +24,11 @@ using ThreadID = UInt32; enum ThreadKind { kAPInvalid, - kAPSystemReserved, // System reserved thread, well user can't use it - kAPStandard, // user thread, cannot be used by Kernel - kAPRealTime, // fallback thread, cannot be used by user if not clear or - // used by Kernel. - kAPBoot, // The core we booted from, the mama. + kAPSystemReserved = 100, // System reserved thread, well user can't use it + kAPStandard, // user thread, cannot be used by Kernel + kAPRealTime, // fallback thread, cannot be used by user if not clear or + // used by Kernel. + kAPBoot, // The core we booted from, the mama. kAPCount, }; diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc index a76caff2..ded49587 100644 --- a/dev/kernel/src/ACPIFactoryInterface.cc +++ b/dev/kernel/src/ACPIFactoryInterface.cc @@ -14,13 +14,12 @@ namespace Kernel { ErrorOr ACPIFactoryInterface::Find(const Char* signature) { MUST_PASS(this->fRsdp); - if (!signature) return ErrorOr{-1}; - - if (*signature == 0) return ErrorOr{-1}; + if (!signature) return ErrorOr{nullptr}; + if (*signature == 0) return ErrorOr{nullptr}; RSDP* rsp_ptr = reinterpret_cast(this->fRsdp); - if (rsp_ptr->Revision <= 1) return ErrorOr{-1}; + if (rsp_ptr->Revision < 1) return ErrorOr{nullptr}; RSDT* xsdt = reinterpret_cast(rsp_ptr->RsdtAddress); diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index 6cb83b3d..eda68104 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -158,12 +158,8 @@ HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept { */ /***********************************************************************************/ Ref HardwareThreadScheduler::operator[](SizeT idx) { - if (idx == 0) { - if (fThreadList[idx].Kind() != kAPSystemReserved) { - fThreadList[idx].fKind = kAPBoot; - } - } else if (idx >= kMaxAPInsideSched) { - static HardwareThread* kFakeThread = nullptr; + if (idx >= kMaxAPInsideSched) { + STATIC HardwareThread* kFakeThread = nullptr; return {kFakeThread}; } diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index b0d56c5d..165cfb5d 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -494,37 +494,28 @@ SizeT UserProcessScheduler::Run() noexcept { //! Check if the process needs to be run. if (UserProcessHelper::CanBeScheduled(process)) { - if (process.StackSize > kSchedMaxStackSz) { - kout << "Process: " << process.Name << ", has not a valid stack size! Crashing it...\r"; - process.Crash(); - continue; - } - kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled...\r"; process.PTime = static_cast(process.Affinity); - if (process.PTime < process.RTime) { + if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) { if (process.RTime < (Int32) AffinityKind::kVeryHigh) - process.RTime = (Int32) AffinityKind::kLowUsage; + process.RTime = (Int32) AffinityKind::kLowUsage / 2; else if (process.RTime < (Int32) AffinityKind::kHigh) - process.RTime = (Int32) AffinityKind::kStandard; + process.RTime = (Int32) AffinityKind::kStandard / 3; else if (process.RTime < (Int32) AffinityKind::kStandard) - process.RTime = (Int32) AffinityKind::kHigh; + process.RTime = (Int32) AffinityKind::kHigh / 4; - process.PTime += process.RTime; + process.PTime -= process.RTime; process.RTime = 0UL; } if (!UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { - break; + continue; } - - mTeam.AsArray()[this->TheCurrentProcess().Leak().ProcessId] = - this->TheCurrentProcess().Leak(); - - this->TheCurrentProcess() = process; } else { + kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled later...\r"; + ++process.RTime; --process.PTime; } @@ -575,14 +566,13 @@ ErrorOr UserProcessHelper::TheCurrentPID() { /// @retval false cannot be schedulded. Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) { if (process.Status != ProcessStatusKind::kRunning) return No; - + if (process.StackSize > kSchedMaxStackSz) return No; if (!process.Name[0]) return No; // real time processes shouldn't wait that much. if (process.Affinity == AffinityKind::kRealTime) return Yes; - if (process.Signal.SignalID == SIGKILL || process.Signal.SignalID == SIGABRT || - process.Signal.SignalID == SIGTRAP) { + if (process.Signal.SignalID == SIGTRAP) { return No; } @@ -625,7 +615,10 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { UserProcessHelper::TheCurrentPID().Leak().Leak() = UserProcessHelper::TheCurrentPID(); - break; + UserProcessScheduler::The().TheCurrentProcess() = + UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid]; + + return YES; } continue; @@ -653,6 +646,9 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].PTime; HardwareThreadScheduler::The()[index].Leak()->Wake(YES); + UserProcessScheduler::The().TheCurrentProcess() = + UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid]; + return YES; } -- cgit v1.2.3 From ce71265ae5bd333c309dff8c2d46e4d52dd78066 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 18 May 2025 20:00:25 +0200 Subject: feat(sched_desgin): better architecture for the HTS. Signed-off-by: Amlal El Mahrouss --- dev/boot/src/HEL/AMD64/BootEFI.cc | 2 +- dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 20 +++++------- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 24 ++++++++------ dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 1 - dev/kernel/KernelKit/HardwareThreadScheduler.h | 4 +-- dev/kernel/src/ACPIFactoryInterface.cc | 8 +++-- dev/kernel/src/HardwareThreadScheduler.cc | 9 +++--- dev/kernel/src/UserProcessScheduler.cc | 37 ++++++---------------- 8 files changed, 45 insertions(+), 60 deletions(-) (limited to 'dev/kernel/src/HardwareThreadScheduler.cc') diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index dbc12265..12a912e5 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -243,7 +243,7 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTa handover_hdr->f_KernelImage = reader_kernel.Blob(); handover_hdr->f_KernelSz = reader_kernel.Size(); - kernel_thread.Start(handover_hdr, YES); + kernel_thread.Start(handover_hdr, NO); } Boot::BootFileReader reader_netboot(L"net.efi", image_handle); diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index 89fe00b5..b12dc7fe 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -44,6 +44,8 @@ /////////////////////////////////////////////////////////////////////////////////////// namespace Kernel::HAL { +EXTERN_C Void sched_jump_to_task(HAL::StackFramePtr stack_frame); + struct HAL_APIC_MADT; struct HAL_HARDWARE_THREAD; @@ -59,9 +61,9 @@ STATIC Int64 kSMPCount = 0; EXTERN_C UIntPtr kApicBaseAddress; -STATIC Int32 kSMPInterrupt = 0; -STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0}; -STATIC VoidPtr kRawMADT = nullptr; +STATIC Int32 kSMPInterrupt = 0; +STATIC UInt64 kAPICLocales[kMaxAPInsideSched] = {0}; +STATIC VoidPtr kRawMADT = nullptr; /// @brief Multiple APIC Descriptor Table. struct HAL_APIC_MADT final SDT_OBJECT { @@ -105,17 +107,11 @@ EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) { } EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) { - MUST_PASS(stack_frame); - - const auto process_index = pid % kSchedProcessLimitPerTeam; - - kHWThread[process_index].mFramePtr = stack_frame; - kHWThread[process_index].mProcessID = pid; - - kHWThread[process_index].mCoreID = kAPICLocales[0]; + if (pid > kSMPCount) return NO; if (mp_is_smp()) { - /// TODO: + kHWThread[pid].mFramePtr = stack_frame; + kHWThread[pid].mProcessID = pid; return YES; } diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index f4585835..6020da3b 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -104,28 +104,34 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { } EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { - Kernel::rtl_create_user_process(sched_idle_task, "MgmtSrv"); //! Mgmt command server. - Kernel::rtl_create_user_process(sched_idle_task, "LaunchSrv"); //! launchd - Kernel::rtl_create_user_process(sched_idle_task, "SecSrv"); //! Login Server + using namespace Kernel; - Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); + for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { + HardwareThreadScheduler::The()[index].Leak()->Kind() = ThreadKind::kAPStandard; + } + + 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 + + HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); #ifdef __FSKIT_INCLUDES_HEFS__ - if (Kernel::HeFS::fs_init_hefs()) { + if (HeFS::fs_init_hefs()) { goto hal_spin_kernel; } #endif - if (!Kernel::NeFS::fs_init_nefs()) { + if (!NeFS::fs_init_nefs()) { kout << "NeFS cannot be formated on the disk. Aborting\r"; dbg_break_point(); } hal_spin_kernel: - Kernel::HAL::Register64 idt_reg; - idt_reg.Base = reinterpret_cast(kInterruptVectorTable); + HAL::Register64 idt_reg; + idt_reg.Base = reinterpret_cast(kInterruptVectorTable); - Kernel::HAL::IDTLoader idt_loader; + HAL::IDTLoader idt_loader; idt_loader.Load(idt_reg); diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index 57e77e77..246c2e02 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -54,7 +54,6 @@ using namespace Kernel; -STATIC HardwareTimer kSATATimer(rtl_milliseconds(5)); STATIC PCI::Device kSATADev; STATIC HbaMemRef kSATAHba; STATIC Lba kSATASectorCount = 0UL; diff --git a/dev/kernel/KernelKit/HardwareThreadScheduler.h b/dev/kernel/KernelKit/HardwareThreadScheduler.h index 4a3220bd..11347c7e 100644 --- a/dev/kernel/KernelKit/HardwareThreadScheduler.h +++ b/dev/kernel/KernelKit/HardwareThreadScheduler.h @@ -23,7 +23,7 @@ class HardwareThreadScheduler; using ThreadID = UInt32; enum ThreadKind { - kAPInvalid, + kAPInvalid = 0, kAPSystemReserved = 100, // System reserved thread, well user can't use it kAPStandard, // user thread, cannot be used by Kernel kAPRealTime, // fallback thread, cannot be used by user if not clear or @@ -58,7 +58,7 @@ class HardwareThread final { void Busy(const BOOL busy = false) noexcept; public: - BOOL Switch(HAL::StackFramePtr frame, const ThreadID& pid); + BOOL Switch(HAL::StackFramePtr frame); BOOL IsWakeup() noexcept; public: diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc index ded49587..47a81f38 100644 --- a/dev/kernel/src/ACPIFactoryInterface.cc +++ b/dev/kernel/src/ACPIFactoryInterface.cc @@ -10,16 +10,18 @@ #include namespace Kernel { +constexpr STATIC const auto kMinACPIVer = 1; + /// @brief Finds a descriptor table inside ACPI XSDT. ErrorOr ACPIFactoryInterface::Find(const Char* signature) { MUST_PASS(this->fRsdp); - if (!signature) return ErrorOr{nullptr}; - if (*signature == 0) return ErrorOr{nullptr}; + if (!signature) return ErrorOr{-kErrorInvalidData}; + if (*signature == 0) return ErrorOr{-kErrorInvalidData}; RSDP* rsp_ptr = reinterpret_cast(this->fRsdp); - if (rsp_ptr->Revision < 1) return ErrorOr{nullptr}; + if (rsp_ptr->Revision < kMinACPIVer) return ErrorOr{-kErrorInvalidData}; RSDT* xsdt = reinterpret_cast(rsp_ptr->RsdtAddress); diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index eda68104..09c1c7d8 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -104,16 +104,13 @@ Void HardwareThread::Wake(const bool wakeup) noexcept { /// @retval true stack was changed, code is running. /// @retval false stack is invalid, previous code is running. /***********************************************************************************/ -Bool HardwareThread::Switch(HAL::StackFramePtr frame, const ThreadID& pid) { +Bool HardwareThread::Switch(HAL::StackFramePtr frame) { if (this->IsBusy()) return NO; this->fStack = frame; - this->fPID = pid; Bool ret = mp_register_process(fStack, this->fPID); - if (ret) this->Busy(YES); - return ret; } @@ -159,10 +156,12 @@ HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept { /***********************************************************************************/ Ref HardwareThreadScheduler::operator[](SizeT idx) { if (idx >= kMaxAPInsideSched) { - STATIC HardwareThread* kFakeThread = nullptr; + HardwareThread* kFakeThread = nullptr; return {kFakeThread}; } + fThreadList[idx].fPID = idx; + return &fThreadList[idx]; } diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 165cfb5d..393f1419 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -25,8 +25,6 @@ ///! BUGS: 0 namespace Kernel { -EXTERN_C Void sched_jump_to_task(HAL::StackFramePtr stack_frame); - /***********************************************************************************/ /// @brief Exit Code global variable. /***********************************************************************************/ @@ -598,41 +596,24 @@ SizeT UserProcessHelper::StartScheduling() { /***********************************************************************************/ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { + (Void)(kout << "IP: " << hex_number(frame_ptr->IP) << kendl); + for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { + if (!HardwareThreadScheduler::The()[index].Leak()) continue; + if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPInvalid || HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot) continue; - // A fallback is a special core for real-time tasks which needs immediate execution. - if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPRealTime) { - if (UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].Affinity != - AffinityKind::kRealTime) - continue; - - if (HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr, new_pid)) { - HardwareThreadScheduler::The()[index].Leak()->fPTime = - UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].PTime; - - UserProcessHelper::TheCurrentPID().Leak().Leak() = UserProcessHelper::TheCurrentPID(); - - UserProcessScheduler::The().TheCurrentProcess() = - UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid]; - - return YES; - } - - continue; - } - - if (UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].Affinity == - AffinityKind::kRealTime) - continue; + (Void)(kout << "AP_" << hex_number(index) << kendl); //////////////////////////////////////////////////////////// /// Prepare task switch. /// //////////////////////////////////////////////////////////// - Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr, new_pid); + HardwareThreadScheduler::The()[index].Leak()->Busy(YES); + Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr); + HardwareThreadScheduler::The()[index].Leak()->Busy(NO); //////////////////////////////////////////////////////////// /// Rollback on fail. /// @@ -652,6 +633,8 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { return YES; } + kout << "Couldn't find a suitable core for the current process!\r"; + return NO; } -- cgit v1.2.3 From a9653add416fbddc1969a75adb733bc9e9c675d6 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 19 May 2025 10:24:52 +0200 Subject: feat(kernel, sched): Architectural improvements, and cleaned up the codebase from previous implementations that didn't work/scale well. Signed-off-by: Amlal El Mahrouss --- dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 42 +++++++++------- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 10 ---- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 7 +++ dev/kernel/HALKit/AMD64/HalKernelPanic.cc | 7 ++- dev/kernel/HALKit/ARM64/ApplicationProcessor.h | 2 +- dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc | 32 ++++++++---- dev/kernel/HALKit/ARM64/HalKernelMain.cc | 55 ++++++++++---------- dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc | 54 +------------------- dev/kernel/KernelKit/MemoryMgr.h | 5 -- dev/kernel/KernelKit/Timer.h | 12 ++--- dev/kernel/NewKit/Array.h | 5 +- dev/kernel/src/HardwareThreadScheduler.cc | 15 ------ dev/kernel/src/MemoryMgr.cc | 15 ------ dev/kernel/src/UserProcessScheduler.cc | 58 +++++++++++++--------- 14 files changed, 137 insertions(+), 182 deletions(-) (limited to 'dev/kernel/src/HardwareThreadScheduler.cc') diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index b12dc7fe..78db9b16 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -51,8 +51,7 @@ struct HAL_HARDWARE_THREAD; struct HAL_HARDWARE_THREAD final { HAL::StackFramePtr mFramePtr; - ProcessID mProcessID{0}; - UInt8 mCoreID{0}; + ProcessID mThreadID{0}; }; STATIC HAL_APIC_MADT* kMADTBlock = nullptr; @@ -100,18 +99,24 @@ Void hal_send_ipi_msg(UInt32 target, UInt32 apic_id, UInt8 vector) { STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}}; -EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) { - const auto process_index = pid % kSchedProcessLimitPerTeam; +EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 thrdid) { + const auto process_index = thrdid % kSchedProcessLimitPerTeam; return kHWThread[process_index].mFramePtr; } -EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) { - if (pid > kSMPCount) return NO; +EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) { + if (thrdid > kSMPCount) return NO; if (mp_is_smp()) { - kHWThread[pid].mFramePtr = stack_frame; - kHWThread[pid].mProcessID = pid; + kHWThread[thrdid].mFramePtr = stack_frame; + kHWThread[thrdid].mThreadID = thrdid; + + STATIC HardwareTimer timer{rtl_milliseconds(1000)}; + + timer.Wait(); + + HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); return YES; } @@ -151,7 +156,14 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { PowerFactoryInterface hw_and_pow_int{vendor_ptr}; - kRawMADT = hw_and_pow_int.Find(APIC_MAG).Leak().Leak(); + auto pwr = hw_and_pow_int.Find(APIC_MAG); + + if (pwr.HasError()) { + kSMPAware = NO; + return; + } + + kRawMADT = pwr.Leak().Leak(); kMADTBlock = reinterpret_cast(kRawMADT); kSMPAware = NO; @@ -181,11 +193,6 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { controller.Write(LAPIC_REG_TIMER_LVT, 32 | (1 << 17)); controller.Write(LAPIC_REG_TIMER_INITCNT, 1000000); - UInt8* trampoline_phys = (UInt8*) 0x7c00; - - *trampoline_phys = 0xcd; - *(trampoline_phys + 1) = 0x00; - volatile UInt8* entry_ptr = reinterpret_cast(kMADTBlock->List); volatile UInt8* end_ptr = ((UInt8*) kMADTBlock) + kMADTBlock->Length; @@ -203,14 +210,15 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { kAPICLocales[kSMPCount] = entry_struct->ProcessorID; ++kSMPCount; - kout << "LAPIC type, also is on...\r"; + kout << "Kind: LAPIC: ON\r"; + // 0x7c00, as recommended by the Intel SDM. hal_send_ipi_msg(kApicBaseAddress, entry_struct->ProcessorID, 0x7c); } else { - kout << "LAPIC type, also is not on...\r"; + kout << "Kind: LAPIC: OFF\r"; } } else { - kout << "Unknown APIC type...\r"; + kout << "Kind: UNKNOWN: ?\r"; } entry_ptr += length; diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index eac6c389..51fc4f0e 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -54,8 +54,6 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { Kernel::kout << "Kernel: SIGKILL status.\r"; process.Leak().Crash(); - - dbg_break_point(); } /// @brief Handle page fault. @@ -82,8 +80,6 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { process.Leak().Signal.Status = process.Leak().Status; process.Leak().Crash(); - - dbg_break_point(); } /// @brief Handle scheduler interrupt. @@ -125,8 +121,6 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { Kernel::kout << "Kernel: SIGKILL status.\r"; process.Leak().Crash(); - - dbg_break_point(); } /// @brief Handle any generic fault. @@ -155,8 +149,6 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { Kernel::kout << "Kernel: SIGKILL status.\r"; process.Leak().Crash(); - - dbg_break_point(); } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { @@ -216,8 +208,6 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { Kernel::kout << "Kernel: SIGKILL status.\r"; process.Leak().Crash(); - - dbg_break_point(); } /// @brief Enter syscall from assembly. diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 6020da3b..4de43f27 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -108,6 +108,13 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { HardwareThreadScheduler::The()[index].Leak()->Kind() = ThreadKind::kAPStandard; + HardwareThreadScheduler::The()[index].Leak()->Busy(NO); + } + + for (SizeT index = 0UL; index < UserProcessScheduler::The().TheCurrentTeam().AsArray().Count(); + ++index) { + UserProcessScheduler::The().TheCurrentTeam().AsArray()[index].Status = + ProcessStatusKind::kInvalid; } rtl_create_user_process(sched_idle_task, "MgmtSrv"); //! Mgmt command server. diff --git a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc index 7ec235bd..76b92574 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc @@ -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/ARM64/ApplicationProcessor.h b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h index 75f4eb07..06a8e2a8 100644 --- a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h +++ b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h @@ -15,5 +15,5 @@ /************************************************** */ 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/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc index a89702ea..d37a3e54 100644 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -7,7 +7,9 @@ #include #include #include +#include #include +#include #define GICD_BASE 0x08000000 // Distributor base address #define GICC_BASE 0x08010000 // CPU interface base address @@ -29,11 +31,12 @@ // ================================================================= // namespace Kernel { -struct PROCESS_CONTROL_BLOCK final { +struct HAL_HARDWARE_THREAD final { HAL::StackFramePtr mFrame; + ProcessID mThreadID{0}; }; -STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0}; +STATIC HAL_HARDWARE_THREAD kHWThread[kMaxAPInsideSched] = {{nullptr}}; namespace Detail { STATIC BOOL kGICEnabled = NO; @@ -86,7 +89,7 @@ namespace Detail { const UInt16 kInterruptScheduler = 0x20; - (Void)(kout << "Handling interrupt for AP: " << interrupt << kendl); + (Void)(kout << "SMP: AP: " << hex_number(interrupt) << kendl); switch (interrupt) { case kInterruptScheduler: { @@ -108,23 +111,32 @@ namespace Detail { } } // namespace Detail -EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID pid) { - return kProcessBlocks[pid % kSchedProcessLimitPerTeam].mFrame; +EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID thrdid) { + return kHWThread[thrdid].mFrame; } -EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) { - MUST_PASS(stack_frame); +EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) { + MUST_PASS(Detail::kGICEnabled); - const auto process_index = pid % kSchedProcessLimitPerTeam; + if (!stack_frame) return NO; + if (thrdid > kMaxAPInsideSched) return NO; - kProcessBlocks[process_index].mFrame = stack_frame; + const auto process_index = thrdid; + + kHWThread[process_index].mFrame = stack_frame; + kHWThread[process_index].mThreadID = thrdid; + + STATIC HardwareTimer timer{rtl_milliseconds(1000)}; + timer.Wait(); + + HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); return YES; } /// @internal /// @brief Initialize the Global Interrupt Controller. -BOOL mp_initialize_gic(Void) { +Void mp_init_cores(Void) noexcept { if (!Detail::kGICEnabled) { Detail::kGICEnabled = YES; Detail::mp_setup_gic_el0(); diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc index bf5849ef..c92b12cd 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc @@ -7,9 +7,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -18,9 +20,10 @@ #include #include -#include - +#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 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/HalPagingMgrARM64.cc b/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc index e0b67489..faad6778 100644 --- a/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc @@ -13,65 +13,15 @@ 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; + if (!virtual_address || !flags) return kErrorInvalidData; - page_store.fStoreOp = No; + NE_UNUSED(physical_address); return kErrorSuccess; } diff --git a/dev/kernel/KernelKit/MemoryMgr.h b/dev/kernel/KernelKit/MemoryMgr.h index d84dc9a4..bf389955 100644 --- a/dev/kernel/KernelKit/MemoryMgr.h +++ b/dev/kernel/KernelKit/MemoryMgr.h @@ -21,11 +21,6 @@ namespace Kernel { /// @return a status code regarding the deallocation. Int32 mm_delete_ptr(VoidPtr heap_ptr); -/// @brief Declare a new size for heap_ptr. -/// @param heap_ptr the pointer. -/// @return unsupported always returns nullptr. -VoidPtr mm_realloc_ptr(VoidPtr heap_ptr, SizeT new_sz); - /// @brief Check if pointer is a valid Kernel pointer. /// @param heap_ptr the pointer /// @return if it exists it returns true. diff --git a/dev/kernel/KernelKit/Timer.h b/dev/kernel/KernelKit/Timer.h index d6cfee39..2d040535 100644 --- a/dev/kernel/KernelKit/Timer.h +++ b/dev/kernel/KernelKit/Timer.h @@ -60,16 +60,16 @@ class HardwareTimer final : public TimerInterface { Int64 fWaitFor{0}; }; -inline Int64 rtl_microseconds(Int64 time) { - if (time < 0) return 0; +inline UInt64 rtl_microseconds(UInt64 time) { + if (time < 1) return 0; // TODO: nanoseconds maybe? - return kTimeUnit * time; + return time / kTimeUnit; } -inline Int64 rtl_milliseconds(Int64 time) { - if (time < 0) return 0; +inline UInt64 rtl_milliseconds(UInt64 time) { + if (time < 1) return 0; - return kTimeUnit * kTimeUnit * time; + return time; } } // namespace Kernel diff --git a/dev/kernel/NewKit/Array.h b/dev/kernel/NewKit/Array.h index 767d8678..2b6d31f3 100644 --- a/dev/kernel/NewKit/Array.h +++ b/dev/kernel/NewKit/Array.h @@ -26,7 +26,10 @@ class Array final { SizeT Capacity() { return N; } - SizeT Count() { return N; } + SizeT Count() { + const static SizeT kArrCnt = N; + return kArrCnt; // avoid constexpr error. + } const T* CData() { return fArray; } diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index 09c1c7d8..b801632c 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -57,19 +57,6 @@ ThreadKind& HardwareThread::Kind() noexcept { //! @return whether the thread is busy or not. /***********************************************************************************/ Bool HardwareThread::IsBusy() noexcept { - STATIC Int64 busy_timer = 0U; - constexpr Int64 kTimeoutMax = - 0x1000000; // an arbitrary value used to tell if the timeout hasn't been reached yet. - - if (fBusy && (busy_timer > kTimeoutMax)) { - busy_timer = 0U; - fBusy = No; - - return No; - } - - ++busy_timer; - return fBusy; } @@ -105,8 +92,6 @@ Void HardwareThread::Wake(const bool wakeup) noexcept { /// @retval false stack is invalid, previous code is running. /***********************************************************************************/ Bool HardwareThread::Switch(HAL::StackFramePtr frame) { - if (this->IsBusy()) return NO; - this->fStack = frame; Bool ret = mp_register_process(fStack, this->fPID); diff --git a/dev/kernel/src/MemoryMgr.cc b/dev/kernel/src/MemoryMgr.cc index f8aa14cf..efb9a35f 100644 --- a/dev/kernel/src/MemoryMgr.cc +++ b/dev/kernel/src/MemoryMgr.cc @@ -93,21 +93,6 @@ namespace Detail { STATIC PageMgr kPageMgr; -/// @brief Declare a new size for ptr_ptr. -/// @param ptr_ptr the pointer. -/// @return Newly allocated heap header. -_Output auto mm_realloc_ptr(VoidPtr ptr_ptr, SizeT new_sz) -> VoidPtr { - if (Detail::mm_check_ptr_address(ptr_ptr) == No) return nullptr; - - if (!ptr_ptr || new_sz < 1) return nullptr; - - kout << "MemoryMgr: This function is not implemented by the kernel yet.\r"; - - ke_panic(RUNTIME_CHECK_INVALID); - - return nullptr; -} - /// @brief Allocate chunk of memory. /// @param sz Size of pointer /// @param wr Read Write bit. diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 393f1419..0de38532 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -492,28 +492,24 @@ SizeT UserProcessScheduler::Run() noexcept { //! Check if the process needs to be run. if (UserProcessHelper::CanBeScheduled(process)) { - kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled...\r"; - - process.PTime = static_cast(process.Affinity); - - if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) { - if (process.RTime < (Int32) AffinityKind::kVeryHigh) - process.RTime = (Int32) AffinityKind::kLowUsage / 2; - else if (process.RTime < (Int32) AffinityKind::kHigh) - process.RTime = (Int32) AffinityKind::kStandard / 3; - else if (process.RTime < (Int32) AffinityKind::kStandard) - process.RTime = (Int32) AffinityKind::kHigh / 4; - - process.PTime -= process.RTime; - process.RTime = 0UL; - } - - if (!UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { - continue; + kout << process.Name << " will be scheduled...\r"; + + if (UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { + process.PTime = static_cast(process.Affinity); + + if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) { + if (process.RTime < (Int32) AffinityKind::kVeryHigh) + process.RTime = (Int32) AffinityKind::kLowUsage / 2; + else if (process.RTime < (Int32) AffinityKind::kHigh) + process.RTime = (Int32) AffinityKind::kStandard / 3; + else if (process.RTime < (Int32) AffinityKind::kStandard) + process.RTime = (Int32) AffinityKind::kHigh / 4; + + process.PTime -= process.RTime; + process.RTime = 0UL; + } } } else { - kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled later...\r"; - ++process.RTime; --process.PTime; } @@ -607,13 +603,19 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { (Void)(kout << "AP_" << hex_number(index) << kendl); + if (HardwareThreadScheduler::The()[index].Leak()->IsBusy()) { + (Void)(kout << "AP_" << hex_number(index)); + kout << " is busy\r"; + continue; + } + //////////////////////////////////////////////////////////// /// Prepare task switch. /// //////////////////////////////////////////////////////////// HardwareThreadScheduler::The()[index].Leak()->Busy(YES); + Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr); - HardwareThreadScheduler::The()[index].Leak()->Busy(NO); //////////////////////////////////////////////////////////// /// Rollback on fail. /// @@ -642,13 +644,23 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { /// @brief this checks if any process is on the team. //////////////////////////////////////////////////////////// UserProcessScheduler::operator bool() { - return mTeam.AsArray().Count() > 0; + for (auto process_index = 0UL; process_index < mTeam.AsArray().Count(); ++process_index) { + auto& process = mTeam.AsArray()[process_index]; + if (UserProcessHelper::CanBeScheduled(process)) return true; + } + + return false; } //////////////////////////////////////////////////////////// /// @brief this checks if no process is on the team. //////////////////////////////////////////////////////////// Bool UserProcessScheduler::operator!() { - return mTeam.AsArray().Count() == 0; + for (auto process_index = 0UL; process_index < mTeam.AsArray().Count(); ++process_index) { + auto& process = mTeam.AsArray()[process_index]; + if (UserProcessHelper::CanBeScheduled(process)) return false; + } + + return true; } } // namespace Kernel -- cgit v1.2.3 From 58d2af14429be02b580cde5b3e23978530d8ab74 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 21 May 2025 10:19:07 +0200 Subject: feat(kernel): Architectural changes, and introducing a kKernelVM. see code for more details. Signed-off-by: Amlal El Mahrouss --- dev/boot/src/BootThread.cc | 3 ++ dev/boot/src/HEL/AMD64/BootEFI.cc | 2 +- dev/kernel/ArchKit/ArchKit.h | 8 +++- dev/kernel/FirmwareKit/Handover.h | 2 + dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 22 +++------- dev/kernel/HALKit/AMD64/HalCommonAPI.asm | 48 +++++++++++++++----- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 51 +--------------------- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 22 ---------- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 27 ++++++++++-- dev/kernel/HALKit/AMD64/Processor.h | 2 - dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc | 2 +- dev/kernel/HALKit/ARM64/Processor.h | 2 - dev/kernel/KernelKit/KernelTaskScheduler.h | 2 +- dev/kernel/src/HardwareThreadScheduler.cc | 4 +- dev/kernel/src/UserProcessScheduler.cc | 23 +++++++--- 15 files changed, 100 insertions(+), 120 deletions(-) (limited to 'dev/kernel/src/HardwareThreadScheduler.cc') diff --git a/dev/boot/src/BootThread.cc b/dev/boot/src/BootThread.cc index ada864bb..b502b52e 100644 --- a/dev/boot/src/BootThread.cc +++ b/dev/boot/src/BootThread.cc @@ -175,6 +175,9 @@ Int32 BootThread::Start(HEL::BootInfoHeader* handover, Bool own_stack) { writer.Write("BootZ: Stack address: ").Write((UIntPtr) &fStack[mib_cast(16) - 1]).Write("\r"); writer.Write("BootZ: Stack size: ").Write(mib_cast(16)).Write("\r"); + fHandover->f_StackTop = &fStack[mib_cast(16) - 1]; + fHandover->f_StackSz = mib_cast(16); + auto ret = rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(16) - 1]); // we don't need the stack anymore. diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index 45566d6c..33dfd3ca 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -243,7 +243,7 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTa handover_hdr->f_KernelImage = reader_kernel.Blob(); handover_hdr->f_KernelSz = reader_kernel.Size(); - kernel_thread.Start(handover_hdr, NO); + kernel_thread.Start(handover_hdr, YES); } Boot::BootFileReader reader_netboot(L"net.efi", image_handle); diff --git a/dev/kernel/ArchKit/ArchKit.h b/dev/kernel/ArchKit/ArchKit.h index 41a36e69..d511658f 100644 --- a/dev/kernel/ArchKit/ArchKit.h +++ b/dev/kernel/ArchKit/ArchKit.h @@ -77,8 +77,14 @@ struct HalSyscallEntry final { operator bool() { return fHooked; } }; +EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid); + inline Kernel::Array kSysCalls; inline Kernel::Array kKernCalls; -EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid); +#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + +inline Kernel::VoidPtr kKernelVM = nullptr; + +#endif // __NE_VIRTUAL_MEMORY_SUPPORT__ \ No newline at end of file diff --git a/dev/kernel/FirmwareKit/Handover.h b/dev/kernel/FirmwareKit/Handover.h index d3ccc724..cda27e52 100644 --- a/dev/kernel/FirmwareKit/Handover.h +++ b/dev/kernel/FirmwareKit/Handover.h @@ -63,6 +63,8 @@ struct BootInfoHeader final { SizeT f_KernelSz; VoidPtr f_StartupImage; SizeT f_StartupSz; + VoidPtr f_StackTop; + SizeT f_StackSz; WideChar f_FirmwareVendorName[32]; SizeT f_FirmwareVendorLen; diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index e4ad1024..ada2ee3f 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -113,27 +113,17 @@ EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 thrdid) { /// @param thrdid The thread ID. /***********************************************************************************/ -EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) { +EXTERN_C BOOL mp_register_task(HAL::StackFramePtr stack_frame, ProcessID thrdid) { if (thrdid > kSMPCount) return NO; - if (!mp_is_smp()) { - if (stack_frame) { - kHWThread[thrdid].mFramePtr = stack_frame; - kHWThread[thrdid].mThreadID = thrdid; - HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); + kHWThread[thrdid].mFramePtr = stack_frame; + kHWThread[thrdid].mThreadID = thrdid; - sched_jump_to_task(stack_frame); + HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); - return YES; - } - } else { - kHWThread[thrdid].mFramePtr = stack_frame; - kHWThread[thrdid].mThreadID = thrdid; - - return YES; - } + sched_jump_to_task(stack_frame); - return NO; + return YES; } /***********************************************************************************/ diff --git a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm index 230f50ed..d0ce2418 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,7 +79,9 @@ mp_system_call_handler: pop r9 pop r8 - o64 sysret + pop rbp + + o64 iret section .text @@ -88,12 +92,40 @@ sched_jump_to_task: push rbp mov rbp, rsp - mov ax, 0x20 + 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: + mov ax, cs + and ax, 3 + + jmp $ + ret + +sched_recover_registers: + push rbp + mov rbp, rsp + mov r8, [rcx + 0x10] mov r9, [rcx + 0x18] mov r10, [rcx + 0x20] @@ -103,14 +135,6 @@ sched_jump_to_task: mov r14, [rcx + 0x40] mov r15, [rcx + 0x48] - mov rax, [rcx + 0x00] - mov rsp, [rcx + 0x08] - - o64 sysret - int 3 ;; Never continue here. + pop rbp -global sched_idle_task - -sched_idle_task: - jmp $ - ret + ret \ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 51fc4f0e..633adccb 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -37,14 +37,6 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "General Access Fault."); - } - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - Kernel::kout << "Kernel: General Access Fault.\r"; process.Leak().Signal.SignalArg = rsp; @@ -63,15 +55,6 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Access Fault."); - } - - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - Kernel::kout << "Kernel: Page Fault.\r"; Kernel::kout << "Kernel: SIGKILL\r"; @@ -104,14 +87,6 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Math Fault."); - } - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - Kernel::kout << "Kernel: Math error (division by zero?).\r"; process.Leak().Signal.SignalArg = rsp; @@ -130,15 +105,6 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Generic Fault."); - } - - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - (Void)(Kernel::kout << "Kernel: Process RSP: " << Kernel::hex_number(rsp) << Kernel::kendl); Kernel::kout << "Kernel: Access Process Fault.\r"; @@ -152,19 +118,9 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - - if (!process) { - while (YES) - ; - } - hal_idt_send_eoi(3); - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } + auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); @@ -189,11 +145,6 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - while (YES) - ; - } - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index a6b194d3..5e82f969 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -20,8 +20,6 @@ __NE_INT_%1: std - add rsp, 8 - o64 iret %endmacro @@ -61,8 +59,6 @@ __NE_INT_0: std - add rsp, 8 - o64 iret __NE_INT_1: @@ -83,8 +79,6 @@ __NE_INT_2: std - add rsp, 8 - o64 iret ;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched. @@ -96,8 +90,6 @@ __NE_INT_3: std - add rsp, 8 - o64 iret __NE_INT_4: @@ -109,16 +101,12 @@ __NE_INT_4: std - add rsp, 8 - o64 iret __NE_INT_5: cld std - add rsp, 8 - o64 iret ;; Invalid opcode interrupt @@ -130,8 +118,6 @@ __NE_INT_6: std - add rsp, 8 - o64 iret __NE_INT_7: @@ -142,8 +128,6 @@ __NE_INT_7: std - add rsp, 8 - o64 iret ;; Invalid opcode interrupt @@ -156,8 +140,6 @@ __NE_INT_8: std - add rsp, 8 - o64 iret IntNormal 9 @@ -187,8 +169,6 @@ __NE_INT_14: std - add rsp, 8 - o64 iret IntNormal 15 @@ -247,8 +227,6 @@ __NE_INT_40: std - add rsp, 8 - o64 iret IntNormal 41 diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 4de43f27..5394645a 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -38,9 +38,9 @@ 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. */ @@ -54,7 +54,12 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { /* INITIALIZE GDT AND SEGMENTS. */ /************************************** */ - STATIC CONST auto kGDTEntriesCount = 6; + STATIC CONST auto kGDTEntriesCount = 8; + + STATIC HAL::Detail::NE_TSS kKernelTSS{}; + + kKernelTSS.fRsp0 = (UInt64) kHandoverHeader->f_StackTop; + kKernelTSS.fIopb = sizeof(HAL::Detail::NE_TSS); /* The GDT, mostly descriptors for user and kernel segments. */ STATIC Kernel::HAL::Detail::NE_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = { @@ -76,6 +81,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, @@ -90,6 +97,20 @@ 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; diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index c574f8d5..3bf0ad3e 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -285,6 +285,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; - #endif // __NE_AMD64__ */ \ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc index 5be41e4e..70a5e2d9 100644 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -113,7 +113,7 @@ EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID thrdid) { /// @param thrdid The thread ID. /***********************************************************************************/ -EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) { +EXTERN_C Bool mp_register_task(HAL::StackFramePtr stack_frame, ProcessID thrdid) { MUST_PASS(Detail::kGICEnabled); if (!stack_frame) return NO; diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index f52b854f..ba1ed11e 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -72,8 +72,6 @@ inline Void hal_wfi(Void) { inline Kernel::VoidPtr kKernelBitMpStart = nullptr; inline Kernel::UIntPtr kKernelBitMpSize = 0UL; -inline Kernel::VoidPtr kKernelPDE = nullptr; - #include #endif // __NE_ARM64__ \ No newline at end of file diff --git a/dev/kernel/KernelKit/KernelTaskScheduler.h b/dev/kernel/KernelKit/KernelTaskScheduler.h index f4ff4125..57b83ccb 100644 --- a/dev/kernel/KernelKit/KernelTaskScheduler.h +++ b/dev/kernel/KernelKit/KernelTaskScheduler.h @@ -16,7 +16,7 @@ namespace Kernel { class KERNEL_TASK final { -public: + public: Char Name[kSchedNameLen] = {"KERNEL_TASK"}; ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemDriver}; HAL::StackFramePtr StackFrame{nullptr}; diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index b801632c..23365af5 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -21,7 +21,7 @@ namespace Kernel { /***********************************************************************************/ EXTERN_C Bool hal_check_stack(HAL::StackFramePtr frame); -EXTERN_C Bool mp_register_process(HAL::StackFramePtr frame, ProcessID pid); +EXTERN_C Bool mp_register_task(HAL::StackFramePtr frame, ProcessID pid); STATIC HardwareThreadScheduler kHardwareThreadScheduler; @@ -94,7 +94,7 @@ Void HardwareThread::Wake(const bool wakeup) noexcept { Bool HardwareThread::Switch(HAL::StackFramePtr frame) { this->fStack = frame; - Bool ret = mp_register_process(fStack, this->fPID); + Bool ret = mp_register_task(fStack, this->fPID); return ret; } diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 0de38532..a901e6d0 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -21,6 +21,7 @@ #include #include #include +#include "NewKit/Macros.h" ///! BUGS: 0 @@ -125,7 +126,7 @@ ErrorOr USER_PROCESS::New(SizeT sz, SizeT pad_amount) { if (this->UsedMemory > kSchedMaxMemoryLimit) return ErrorOr(-kErrorHeapOutOfMemory); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto vm_register = kKernelCR3; + auto vm_register = kKernelVM; hal_write_cr3(this->VMRegister); auto ptr = mm_new_ptr(sz, Yes, Yes, pad_amount); @@ -271,7 +272,7 @@ Void USER_PROCESS::Exit(const Int32& exit_code) { auto memory_ptr_list = this->HeapTree; #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto pd = kKernelCR3; + auto pd = kKernelVM; hal_write_cr3(this->VMRegister); #endif @@ -384,7 +385,7 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im rt_copy_memory(reinterpret_cast(const_cast(name)), process.Name, len); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - process.VMRegister = kKernelCR3; + process.VMRegister = kKernelVM; #else process.VMRegister = 0UL; #endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ @@ -401,6 +402,15 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im process.StackFrame->IP = reinterpret_cast(code); process.StackFrame->SP = reinterpret_cast(&process.StackReserve[0] + process.StackSize); +#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + HAL::mm_map_page((VoidPtr) process.StackFrame->IP, + (VoidPtr) HAL::mm_get_phys_address((VoidPtr) process.StackFrame->IP), + HAL::kMMFlagsUser | HAL::kMMFlagsPresent); + HAL::mm_map_page((VoidPtr) process.StackFrame->SP, + (VoidPtr) HAL::mm_get_phys_address((VoidPtr) process.StackFrame->SP), + HAL::kMMFlagsUser | HAL::kMMFlagsPresent); +#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + process.StackSize = kSchedMaxStackSz; rt_set_memory(process.StackReserve, 0, process.StackSize); @@ -494,6 +504,8 @@ SizeT UserProcessScheduler::Run() noexcept { if (UserProcessHelper::CanBeScheduled(process)) { kout << process.Name << " will be scheduled...\r"; + this->TheCurrentProcess() = process; + if (UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { process.PTime = static_cast(process.Affinity); @@ -606,6 +618,7 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { if (HardwareThreadScheduler::The()[index].Leak()->IsBusy()) { (Void)(kout << "AP_" << hex_number(index)); kout << " is busy\r"; + continue; } @@ -627,10 +640,6 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].PTime; - HardwareThreadScheduler::The()[index].Leak()->Wake(YES); - - UserProcessScheduler::The().TheCurrentProcess() = - UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid]; return YES; } -- cgit v1.2.3 From 54a0f4c49d9bfb955174c87dae2f442d7f5a8b25 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Fri, 23 May 2025 11:12:31 +0200 Subject: feat!(Kernel): Improvements on the BitMapMgr, HTS, and UPS. other: - Add ZXD header file. - Reworking AMD64 interrupts. - Improved HTS's design implementation. - Improved UPS's balancing implementation. breaking changes: - Rename MemoryMgr to HeapMgr. Signed-off-by: Amlal El Mahrouss --- dev/boot/src/HEL/AMD64/BootATA+Next.cc | 270 --------------------- dev/boot/src/HEL/AMD64/BootATA.cc | 256 ------------------- dev/boot/src/HEL/AMD64/BootATAcc | 266 ++++++++++++++++++++ dev/boot/src/HEL/AMD64/BootEFI.cc | 20 +- dev/boot/src/docs/KERN_VER.md | 18 +- dev/boot/src/docs/MKFS_HEFS.md | 106 ++++++++ dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc | 2 +- dev/kernel/HALKit/AMD64/HalAPStartup.s | 12 - dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 2 - .../HALKit/AMD64/HalApplicationProcessorStartup.s | 14 ++ dev/kernel/HALKit/AMD64/HalCommonAPI.asm | 3 - .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 66 +---- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 1 + dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc | 26 +- dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc | 2 +- .../HALKit/ARM64/HalApplicationProcessorStartup.s | 12 + dev/kernel/HALKit/ARM64/HalKernelMain.cc | 2 +- dev/kernel/KernelKit/FileMgr.h | 11 +- dev/kernel/KernelKit/HardwareThreadScheduler.h | 1 - dev/kernel/KernelKit/HeapMgr.h | 58 +++++ dev/kernel/KernelKit/HeapMgr.inl | 35 +++ dev/kernel/KernelKit/MemoryMgr.h | 78 ------ dev/kernel/KernelKit/Zxd.h | 37 +++ dev/kernel/NeKit/Function.h | 1 - dev/kernel/NeKit/New.h | 2 +- dev/kernel/NeKit/Ref.h | 2 +- dev/kernel/src/ACPIFactoryInterface.cc | 2 +- dev/kernel/src/BitMapMgr.cc | 10 +- dev/kernel/src/FS/Ext2+FileMgr.cc | 2 +- dev/kernel/src/FS/HeFS+FileMgr.cc | 2 +- dev/kernel/src/FS/NeFS+FileMgr.cc | 2 +- dev/kernel/src/HardwareThreadScheduler.cc | 13 +- dev/kernel/src/HeapMgr.cc | 260 ++++++++++++++++++++ dev/kernel/src/KPC.cc | 2 +- dev/kernel/src/MemoryMgr.cc | 260 -------------------- dev/kernel/src/New+Delete.cc | 2 +- dev/kernel/src/PEFCodeMgr.cc | 2 +- dev/kernel/src/User.cc | 2 +- dev/kernel/src/UserProcessScheduler.cc | 22 +- docs/drawio/ZXD_DESIGN.drawio | 62 ++--- tooling/mkfs.hefs.cc | 4 +- 41 files changed, 918 insertions(+), 1032 deletions(-) delete mode 100644 dev/boot/src/HEL/AMD64/BootATA+Next.cc delete mode 100644 dev/boot/src/HEL/AMD64/BootATA.cc create mode 100644 dev/boot/src/HEL/AMD64/BootATAcc create mode 100644 dev/boot/src/docs/MKFS_HEFS.md delete mode 100644 dev/kernel/HALKit/AMD64/HalAPStartup.s create mode 100644 dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s create mode 100644 dev/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s create mode 100644 dev/kernel/KernelKit/HeapMgr.h create mode 100644 dev/kernel/KernelKit/HeapMgr.inl delete mode 100644 dev/kernel/KernelKit/MemoryMgr.h create mode 100644 dev/kernel/KernelKit/Zxd.h create mode 100644 dev/kernel/src/HeapMgr.cc delete mode 100644 dev/kernel/src/MemoryMgr.cc (limited to 'dev/kernel/src/HardwareThreadScheduler.cc') diff --git a/dev/boot/src/HEL/AMD64/BootATA+Next.cc b/dev/boot/src/HEL/AMD64/BootATA+Next.cc deleted file mode 100644 index 547d4f99..00000000 --- a/dev/boot/src/HEL/AMD64/BootATA+Next.cc +++ /dev/null @@ -1,270 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -/** - * @file BootATA.cc - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief ATA driver. - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Amlal El Mahrouss - * - */ - -#if 0 - -#include -#include -#include - -#define kATADataLen (256) - -/// bugs: 0 - -using namespace Boot; - -static Boolean kATADetected = false; -static UInt16 kATAData[kATADataLen] = {0}; - -Boolean boot_ata_detected(Void); - -STATIC Boolean boot_ata_wait_io(UInt16 IO) { - for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto status_rdy = rt_in8(IO + ATA_REG_STATUS); - - if ((status_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - status_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (status_rdy & ATA_SR_ERR) return false; - - if (!(status_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; - - return true; -} - -Void boot_ata_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 boot_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { - NE_UNUSED(Drive); - - if (boot_ata_detected()) return true; - - BootTextWriter writer; - - UInt16 IO = Bus; - - boot_ata_select(IO); - - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); - - // identify until it's good. -ATAInit_Retry: - auto status_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (status_rdy & ATA_SR_ERR) { - writer.Write(L"BootZ: ATA: Not an IDE based drive.\r"); - - return false; - } - - if ((status_rdy & ATA_SR_BSY)) goto ATAInit_Retry; - - boot_ata_select(IO); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - /// fetch serial info - /// model, speed, number of sectors... - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); - - for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) { - kATAData[indexData] = rt_in16(IO + ATA_REG_DATA); - } - - OutBus = (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary; - - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - - return true; -} - -Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz, - SizeT Size) { - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - boot_ata_wait_io(IO); - boot_ata_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) { - boot_ata_wait_io(IO); - - auto in = rt_in16(IO + ATA_REG_DATA); - - Buf[IndexOff] = in & 0xFF; - Buf[IndexOff + 1] = (in >> 8) & 0xFF; - boot_ata_wait_io(IO); - } -} - -Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz, - SizeT Size) { - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - boot_ata_wait_io(IO); - boot_ata_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) { - boot_ata_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); - - boot_ata_wait_io(IO); - } - - boot_ata_wait_io(IO); -} - -/// @check is ATA detected? -Boolean boot_ata_detected(Void) { - return kATADetected; -} - -/*** - * - * - * @brief ATA Device class. - * - * - */ - -/** - * @brief ATA Device constructor. - * @param void none. - */ -BootDeviceATA::BootDeviceATA() noexcept { - if (boot_ata_init(ATA_PRIMARY_IO, true, this->Leak().mBus, this->Leak().mMaster) || - boot_ata_init(ATA_SECONDARY_IO, true, this->Leak().mBus, this->Leak().mMaster)) { - kATADetected = true; - } -} -/** - * @brief Is ATA detected? - */ -BootDeviceATA::operator bool() { - return boot_ata_detected(); -} - -/** - @brief Read Buf from disk - @param Sz Sector size - @param Buf buffer -*/ -BootDeviceATA& BootDeviceATA::Read(CharacterTypeASCII* Buf, SizeT SectorSz) { - if (!boot_ata_detected()) { - Leak().mErr = true; - return *this; - } - - this->Leak().mErr = false; - - if (!Buf || SectorSz < 1) return *this; - - boot_ata_read(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz, - this->Leak().mSize); - - return *this; -} - -/** - @brief Write Buf into disk - @param Sz Sector size - @param Buf buffer -*/ -BootDeviceATA& BootDeviceATA::Write(CharacterTypeASCII* Buf, SizeT SectorSz) { - if (!boot_ata_detected()) { - Leak().mErr = true; - return *this; - } - - Leak().mErr = false; - - if (!Buf || SectorSz < 1 || this->Leak().mSize < 1) { - Leak().mErr = true; - return *this; - } - - boot_ata_write(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz, - this->Leak().mSize); - - return *this; -} - -/** - * @brief ATA trait getter. - * @return BootDeviceATA::ATATrait& the drive config. - */ -BootDeviceATA::ATATrait& BootDeviceATA::Leak() { - return mTrait; -} - -/*** - @brief Getter, gets the number of sectors inside the drive. -*/ -SizeT BootDeviceATA::GetSectorsCount() noexcept { - return (kATAData[61] << 16) | kATAData[60]; -} - -SizeT BootDeviceATA::GetDiskSize() noexcept { - return this->GetSectorsCount() * BootDeviceATA::kSectorSize; -} - -#endif \ No newline at end of file diff --git a/dev/boot/src/HEL/AMD64/BootATA.cc b/dev/boot/src/HEL/AMD64/BootATA.cc deleted file mode 100644 index 903a650d..00000000 --- a/dev/boot/src/HEL/AMD64/BootATA.cc +++ /dev/null @@ -1,256 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -/** - * @file BootATA.cc - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief ATA driver. - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Amlal El Mahrouss - * - */ - -#include -#include -#include - -#define kATADataLen (256) - -/// bugs: 0 - -using namespace Boot; - -static Boolean kATADetected = false; -static UInt16 kATAData[kATADataLen] = {0}; - -Boolean boot_ata_detected(Void); - -STATIC Boolean boot_ata_wait_io(UInt16 IO) { - for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto status_rdy = rt_in8(IO + ATA_REG_STATUS); - - if ((status_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - status_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (status_rdy & ATA_SR_ERR) return false; - - if (!(status_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; - - return true; -} - -Void boot_ata_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 boot_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { - NE_UNUSED(Drive); - - if (boot_ata_detected()) return true; - - BootTextWriter writer; - - UInt16 IO = Bus; - - boot_ata_select(IO); - - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); - - // identify until it's good. -ATAInit_Retry: - auto status_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (status_rdy & ATA_SR_ERR) { - writer.Write(L"BootZ: ATA: Not an IDE based drive.\r"); - - return false; - } - - if ((status_rdy & ATA_SR_BSY)) goto ATAInit_Retry; - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - /// fetch serial info - /// model, speed, number of sectors... - - boot_ata_wait_io(IO); - - for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) { - kATAData[indexData] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); - } - - OutBus = (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary; - - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - - // 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 - return NO; -} - -Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz, - SizeT Size) { - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - boot_ata_wait_io(IO); - boot_ata_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); - - boot_ata_wait_io(IO); - - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { - boot_ata_wait_io(IO); - Buf[IndexOff] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); - boot_ata_wait_io(IO); - } -} - -Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz, - SizeT Size) { - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - boot_ata_wait_io(IO); - boot_ata_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); - - boot_ata_wait_io(IO); - - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { - boot_ata_wait_io(IO); - rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); - boot_ata_wait_io(IO); - } - - boot_ata_wait_io(IO); -} - -/// @check is ATA detected? -Boolean boot_ata_detected(Void) { - return kATADetected; -} - -/*** - * - * - * @brief ATA Device class. - * - * - */ - -/** - * @brief ATA Device constructor. - * @param void none. - */ -BootDeviceATA::BootDeviceATA() noexcept { - if (boot_ata_init(ATA_PRIMARY_IO, true, this->Leak().mBus, this->Leak().mMaster) || - boot_ata_init(ATA_SECONDARY_IO, true, this->Leak().mBus, this->Leak().mMaster)) { - kATADetected = true; - } -} -/** - * @brief Is ATA detected? - */ -BootDeviceATA::operator bool() { - return boot_ata_detected(); -} - -/** - @brief Read Buf from disk - @param Sz Sector size - @param Buf buffer -*/ -BootDeviceATA& BootDeviceATA::Read(CharacterTypeASCII* Buf, SizeT SectorSz) { - if (!boot_ata_detected()) { - Leak().mErr = true; - return *this; - } - - this->Leak().mErr = false; - - if (!Buf || SectorSz < 1) return *this; - - boot_ata_read(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz, - this->Leak().mSize); - - return *this; -} - -/** - @brief Write Buf into disk - @param Sz Sector size - @param Buf buffer -*/ -BootDeviceATA& BootDeviceATA::Write(CharacterTypeASCII* Buf, SizeT SectorSz) { - if (!boot_ata_detected()) { - Leak().mErr = true; - return *this; - } - - Leak().mErr = false; - - if (!Buf || SectorSz < 1 || this->Leak().mSize < 1) { - Leak().mErr = true; - return *this; - } - - boot_ata_write(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz, - this->Leak().mSize); - - return *this; -} - -/** - * @brief ATA trait getter. - * @return BootDeviceATA::ATATrait& the drive config. - */ -BootDeviceATA::ATATrait& BootDeviceATA::Leak() { - return mTrait; -} - -/*** - @brief Getter, gets the number of sectors inside the drive. -*/ -SizeT BootDeviceATA::GetSectorsCount() noexcept { - return (kATAData[61] << 16) | kATAData[60]; -} - -SizeT BootDeviceATA::GetDiskSize() noexcept { - return this->GetSectorsCount() * BootDeviceATA::kSectorSize; -} diff --git a/dev/boot/src/HEL/AMD64/BootATAcc b/dev/boot/src/HEL/AMD64/BootATAcc new file mode 100644 index 00000000..4fd6dc16 --- /dev/null +++ b/dev/boot/src/HEL/AMD64/BootATAcc @@ -0,0 +1,266 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +/** + * @file BootATA.cc + * @author Amlal El Mahrouss (amlal@nekernel.org) + * @brief ATA driver. + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) Amlal El Mahrouss + * + */ + +#include +#include +#include + +#define kATADataLen (256) + +/// bugs: 0 + +using namespace Boot; + +static Boolean kATADetected = false; +static UInt16 kATAData[kATADataLen] = {0}; + +Boolean boot_ata_detected(Void); + +STATIC Boolean boot_ata_wait_io(UInt16 IO) { + for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS); + +ATAWaitForIO_Retry: + auto status_rdy = rt_in8(IO + ATA_REG_STATUS); + + if ((status_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; + +ATAWaitForIO_Retry2: + status_rdy = rt_in8(IO + ATA_REG_STATUS); + + if (status_rdy & ATA_SR_ERR) return false; + + if (!(status_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; + + return true; +} + +Void boot_ata_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 boot_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { + NE_UNUSED(Drive); + + if (boot_ata_detected()) return true; + + BootTextWriter writer; + + UInt16 IO = Bus; + + boot_ata_select(IO); + + // Bus init, NEIN bit. + rt_out8(IO + ATA_REG_NEIN, 1); + + // identify until it's good. +ATAInit_Retry: + auto status_rdy = rt_in8(IO + ATA_REG_STATUS); + + if (status_rdy & ATA_SR_ERR) { + writer.Write(L"BootZ: ATA: Not an IDE based drive.\r"); + + return false; + } + + if ((status_rdy & ATA_SR_BSY)) goto ATAInit_Retry; + + boot_ata_select(IO); + + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + + /// fetch serial info + /// model, speed, number of sectors... + + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); + + for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) { + kATAData[indexData] = rt_in16(IO + ATA_REG_DATA); + } + + OutBus = (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary; + + OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + + return true; +} + +Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz, + SizeT Size) { + Lba /= SectorSz; + + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + + boot_ata_wait_io(IO); + boot_ata_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) { + boot_ata_wait_io(IO); + + auto in = rt_in16(IO + ATA_REG_DATA); + + Buf[IndexOff] = in & 0xFF; + Buf[IndexOff + 1] = (in >> 8) & 0xFF; + boot_ata_wait_io(IO); + } +} + +Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeASCII* Buf, SizeT SectorSz, + SizeT Size) { + Lba /= SectorSz; + + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + + boot_ata_wait_io(IO); + boot_ata_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) { + boot_ata_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); + + boot_ata_wait_io(IO); + } + + boot_ata_wait_io(IO); +} + +/// @check is ATA detected? +Boolean boot_ata_detected(Void) { + return kATADetected; +} + +/*** + * + * + * @brief ATA Device class. + * + * + */ + +/** + * @brief ATA Device constructor. + * @param void none. + */ +BootDeviceATA::BootDeviceATA() noexcept { + if (boot_ata_init(ATA_PRIMARY_IO, true, this->Leak().mBus, this->Leak().mMaster) || + boot_ata_init(ATA_SECONDARY_IO, true, this->Leak().mBus, this->Leak().mMaster)) { + kATADetected = true; + } +} +/** + * @brief Is ATA detected? + */ +BootDeviceATA::operator bool() { + return boot_ata_detected(); +} + +/** + @brief Read Buf from disk + @param Sz Sector size + @param Buf buffer +*/ +BootDeviceATA& BootDeviceATA::Read(CharacterTypeASCII* Buf, SizeT SectorSz) { + if (!boot_ata_detected()) { + Leak().mErr = true; + return *this; + } + + this->Leak().mErr = false; + + if (!Buf || SectorSz < 1) return *this; + + boot_ata_read(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz, + this->Leak().mSize); + + return *this; +} + +/** + @brief Write Buf into disk + @param Sz Sector size + @param Buf buffer +*/ +BootDeviceATA& BootDeviceATA::Write(CharacterTypeASCII* Buf, SizeT SectorSz) { + if (!boot_ata_detected()) { + Leak().mErr = true; + return *this; + } + + Leak().mErr = false; + + if (!Buf || SectorSz < 1 || this->Leak().mSize < 1) { + Leak().mErr = true; + return *this; + } + + boot_ata_write(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz, + this->Leak().mSize); + + return *this; +} + +/** + * @brief ATA trait getter. + * @return BootDeviceATA::ATATrait& the drive config. + */ +BootDeviceATA::ATATrait& BootDeviceATA::Leak() { + return mTrait; +} + +/*** + @brief Getter, gets the number of sectors inside the drive. +*/ +SizeT BootDeviceATA::GetSectorsCount() noexcept { + return (kATAData[61] << 16) | kATAData[60]; +} + +SizeT BootDeviceATA::GetDiskSize() noexcept { + return this->GetSectorsCount() * BootDeviceATA::kSectorSize; +} diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index 1d46b731..84a4d295 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -196,16 +196,6 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTa WideChar kernel_path[256U] = L"krnl.efi"; UInt32 kernel_path_sz = StrLen("krnl.efi"); - if (ST->RuntimeServices->GetVariable(L"/props/kernel_path", kEfiGlobalNamespaceVarGUID, nullptr, - &kernel_path_sz, kernel_path) != kEfiOk) { - /// access attributes (in order) - /// EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS - UInt32 attr = 0x00000001 | 0x00000002 | 0x00000004; - - ST->RuntimeServices->SetVariable(L"/props/kernel_path", kEfiGlobalNamespaceVarGUID, &attr, - &kernel_path_sz, kernel_path); - } - UInt32 sz_ver = sizeof(UInt64); UInt64 ver = KERNEL_VERSION_BCD; @@ -219,6 +209,16 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTa &sz_ver, &ver); writer.Write("BootZ: Version has been updated: ").Write(ver).Write("\r"); + + if (ST->RuntimeServices->GetVariable(L"/props/kernel_path", kEfiGlobalNamespaceVarGUID, nullptr, + &kernel_path_sz, kernel_path) != kEfiOk) { + /// access attributes (in order) + /// EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS + UInt32 attr = 0x00000001 | 0x00000002 | 0x00000004; + + ST->RuntimeServices->SetVariable(L"/props/kernel_path", kEfiGlobalNamespaceVarGUID, &attr, + &kernel_path_sz, kernel_path); + } } else { writer.Write("BootZ: Version: ").Write(ver).Write("\r"); } diff --git a/dev/boot/src/docs/KERN_VER.md b/dev/boot/src/docs/KERN_VER.md index cabdb1d2..0659431b 100644 --- a/dev/boot/src/docs/KERN_VER.md +++ b/dev/boot/src/docs/KERN_VER.md @@ -1,6 +1,18 @@ -# The `/props/kern_ver` NVRAM variable +# `/props/kern_ver` โ€” NVRAM EFI Variable The `/props/kern_ver` variable is used to track NeKernel's current version in a BCD format. -- Use it to track the current's NeKernel version, in order to adapt your drivers to it. -- It is also useful to keep track of it, for other purposes (bug tracking, development of new features) \ No newline at end of file +## ๐Ÿ›  Reason + +- It is also used for: + - Bug tracking and system patching. + - Version and compatibility checking. + +## ๐Ÿงช Usage + +N/A + +## ยฉ License + + Copyright (C) 2025, + Amlal El Mahrouss โ€“ All rights reserved. \ No newline at end of file diff --git a/dev/boot/src/docs/MKFS_HEFS.md b/dev/boot/src/docs/MKFS_HEFS.md new file mode 100644 index 00000000..c9aa0628 --- /dev/null +++ b/dev/boot/src/docs/MKFS_HEFS.md @@ -0,0 +1,106 @@ +# `mkfs.hefs` โ€“ HeFS Filesystem Formatter + +`mkfs.hefs` is a command-line utility used to format a block device or disk image with the **High-throughput Extended File System (HeFS)** used by NeKernel. This tool initializes a HeFS volume by writing a boot node and configuring directory and inode index regions, block ranges, and volume metadata. + +--- + +## ๐Ÿ›  Features + +- Writes a valid `BootNode` to the specified output device or file. +- Sets disk size, sector size, and volume label. +- Supports user-defined ranges for: + - Index Node Directory (IND) + - Inodes (IN) + - Data blocks +- UTF-8 encoded volume label support. +- Fully compatible with NeKernel's VFS subsystem. + +--- + +## ๐Ÿงช Usage + + mkfs.hefs -L