diff options
author | Kimapr <kimapr@mail.ru> | 2023-12-20 14:51:37 +0500 |
---|---|---|
committer | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2023-12-21 22:54:34 +0100 |
commit | 2834bff2cf6131202a788b59a5fd81994e1ed5aa (patch) | |
tree | 9a1ace6488e16d15af474cd027f2387c91ebbc12 | |
parent | 43a856b5d40ceb570af7755d9f1222093a48aa64 (diff) | |
download | cuddles-2834bff2cf6131202a788b59a5fd81994e1ed5aa.tar.xz |
rtc clock driver
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | stage3/clock.c | 34 | ||||
-rw-r--r-- | stage3/clock.h | 18 | ||||
-rw-r--r-- | stage3/interrupts.c | 37 | ||||
-rw-r--r-- | stage3/main.c | 4 | ||||
-rw-r--r-- | stage3/shell.c | 47 |
6 files changed, 112 insertions, 29 deletions
@@ -18,6 +18,7 @@ STAGE3_C = \ stage3/halt.o \ stage3/interrupts.o \ stage3/pic.o \ + stage3/clock.o \ stage3/memory.o \ stage3/heap.o \ stage3/font.o \ diff --git a/stage3/clock.c b/stage3/clock.c new file mode 100644 index 0000000..372d3da --- /dev/null +++ b/stage3/clock.c @@ -0,0 +1,34 @@ +#include "clock.h" +#include "pic.h" +#include "font.h" +#include "io.h" +#include "thread.h" +#include "heap.h" +#include "halt.h" + +u64 monoclock_rtc_time = 0; + +void clock_init() +{ + outb(0x70, 0x8B); + char prev = inb(0x71); + outb(0x70, 0x8B); + outb(0x71, prev | 0x40); + unmask_irq(8); +} + +u64 clock_monotonic_coarse() { + return monoclock_rtc_time; +} + +u64 clock_monotonic() +{ + return monoclock_rtc_time; // TODO: high resolution clock +} + +u64 clock_cycles() +{ + u64 lo,hi; + asm volatile("rdtsc\n\t": "=a" (lo), "=d" (hi)); + return lo | hi << 32; +} diff --git a/stage3/clock.h b/stage3/clock.h new file mode 100644 index 0000000..f0255bc --- /dev/null +++ b/stage3/clock.h @@ -0,0 +1,18 @@ +#ifndef CLOCK_H +#define CLOCK_H + +#include "def.h" + +#define NANOSECONDS 1000000000 +#define RTC_FREQ 1024 +#define RTC_RATE NANOSECONDS/RTC_FREQ + +extern u64 monoclock_rtc_time; + +void clock_init(); + +u64 clock_cycles(); +u64 clock_monotonic_coarse(); +u64 clock_monotonic(); + +#endif diff --git a/stage3/interrupts.c b/stage3/interrupts.c index 0a2dd6f..4d311a5 100644 --- a/stage3/interrupts.c +++ b/stage3/interrupts.c @@ -1,3 +1,4 @@ +#include "clock.h" #include "def.h" #include "halt.h" #include "font.h" @@ -195,25 +196,33 @@ void interrupt_handler(interrupt_frame *frame) dump_frame(frame); freeze(); } else if (frame->which-32 < 16) { - if (queue_write.len == queue_write.cap) { - panic(S("queue exceeded\n")); - /* - // TODO: malloc would cause a race condition - queue_write.cap = queue_write.cap == 0 ? 1 : queue_write.cap * 2; - queue_write.data = realloc(queue_write.data, queue_write.cap); - */ - } + u64 irq = frame->which-32; - event *e = &queue_write.data[queue_write.len++]; - e->irq = frame->which-32; + if (irq == 8) { + outb(0x70, 0x0C); + inb(0x71); + monoclock_rtc_time += RTC_RATE; + } else { + if (queue_write.len == queue_write.cap) { + panic(S("queue exceeded\n")); + /* + // TODO: malloc would cause a race condition + queue_write.cap = queue_write.cap == 0 ? 1 : queue_write.cap * 2; + queue_write.data = realloc(queue_write.data, queue_write.cap); + */ + } - if (e->irq == 1) { - e->data.scancode = inb(IO_PS2_DATA); + event *e = &queue_write.data[queue_write.len++]; + e->irq = irq; + + if (e->irq == 1) { + e->data.scancode = inb(IO_PS2_DATA); + } } - ack_irq(e->irq); + ack_irq(irq); } else { - // print("Spurious Interrupt "); print_num(frame->which, 10, 0); print("\n"); + // print(S("Spurious Interrupt ")); print_num(frame->which, 10); print(S("\n")); // dump_frame(frame); } } diff --git a/stage3/main.c b/stage3/main.c index a03dc5d..a30c3b9 100644 --- a/stage3/main.c +++ b/stage3/main.c @@ -14,6 +14,7 @@ #include "shell.h" #include "fs.h" #include "gfx.h" +#include "clock.h" char keymap[256] = { '\0' }; @@ -142,6 +143,9 @@ void kmain() irq_services[1] = keyboard_thread; unmask_irq(1); + unmask_irq(2); + clock_init(); + thread_resume(nil, keyboard_thread); enable_irqs(); thread_sched(nil, nil); diff --git a/stage3/shell.c b/stage3/shell.c index 5b79e58..825723b 100644 --- a/stage3/shell.c +++ b/stage3/shell.c @@ -8,6 +8,9 @@ #include "memory.h" #include "io.h" #include "math.h" +#include "clock.h" +#include "pic.h" +#include "thread.h" static void cmd_echo(str arg) { @@ -301,27 +304,41 @@ static void cmd_watchdog(str arg) print(S("\n")); } +static void cmd_clocktest(str arg) +{ + (void) arg; + while(1) { + print_num(clock_monotonic(), 10); + print(S(" ")); + print_num(clock_monotonic_coarse(), 10); + //wait_irq(); + yield(nil); + print(S("\r")); + } +} + typedef struct { str name; void (*fn)(str arg); } command; static command registry[] = { - { S("echo"), &cmd_echo }, - { S("cat"), &cmd_cat }, - { S("font"), &cmd_font }, - { S("fontdemo"), &cmd_fontdemo }, - { S("img"), &cmd_img }, - { S("lspci"), &cmd_lspci }, - { S("run"), &cmd_run }, - { S("loadkeys"), &cmd_loadkeys }, - { S("clear"), &cmd_clear }, - { S("love"), &cmd_love }, - { S("uname"), &cmd_uname }, - { S("ls"), &cmd_ls }, - { S("shutdown"), &cmd_shutdown }, - { S("cheese"), &cmd_cheese }, - { S("watchdog"), &cmd_watchdog }, + { S("echo"), &cmd_echo }, + { S("cat"), &cmd_cat }, + { S("font"), &cmd_font }, + { S("fontdemo"), &cmd_fontdemo }, + { S("img"), &cmd_img }, + { S("lspci"), &cmd_lspci }, + { S("run"), &cmd_run }, + { S("loadkeys"), &cmd_loadkeys }, + { S("clear"), &cmd_clear }, + { S("love"), &cmd_love }, + { S("uname"), &cmd_uname }, + { S("ls"), &cmd_ls }, + { S("shutdown"), &cmd_shutdown }, + { S("cheese"), &cmd_cheese }, + { S("watchdog"), &cmd_watchdog }, + { S("clocktest"), &cmd_clocktest }, }; void shell_run_cmd(str cmd) |