diff options
author | Marvin Borner | 2021-07-01 21:13:01 +0200 |
---|---|---|
committer | Marvin Borner | 2021-07-01 22:32:16 +0200 |
commit | f3e85eedc434da973267f360abdbb79cb6f24100 (patch) | |
tree | 9fd71ec70454474a0a2cff479c7d9b949e779c74 /kernel/drivers | |
parent | 340e841772eb13d9087235b8707c1cfeff8710cb (diff) |
Timing is everything
Diffstat (limited to 'kernel/drivers')
-rw-r--r-- | kernel/drivers/int.c | 21 | ||||
-rw-r--r-- | kernel/drivers/pit.c | 20 | ||||
-rw-r--r-- | kernel/drivers/rtc.c | 2 | ||||
-rw-r--r-- | kernel/drivers/timer.c | 76 |
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); -} |