diff options
author | Ian Moffett <ian@osmora.org> | 2024-05-26 23:35:16 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-05-26 23:35:16 -0400 |
commit | 97ccc71cfd0b15b8cc7b54405c1231e0e63c7f9c (patch) | |
tree | e10d21243980f9ebb7bcfd0a94853055f77271d8 | |
parent | 44b65521e0e87f7979d2ed0cbf602be627737eb9 (diff) |
kernel/amd64: Support fetching time since startup
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | sys/arch/amd64/amd64/hpet.c | 25 | ||||
-rw-r--r-- | sys/include/sys/timer.h | 2 |
2 files changed, 27 insertions, 0 deletions
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); |