/* 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 #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 }; /** @deprecated this shouldn't be used */ inline uint64_t ConvertUnit(const 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: assert(!"Invalid time unit"); } } class HighPrecisionEventTimer { private: struct HPET { uint64_t GeneralCapabilities; uint64_t Reserved0; uint64_t GeneralConfiguration; uint64_t Reserved1; uint64_t GeneralIntStatus; uint64_t Reserved2; uint64_t Reserved3[24]; uint64_t MainCounterValue; uint64_t Reserved4; }; uint32_t clk = 0; HPET *hpet = nullptr; uint64_t ClassCreationTime = 0; public: bool Sleep(size_t Duration, Units Unit); uint64_t GetCounter(); uint64_t CalculateTarget(uint64_t Target, Units Unit); uint64_t GetNanosecondsSinceClassCreation(); HighPrecisionEventTimer(void *hpet); ~HighPrecisionEventTimer(); }; class TimeStampCounter { private: uint64_t clk = 0; uint64_t ClassCreationTime = 0; public: bool Sleep(size_t Duration, Units Unit); uint64_t GetCounter(); uint64_t CalculateTarget(uint64_t Target, Units Unit); uint64_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); uint64_t GetCounter(); uint64_t CalculateTarget(uint64_t Target, Units Unit); uint64_t GetNanosecondsSinceClassCreation(); void FindTimers(void *acpi); time(); ~time(); }; } #endif // !__FENNIX_KERNEL_TIME_H__