From 067dd09234b8d8e97b9a34fec48461e004f518f0 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sat, 22 Apr 2023 21:29:07 -0300 Subject: [PATCH] kernel: initial timekeeper implementation --- kernel-src/arch/x86-64/main.c | 5 +++- kernel-src/include/kernel/timekeeper.h | 10 +++++++ kernel-src/sys/timekeeper.c | 41 ++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 kernel-src/include/kernel/timekeeper.h create mode 100644 kernel-src/sys/timekeeper.c diff --git a/kernel-src/arch/x86-64/main.c b/kernel-src/arch/x86-64/main.c index fa5eec79..dac3d9c8 100644 --- a/kernel-src/arch/x86-64/main.c +++ b/kernel-src/arch/x86-64/main.c @@ -12,6 +12,7 @@ #include #include #include +#include static cpu_t bsp_cpu; @@ -30,6 +31,8 @@ void kernel_entry() { arch_acpi_init(); arch_apic_init(); arch_apic_initap(); - arch_hpet_init(); + // XXX fall back to another clock source + time_t u = arch_hpet_init(); + timekeeper_init(arch_hpet_ticks, u); __assert(!"kernel entry end"); } diff --git a/kernel-src/include/kernel/timekeeper.h b/kernel-src/include/kernel/timekeeper.h new file mode 100644 index 00000000..1d863f5f --- /dev/null +++ b/kernel-src/include/kernel/timekeeper.h @@ -0,0 +1,10 @@ +#ifndef _TIMEKEEPER_H +#define _TIMEKEEPER_H + +#include + +void timekeeper_init(time_t (*tick)(), time_t ticksperus); +timespec_t timekeeper_timefromboot(); +timespec_t timekeeper_time(); + +#endif diff --git a/kernel-src/sys/timekeeper.c b/kernel-src/sys/timekeeper.c new file mode 100644 index 00000000..8090723b --- /dev/null +++ b/kernel-src/sys/timekeeper.c @@ -0,0 +1,41 @@ +#include +#include +#include + +static volatile struct limine_boot_time_request timereq = { + .id = LIMINE_BOOT_TIME_REQUEST, + .revision = 0 +}; + +static time_t bootunix; +static time_t ticksperus; +static time_t (*clockticks)(); +static time_t initclockticks; + +timespec_t timekeeper_timefromboot() { + timespec_t ts; + time_t ticks = clockticks() - initclockticks; + time_t uspassed = ticks / ticksperus; + ts.s = uspassed / 1000000; + ts.ns = (uspassed * 1000) % 1000000000; + return ts; +} + +timespec_t timekeeper_time() { + timespec_t fromboot = timekeeper_timefromboot(); + timespec_t unix; + unix.s = bootunix; + unix.ns = 0; + return timespec_add(unix, fromboot); +} + +// tick is a function that returns the amount of ticks since the timer's initialisation +void timekeeper_init(time_t (*tick)(), time_t _ticksperus) { + __assert(timereq.response); + bootunix = timereq.response->boot_time; + printf("timekeeper: unix time at boot: %lu\n", bootunix); + initclockticks = tick(); + ticksperus = _ticksperus; + clockticks = tick; + printf("timekeeper: %lu clock ticks at init (%lu ticks per us)\n", initclockticks, ticksperus); +}