From 97ccc71cfd0b15b8cc7b54405c1231e0e63c7f9c Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sun, 26 May 2024 23:35:16 -0400 Subject: kernel/amd64: Support fetching time since startup Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/hpet.c | 25 +++++++++++++++++++++++++ sys/include/sys/timer.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/sys/arch/amd64/amd64/hpet.c b/sys/arch/amd64/amd64/hpet.c index 71557eb..f63b47e 100644 --- a/sys/arch/amd64/amd64/hpet.c +++ b/sys/arch/amd64/amd64/hpet.c @@ -51,6 +51,9 @@ __KERNEL_META("$Hyra$: hpet.c, Ian Marco Moffett, " #define CAP_VENDOR_ID(caps) __SHIFTOUT(caps, 0xFFFF << 16) #define CAP_CLK_PERIOD(caps) (caps >> 32) +#define FSEC_PER_SECOND 1000000000000000ULL +#define USEC_PER_SECOND 1000000ULL + static struct timer timer = { 0 }; static struct hpet *acpi_hpet = NULL; static void *hpet_base = NULL; @@ -129,6 +132,26 @@ hpet_nsleep(size_t ns) return hpet_sleep(ns, 1000000); } +static size_t +hpet_time_usec(void) +{ + uint64_t period, freq, caps; + uint64_t counter; + + caps = hpet_read(HPET_REG_CAPS); + period = CAP_CLK_PERIOD(caps); + freq = FSEC_PER_SECOND / period; + + counter = hpet_read(HPET_REG_MAIN_COUNTER); + return (counter * USEC_PER_SECOND) / freq; +} + +static size_t +hpet_time_sec(void) +{ + return hpet_time_usec() / USEC_PER_SECOND; +} + int hpet_init(void) { @@ -172,6 +195,8 @@ hpet_init(void) timer.msleep = hpet_msleep; timer.usleep = hpet_usleep; timer.nsleep = hpet_nsleep; + timer.get_time_usec = hpet_time_usec; + timer.get_time_sec = hpet_time_sec; register_timer(TIMER_GP, &timer); /* Not faulty */ diff --git a/sys/include/sys/timer.h b/sys/include/sys/timer.h index a255bab..e33b2d3 100644 --- a/sys/include/sys/timer.h +++ b/sys/include/sys/timer.h @@ -72,6 +72,8 @@ typedef int tmrr_status_t; struct timer { const char *name; /* e.g "HPET" */ size_t(*calibrate)(void); /* Returns frequency, 0 for unspecified */ + size_t(*get_time_usec)(void); /* Time since init (microseconds) */ + size_t(*get_time_sec)(void); /* Time since init (seconds) */ int(*msleep)(size_t ms); int(*usleep)(size_t us); int(*nsleep)(size_t ns); -- cgit v1.2.3