diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-08-20 02:53:51 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-08-20 02:53:51 +0200 |
| commit | 4eb813ba7247d9e2bebf255ecc50f68c0a71bb72 (patch) | |
| tree | f818bb72f3dcad6e03d77d7b2280b3172f9d29df /dev/ZKA | |
| parent | 860e40b89cca46050850afc79da958bb651d713f (diff) | |
+ 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 <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/ZKA')
| -rw-r--r-- | dev/ZKA/FirmwareKit/EFI/EFI.hxx | 103 | ||||
| -rw-r--r-- | dev/ZKA/FirmwareKit/Handover.hxx | 6 | ||||
| -rw-r--r-- | dev/ZKA/HALKit/AMD64/HalACPIFactoryInterface.cxx | 3 | ||||
| -rw-r--r-- | dev/ZKA/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx | 100 | ||||
| -rw-r--r-- | dev/ZKA/HALKit/AMD64/HalTimer.cxx | 65 | ||||
| -rw-r--r-- | dev/ZKA/KernelKit/Semaphore.hxx | 2 | ||||
| -rw-r--r-- | dev/ZKA/KernelKit/Timer.hxx | 37 | ||||
| -rw-r--r-- | dev/ZKA/Modules/ACPI/ACPI.hxx | 22 | ||||
| -rw-r--r-- | dev/ZKA/NewKit/String.hxx | 9 | ||||
| -rw-r--r-- | dev/ZKA/Sources/Semaphore.cxx | 2 | ||||
| -rw-r--r-- | dev/ZKA/Sources/String.cxx | 11 | ||||
| -rw-r--r-- | dev/ZKA/Sources/Timer.cxx | 18 |
12 files changed, 279 insertions, 99 deletions
diff --git a/dev/ZKA/FirmwareKit/EFI/EFI.hxx b/dev/ZKA/FirmwareKit/EFI/EFI.hxx index 2237ce36..13ddec1c 100644 --- a/dev/ZKA/FirmwareKit/EFI/EFI.hxx +++ b/dev/ZKA/FirmwareKit/EFI/EFI.hxx @@ -24,6 +24,10 @@ using namespace Kernel; #define EFI_API __attribute__((ms_abi)) #endif // ifndef EPI_API +#define IN +#define OUT +#define OPTIONAL + // Forward decls struct EfiTableHeader; @@ -46,7 +50,7 @@ typedef UInt64 EfiStatusType; /// This is like NT's Win32 HANDLE type. typedef struct EfiHandle { -}* EfiHandlePtr; +} * EfiHandlePtr; /* UEFI uses wide characters by default. */ typedef WideChar EfiCharType; @@ -589,7 +593,7 @@ typedef struct EfiSystemTable { EfiGUID VendorGUID; VoidPtr VendorTable; - }* ConfigurationTable; + } * ConfigurationTable; } EfiSystemTable; #define kEfiOk 0 @@ -781,4 +785,99 @@ struct EfiFileInfo final #define EFI_EXTRA_DESCRIPTOR_SIZE 8 +#define EFI_MP_SERVICES_PROTOCOL_GUID \ + { \ + 0x3fdda605, 0xa76e, 0x4f46, \ + { \ + 0xad, 0x29, 0x12, 0xf4, \ + 0x53, 0x1b, 0x3d, 0x08 \ + } \ + } + +//******************************************************* +// EFI_CPU_PHYSICAL_LOCATION +// @note As in the EFI specs. +//******************************************************* +typedef struct _EfiCPUPhyiscalLocation +{ + UInt32 Package; + UInt32 Core; + UInt32 Thread; +} EfiCPUPhyiscalLocation; + +typedef union _EfiExtendedProcessorInformation { + EfiCPUPhyiscalLocation Location2; +} EfiExtendedProcessorInformation; + +typedef struct _EfiProcessorInformation +{ + UInt64 ProcessorId; + UInt32 StatusFlag; + EfiCPUPhyiscalLocation Location; + EfiExtendedProcessorInformation ExtendedInformation; +} EfiProcessorInformation; + +#define PROCESSOR_AS_BSP_BIT 0x00000001 +#define PROCESSOR_ENABLED_BIT 0x00000002 +#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004 + +typedef EfiStatusType EFI_API (*EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS)( + IN struct _EfiMpServicesProtocol* Self, + OUT UInt32* NumberOfProcessors, + OUT UInt32* NumberOfEnabledProcessors); + +typedef EfiStatusType EFI_API (*EFI_MP_SERVICES_GET_PROCESSOR_INFO)( + IN struct _EfiMpServicesProtocol* Self, + IN UInt32* ProcessorNumber, + OUT struct _EfiProcessorInformation* NumberOfEnabledProcessors); + +#define END_OF_CPU_LIST 0xffffffff + +typedef void EFI_API (*EFI_AP_PROCEDURE)( + IN VoidPtr ProcedureArgument); + +typedef EfiStatusType EFI_API (*EFI_MP_SERVICES_STARTUP_ALL_APS)( + IN struct _EfiMpServicesProtocol* This, + IN EFI_AP_PROCEDURE Procedure, + IN Boolean SingleThread, + IN VoidPtr WaitEvent OPTIONAL, // EFI_EVENT first, but unused here. + IN UInt32 TimeoutInMicroSeconds, + IN Void* ProcedureArgument OPTIONAL, + OUT UInt32** FailedCpuList OPTIONAL); + +typedef EfiStatusType EFI_API (*EFI_MP_SERVICES_SWITCH_BSP)( + IN struct _EfiMpServicesProtocol* This, + IN UInt32 ProcessorNumber, + IN Boolean EnableOldBSP); + +typedef EfiStatusType EFI_API (*EFI_MP_SERVICES_STARTUP_THIS_AP)( + IN struct _EfiMpServicesProtocol* This, + IN EFI_AP_PROCEDURE Procedure, + IN UInt32 ProcessorNumber, + IN VoidPtr WaitEvent OPTIONAL, + IN UInt32 TimeoutInMicroseconds, + IN Void* ProcedureArgument OPTIONAL, + OUT Boolean* Finished OPTIONAL); + +typedef EfiStatusType EFI_API (*EFI_MP_SERVICES_ENABLEDISABLEAP)( + IN struct _EfiMpServicesProtocol* This, + IN UInt32 ProcessorNumber, + IN Boolean EnableAP, + IN UInt32* HealthFlag OPTIONAL); + +typedef EfiStatusType EFI_API(* EFI_MP_SERVICES_WHOAMI)( + IN struct _EfiMpServicesProtocol* This, + OUT UInt32* ProcessorNumber); + +typedef struct _EfiMpServicesProtocol +{ + EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors; + EFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo; + EFI_MP_SERVICES_STARTUP_ALL_APS StartupAllAPs; + EFI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP; + EFI_MP_SERVICES_SWITCH_BSP SwitchBSP; + EFI_MP_SERVICES_ENABLEDISABLEAP EnableDisableAP; + EFI_MP_SERVICES_WHOAMI WhoAmI; +} EfiMpServicesProtocol; + #endif // ifndef __EFI__ diff --git a/dev/ZKA/FirmwareKit/Handover.hxx b/dev/ZKA/FirmwareKit/Handover.hxx index 96daa1dc..fba6017d 100644 --- a/dev/ZKA/FirmwareKit/Handover.hxx +++ b/dev/ZKA/FirmwareKit/Handover.hxx @@ -22,10 +22,13 @@ /* useful macros */ #define kHandoverMagic 0xBADCC -#define kHandoverVersion 0x113 +#define kHandoverVersion 0x114 #define kHandoverMaxCmdLine 8 +#define kHandoverBetterEFI "ZKA_EFI" +#define kHandoverBetterEFI_U L"ZKA_EFI" + #define kHandoverHeapSz gib_cast(2) #define kHandoverStructSz sizeof(HEL::HandoverHeader) @@ -71,6 +74,7 @@ namespace Kernel::HEL { VoidPtr f_SmBios; VoidPtr f_VendorPtr; + VoidPtr f_MPPtr; } f_HardwareTables; struct 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<voidPtr>(reinterpret_cast<voidPtr>(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 <KernelKit/ProcessScheduler.hxx> #include <KernelKit/Timer.hxx> +#include <FirmwareKit/EFI.hxx> + // Needed for SMP. // #include <KernelKit/MP.hxx> @@ -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<EfiMpServicesProtocol*>(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<MADT_TABLE*>(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 <ArchKit/ArchKit.hxx>
\ No newline at end of file +#include <Modules/ACPI/ACPIFactoryInterface.hxx>
+#include <ArchKit/ArchKit.hxx>
+#include <KernelKit/Timer.hxx>
+
+///! 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;
+}
diff --git a/dev/ZKA/KernelKit/Semaphore.hxx b/dev/ZKA/KernelKit/Semaphore.hxx index 33dfe651..efef472a 100644 --- a/dev/ZKA/KernelKit/Semaphore.hxx +++ b/dev/ZKA/KernelKit/Semaphore.hxx @@ -32,7 +32,7 @@ namespace Kernel public: bool Lock(PROCESS_HEADER_BLOCK* process); - bool LockOrWait(PROCESS_HEADER_BLOCK* process, HardwareTimerInterface* timer); + bool LockOrWait(PROCESS_HEADER_BLOCK* process, TimerInterface* timer); public: NEWOS_COPY_DEFAULT(Semaphore); diff --git a/dev/ZKA/KernelKit/Timer.hxx b/dev/ZKA/KernelKit/Timer.hxx index e6ef5d03..603cacff 100644 --- a/dev/ZKA/KernelKit/Timer.hxx +++ b/dev/ZKA/KernelKit/Timer.hxx @@ -12,24 +12,41 @@ namespace Kernel { - class HardwareTimer; - class HardwareTimerInterface; + class SoftwareTimer; + class TimerInterface; - class HardwareTimerInterface + class TimerInterface { public: /// @brief Default constructor - explicit HardwareTimerInterface() = default; - virtual ~HardwareTimerInterface() = default; + explicit TimerInterface() = default; + virtual ~TimerInterface() = default; public: - NEWOS_COPY_DEFAULT(HardwareTimerInterface); + NEWOS_COPY_DEFAULT(TimerInterface); public: virtual Int32 Wait() noexcept; }; - class HardwareTimer final : public HardwareTimerInterface + class SoftwareTimer final : public TimerInterface + { + public: + explicit SoftwareTimer(Int64 seconds); + ~SoftwareTimer() override; + + public: + NEWOS_COPY_DEFAULT(SoftwareTimer); + + public: + Int32 Wait() noexcept override; + + private: + IntPtr* fDigitalTimer{nullptr}; + Int64 fWaitFor{0}; + }; + + class HardwareTimer final : public TimerInterface { public: explicit HardwareTimer(Int64 seconds); @@ -41,7 +58,7 @@ namespace Kernel public: Int32 Wait() noexcept override; - public: + private: IntPtr* fDigitalTimer{nullptr}; Int64 fWaitFor{0}; }; @@ -51,7 +68,7 @@ namespace Kernel if (time < 0) return 0; - return 1000 / time; + return 1000 * time; } inline Int64 Milliseconds(Int64 time) @@ -59,6 +76,6 @@ namespace Kernel if (time < 0) return 0; - return 1000 / Seconds(time); + return 1000 * Seconds(time); } } // namespace Kernel diff --git a/dev/ZKA/Modules/ACPI/ACPI.hxx b/dev/ZKA/Modules/ACPI/ACPI.hxx index 7ea34bd0..44e9fa1b 100644 --- a/dev/ZKA/Modules/ACPI/ACPI.hxx +++ b/dev/ZKA/Modules/ACPI/ACPI.hxx @@ -48,28 +48,28 @@ namespace Kernel UInt32 Reserved; }; - enum class AddressSpace : UInt8 + enum class ACPI_ADDRESS_SPACE_KIND : UInt8 { - SystemMemory = 0, - SystemIO = 1, - Pci = 2, - Controller = 3, - SmBus = 4, - Count = 5, - Invalid = 0xFF, + eSystemMemory = 0, + eSystemIO = 1, + ePci = 2, + eController = 3, + eSmBus = 4, + eCount = 5, + eInvalid = 0xFF, }; - class PACKED Address + class PACKED ACPI_ADDRESS final { public: - AddressSpace AddressSpaceId; + ACPI_ADDRESS_SPACE_KIND AddressSpaceId; UInt8 RegisterBitWidth; UInt8 RegisterBitOffset; UInt8 Reserved; UIntPtr Address; }; - class PACKED RSDT + class PACKED RSDT final { public: Char Signature[4]; diff --git a/dev/ZKA/NewKit/String.hxx b/dev/ZKA/NewKit/String.hxx index 2f3d2096..5d9ebd21 100644 --- a/dev/ZKA/NewKit/String.hxx +++ b/dev/ZKA/NewKit/String.hxx @@ -79,9 +79,10 @@ namespace Kernel struct StringBuilder final { static ErrorOr<StringView> Construct(const Char* data); - static const char* FromInt(const char* fmt, int n); - static const char* FromBool(const char* fmt, bool n); - static const char* Format(const char* fmt, const char* from); - static bool Equals(const char* lhs, const char* rhs); + static const char* FromInt(const Char* fmt, int n); + static const char* FromBool(const Char* fmt, bool n); + static const char* Format(const Char* fmt, const Char* from); + static bool Equals(const Char* lhs, const Char* rhs); + static bool Equals(const WideChar* lhs, const WideChar* rhs); }; } // namespace Kernel diff --git a/dev/ZKA/Sources/Semaphore.cxx b/dev/ZKA/Sources/Semaphore.cxx index c159240e..f9da0703 100644 --- a/dev/ZKA/Sources/Semaphore.cxx +++ b/dev/ZKA/Sources/Semaphore.cxx @@ -32,7 +32,7 @@ namespace Kernel return fLockingProcess; } - bool Semaphore::LockOrWait(PROCESS_HEADER_BLOCK* process, HardwareTimerInterface* timer) + bool Semaphore::LockOrWait(PROCESS_HEADER_BLOCK* process, TimerInterface* timer) { if (process == nullptr) return false; diff --git a/dev/ZKA/Sources/String.cxx b/dev/ZKA/Sources/String.cxx index 8ea7d65f..8c928aa5 100644 --- a/dev/ZKA/Sources/String.cxx +++ b/dev/ZKA/Sources/String.cxx @@ -183,6 +183,17 @@ namespace Kernel return true; } + bool StringBuilder::Equals(const WideChar* lhs, const WideChar* rhs) + { + for (Size index = 0; rhs[index] != 0; ++index) + { + if (rhs[index] != lhs[index]) + return false; + } + + return true; + } + const char* StringBuilder::Format(const char* fmt, const char* fmt2) { if (!fmt || !fmt2) diff --git a/dev/ZKA/Sources/Timer.cxx b/dev/ZKA/Sources/Timer.cxx index 041c4b67..7a5ebd8d 100644 --- a/dev/ZKA/Sources/Timer.cxx +++ b/dev/ZKA/Sources/Timer.cxx @@ -8,36 +8,40 @@ ///! BUGS: 0 ///! @file Timer.cxx +///! @brief Software Timer implementation using namespace Kernel; /// @brief Unimplemented as it is an interface. -Int32 HardwareTimerInterface::Wait() noexcept +Int32 TimerInterface::Wait() noexcept { return kErrorUnimplemented; } -/// @brief HardwareTimer class, meant to be generic. +/// @brief SoftwareTimer class, meant to be generic. -HardwareTimer::HardwareTimer(Int64 seconds) +SoftwareTimer::SoftwareTimer(Int64 seconds) : fWaitFor(seconds) { - MUST_PASS(fWaitFor > 0); + fDigitalTimer = new IntPtr(); + MUST_PASS(fDigitalTimer); + } -HardwareTimer::~HardwareTimer() +SoftwareTimer::~SoftwareTimer() { + delete fDigitalTimer; fWaitFor = 0; } -Int32 HardwareTimer::Wait() noexcept +Int32 SoftwareTimer::Wait() noexcept { if (fWaitFor < 1) return -1; while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) { - ; + ++fDigitalTimer; } return 0; |
