From 349fe48baf941b2d1b571d3a5d0d796823bae312 Mon Sep 17 00:00:00 2001 From: Amlal EL Mahrouss Date: Thu, 13 Jun 2024 17:41:19 +0200 Subject: MHR-31: New systemcall/kernelcall architecture. Signed-off-by: Amlal EL Mahrouss --- Kernel/HALKit/AMD64/HalInterruptAPI.asm | 59 +++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'Kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/Kernel/HALKit/AMD64/HalInterruptAPI.asm index ef5a8319..e88ffc0d 100644 --- a/Kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/Kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -195,15 +195,69 @@ IntNormal 47 IntNormal 48 IntNormal 49 +[extern hal_system_call_enter] +[extern hal_kernel_call_enter] + __NEW_INT_50: cli - ;; todo handle system calls. + push rax + + call hal_system_call_enter + + pop rax + + sti + iretq + +__NEW_INT_51: + cli + + push 0 + push 51 + push rax + push rcx + push rdx + push rbx + push rbp + push rsi + push rdi + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + push gs + push fs + + mov rcx, rbp + + call hal_kernel_call_enter + + pop fs + pop gs + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rdi + pop rsi + pop rbp + pop rbx + pop rdx + pop rcx + pop rax sti iretq -IntNormal 51 IntNormal 52 IntNormal 53 IntNormal 54 @@ -223,6 +277,7 @@ IntNormal 60 ;; this one is doing a POST for us. ;; testing interrupts. _ke_power_on_self_test: + mov rcx, 0x10 int 0x32 int 0x32 int 0x32 -- cgit v1.2.3 From 7327f305efb1c6678722308cc5f9645dd39f451e Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 13 Jun 2024 19:38:29 +0200 Subject: MHR-31: Lots of fixes and improvements regarding the kernel. Signed-off-by: Amlal El Mahrouss --- Boot/makefile | 2 +- Kernel/ArchKit/ArchKit.hpp | 4 +- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp | 25 +-------- .../HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp | 7 +-- Kernel/HALKit/AMD64/HalHardwareMP.cpp | 30 ----------- Kernel/HALKit/AMD64/HalHart.cpp | 30 +++++++++++ Kernel/HALKit/AMD64/HalInterruptAPI.asm | 47 +++++------------ Kernel/HALKit/AMD64/HalKernelMain.cxx | 19 ++++++- Kernel/HALKit/AMD64/PCI/Iterator.cxx | 6 +-- Kernel/KernelKit/ProcessScheduler.hxx | 19 ++----- Kernel/KernelKit/SMPManager.hpp | 6 +-- Kernel/NewKit/Array.hpp | 4 +- Kernel/NewKit/MutableArray.hpp | 7 +++ Kernel/Sources/HError.cxx | 3 +- Kernel/Sources/KeMain.cxx | 5 -- Kernel/Sources/ProcessScheduler.cxx | 61 +++++++++++----------- Kernel/Sources/SMPManager.cxx | 46 +++++++++------- 17 files changed, 145 insertions(+), 176 deletions(-) delete mode 100644 Kernel/HALKit/AMD64/HalHardwareMP.cpp create mode 100644 Kernel/HALKit/AMD64/HalHart.cpp (limited to 'Kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/Boot/makefile b/Boot/makefile index e54b1aa8..4bee19a2 100644 --- a/Boot/makefile +++ b/Boot/makefile @@ -26,7 +26,7 @@ BIOS=OVMF.fd IMG=epm.img IMG_2=epm-slave.img -EMU_FLAGS=-net none -smp 4 -m 4G -M q35 \ +EMU_FLAGS=-net none -smp 4 -serial stdio -m 4G -M q35 \ -bios $(BIOS) -device piix3-ide,id=ide \ -drive id=disk,file=$(IMG),format=raw,if=none \ -device ide-hd,drive=disk,bus=ide.0 -drive \ diff --git a/Kernel/ArchKit/ArchKit.hpp b/Kernel/ArchKit/ArchKit.hpp index c2e5a967..6407a0d8 100644 --- a/Kernel/ArchKit/ArchKit.hpp +++ b/Kernel/ArchKit/ArchKit.hpp @@ -79,7 +79,7 @@ namespace NewOS #define kKernelMaxSystemCalls (256) -typedef NewOS::Void (*rt_syscall_proc)(NewOS::HAL::StackFramePtr); +typedef NewOS::Void (*rt_syscall_proc)(NewOS::VoidPtr); struct RTSyscallInfoHdr final { @@ -95,7 +95,7 @@ inline NewOS::Array kKerncalls; - + EXTERN_C NewOS::HAL::StackFramePtr rt_get_current_context(); EXTERN_C NewOS::Void rt_do_context_switch(NewOS::HAL::StackFramePtr stackFrame); diff --git a/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp b/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp index a21a4c47..51570b86 100644 --- a/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp +++ b/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cpp @@ -12,11 +12,6 @@ /// @param rsp EXTERN_C void idt_handle_gpf(NewOS::UIntPtr rsp) { - MUST_PASS(NewOS::ProcessScheduler::The().Leak().GetCurrent()); - - NewOS::kcout << "newoskrnl: Stack Pointer: " - << NewOS::StringBuilder::FromInt("rsp{%}", rsp); - NewOS::kcout << "newoskrnl: General Protection Fault, caused by " << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName(); @@ -28,9 +23,6 @@ EXTERN_C void idt_handle_gpf(NewOS::UIntPtr rsp) /// @param rsp EXTERN_C void idt_handle_pf(NewOS::UIntPtr rsp) { - MUST_PASS(NewOS::ProcessScheduler::The().Leak().GetCurrent()); - NewOS::kcout << NewOS::StringBuilder::FromInt("rsp{%}", rsp); - NewOS::kcout << "newoskrnl: Segmentation Fault, caused by " << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName(); @@ -42,9 +34,6 @@ EXTERN_C void idt_handle_pf(NewOS::UIntPtr rsp) /// @param rsp EXTERN_C void idt_handle_math(NewOS::UIntPtr rsp) { - MUST_PASS(NewOS::ProcessScheduler::The().Leak().GetCurrent()); - NewOS::kcout << NewOS::StringBuilder::FromInt("rsp{%}", rsp); - NewOS::kcout << "newoskrnl: Math error, caused by " << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName(); @@ -56,9 +45,6 @@ EXTERN_C void idt_handle_math(NewOS::UIntPtr rsp) /// @param rsp EXTERN_C void idt_handle_generic(NewOS::UIntPtr rsp) { - MUST_PASS(NewOS::ProcessScheduler::The().Leak().GetCurrent()); - NewOS::kcout << NewOS::StringBuilder::FromInt("sp{%}", rsp); - NewOS::kcout << "newoskrnl: Execution error, caused by " << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName(); @@ -70,11 +56,6 @@ EXTERN_C void idt_handle_generic(NewOS::UIntPtr rsp) /// @param rsp EXTERN_C void idt_handle_ud(NewOS::UIntPtr rsp) { - MUST_PASS(NewOS::ProcessScheduler::The().Leak().GetCurrent()); - - NewOS::kcout << "newoskrnl: Stack Pointer: " - << NewOS::StringBuilder::FromInt("rsp{%}", rsp); - NewOS::kcout << "newoskrnl: Invalid interrupt, caused by " << NewOS::ProcessScheduler::The().Leak().GetCurrent().Leak().GetName(); @@ -91,10 +72,8 @@ EXTERN_C NewOS::Void hal_system_call_enter(NewOS::UIntPtr rcx, NewOS::UIntPtr rd { NewOS::kcout << "newoskrnl: syscall: enter.\r"; - NewOS::kcout << "rcx: " << NewOS::number(rcx) << NewOS::endl; - - if (kSyscalls[rcx].Leak().Leak().fHooked) - (kSyscalls[rcx].Leak().Leak().fProc)((NewOS::HAL::StackFramePtr)rdx); + if (kSyscalls[rcx].Leak().Leak()->fHooked) + (kSyscalls[rcx].Leak().Leak()->fProc)((NewOS::VoidPtr)rdx); NewOS::kcout << "newoskrnl: syscall: exit.\r"; } diff --git a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp index e2520332..c15a7b55 100644 --- a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp +++ b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp @@ -16,9 +16,6 @@ #define kAPIC_SIPI_Vector 0x00500 #define kAPIC_EIPI_Vector 0x00400 -/// @brief This symbol is the kernel main symbol. -EXTERN_C void KeMain(); - /// @brief assembly routine. internal use only. EXTERN_C void _hal_enable_smp(void); @@ -159,9 +156,7 @@ namespace NewOS::HAL EXTERN_C Void hal_apic_acknowledge_cont(Void) { - /// TODO: better init code. - KeMain(); - + ProcessHelper::StartScheduling(); _hal_spin_core(); } diff --git a/Kernel/HALKit/AMD64/HalHardwareMP.cpp b/Kernel/HALKit/AMD64/HalHardwareMP.cpp deleted file mode 100644 index 92e075aa..00000000 --- a/Kernel/HALKit/AMD64/HalHardwareMP.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* ------------------------------------------- - - Copyright Zeta Electronics Corporation - -------------------------------------------- */ - -#include - -// bugs = 0 - -namespace NewOS -{ - /// @brief wakes up thread. - /// wakes up thread from hang. - void rt_wakeup_thread(HAL::StackFrame* stack) - { - HAL::rt_cli(); - - HAL::rt_sti(); - } - - /// @brief makes thread sleep. - /// hooks and hangs thread to prevent code from executing. - void rt_hang_thread(HAL::StackFrame* stack) - { - HAL::rt_cli(); - - HAL::rt_sti(); - } -} // namespace NewOS diff --git a/Kernel/HALKit/AMD64/HalHart.cpp b/Kernel/HALKit/AMD64/HalHart.cpp new file mode 100644 index 00000000..92e075aa --- /dev/null +++ b/Kernel/HALKit/AMD64/HalHart.cpp @@ -0,0 +1,30 @@ +/* ------------------------------------------- + + Copyright Zeta Electronics Corporation + +------------------------------------------- */ + +#include + +// bugs = 0 + +namespace NewOS +{ + /// @brief wakes up thread. + /// wakes up thread from hang. + void rt_wakeup_thread(HAL::StackFrame* stack) + { + HAL::rt_cli(); + + HAL::rt_sti(); + } + + /// @brief makes thread sleep. + /// hooks and hangs thread to prevent code from executing. + void rt_hang_thread(HAL::StackFrame* stack) + { + HAL::rt_cli(); + + HAL::rt_sti(); + } +} // namespace NewOS diff --git a/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/Kernel/HALKit/AMD64/HalInterruptAPI.asm index e88ffc0d..150cfc10 100644 --- a/Kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/Kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -201,11 +201,15 @@ IntNormal 49 __NEW_INT_50: cli + push rcx + push rdx push rax call hal_system_call_enter pop rax + pop rdx + pop rcx sti iretq @@ -213,47 +217,19 @@ __NEW_INT_50: __NEW_INT_51: cli - push 0 - push 51 - push rax push rcx push rdx - push rbx - push rbp - push rsi - push rdi push r8 push r9 - push r10 - push r11 - push r12 - push r13 - push r14 - push r15 - push gs - push fs - - mov rcx, rbp + push rax call hal_kernel_call_enter - pop fs - pop gs - pop r15 - pop r14 - pop r13 - pop r12 - pop r11 - pop r10 + pop rax pop r9 pop r8 - pop rdi - pop rsi - pop rbp - pop rbx pop rdx pop rcx - pop rax sti iretq @@ -278,13 +254,18 @@ IntNormal 60 ;; testing interrupts. _ke_power_on_self_test: mov rcx, 0x10 - int 0x32 - int 0x32 - int 0x32 + mov rdx, _ke_string_post + int 0x32 ret +section .data +_ke_string_post: + db "POST has been successful.", 0 + +section .text + [global hal_load_gdt] hal_load_gdt: diff --git a/Kernel/HALKit/AMD64/HalKernelMain.cxx b/Kernel/HALKit/AMD64/HalKernelMain.cxx index 708004b3..6f01734e 100644 --- a/Kernel/HALKit/AMD64/HalKernelMain.cxx +++ b/Kernel/HALKit/AMD64/HalKernelMain.cxx @@ -14,6 +14,10 @@ #include #include #include +#include + +/// @brief This symbol is the kernel main symbol. +EXTERN_C void KeMain(); EXTERN_C NewOS::VoidPtr kInterruptVectorTable[]; @@ -72,13 +76,24 @@ EXTERN_C void hal_init_platform( /// START POST + constexpr auto cDummyInterrupt = 0x10; // 16 + + kSyscalls[cDummyInterrupt].Leak().Leak()->fProc = [](NewOS::VoidPtr sf) -> void { + const char* msg = (const char*)sf; + NewOS::kcout << "newoskrnl: " << msg << "\r"; + }; + + kSyscalls[cDummyInterrupt].Leak().Leak()->fHooked = true; + NewOS::HAL::Detail::_ke_power_on_self_test(); + auto cLoaderName = "newoskrnl"; + NewOS::execute_from_image(KeMain, cLoaderName); + NewOS::HAL::hal_system_get_cores(kHandoverHeader->f_HardwareTables.f_RsdPtr); NewOS::kcout << "newoskrnl: We're done here...\r"; while (true) - { - } + {} } diff --git a/Kernel/HALKit/AMD64/PCI/Iterator.cxx b/Kernel/HALKit/AMD64/PCI/Iterator.cxx index 8675f171..297aa89c 100644 --- a/Kernel/HALKit/AMD64/PCI/Iterator.cxx +++ b/Kernel/HALKit/AMD64/PCI/Iterator.cxx @@ -7,8 +7,8 @@ #include #define PCI_ITERATOR_FIND_AND_UNWRAP(DEV, SZ) \ - if (DEV.Leak()) \ - return DEV.Leak(); + if (DEV.Leak().Leak()) \ + return *DEV.Leak().Leak(); namespace NewOS::PCI { @@ -25,7 +25,7 @@ namespace NewOS::PCI if (dev.Class() == (UChar)type) { - fDevices[bus].Leak().Leak() = dev; + *fDevices[bus].Leak().Leak() = dev; } } } diff --git a/Kernel/KernelKit/ProcessScheduler.hxx b/Kernel/KernelKit/ProcessScheduler.hxx index c6e090e4..8c1971b0 100644 --- a/Kernel/KernelKit/ProcessScheduler.hxx +++ b/Kernel/KernelKit/ProcessScheduler.hxx @@ -17,7 +17,7 @@ #define kSchedMinMicroTime (AffinityKind::kHartStandard) #define kSchedInvalidPID (-1) -#define kSchedProcessLimitPerTeam (100U) +#define kSchedProcessLimitPerTeam (16U) //////////////////////////////////////////////////// @@ -134,7 +134,6 @@ namespace NewOS explicit ProcessHeader(VoidPtr startImage = nullptr) : Image(startImage) { - MUST_PASS(startImage); } ~ProcessHeader() = default; @@ -145,7 +144,7 @@ namespace NewOS void SetEntrypoint(UIntPtr& imageStart) noexcept; public: - Char Name[kProcessLen] = {"NewOS Process"}; + Char Name[kProcessLen] = {"Process"}; ProcessSubsystem SubSystem{ProcessSubsystem::eProcessSubsystemInvalid}; ProcessSelector Selector{ProcessSelector::kRingUser}; HAL::StackFramePtr StackFrame{nullptr}; @@ -240,23 +239,15 @@ namespace NewOS /// The main class which you call to schedule an app. class ProcessScheduler final { - private: - explicit ProcessScheduler() = default; + explicit ProcessScheduler() = default; public: ~ProcessScheduler() = default; NEWOS_COPY_DEFAULT(ProcessScheduler) - operator bool() - { - return mTeam.AsArray().Count() > 0; - } - - bool operator!() - { - return mTeam.AsArray().Count() == 0; - } + operator bool(); + bool operator!(); public: ProcessTeam& CurrentTeam(); diff --git a/Kernel/KernelKit/SMPManager.hpp b/Kernel/KernelKit/SMPManager.hpp index 985050f1..ba706cf6 100644 --- a/Kernel/KernelKit/SMPManager.hpp +++ b/Kernel/KernelKit/SMPManager.hpp @@ -94,11 +94,11 @@ namespace NewOS NEWOS_COPY_DEFAULT(SMPManager); public: - bool Switch(HAL::StackFrame* the); - HAL::StackFramePtr GetStackFrame() noexcept; + bool Switch(HAL::StackFramePtr the); + HAL::StackFramePtr Leak() noexcept; public: - Ref operator[](const SizeT& idx); + Ref operator[](const SizeT& idx); bool operator!() noexcept; operator bool() noexcept; diff --git a/Kernel/NewKit/Array.hpp b/Kernel/NewKit/Array.hpp index 1c89f365..dca5c13f 100644 --- a/Kernel/NewKit/Array.hpp +++ b/Kernel/NewKit/Array.hpp @@ -21,13 +21,13 @@ namespace NewOS Array& operator=(const Array&) = default; Array(const Array&) = default; - ErrorOr operator[](Size At) + ErrorOr operator[](Size At) { if (At > N) return {}; kcout << "Returning element\r"; - return ErrorOr(fArray[At]); + return ErrorOr(&fArray[At]); } Boolean Empty() const diff --git a/Kernel/NewKit/MutableArray.hpp b/Kernel/NewKit/MutableArray.hpp index f9c79301..a3ad4cb1 100644 --- a/Kernel/NewKit/MutableArray.hpp +++ b/Kernel/NewKit/MutableArray.hpp @@ -170,6 +170,13 @@ namespace NewOS Boolean Add(const T val) { auto* iterationNode = fFirstNode; + + if (!iterationNode) + { + fFirstNode = new MutableLinkedList(); + iterationNode = fFirstNode; + } + MUST_PASS(iterationNode); while (iterationNode) diff --git a/Kernel/Sources/HError.cxx b/Kernel/Sources/HError.cxx index 937e983a..1f36d020 100644 --- a/Kernel/Sources/HError.cxx +++ b/Kernel/Sources/HError.cxx @@ -13,6 +13,7 @@ namespace NewOS /// @return if error-free: true, otherwise false. Boolean ke_bug_check(void) noexcept { - return true; + /// TODO: + return false; } } // namespace NewOS diff --git a/Kernel/Sources/KeMain.cxx b/Kernel/Sources/KeMain.cxx index e2f41464..60494ee3 100644 --- a/Kernel/Sources/KeMain.cxx +++ b/Kernel/Sources/KeMain.cxx @@ -220,9 +220,4 @@ EXTERN_C NewOS::Void KeMain(NewOS::Void) auto cLoaderName = "SystemLauncher"; NewOS::execute_from_image(NewOS::Detail::SystemLauncher_Main, cLoaderName); - - while (true) - { - NewOS::ProcessScheduler::The().Leak().Run(); - } } diff --git a/Kernel/Sources/ProcessScheduler.cxx b/Kernel/Sources/ProcessScheduler.cxx index 08a7971e..7008eafe 100644 --- a/Kernel/Sources/ProcessScheduler.cxx +++ b/Kernel/Sources/ProcessScheduler.cxx @@ -18,7 +18,7 @@ ///! BUGS: 0 /***********************************************************************************/ -/* This file handles the process scheduling. +/* This file handles the process scheduling. */ /***********************************************************************************/ namespace NewOS @@ -42,7 +42,8 @@ namespace NewOS void ProcessHeader::Crash() { - kcout << this->Name << ": crashed. (id = " << number(kErrorProcessFault); + kcout << (*this->Name == 0 ? "Unknown" : this->Name) << ": crashed. (id = "; + kcout.Number(kErrorProcessFault); kcout << ")\r"; if (this->Ring != kRingUserKind) @@ -201,9 +202,6 @@ namespace NewOS /// @return SizeT ProcessScheduler::Add(Ref& process) { - if (!process) - return -1; - if (!process.Leak().Image) { if (process.Leak().Kind != ProcessHeader::kShLibKind) @@ -212,7 +210,7 @@ namespace NewOS } } - if (!mTeam.AsArray().Count() > kSchedProcessLimitPerTeam) + if (mTeam.AsArray().Count() > kSchedProcessLimitPerTeam) return -kErrorOutOfTeamSlot; kcout << "ProcessScheduler::Add(Ref& process)\r"; @@ -262,8 +260,8 @@ namespace NewOS { auto process = mTeam.AsArray()[processIndex]; - MUST_PASS(process); //! no need for a MUST_PASS(process.Leak());, it is - //! recursive because of the nature of the class; + if (!process) + continue; //! run any process needed to be scheduled. if (ProcessHelper::CanBeScheduled(process.Leak())) @@ -351,22 +349,11 @@ namespace NewOS bool ProcessHelper::StartScheduling() { - if (ProcessHelper::CanBeScheduled( - ProcessScheduler::The().Leak().GetCurrent())) - { - --ProcessScheduler::The().Leak().GetCurrent().Leak().PTime; - return false; - } - - auto processRef = ProcessScheduler::The().Leak(); - - if (!processRef) - return false; // we have nothing to schedule. simply return. + auto& processRef = ProcessScheduler::The().Leak(); + SizeT ret = processRef.Run(); - SizeT ret = processRef.Run(); - - kcout << StringBuilder::FromInt( - "ProcessHelper::StartScheduling() Iterated over {%} jobs inside team.\r", ret); + kcout << "newoskrnl: Iterated over: " << number(ret); + kcout << " processes.\r"; return true; } @@ -384,30 +371,42 @@ namespace NewOS for (SizeT index = 0UL; index < SMPManager::The().Leak().Count(); ++index) { - if (SMPManager::The().Leak()[index].Leak().Kind() == kInvalidHart) + if (SMPManager::The().Leak()[index].Leak()->Kind() == kInvalidHart) continue; - if (SMPManager::The().Leak()[index].Leak().StackFrame() == the_stack) + if (SMPManager::The().Leak()[index].Leak()->StackFrame() == the_stack) { - SMPManager::The().Leak()[index].Leak().Busy(false); + SMPManager::The().Leak()[index].Leak()->Busy(false); continue; } - if (SMPManager::The().Leak()[index].Leak().IsBusy()) + if (SMPManager::The().Leak()[index].Leak()->IsBusy()) continue; - if (SMPManager::The().Leak()[index].Leak().Kind() != + if (SMPManager::The().Leak()[index].Leak()->Kind() != ThreadKind::kHartBoot && - SMPManager::The().Leak()[index].Leak().Kind() != + SMPManager::The().Leak()[index].Leak()->Kind() != ThreadKind::kHartSystemReserved) { - SMPManager::The().Leak()[index].Leak().Busy(true); + SMPManager::The().Leak()[index].Leak()->Busy(true); ProcessHelper::GetCurrentPID() = new_pid; - return SMPManager::The().Leak()[index].Leak().Switch(the_stack); + return SMPManager::The().Leak()[index].Leak()->Switch(the_stack); } } return false; } + + /// @brief this checks if any process is on the team. + ProcessScheduler::operator bool() + { + return mTeam.AsArray().Count() > 0; + } + + /// @brief this checks if no process is on the team. + bool ProcessScheduler::operator!() + { + return mTeam.AsArray().Count() == 0; + } } // namespace NewOS diff --git a/Kernel/Sources/SMPManager.cxx b/Kernel/Sources/SMPManager.cxx index 99a3b025..683343ff 100644 --- a/Kernel/Sources/SMPManager.cxx +++ b/Kernel/Sources/SMPManager.cxx @@ -117,7 +117,7 @@ namespace NewOS } rt_do_context_switch(fStack); - + return true; } @@ -143,12 +143,12 @@ namespace NewOS } /// @brief Get Stack Frame of Core - HAL::StackFramePtr SMPManager::GetStackFrame() noexcept + HAL::StackFramePtr SMPManager::Leak() noexcept { if (fThreadList[fCurrentThread].Leak() && ProcessHelper::GetCurrentPID() == - fThreadList[fCurrentThread].Leak().Leak().fPID) - return fThreadList[fCurrentThread].Leak().Leak().fStack; + fThreadList[fCurrentThread].Leak().Leak()->fPID) + return fThreadList[fCurrentThread].Leak().Leak()->fStack; return nullptr; } @@ -163,35 +163,35 @@ namespace NewOS { // stack != nullptr -> if core is used, then continue. if (!fThreadList[idx].Leak() || - !fThreadList[idx].Leak().Leak().IsWakeup() || - fThreadList[idx].Leak().Leak().IsBusy()) + !fThreadList[idx].Leak().Leak()->IsWakeup() || + fThreadList[idx].Leak().Leak()->IsBusy()) continue; // to avoid any null deref. - if (!fThreadList[idx].Leak().Leak().fStack) + if (!fThreadList[idx].Leak().Leak()->fStack) continue; - if (fThreadList[idx].Leak().Leak().fStack->Rsp == 0) + if (fThreadList[idx].Leak().Leak()->fStack->Rsp == 0) continue; - if (fThreadList[idx].Leak().Leak().fStack->Rbp == 0) + if (fThreadList[idx].Leak().Leak()->fStack->Rbp == 0) continue; - fThreadList[idx].Leak().Leak().Busy(true); + fThreadList[idx].Leak().Leak()->Busy(true); - fThreadList[idx].Leak().Leak().fID = idx; + fThreadList[idx].Leak().Leak()->fID = idx; /// I figured out this: /// Allocate stack /// Set APIC base to stack /// Do stuff and relocate stack based on this code. /// - Amlel - rt_copy_memory(stack, fThreadList[idx].Leak().Leak().fStack, + rt_copy_memory(stack, fThreadList[idx].Leak().Leak()->fStack, sizeof(HAL::StackFrame)); - fThreadList[idx].Leak().Leak().Switch(fThreadList[idx].Leak().Leak().fStack); + fThreadList[idx].Leak().Leak()->Switch(fThreadList[idx].Leak().Leak()->fStack); - fThreadList[idx].Leak().Leak().fPID = ProcessHelper::GetCurrentPID(); + fThreadList[idx].Leak().Leak()->fPID = ProcessHelper::GetCurrentPID(); - fThreadList[idx].Leak().Leak().Busy(false); + fThreadList[idx].Leak().Leak()->Busy(false); return true; } @@ -204,19 +204,25 @@ namespace NewOS * @param idx the index * @return the reference to the hardware thread. */ - Ref SMPManager::operator[](const SizeT& idx) + Ref SMPManager::operator[](const SizeT& idx) { if (idx == 0) { - if (fThreadList[idx].Leak().Leak().Kind() != kHartSystemReserved) + if (fThreadList[idx].Leak().Leak()->Kind() != kHartSystemReserved) { - fThreadList[idx].Leak().Leak().fKind = kHartBoot; + fThreadList[idx].Leak().Leak()->fKind = kHartBoot; } } else if (idx >= kMaxHarts) { - HardwareThread fakeThread; - fakeThread.fKind = kInvalidHart; + static HardwareThread* fakeThread = new HardwareThread(); + + if (!fakeThread) + { + fakeThread = new HardwareThread(); + } + + fakeThread->fKind = kInvalidHart; return {fakeThread}; } -- cgit v1.2.3 From dd7b72379108c10cd68853d2a8a0332784ebb8cb Mon Sep 17 00:00:00 2001 From: Amlal EL Mahrouss Date: Fri, 14 Jun 2024 09:58:11 +0200 Subject: Kernel: Scheduler: ProcessHeader::New: do not get the pointer before allocating it! Kernel: HAL: AMD64: Two things. - Switching to an ARM HAL for our Zeta platform. - Fix return register when sending acknowledge on APIC, which was using the 32-bit eax instead of rax. Kernel: Boot: Update uname for Windows. Kernel: GDT: move as global (HalKenelMain.cxx) Signed-off-by: Amlal EL Mahrouss --- Boot/makefile | 6 +++-- Kernel/HALKit/AMD64/HalInterruptAPI.asm | 4 +-- Kernel/HALKit/AMD64/HalKernelMain.cxx | 37 +++++++++++++-------------- Kernel/Sources/KeMain.cxx | 11 ++++++-- Kernel/Sources/ProcessScheduler.cxx | 45 ++++++++++++++++++--------------- 5 files changed, 56 insertions(+), 47 deletions(-) (limited to 'Kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/Boot/makefile b/Boot/makefile index e54b1aa8..98726bbe 100644 --- a/Boot/makefile +++ b/Boot/makefile @@ -12,10 +12,12 @@ ADD_FILE=touch COPY=cp HTTP_GET=wget -ifneq ($(shell uname), Windows_NT) +# Select this for UNIX distributions +ifneq ($(shell uname), CYGWIN_NT-10.0-19045) EMU=qemu-system-x86_64 else -EMU=qemu-system-x86_64w +# this for NT distributions +EMU=qemu-system-x86_64w.exe endif ifeq ($(NEWS_MODEL), ) diff --git a/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/Kernel/HALKit/AMD64/HalInterruptAPI.asm index 150cfc10..4832ecf3 100644 --- a/Kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/Kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -157,10 +157,10 @@ __NEW_INT_32: pop rcx pop rax - mov eax, 0 + mov rax, 0 ;; tell there local apic that we're done. - mov dword [0xFEE00000 + 0xB0], eax ; LAPIC_EOI + mov [0xFEE00000 + 0xB0], rax ; LAPIC_EOI iretq diff --git a/Kernel/HALKit/AMD64/HalKernelMain.cxx b/Kernel/HALKit/AMD64/HalKernelMain.cxx index 9b605e1a..cafa6388 100644 --- a/Kernel/HALKit/AMD64/HalKernelMain.cxx +++ b/Kernel/HALKit/AMD64/HalKernelMain.cxx @@ -28,9 +28,21 @@ namespace NewOS::HAL extern void hal_system_get_cores(NewOS::voidPtr rsdPtr); } // namespace NewOS::HAL +/* GDT constant. */ +STATIC NewOS::HAL::Detail::NewOSGDT cGdt = { + {0, 0, 0, 0x00, 0x00, 0}, // null entry + {0, 0, 0, 0x9a, 0xaf, 0}, // kernel code + {0, 0, 0, 0x92, 0xaf, 0}, // kernel data + {0, 0, 0, 0x00, 0x00, 0}, // null entry + {0, 0, 0, 0x9a, 0xaf, 0}, // user code + {0, 0, 0, 0x92, 0xaf, 0}, // user data +}; + EXTERN_C void hal_init_platform( NewOS::HEL::HandoverInformationHeader* HandoverHeader) { + /* Setup globals. */ + kHandoverHeader = HandoverHeader; if (kHandoverHeader->f_Magic != kHandoverMagic && @@ -39,29 +51,17 @@ EXTERN_C void hal_init_platform( return; } - /// Setup kernel globals. kKernelVirtualSize = HandoverHeader->f_VirtualSize; kKernelVirtualStart = reinterpret_cast( reinterpret_cast(HandoverHeader->f_VirtualStart) + kVirtualAddressStartOffset); kKernelPhysicalStart = HandoverHeader->f_PhysicalStart; - STATIC NewOS::HAL::Detail::NewOSGDT GDT = { - {0, 0, 0, 0x00, 0x00, 0}, // null entry - {0, 0, 0, 0x9a, 0xaf, 0}, // kernel code - {0, 0, 0, 0x92, 0xaf, 0}, // kernel data - {0, 0, 0, 0x00, 0x00, 0}, // null entry - {0, 0, 0, 0x9a, 0xaf, 0}, // user code - {0, 0, 0, 0x92, 0xaf, 0}, // user data - }; - NewOS::HAL::RegisterGDT gdtBase; - gdtBase.Base = reinterpret_cast(&GDT); + gdtBase.Base = reinterpret_cast(&cGdt); gdtBase.Limit = sizeof(NewOS::HAL::Detail::NewOSGDT) - 1; - /// Load GDT. - NewOS::HAL::GDTLoader gdt; gdt.Load(gdtBase); @@ -74,7 +74,7 @@ EXTERN_C void hal_init_platform( NewOS::HAL::IDTLoader idt; idt.Load(idtBase); - /// START POST + /* install basic hooks. */ constexpr auto cDummyInterrupt = 0x10; // 16 @@ -87,12 +87,9 @@ EXTERN_C void hal_init_platform( NewOS::HAL::Detail::_ke_power_on_self_test(); - auto cLoaderName = "LaunchDevil"; - NewOS::execute_from_image(KeMain, cLoaderName); + /* Call generic kernel entrypoint. */ - NewOS::HAL::hal_system_get_cores(kHandoverHeader->f_HardwareTables.f_RsdPtr); + KeMain(); - while (true) - { - } + NewOS::ke_stop(RUNTIME_CHECK_BOOTSTRAP); } diff --git a/Kernel/Sources/KeMain.cxx b/Kernel/Sources/KeMain.cxx index 58c76dc4..23e32c1d 100644 --- a/Kernel/Sources/KeMain.cxx +++ b/Kernel/Sources/KeMain.cxx @@ -203,8 +203,6 @@ namespace NewOS::Detail NewOS::Utils::execute_from_image(stageBoard, NewOS::ProcessHeader::kAppKind); - - /// TODO: now jump to user mode using the HAL. } } // namespace NewOS::Detail @@ -217,4 +215,13 @@ EXTERN_C NewOS::Void KeMain(NewOS::Void) NewOS::Detail::FilesystemWizard wizard; // automatic. NewOS::Detail::SystemLauncher_Main(); + + // fetch system cores. + NewOS::HAL::hal_system_get_cores(kHandoverHeader->f_HardwareTables.f_RsdPtr); + + while (true) + { + // start scheduling. + NewOS::ProcessHelper::StartScheduling(); + } } diff --git a/Kernel/Sources/ProcessScheduler.cxx b/Kernel/Sources/ProcessScheduler.cxx index d9d013c6..dc273cf6 100644 --- a/Kernel/Sources/ProcessScheduler.cxx +++ b/Kernel/Sources/ProcessScheduler.cxx @@ -59,18 +59,20 @@ namespace NewOS VoidPtr ProcessHeader::New(const SizeT& sz) { - if (this->FreeMemory < 1) + if (this->HeapCursor) { - DbgLastError() = kErrorHeapOutOfMemory; - this->Crash(); /// out of memory. + if (this->FreeMemory < 1) + { + DbgLastError() = kErrorHeapOutOfMemory; + + /* we're going out of memory */ + this->Crash(); - return nullptr; - } + return nullptr; + } - if (this->HeapCursor) - { - VoidPtr ptr = this->HeapCursor; this->HeapCursor = (VoidPtr)((UIntPtr)this->HeapCursor + (sizeof(sz))); + VoidPtr ptr = this->HeapCursor; ++this->UsedMemory; --this->FreeMemory; @@ -206,12 +208,14 @@ namespace NewOS ke_new_ke_heap(sizeof(HAL::StackFrame), true, false)); MUST_PASS(process.Leak().StackFrame); + + process.Leak().Status = ProcessStatus::kRunning; - mTeam.AsArray().Add(process); - - process.Leak().ProcessId = mTeam.AsArray().Count() - 1; + process.Leak().ProcessId = (mTeam.AsArray().Count() - 1); process.Leak().HeapCursor = process.Leak().HeapPtr; + mTeam.AsArray().Add(process); + return mTeam.AsArray().Count() - 1; } @@ -232,17 +236,14 @@ namespace NewOS /// @return SizeT ProcessScheduler::Run() noexcept { - SizeT processIndex = 0; //! we store this guy to tell the scheduler how many + SizeT process_index = 0; //! we store this guy to tell the scheduler how many //! things we have scheduled. - for (; processIndex < mTeam.AsArray().Count(); ++processIndex) + for (; process_index < mTeam.AsArray().Count(); ++process_index) { - auto process = mTeam.AsArray()[processIndex]; - - if (!process) - continue; + auto process = mTeam.AsArray()[process_index]; - //! run any process needed to be scheduled. + //! check if process needs to be scheduled. if (ProcessHelper::CanBeScheduled(process.Leak())) { auto unwrapped_process = *process.Leak(); @@ -255,6 +256,8 @@ namespace NewOS // tell helper to find a core to schedule on. ProcessHelper::Switch(mTeam.AsRef().Leak().StackFrame, mTeam.AsRef().Leak().ProcessId); + + kcout << unwrapped_process.Name << ": process switched.\r"; } else { @@ -263,7 +266,7 @@ namespace NewOS } } - return processIndex; + return process_index; } /// @brief Gets the current scheduled team. @@ -328,8 +331,8 @@ namespace NewOS bool ProcessHelper::StartScheduling() { - auto& processRef = ProcessScheduler::The().Leak(); - SizeT ret = processRef.Run(); + auto& process_ref = ProcessScheduler::The().Leak(); + SizeT ret = process_ref.Run(); kcout << "newoskrnl: Iterated over: "; kcout.Number(ret); -- cgit v1.2.3