summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2022-02-18 17:24:17 +0000
committerAda Christine <adachristine18@gmail.com>2022-02-18 17:24:17 +0000
commit21bcfa6b707403a43ea8ac4a285114951cf29059 (patch)
treeb99a41fb9e38e5032a2987b495039e20cb30eeff
parent91ad310687ae37339db3dd5d51d47db87f2cf749 (diff)
timer callback interface
-rw-r--r--kc/core/pit8253.c58
-rw-r--r--kc/core/pit8253.h3
-rw-r--r--kc/core/timer.h11
3 files changed, 69 insertions, 3 deletions
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 <stdatomic.h>
@@ -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);
};