Tue, 02 Jan 2024 19:51:25 +0100
5 files changed,
73 insertions(+),
11 deletions(-)
M
kernel/main.c
→
kernel/main.c
@@ -2,6 +2,7 @@ #include "drivers/console.h"
#include "drivers/keyboard.h" #include "drivers/graphics.h" +#include "time.h" #include "sched/sched.h" #include "sched/process.h"@@ -61,6 +62,10 @@ printk("done.\n");
printk("Installing syscalls..."); syscall_init(); + printk("done.\n"); + + printk("Initializing RTC..."); + time_init(); printk("done.\n"); printk("Initializing scheduler...");
M
kernel/sched/sched.h
→
kernel/sched/sched.h
@@ -11,7 +11,7 @@
#include "mm/paging.h" // 11928 ~ 10ms per interval -#define SCHED_INTERVAL (1193) +#define SCHED_INTERVAL (11928) /*! * Structure of the process stack when the scheduler is executed.
M
kernel/sched/sched.s
→
kernel/sched/sched.s
@@ -16,7 +16,6 @@ // pass process stack as arguments
push %ebx push %eax xor %eax, %eax - call time_tick call sched_interrupt_c pop %eax pop %ebx
M
kernel/time.c
→
kernel/time.c
@@ -1,5 +1,8 @@
#include "time.h" #include "assembly.h" +#include "interrupts.h" +#include "pic.h" +#include "core.h" #define RTC_COMMAND 0x70 #define RTC_DATA 0x71@@ -9,6 +12,7 @@
#define RTC_REGISTER_A 0x0A #define RTC_REGISTER_B 0x0B #define RTC_REGISTER_C 0x0C +#define RTC_REGISTER_D 0x0D #define RTC_GET_SECONDS 0x00 #define RTC_GET_MINUTES 0x02@@ -17,6 +21,11 @@
#define RTC_GET_DAY 0x07 #define RTC_GET_MONTH 0x08 #define RTC_GET_YEAR 0x09 + +#define RTC_DISABLE_NMI 0x80 +#define RTC_ENABLE_NMI 0x00 + +#define RTC_ENABLE_INT8 0x40 int ticks = 0;@@ -30,22 +39,65 @@ }
static uint8_t rtc_get(uint8_t reg) { outb(reg, RTC_COMMAND); + /*nop(); nop(); nop(); + nop();*/ + uint8_t res = inb(RTC_DATA); + return res; +} + +static uint8_t from_BCD(uint8_t bcd_value) { + return (bcd_value >> 4) * 10 + (bcd_value & 0x0F); +} + +static uint8_t rtc_set(uint8_t reg, uint8_t value) { + outb(reg, RTC_COMMAND); + /*nop(); nop(); nop(); - uint8_t res = inb(RTC_DATA); - return (res >> 4) * 10 + (res & 0x0F); + nop();*/ + outb(value, RTC_DATA); } int time_now(datetime_t *buffer) { - buffer->year = 2000 + rtc_get(RTC_GET_YEAR); - buffer->month = rtc_get(RTC_GET_MONTH); - buffer->day = rtc_get(RTC_GET_DAY); + buffer->year = 2000 + from_BCD(rtc_get(RTC_GET_YEAR)); + buffer->month = from_BCD(rtc_get(RTC_GET_MONTH)); + buffer->day = from_BCD(rtc_get(RTC_GET_DAY)); - buffer->hour = rtc_get(RTC_GET_HOURS); - buffer->minute = rtc_get(RTC_GET_MINUTES); - buffer->second = rtc_get(RTC_GET_SECONDS); + buffer->hour = from_BCD(rtc_get(RTC_GET_HOURS)); + buffer->minute = from_BCD(rtc_get(RTC_GET_MINUTES)); + buffer->second = from_BCD(rtc_get(RTC_GET_SECONDS)); return 0; -}+} + +INTERRUPT(rtc_interrupt, frame) { + time_tick(); + + rtc_get(RTC_REGISTER_C); + + pic2_eoi(); +} + +int time_init(void) { + install_interrupt(PIC2_IRQ(0x00), rtc_interrupt, 0x18, INT_GATE); + + // disable all interrupts + cli(); + + uint8_t reg_a = rtc_get(RTC_REGISTER_A | RTC_DISABLE_NMI); + rtc_set(RTC_REGISTER_A | RTC_DISABLE_NMI, (reg_a & 0xF0) | RTC_INT_RATE); + + uint8_t reg_b = rtc_get(RTC_REGISTER_B | RTC_DISABLE_NMI); + rtc_set(RTC_REGISTER_B | RTC_DISABLE_NMI, reg_b | RTC_ENABLE_INT8); + + reg_b = rtc_get(RTC_REGISTER_B); + + rtc_get(RTC_REGISTER_C); + rtc_get(RTC_REGISTER_D); + // enable interrupts again + sti(); + + pic_unmask_interrupt(8); +}
M
kernel/time.h
→
kernel/time.h
@@ -1,6 +1,10 @@
#ifndef __TIME_H #define __TIME_H +// frequency = 32768 >> (rate-1); +// rate at least 2 (~8kHz) +#define RTC_INT_RATE 2 + typedef struct { int year; int month;@@ -10,6 +14,8 @@ int hour;
int minute; int second; } datetime_t; + +int time_init(void); void time_tick(void);