From 07c35bb2e8462b45feddcc98f3a512eee29c69b3 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 11 Jun 2024 09:55:01 +0200 Subject: MHR-23: copyright change. Signed-off-by: Amlal El Mahrouss --- Kernel/HALKit/AMD64/HalInterruptAPI.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/Kernel/HALKit/AMD64/HalInterruptAPI.asm index 875a1abc..074ba472 100644 --- a/Kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/Kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -1,7 +1,7 @@ ;; /* ;; * --------------------------------------------------- ;; * -;; * Copyright SoftwareLabs, all rights reserved. +;; * Copyright Zeta Electronics Corporation, all rights reserved. ;; * ;; * File: HalInterruptAPI.asm ;; * Purpose: Interrupt routing, redirect raw interrupts into their handlers. -- cgit v1.2.3 From 6a3b080067ff47f84c400987982cfa44927fe7e0 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 12 Jun 2024 14:42:29 +0200 Subject: MHR-23: SMP support inside kernel, need to add I/O for the scheduler now. Signed-off-by: Amlal El Mahrouss --- Boot/makefile | 4 +- .../HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp | 92 +++++++++++++++++++--- Kernel/HALKit/AMD64/HalInterruptAPI.asm | 50 +++++++++++- Kernel/HALKit/AMD64/HalKernelMain.cxx | 9 +-- Kernel/HALKit/AMD64/HalSMPCoreManager.asm | 21 ++++- 5 files changed, 154 insertions(+), 22 deletions(-) (limited to 'Kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/Boot/makefile b/Boot/makefile index 83f94bd9..0c4f5854 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 2 -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 \ @@ -74,7 +74,7 @@ compile-amd64: $(RESCMD) $(CC_GNU) $(NEWOS_MODEL) $(STANDALONE_MACRO) $(FLAG_GNU) $(DEBUG) \ $(wildcard Sources/HEL/AMD64/*.cxx) \ - $(wildcard Sources/HEL/AMD64/*.S) + $(wildcard Sources/HEL/AMD64/*.S) $(wildcard Sources/*.cxx) .PHONY: run-efi-amd64 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 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 -- cgit v1.2.3