diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-07-10 01:13:08 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-07-10 01:13:08 +0200 |
| commit | 5f6549b7d46118ba416faa170ff088d98c9144f0 (patch) | |
| tree | 23d19bc039a547f27275065d96c52551d8ca989f | |
| parent | dfaf137915094e7ba72f7d7f1f57dc5158d1b6ab (diff) | |
MHR-36: See below.
- Implement MSR functions has_msr, get_msr, set_msr.
- Moved SMP interrupt to interrupt 34 in AMD64.
- Fix syntax error in STB.hxx.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
| -rw-r--r-- | Boot/BootKit/STB.hxx | 4 | ||||
| -rw-r--r-- | Boot/Sources/HEL/AMD64/BootMain.cxx | 3 | ||||
| -rw-r--r-- | Boot/amd64-efi.make | 2 | ||||
| -rw-r--r-- | Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp | 93 | ||||
| -rw-r--r-- | Kernel/HALKit/AMD64/HalInterruptAPI.asm | 45 | ||||
| -rw-r--r-- | Kernel/HALKit/AMD64/Processor.hpp | 26 | ||||
| -rw-r--r-- | Kernel/Sources/KeMain.cxx | 16 |
7 files changed, 89 insertions, 100 deletions
diff --git a/Boot/BootKit/STB.hxx b/Boot/BootKit/STB.hxx index b94572d7..6e9b8067 100644 --- a/Boot/BootKit/STB.hxx +++ b/Boot/BootKit/STB.hxx @@ -18,8 +18,10 @@ #define STBI_ASSERT(x) MUST_PASS(x) #define STBI_MALLOC(x) Kernel::ke_new_ke_heap(x, true, true) -#define STBI_REALLOC(p, x) Kernel::ke_update_ke_heap(p, x); +#define STBI_REALLOC(p, x) Kernel::ke_realloc_ke_heap(p, x); #define STBI_FREE(x) Kernel::ke_delete_ke_heap(x) #define STB_IMAGE_IMPLEMENTATION 1 +#include <KernelKit/KernelHeap.hpp> + #include <BootKit/Vendor/stb_image.hxx> diff --git a/Boot/Sources/HEL/AMD64/BootMain.cxx b/Boot/Sources/HEL/AMD64/BootMain.cxx index 928bc5de..ce4074b2 100644 --- a/Boot/Sources/HEL/AMD64/BootMain.cxx +++ b/Boot/Sources/HEL/AMD64/BootMain.cxx @@ -16,10 +16,9 @@ #include <NewKit/Macros.hpp> #include <NewKit/Ref.hpp> #include <BootKit/ProgramLoader.hxx> -#include <KernelKit/KernelHeap.hpp> #include <cstring> -#include <BootKit/Vendor/Support.hxx>ke_realloc_ke_heap +#include <BootKit/Vendor/Support.hxx> #include <BootKit/STB.hxx> /// make the compiler shut up. diff --git a/Boot/amd64-efi.make b/Boot/amd64-efi.make index 1ce6e295..294bfb9e 100644 --- a/Boot/amd64-efi.make +++ b/Boot/amd64-efi.make @@ -29,7 +29,7 @@ IMG=epm-master-1.img IMG_2=epm-slave.img IMG_3=epm-master-2.img -EMU_FLAGS=-net none -m 4G -M q35 -d int \ +EMU_FLAGS=-net none -smp 2 -m 4G -M q35 -serial stdio \ -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/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp index 275a511b..8f619b4f 100644 --- a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp +++ b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp @@ -17,6 +17,10 @@ #define kAPIC_SIPI_Vector 0x00500 #define kAPIC_EIPI_Vector 0x00400 +#define kAPIC_BASE_MSR 0x1B +#define kAPIC_BASE_MSR_BSP 0x100 +#define kAPIC_BASE_MSR_ENABLE 0x800 + /// @brief assembly routine. internal use only. EXTERN_C void _hal_enable_smp(void); @@ -57,8 +61,8 @@ namespace Kernel::HAL } Selector; }; - STATIC voidPtr kApicMadt = nullptr; - STATIC const char* kApicSignature = "APIC"; + STATIC VoidPtr kApicMadt = nullptr; + STATIC const Char* kApicSignature = "APIC"; /// @brief Multiple APIC Descriptor Table. struct MadtType final : public SDT @@ -122,11 +126,7 @@ namespace Kernel::HAL UInt32 fKind{0}; } kApicMadtAddresses[255] = {}; - STATIC SizeT kApicMadtAddressesCount = 0UL; - STATIC UIntPtr cBaseAddressAPIC = 0xFEE00000; - - /// @brief this will help us schedule our cores. - STATIC Boolean* cProgramInitialized = nullptr; + STATIC SizeT kApicMadtAddressesCount = 0UL; enum { @@ -142,7 +142,7 @@ namespace Kernel::HAL /// @return Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress) { - Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, apicId << 24); + Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24)); Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_SIPI_Vector | vector); } @@ -160,14 +160,15 @@ namespace Kernel::HAL } STATIC HAL::StackFramePtr cFramePtr = nullptr; - STATIC Int32 cSMPInterrupt = 0x40; + STATIC Int32 cSMPInterrupt = 34; EXTERN_C Void hal_apic_acknowledge_cont(Void) { - kcout << "newoskrnl: stopping core...\r"; - ke_stop(RUNTIME_CHECK_BOOTSTRAP); + kcout << "newoskrnl: Acknowledged.\r"; } + /// @brief Current context getter. + /// @retval StackFramePtr the current context. EXTERN_C StackFramePtr _hal_leak_current_context(Void) { return cFramePtr; @@ -192,12 +193,30 @@ namespace Kernel::HAL cFramePtr = stackFrame; - /// yes the exception field contains the core id. - hal_send_start_ipi(stackFrame->A0, cSMPInterrupt, cBaseAddressAPIC); - sem.Unlock(); } + STATIC auto cAPICAddress = 0x0FEC00000; + + STATIC void cpu_set_apic_base(UIntPtr apic) + { + UInt32 edx = 0; + UInt32 eax = (apic & 0xfffff0000) | kAPIC_BASE_MSR_ENABLE; + + edx = (apic >> 32) & 0x0f; + + hal_set_msr(kAPIC_BASE_MSR, eax, edx); + } + + STATIC UIntPtr cpu_get_apic_base() + { + UInt32 eax, edx; + + hal_get_msr(kAPIC_BASE_MSR, &eax, &edx); + + return (eax & 0xfffff000) | ((UIntPtr)(edx & 0x0f) << 32); + } + /// @brief Fetch and enable cores inside main CPU. /// @param rsdPtr RSD PTR structure. Void hal_system_get_cores(voidPtr rsdPtr) @@ -209,47 +228,29 @@ namespace Kernel::HAL { MadtType* madt = reinterpret_cast<MadtType*>(kApicMadt); - constexpr auto cMaxProbableCores = 4; // the amount of cores we want. - constexpr auto cStartAt = 0; // start here to avoid boot core. + const auto cMaxProbableCores = madt->Length / sizeof(MadtType::MadtAddress); // the amount of cores we want. + constexpr auto cStartAt = 0; // start here to avoid boot core. - for (SizeT coreAt = cStartAt; coreAt < cMaxProbableCores; ++coreAt) - { - if (madt->MadtRecords[coreAt].Flags < kThreadBoot) // if local apic. - { - MadtType::MadtAddress& madtRecord = madt->MadtRecords[coreAt]; + cpu_set_apic_base(cpu_get_apic_base()); - // then register as a core for scheduler. - kcout << "newoskrnl: Register APIC.\r"; - - kApicMadtAddresses[kApicMadtAddressesCount].fAddress = madtRecord.Address; - kApicMadtAddresses[kApicMadtAddressesCount].fKind = madt->MadtRecords[coreAt].Flags; - - ++kApicMadtAddressesCount; - } - } + // set SVR register to bit 8 to start recieve interrupts. - /////////////////////////////////////////////////////////////////////////// - /// Start local APIC now. - /////////////////////////////////////////////////////////////////////////// - - auto flagsSet = Kernel::ke_dma_read(cBaseAddressAPIC, 0xF0); // SVR register. - - // enable APIC. + auto flagsSet = Kernel::ke_dma_read(cAPICAddress, 0xF0); // SVR register. flagsSet |= 0x100; - Kernel::ke_dma_write(cBaseAddressAPIC, 0xF0, flagsSet); - - /// Set sprurious interrupt vector. - Kernel::ke_dma_write(cBaseAddressAPIC, 0xF0, 0x100 | 0xFF); + Kernel::ke_dma_write(cAPICAddress, 0xF0, flagsSet | 0x100); - // highest task priority. for our realtime kernel. - Kernel::ke_dma_write(cBaseAddressAPIC, 0x21, 0); + for (SizeT coreAt = cStartAt; coreAt < cMaxProbableCores; ++coreAt) + { + MadtType::MadtAddress& madtRecord = madt->MadtRecords[coreAt]; - cProgramInitialized = new Boolean(true); + kApicMadtAddresses[kApicMadtAddressesCount].fAddress = madtRecord.Address; + kApicMadtAddresses[kApicMadtAddressesCount].fKind = madt->MadtRecords[coreAt].RecordType; - constexpr auto cWhatCore = 1; + kcout << "newoskrnl: register ipi...\r"; - hal_send_start_ipi(cWhatCore, cSMPInterrupt, cBaseAddressAPIC); + ++kApicMadtAddressesCount; + } } else { diff --git a/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/Kernel/HALKit/AMD64/HalInterruptAPI.asm index 016c9cd8..4e9ace6f 100644 --- a/Kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/Kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -121,53 +121,24 @@ IntNormal 31 [extern hal_apic_acknowledge] -__NEW_INT_32: +%define cAPICAddress 0xFEE00000 + +__NEW_INT_34: ;; make this active, SMP works again. -%if 0 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 + call hal_apic_acknowledge pop rax mov rax, 0 ;; tell there local apic that we're done. - mov [0xFEE00000 + 0xB0], rax ; LAPIC_EOI -%endif + mov [cAPICAddress + 0xB0], rax ; send end of interrupt. + iretq -IntNormal 33 +IntNormal 32 -IntNormal 34 +IntNormal 33 IntNormal 35 IntNormal 36 IntNormal 37 diff --git a/Kernel/HALKit/AMD64/Processor.hpp b/Kernel/HALKit/AMD64/Processor.hpp index 27c1bfbb..ff7045c2 100644 --- a/Kernel/HALKit/AMD64/Processor.hpp +++ b/Kernel/HALKit/AMD64/Processor.hpp @@ -19,6 +19,8 @@ #include <FirmwareKit/Handover.hxx> #include <HALKit/AMD64/HalPageAlloc.hpp> +#include <cpuid.h> + #ifdef kCPUBackendName #undef kCPUBackendName #endif // ifdef kCPUBackendName @@ -230,6 +232,30 @@ namespace Kernel::HAL Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress); Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress); + inline Bool hal_has_msr() noexcept + { + static UInt32 eax, unused, edx; // eax, edx + + __get_cpuid(1, &eax, &unused, &unused, &edx); + + // edx returns the flag for MSR (which is 1 shifted to 5.) + return edx & (1 << 5); + } + + inline Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept + { + asm volatile("rdmsr" + : "=a"(*lo), "=d"(*hi) + : "c"(msr)); + } + + inline Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept + { + asm volatile("wrmsr" + : + : "a"(lo), "d"(hi), "c"(msr)); + } + /// @brief Processor specific structures. namespace Detail { diff --git a/Kernel/Sources/KeMain.cxx b/Kernel/Sources/KeMain.cxx index d4c02990..011e59a4 100644 --- a/Kernel/Sources/KeMain.cxx +++ b/Kernel/Sources/KeMain.cxx @@ -63,7 +63,7 @@ namespace Kernel::Detail if (catalogDir) { - Kernel::kcout << "newoskrnl: Already here\r"; + Kernel::kcout << "newoskrnl: already here.\r"; delete catalogDir; continue; @@ -186,18 +186,8 @@ namespace Kernel::Detail /// @brief Loads necessary servers for the kernel -> user mode switch. /// @param void no args. /// @return void no return value. - STATIC Kernel::Void ke_launch_srv(Kernel::Void) + STATIC Kernel::Void ke_user_switch(Kernel::Void) { - // load security server. - Kernel::PEFLoader simConn("C:\\System\\SimConnect"); - - if (!simConn.IsLoaded()) - { - Kernel::ke_stop(RUNTIME_CHECK_FAILED); - } - - Kernel::Utils::execute_from_image(simConn, - Kernel::ProcessHeader::kAppKind); } } // namespace Kernel::Detail @@ -208,5 +198,5 @@ EXTERN_C Kernel::Void KeMain(Kernel::Void) { /// Now run kernel loop, until no process are running. Kernel::Detail::FilesystemInstaller(); // automatic filesystem creation. - Kernel::Detail::ke_launch_srv(); + Kernel::Detail::ke_user_switch(); } |
