diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-06-12 14:42:29 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-06-12 14:42:29 +0200 |
| commit | 6a3b080067ff47f84c400987982cfa44927fe7e0 (patch) | |
| tree | 82351e411eccd00c0e4217f82e711a5cba75fd5a /Kernel/HALKit | |
| parent | 07c35bb2e8462b45feddcc98f3a512eee29c69b3 (diff) | |
MHR-23: SMP support inside kernel, need to add I/O for the scheduler
now.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Kernel/HALKit')
| -rw-r--r-- | Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp | 92 | ||||
| -rw-r--r-- | Kernel/HALKit/AMD64/HalInterruptAPI.asm | 50 | ||||
| -rw-r--r-- | Kernel/HALKit/AMD64/HalKernelMain.cxx | 9 | ||||
| -rw-r--r-- | Kernel/HALKit/AMD64/HalSMPCoreManager.asm | 21 |
4 files changed, 152 insertions, 20 deletions
diff --git a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp index 02f654ab..2824b176 100644 --- a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp +++ b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp @@ -14,6 +14,8 @@ #define kAPIC_SIPI_Vector 0x00500 #define kAPIC_EIPI_Vector 0x00400 +EXTERN_C void AppMain(); + /////////////////////////////////////////////////////////////////////////////////////// //! NOTE: fGSI stands 'Field Global System Interrupt' @@ -104,7 +106,18 @@ namespace NewOS::HAL /////////////////////////////////////////////////////////////////////////////////////// - STATIC MadtType* kApicInfoBlock = nullptr; + STATIC MadtType* kApicInfoBlock = nullptr; + STATIC UIntPtr kApicMadtAddresses[255] = {0}; + STATIC SizeT kApicMadtAddressesCount = 0UL; + STATIC UIntPtr cBaseAddressAPIC = 0xFEE00000; + + /// @brief this will help us schedule our cores. + STATIC Boolean* cProgramInitialized = nullptr; + + enum + { + cAPICEOI = 0xb0, + }; /////////////////////////////////////////////////////////////////////////////////////// @@ -119,6 +132,8 @@ namespace NewOS::HAL NewOS::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_SIPI_Vector | vector); } + EXTERN_C Void _hal_spin_core(Void); + /// @brief Send end IPI for CPU. /// @param apicId /// @param vector @@ -130,6 +145,42 @@ namespace NewOS::HAL NewOS::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_EIPI_Vector | vector); } + /// @brief assembly routine. internal use only. + EXTERN_C Void _hal_enable_smp(Void); + + EXTERN_C Void hal_apic_acknowledge_cont(Void) + { + kcout << "newoskrnl: finish kernel init... \r"; + + if (cProgramInitialized && + *cProgramInitialized) + { + *cProgramInitialized = false; + + AppMain(); + + while (true) + { + + } + } + else + { + kcout << "newoskrnl: putting thread to sleep...\r"; + + AppMain(); + + while (true) + { + } + } + } + + EXTERN_C Void hal_apic_acknowledge(Void) + { + hal_apic_acknowledge_cont(); + } + Void hal_system_get_cores(voidPtr rsdPtr) { auto acpi = ACPIFactoryInterface(rsdPtr); @@ -139,16 +190,37 @@ namespace NewOS::HAL { MadtType* madt = (MadtType*)kApicMadt; - constexpr auto cMaxProbableCores = 4; + constexpr auto cMaxProbableCores = 4; + + for (SizeT i = 2; i < cMaxProbableCores; ++i) + { + if (madt->MadtRecords[i].Flags == 0x01) // if local apic. + { + MadtType::MadtAddress& madtRecord = madt->MadtRecords[i]; + // then register as a core for scheduler. + kcout << "newoskrnl: register core as scheduler thread.\r"; + + kApicMadtAddresses[kApicMadtAddressesCount] = madtRecord.Address; + ++kApicMadtAddressesCount; + + auto flagsSet = NewOS::ke_dma_read(madtRecord.Address, 0xF0); // SVR register. + + // enable APIC. + flagsSet |= 0x100; + + NewOS::ke_dma_write(cBaseAddressAPIC, 0xF0, flagsSet); + + /// Set sprurious interrupt vector. + NewOS::ke_dma_write(cBaseAddressAPIC, 0xF0, 0x100 | 0xFF); + + // highest task priority. for our realtime kernel. + NewOS::ke_dma_write(cBaseAddressAPIC, 0x21, 0); + + cProgramInitialized = new Boolean(true); - for (SizeT i = 0; i < cMaxProbableCores; ++i) - { - if (madt->MadtRecords[i].Flags == 0x01) // if local apic. - { - // then register as a core for scheduler. - kcout << "newoskrnl: register core as scheduler thread.\r"; - } - } + hal_send_start_ipi(kApicMadtAddressesCount, 0x40, cBaseAddressAPIC); + } + } } else { diff --git a/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/Kernel/HALKit/AMD64/HalInterruptAPI.asm index 074ba472..ef5a8319 100644 --- a/Kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/Kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -14,7 +14,7 @@ %define kInterruptId 0x21 %macro IntExp 1 -global __NEW_INT_%1 +global __NEW_INT_%1 __NEW_INT_%1: cld @@ -22,7 +22,7 @@ __NEW_INT_%1: %endmacro %macro IntNormal 1 -global __NEW_INT_%1 +global __NEW_INT_%1 __NEW_INT_%1: cld @@ -100,7 +100,7 @@ __NEW_INT_14: sti iretq - + IntNormal 15 IntNormal 16 IntExp 17 @@ -120,7 +120,49 @@ IntExp 30 IntNormal 31 -IntNormal 32 +[extern hal_apic_acknowledge] + +__NEW_INT_32: + 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 + + jmp hal_apic_acknowledge + + 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 + + mov eax, 0 + + ;; tell there local apic that we're done. + mov dword [0xFEE00000 + 0xB0], eax ; LAPIC_EOI + + iretq IntNormal 33 diff --git a/Kernel/HALKit/AMD64/HalKernelMain.cxx b/Kernel/HALKit/AMD64/HalKernelMain.cxx index 9d7125d2..708004b3 100644 --- a/Kernel/HALKit/AMD64/HalKernelMain.cxx +++ b/Kernel/HALKit/AMD64/HalKernelMain.cxx @@ -16,7 +16,6 @@ #include <NewKit/Json.hpp> EXTERN_C NewOS::VoidPtr kInterruptVectorTable[]; -EXTERN_C void AppMain(); namespace NewOS::HAL { @@ -77,9 +76,9 @@ EXTERN_C void hal_init_platform( NewOS::HAL::hal_system_get_cores(kHandoverHeader->f_HardwareTables.f_RsdPtr); - /// END POST + NewOS::kcout << "newoskrnl: We're done here...\r"; - AppMain(); - - NewOS::ke_stop(RUNTIME_CHECK_BOOTSTRAP); + while (true) + { + } } diff --git a/Kernel/HALKit/AMD64/HalSMPCoreManager.asm b/Kernel/HALKit/AMD64/HalSMPCoreManager.asm index abf12228..5ecc2370 100644 --- a/Kernel/HALKit/AMD64/HalSMPCoreManager.asm +++ b/Kernel/HALKit/AMD64/HalSMPCoreManager.asm @@ -11,6 +11,8 @@ [global rt_get_current_context] [global rt_do_context_switch] +[global _hal_enable_smp] +[global _hal_spin_core] section .text @@ -18,9 +20,26 @@ section .text ;; rcx: Stack Pointer ;; rdx: SMP core address. rt_do_context_switch: - retfq ;; gets the current stack frame. rt_get_current_context: retfq + +;; @brief enables a smp core to run. +_hal_enable_smp: +; Read the APIC base MSR + mov ecx, 0x1B ; IA32_APIC_BASE MSR + rdmsr + ; Enable the APIC by setting bit 11 (APIC Global Enable) + or rdx, 0x800 + ; Set the base address (0xFEE00000) + mov eax, 0xFEE + shl rax, 12 + or rax, rdx + wrmsr + ret + +_hal_spin_core: + jmp $ + ret |
