/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_KERNEL_TIME_H__ #define __FENNIX_KERNEL_TIME_H__ #include #include namespace Time { struct Clock { int Year, Month, Day, Hour, Minute, Second; size_t Counter; }; Clock ReadClock(); Clock ConvertFromUnix(int Timestamp); enum Units { Femtoseconds, Picoseconds, Nanoseconds, Microseconds, Milliseconds, Seconds, Minutes, Hours, Days, Months, Years }; class HighPrecisionEventTimer { private: struct HPET { uintptr_t GeneralCapabilities; uintptr_t Reserved0; uintptr_t GeneralConfiguration; uintptr_t Reserved1; uintptr_t GeneralIntStatus; uintptr_t Reserved2; uintptr_t Reserved3[24]; uintptr_t MainCounterValue; uintptr_t Reserved4; }; uint32_t clk = 0; HPET *hpet = nullptr; size_t ClassCreationTime = 0; inline size_t ConvertUnit(Units Unit) { switch (Unit) { case Femtoseconds: return 1; case Picoseconds: return 1000; case Nanoseconds: return 1000000; case Microseconds: return 1000000000; case Milliseconds: return 1000000000000; case Seconds: return 1000000000000000; case Minutes: return 1000000000000000000; // case Hours: // return 1000000000000000000000; // case Days: // return 1000000000000000000000000; // case Months: // return 1000000000000000000000000000; // case Years: // return 1000000000000000000000000000000; default: error("Invalid time unit %d", Unit); return 1; } } public: bool Sleep(size_t Duration, Units Unit); size_t GetCounter(); size_t CalculateTarget(size_t Target, Units Unit); size_t GetNanosecondsSinceClassCreation(); HighPrecisionEventTimer(void *hpet); ~HighPrecisionEventTimer(); }; class TimeStampCounter { private: size_t clk = 0; size_t ClassCreationTime = 0; inline size_t ConvertUnit(Units Unit) { switch (Unit) { case Femtoseconds: return 1; case Picoseconds: return 1000; case Nanoseconds: return 1000000; case Microseconds: return 1000000000; case Milliseconds: return 1000000000000; case Seconds: return 1000000000000000; case Minutes: return 1000000000000000000; // case Hours: // return 1000000000000000000000; // case Days: // return 1000000000000000000000000; // case Months: // return 1000000000000000000000000000; // case Years: // return 1000000000000000000000000000000; default: error("Invalid time unit %d", Unit); return 1; } } public: bool Sleep(size_t Duration, Units Unit); size_t GetCounter(); size_t CalculateTarget(size_t Target, Units Unit); size_t GetNanosecondsSinceClassCreation(); TimeStampCounter(); ~TimeStampCounter(); }; class time { public: enum TimeActiveTimer { NONE = 0b0, RTC = 0b1, PIT = 0b10, HPET = 0b100, ACPI = 0b1000, APIC = 0b10000, TSC = 0b100000 }; private: int SupportedTimers = 0; TimeActiveTimer ActiveTimer = NONE; HighPrecisionEventTimer *hpet; TimeStampCounter *tsc; public: int GetSupportedTimers() { return SupportedTimers; } TimeActiveTimer GetActiveTimer() { return ActiveTimer; } bool ChangeActiveTimer(TimeActiveTimer Timer) { if (!(SupportedTimers & Timer)) return false; ActiveTimer = Timer; return true; } bool Sleep(size_t Duration, Units Unit); size_t GetCounter(); size_t CalculateTarget(size_t Target, Units Unit); size_t GetNanosecondsSinceClassCreation(); void FindTimers(void *acpi); time(); ~time(); }; } #endif // !__FENNIX_KERNEL_TIME_H__