From ca5a097ef5acb6309603976de9d006cd4a1c0255 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 4 Aug 2023 15:44:32 +0300 Subject: [PATCH] Kernel: Add function to retrieve boot time as timespec --- kernel/include/kernel/Timer/HPET.h | 1 + kernel/include/kernel/Timer/PIT.h | 1 + kernel/include/kernel/Timer/Timer.h | 7 +++++-- kernel/kernel/Input/PS2Keyboard.cpp | 5 ++++- kernel/kernel/Timer/HPET.cpp | 26 +++++++++++++++++++++++++- kernel/kernel/Timer/PIT.cpp | 16 ++++++++++++++-- kernel/kernel/Timer/Timer.cpp | 5 +++++ 7 files changed, 55 insertions(+), 6 deletions(-) diff --git a/kernel/include/kernel/Timer/HPET.h b/kernel/include/kernel/Timer/HPET.h index 3b6bdc1a9e..69b2610169 100644 --- a/kernel/include/kernel/Timer/HPET.h +++ b/kernel/include/kernel/Timer/HPET.h @@ -11,6 +11,7 @@ namespace Kernel static BAN::ErrorOr> create(); virtual uint64_t ms_since_boot() const override; + virtual timespec time_since_boot() const override; private: HPET() = default; diff --git a/kernel/include/kernel/Timer/PIT.h b/kernel/include/kernel/Timer/PIT.h index 36703636f5..23e5000e69 100644 --- a/kernel/include/kernel/Timer/PIT.h +++ b/kernel/include/kernel/Timer/PIT.h @@ -14,6 +14,7 @@ namespace Kernel static BAN::ErrorOr> create(); virtual uint64_t ms_since_boot() const override; + virtual timespec time_since_boot() const override; private: void initialize(); diff --git a/kernel/include/kernel/Timer/Timer.h b/kernel/include/kernel/Timer/Timer.h index 56e5d5198c..5f1ba382d8 100644 --- a/kernel/include/kernel/Timer/Timer.h +++ b/kernel/include/kernel/Timer/Timer.h @@ -12,16 +12,19 @@ namespace Kernel public: virtual ~Timer() {}; virtual uint64_t ms_since_boot() const = 0; + virtual timespec time_since_boot() const = 0; }; - class TimerHandler + class TimerHandler : public Timer { public: static void initialize(); static TimerHandler& get(); static bool is_initialized(); - uint64_t ms_since_boot() const; + virtual uint64_t ms_since_boot() const override; + virtual timespec time_since_boot() const override; + void sleep(uint64_t) const; uint64_t get_unix_timestamp(); diff --git a/kernel/kernel/Input/PS2Keyboard.cpp b/kernel/kernel/Input/PS2Keyboard.cpp index 91fc7d9c61..716d47ffa0 100644 --- a/kernel/kernel/Input/PS2Keyboard.cpp +++ b/kernel/kernel/Input/PS2Keyboard.cpp @@ -215,7 +215,10 @@ namespace Kernel::Input event.key = key; if (event.pressed() && event.key == Input::Key::F11) - dprintln("{} ms", TimerHandler::get().ms_since_boot()); + { + auto time = TimerHandler::get().time_since_boot(); + dprintln("{}.{9} s", time.tv_sec, time.tv_nsec); + } if (m_event_queue.full()) { diff --git a/kernel/kernel/Timer/HPET.cpp b/kernel/kernel/Timer/HPET.cpp index c6d58426c2..c4eda02a93 100644 --- a/kernel/kernel/Timer/HPET.cpp +++ b/kernel/kernel/Timer/HPET.cpp @@ -22,7 +22,10 @@ #define HPET_Tn_PER_INT_CAP (1 << 4) #define HPET_Tn_VAL_SET_CNF (1 << 6) -#define FS_PER_MS 1'000'000'000'000 +#define FS_PER_S 1'000'000'000'000'000 +#define FS_PER_MS 1'000'000'000'000 +#define FS_PER_US 1'000'000'000 +#define FS_PER_NS 1'000'000 namespace Kernel { @@ -66,6 +69,18 @@ namespace Kernel m_counter_tick_period_fs = read_register(HPET_REG_CAPABILIES) >> 32; uint64_t ticks_per_ms = FS_PER_MS / m_counter_tick_period_fs; + + { + const char* units[] = { "fs", "ps", "ns", "us", "ms", "s" }; + int index = 0; + uint64_t temp = m_counter_tick_period_fs; + while (temp >= 1000) + { + temp /= 1000; + index++; + } + dprintln("HPET percision {} {}", temp, units[index]); + } uint64_t timer0_config = read_register(HPET_REG_TIMER_CONFIG(0)); if (!(timer0_config & HPET_Tn_PER_INT_CAP)) @@ -100,6 +115,15 @@ namespace Kernel return read_register(HPET_REG_COUNTER) * m_counter_tick_period_fs / FS_PER_MS; } + timespec HPET::time_since_boot() const + { + uint64_t time_fs = read_register(HPET_REG_COUNTER) * m_counter_tick_period_fs; + return timespec { + .tv_sec = time_fs / FS_PER_S, + .tv_nsec = (long)((time_fs % FS_PER_S) / FS_PER_NS) + }; + } + void HPET::write_register(ptrdiff_t reg, uint64_t value) const { MMIO::write64(m_mmio_base + reg, value); diff --git a/kernel/kernel/Timer/PIT.cpp b/kernel/kernel/Timer/PIT.cpp index 003893834c..50f58c1d23 100644 --- a/kernel/kernel/Timer/PIT.cpp +++ b/kernel/kernel/Timer/PIT.cpp @@ -21,6 +21,9 @@ #define BASE_FREQUENCY 1193182 #define TICKS_PER_SECOND 1000 +#define MS_PER_S 1'000 +#define NS_PER_S 1'000'000'000 + namespace Kernel { @@ -34,7 +37,7 @@ namespace Kernel BAN::ErrorOr> PIT::create() { - PIT* pit = new PIT; + PIT* pit = new PIT(); if (pit == nullptr) return BAN::Error::from_errno(ENOMEM); pit->initialize(); @@ -57,7 +60,16 @@ namespace Kernel uint64_t PIT::ms_since_boot() const { - return s_system_time; + return s_system_time * (MS_PER_S / TICKS_PER_SECOND); + } + + timespec PIT::time_since_boot() const + { + uint64_t ticks = s_system_time; + return timespec { + .tv_sec = ticks / TICKS_PER_SECOND, + .tv_nsec = (long)((ticks % TICKS_PER_SECOND) * (NS_PER_S / TICKS_PER_SECOND)) + }; } } diff --git a/kernel/kernel/Timer/Timer.cpp b/kernel/kernel/Timer/Timer.cpp index f96fd0cd9c..e628801a75 100644 --- a/kernel/kernel/Timer/Timer.cpp +++ b/kernel/kernel/Timer/Timer.cpp @@ -59,6 +59,11 @@ namespace Kernel return m_timer->ms_since_boot(); } + timespec TimerHandler::time_since_boot() const + { + return m_timer->time_since_boot(); + } + void TimerHandler::sleep(uint64_t ms) const { if (ms == 0)