aboutsummaryrefslogtreecommitdiff
path: root/kernel/drivers
diff options
context:
space:
mode:
authorMarvin Borner2021-07-01 21:13:01 +0200
committerMarvin Borner2021-07-01 22:32:16 +0200
commitf3e85eedc434da973267f360abdbb79cb6f24100 (patch)
tree9fd71ec70454474a0a2cff479c7d9b949e779c74 /kernel/drivers
parent340e841772eb13d9087235b8707c1cfeff8710cb (diff)
Timing is everything
Diffstat (limited to 'kernel/drivers')
-rw-r--r--kernel/drivers/int.c21
-rw-r--r--kernel/drivers/pit.c20
-rw-r--r--kernel/drivers/rtc.c2
-rw-r--r--kernel/drivers/timer.c76
4 files changed, 38 insertions, 81 deletions
diff --git a/kernel/drivers/int.c b/kernel/drivers/int.c
index f6a5134..d5f0a67 100644
--- a/kernel/drivers/int.c
+++ b/kernel/drivers/int.c
@@ -172,19 +172,32 @@ static u32 int_special_handler(struct int_frame *frame)
* Universal handler
*/
+static u8 int_enabled = 1;
+
u32 int_handler(u32 esp);
u32 int_handler(u32 esp)
{
struct int_frame *frame = (struct int_frame *)esp;
- if (frame->int_no < 32)
+ if (frame->int_no < 32) {
int_trap_handler(frame);
- else if (frame->int_no < 48)
+ } else if (int_enabled && frame->int_no < 48) {
esp = int_event_handler(frame);
- else if (frame->int_no >= 128 && frame->int_no < 144)
+ } else if (frame->int_no >= 128 && frame->int_no < 144) {
esp = int_special_handler(frame);
- else
+ } else if (frame->int_no >= 48) {
panic("Unknown interrupt: %d\n", frame->int_no);
+ }
pic_ack(frame->int_no);
return esp;
}
+
+void int_disable(void)
+{
+ int_enabled = 0;
+}
+
+void int_enable(void)
+{
+ int_enabled = 1;
+}
diff --git a/kernel/drivers/pit.c b/kernel/drivers/pit.c
new file mode 100644
index 0000000..abba5e8
--- /dev/null
+++ b/kernel/drivers/pit.c
@@ -0,0 +1,20 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#include <def.h>
+#include <drivers/cpu.h>
+#include <drivers/pit.h>
+#include <timer.h>
+
+CLEAR static void pit_phase(u32 hz)
+{
+ u32 divisor = 3579545 / 3 / hz;
+ outb(0x43, 0x36); // 01 10 11 0b // CTR, RW, MODE, BCD
+ outb(0x40, (u8)(divisor & 0xFF));
+ outb(0x40, (u8)(divisor >> 8));
+}
+
+CLEAR void pit_install(void)
+{
+ pit_phase(1000);
+ timer_install_handler();
+}
diff --git a/kernel/drivers/rtc.c b/kernel/drivers/rtc.c
index b67829e..0a9a3fd 100644
--- a/kernel/drivers/rtc.c
+++ b/kernel/drivers/rtc.c
@@ -3,10 +3,10 @@
#include <def.h>
#include <drivers/cpu.h>
#include <drivers/rtc.h>
-#include <drivers/timer.h>
#include <fs.h>
#include <mem.h>
#include <str.h>
+#include <timer.h>
static u8 rtc_busy(void)
{
diff --git a/kernel/drivers/timer.c b/kernel/drivers/timer.c
deleted file mode 100644
index 977647c..0000000
--- a/kernel/drivers/timer.c
+++ /dev/null
@@ -1,76 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#include <def.h>
-#include <dev.h>
-#include <drivers/cpu.h>
-#include <drivers/int.h>
-#include <drivers/rtc.h>
-#include <drivers/timer.h>
-#include <mem.h>
-#include <proc.h>
-
-static u32 timer_ticks = 0;
-
-CLEAR static void timer_phase(int hz)
-{
- int divisor = 3579545 / 3 / hz;
- outb(0x43, 0x36); // 01 10 11 0b // CTR, RW, MODE, BCD
- outb(0x40, (u8)(divisor & 0xFF));
- outb(0x40, (u8)(divisor >> 8));
-}
-
-u32 timer_get(void)
-{
- return timer_ticks;
-}
-
-static void timer_handler(void)
-{
- if (timer_ticks >= U32_MAX)
- timer_ticks = 0;
- else
- timer_ticks++;
-}
-
-// "Delay" function with CPU sleep
-void timer_wait(u32 ticks)
-{
- u32 eticks = timer_ticks + ticks;
- while (timer_ticks < eticks)
- __asm__ volatile("sti\nhlt\ncli");
-}
-
-static struct timer timer_struct(void)
-{
- struct proc *proc = proc_current();
- struct timer timer = {
- .rtc = rtc_stamp(),
- .ticks.user = proc->ticks.user,
- .ticks.kernel = proc->ticks.kernel,
- .time = timer_get(),
- };
- return timer;
-}
-
-static res timer_read(void *buf, u32 offset, u32 count)
-{
- UNUSED(offset);
-
- struct timer timer = timer_struct();
- memcpy_user(buf, &timer, MIN(count, sizeof(timer)));
-
- return MIN(count, sizeof(timer));
-}
-
-// Install timer handler into IRQ0
-CLEAR void timer_install(void)
-{
- /* hpet_install(10000); // TODO: Find optimal femtosecond period */
- /* if (!hpet) */
- timer_phase(1000);
- int_event_handler_add(0, timer_handler);
-
- struct dev_dev *dev = zalloc(sizeof(*dev));
- dev->read = timer_read;
- dev_add(DEV_TIMER, dev);
-}