summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimapr <kimapr@mail.ru>2023-12-20 14:51:37 +0500
committerLizzy Fleckenstein <lizzy@vlhl.dev>2023-12-21 22:54:34 +0100
commit2834bff2cf6131202a788b59a5fd81994e1ed5aa (patch)
tree9a1ace6488e16d15af474cd027f2387c91ebbc12
parent43a856b5d40ceb570af7755d9f1222093a48aa64 (diff)
downloadcuddles-2834bff2cf6131202a788b59a5fd81994e1ed5aa.tar.xz
rtc clock driver
-rw-r--r--Makefile1
-rw-r--r--stage3/clock.c34
-rw-r--r--stage3/clock.h18
-rw-r--r--stage3/interrupts.c37
-rw-r--r--stage3/main.c4
-rw-r--r--stage3/shell.c47
6 files changed, 112 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index ea2f5bf..a98b181 100644
--- a/Makefile
+++ b/Makefile
@@ -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)