From 4eb813ba7247d9e2bebf255ecc50f68c0a71bb72 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 20 Aug 2024 02:53:51 +0200 Subject: + IMP: Using Hybrid MP services on ZKA_EFI firmware. + Implement HPET on HardwareTimer and added a SoftwareTimer. + Implemented Hybrid MP Services on EFI.hxx. Signed-off-by: Amlal El Mahrouss --- dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx | 3 + .../HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx | 100 ++++++++------------- dev/ZKA/HALKit/AMD64/HalTimer.cxx | 65 +++++++++++++- 3 files changed, 106 insertions(+), 62 deletions(-) (limited to 'dev/ZKA/HALKit') diff --git a/dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx b/dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx index 4a9af53b..1fe14b4b 100644 --- a/dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx +++ b/dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx @@ -113,7 +113,10 @@ namespace Kernel break; if (signature_index == (cAcpiSignatureLength - 1)) + { + kcout << "ACPI: Found the SDT. " << endl; return ErrorOr(reinterpret_cast(xsdt->AddressArr[index])); + } } } diff --git a/dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx b/dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx index 6018d20f..0f1c9fcb 100644 --- a/dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx +++ b/dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx @@ -12,6 +12,8 @@ #include #include +#include + // Needed for SMP. // #include @@ -56,34 +58,14 @@ namespace Kernel::HAL STATIC VoidPtr kRawMADT = nullptr; - /* - * - * this is used to store info about the current running thread - * we use this struct to determine if we can use it, or mark it as used or on - * sleep. - * - */ - - struct ProcessorInfoAMD64 final - { - Int32 ThreadType; - UIntPtr JumpAddress; - - struct - { - UInt32 Code; - UInt32 Data; - UInt32 BSS; - } Selector; - }; - /// @brief Multiple APIC Descriptor Table. struct MADT_TABLE final : public SDT { UInt32 Address; // Madt address - UInt32 Flags; // Madt flags + UInt32 Flags; // Madt flags - struct { + struct + { UInt8 Type; UInt8 Len; } Records[]; // Records List @@ -129,68 +111,64 @@ namespace Kernel::HAL struct PROCESS_CONTROL_BLOCK final { - PROCESS_HEADER_BLOCK* f_Header; - HAL::StackFramePtr f_StackFrame; + PROCESS_HEADER_BLOCK* f_PHB; + HAL::StackFramePtr f_Frame; } fBlocks[cMaxPCBBlocks] = {0}; EXTERN_C HAL::StackFramePtr _hal_leak_current_context(Void) { - return fBlocks[ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId % cMaxPCBBlocks].f_StackFrame; + return fBlocks[ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId % cMaxPCBBlocks].f_Frame; } STATIC Void hal_switch_context(HAL::StackFramePtr stack_frame) { - STATIC Semaphore sem; + Semaphore semaphore_process; - constexpr auto cSeconds = 1U; + const auto cDurationSeconds = Seconds(5); - HardwareTimer timer(Seconds(cSeconds)); - sem.LockOrWait(&ProcessScheduler::The().Leak().TheCurrent().Leak(), &timer); + HardwareTimer timer(cDurationSeconds); + semaphore_process.LockOrWait(&ProcessScheduler::The().Leak().TheCurrent().Leak(), &timer); - fBlocks[ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId % cMaxPCBBlocks].f_Header = &ProcessScheduler::The().Leak().TheCurrent().Leak(); - fBlocks[ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId % cMaxPCBBlocks].f_StackFrame = stack_frame; + fBlocks[ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId % cMaxPCBBlocks].f_PHB = &ProcessScheduler::The().Leak().TheCurrent().Leak(); + fBlocks[ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId % cMaxPCBBlocks].f_Frame = stack_frame; - sem.Unlock(); + semaphore_process.Unlock(); } - STATIC auto cAPICAddress = 0x0FEC00000; - - STATIC Void cpu_set_apic_base(UIntPtr apic) + /// @brief Fetch and enable cores inside main CPU. + /// @param rsdPtr RSD PTR structure. + Void hal_system_get_cores(voidPtr rsdPtr) { - UInt32 edx = 0; - UInt32 eax = (apic & 0xfffff0000) | kAPIC_BASE_MSR_ENABLE; - - edx = (apic >> 32) & 0x0f; - - hal_set_msr(kAPIC_BASE_MSR, eax, edx); - } + if (StringBuilder::Equals(kHandoverHeader->f_FirmwareVendorName, kHandoverBetterEFI_U)) + { + // Our EFI way using Hybrid MP services. + EfiMpServicesProtocol* mp = reinterpret_cast(kHandoverHeader->f_HardwareTables.f_MPPtr); - STATIC UIntPtr cpu_get_apic_base(Void) - { - UInt32 eax, edx; + UInt32 who_is_this = -1; - hal_get_msr(kAPIC_BASE_MSR, &eax, &edx); + mp->WhoAmI(mp, &who_is_this); - return (eax & 0xfffff000) | ((UIntPtr)(edx & 0x0f) << 32); - } + kcout << "newoskrnl: Processor #0 WhoAmI: " << number(who_is_this) << endl; - EXTERN_C Void hal_ap_trampoline(Void); + UInt32 health_flag = 0; - /// @brief Fetch and enable cores inside main CPU. - /// @param rsdPtr RSD PTR structure. - Void hal_system_get_cores(voidPtr rsdPtr) - { - auto acpi = ACPIFactoryInterface(rsdPtr); - kRawMADT = acpi.Find(kApicSignature).Leak().Leak(); + UInt32 num = 0; + UInt32 enabled_num = 0; - kSMPBlock = reinterpret_cast(kRawMADT); + mp->GetNumberOfProcessors(mp, &num, &enabled_num); - if (!kSMPBlock) - kSMPAware = false; + kcout << "newoskrnl: Processor #: " << number(num) << endl; + kcout << "newoskrnl: Enabled processors #: " << number(enabled_num) << endl; - if (kSMPBlock) + if (enabled_num < 2) + { + ke_stop(RUNTIME_CHECK_PROCESS); + } + } + else { - kSMPAware = true; + // Classic way (MADT) + kcout << "Non ZKA EFI system detected.\r"; } } } // namespace Kernel::HAL diff --git a/dev/ZKA/HALKit/AMD64/HalTimer.cxx b/dev/ZKA/HALKit/AMD64/HalTimer.cxx index ff65a4a1..e6e21a67 100644 --- a/dev/ZKA/HALKit/AMD64/HalTimer.cxx +++ b/dev/ZKA/HALKit/AMD64/HalTimer.cxx @@ -11,4 +11,67 @@ ------------------------------------------- */ -#include \ No newline at end of file +#include +#include +#include + +///! BUGS: 0 +///! @file HalTimer.cxx +///! @brief Hardware Timer. + +namespace Kernel::Detail +{ + struct HPET_BLOCK : public Kernel::SDT + { + Kernel::UInt8 hardware_rev_id; + Kernel::UInt8 comparator_count : 5; + Kernel::UInt8 counter_size : 1; + Kernel::UInt8 reserved : 1; + Kernel::UInt8 legacy_replacement : 1; + Kernel::UInt16 pci_vendor_id; + Kernel::ACPI_ADDRESS address; + Kernel::UInt8 hpet_number; + Kernel::UInt16 minimum_tick; + Kernel::UInt8 page_protection; + } __attribute__((packed)); +} // namespace Kernel::Detail + +using namespace Kernel; + +HardwareTimer::HardwareTimer(Int64 ms) + : fWaitFor(ms) +{ + auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr); + + auto hpet = (Detail::HPET_BLOCK*)power.Find("HPET").Leak().Leak(); + fDigitalTimer = (IntPtr*)hpet->address.Address; + MUST_PASS(fDigitalTimer); +} + +HardwareTimer::~HardwareTimer() +{ + fDigitalTimer = nullptr; + fWaitFor = 0; +} + +Int32 HardwareTimer::Wait() noexcept +{ + if (fWaitFor < 1) + return -1; + + UInt32 minimum_tick = *(fDigitalTimer) >> 32; + + const UInt64 cLimitVal = 0x10000000000000; + + UInt64 microsecond = fWaitFor / minimum_tick; + + *(fDigitalTimer + 0x0f0) = cLimitVal - microsecond; + *(fDigitalTimer + 0x010) = 0x1; + + kcout << "MS: " << number(microsecond) << endl; + + while (*(fDigitalTimer + 0x0f0) <= cLimitVal) + ; + + return 0; +} -- cgit v1.2.3