From 21bcfa6b707403a43ea8ac4a285114951cf29059 Mon Sep 17 00:00:00 2001 From: Ada Christine Date: Fri, 18 Feb 2022 17:24:17 +0000 Subject: timer callback interface --- kc/core/pit8253.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- kc/core/pit8253.h | 3 +++ kc/core/timer.h | 11 +++++++++++ 3 files changed, 69 insertions(+), 3 deletions(-) (limited to 'kc') diff --git a/kc/core/pit8253.c b/kc/core/pit8253.c index 6f6256a..5653eb9 100644 --- a/kc/core/pit8253.c +++ b/kc/core/pit8253.c @@ -2,6 +2,7 @@ #include "pic8259.h" #include "port.h" #include "kprint.h" +#include "memory.h" #include @@ -19,10 +20,11 @@ #define PIT_HZ 1193182U #define PIT_HZ_MIN (PIT_HZ/0xffff) -static void pit8253_set_divisor(uint16_t divisor); +static void set_divisor(uint16_t divisor); static volatile atomic_uint_fast64_t count = 0; static uint16_t divisor = 0; +static struct timer_callback_list *callback_list; const struct timer_source pit8253_timer_source = { @@ -34,6 +36,9 @@ const struct timer_source pit8253_timer_source = pit8253_set_frequency, pit8253_get_frequency, + pit8253_append_callback, + pit8253_delete_callback, + pit8253_nanoseconds_elapsed, pit8253_nanoseconds_delta }; @@ -43,6 +48,15 @@ int pit8253_callback(uint8_t irq) (void)irq; count++; + struct timer_callback_list *l = callback_list; + uint64_t time_now = pit8253_nanoseconds_elapsed(); + + while (l) + { + l->func(time_now); + l = l->next; + } + return 0; } @@ -72,7 +86,7 @@ void pit8253_set_frequency(uint32_t frequency) kprintf("warning: set timer to minimum frequency\n"); } - pit8253_set_divisor(d); + set_divisor(d); } uint32_t pit8253_get_frequency(void) @@ -80,6 +94,44 @@ uint32_t pit8253_get_frequency(void) return PIT_HZ/divisor; } +static struct timer_callback_list *find_callback(timer_callback func) +{ + struct timer_callback_list *l = callback_list; + + while (l) + { + if (l->func == func) + { + return l; + } + + l = l->next; + } + + return NULL; +} + +int pit8253_append_callback(timer_callback func) +{ + if (!find_callback(func)) + { + struct timer_callback_list *item = heap_alloc(sizeof(*item)); + item->func = func; + item->next = callback_list; + callback_list = item; + + return 0; + } + + return -1; +} + +void pit8253_delete_callback(timer_callback func) +{ + // TODO: implement this + (void)func; +} + uint64_t pit8253_nanoseconds_elapsed(void) { return pit8253_nanoseconds_delta() * atomic_load(&count); @@ -90,7 +142,7 @@ uint64_t pit8253_nanoseconds_delta(void) return (TIMER_NANOSECOND * divisor)/PIT_HZ; } -static void pit8253_set_divisor(uint16_t d) +static void set_divisor(uint16_t d) { outb(PIT8253_CMD, CONFIG_CHANNEL_0); outb(PIT8253_DATA0, (uint8_t)d); diff --git a/kc/core/pit8253.h b/kc/core/pit8253.h index 32cb9b1..b6f3d10 100644 --- a/kc/core/pit8253.h +++ b/kc/core/pit8253.h @@ -10,6 +10,9 @@ void pit8253_stop(void); void pit8253_set_frequency(uint32_t frequency); uint32_t pit8253_get_frequency(void); +int pit8253_append_callback(timer_callback func); +void pit8253_delete_callback(timer_callback func); + uint64_t pit8253_nanoseconds_elapsed(void); uint64_t pit8253_nanoseconds_delta(void); diff --git a/kc/core/timer.h b/kc/core/timer.h index 6960a4b..b41aa35 100644 --- a/kc/core/timer.h +++ b/kc/core/timer.h @@ -5,6 +5,14 @@ #define TIMER_MICROSECOND 1000000ULL #define TIMER_NANOSECOND 1000000000ULL +typedef int (*timer_callback)(uint64_t nanoseconds); + +struct timer_callback_list +{ + timer_callback func; + struct timer_callback_list *next; +}; + struct timer_source { const char *name; @@ -15,6 +23,9 @@ struct timer_source void (*set_frequency)(uint32_t frequency); uint32_t (*get_frequency)(void); + int (*append_callback)(timer_callback func); + void (*delete_callback)(timer_callback func); + uint64_t (*nanoseconds_elapsed)(void); uint64_t (*nanoseconds_delta)(void); }; -- cgit v1.3.1-1-g115d