From 6f1b50a4cc6c232ee505a543f006abb1c6cd33cf Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Fri, 19 Feb 2021 23:41:56 -0500 Subject: rtc fixes, time command --- src/kernel/cmos.c | 18 ++++++++++---- src/kernel/cmos.h | 1 + src/kernel/main.c | 1 + src/user/include/knob/time.h | 13 ++++++++++ src/user/knob/time.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ src/user/time/time.c | 24 +++++++++++++++++++ 6 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 src/user/include/knob/time.h create mode 100644 src/user/knob/time.c create mode 100644 src/user/time/time.c (limited to 'src') diff --git a/src/kernel/cmos.c b/src/kernel/cmos.c index 39f7c4f..1a95805 100644 --- a/src/kernel/cmos.c +++ b/src/kernel/cmos.c @@ -3,9 +3,22 @@ static inline uint8_t read_cmos(uint8_t reg) { outb(0x0070, reg); + for (uint32_t i = 0; i < 1000000; ++i) + ;//spin return inb(0x0071); } +static inline void write_cmos(uint8_t reg, uint8_t value) { + outb(0x0070, reg); + for (uint32_t i = 0; i < 1000000; ++i) + ;//spin + outb(0x0071, value); +} + +void cmos_init() { + write_cmos(0x0b, read_cmos(0x0b) | 0x06); +} + //The idea of reading until you get the same value twice, and checking the status register // is from the OSDev Wiki page at . struct rtc_time get_rtc_time() { @@ -21,11 +34,6 @@ get_sec: } ret.minutes = read_cmos(0x02); ret.hours = read_cmos(0x04); - if (ret.hours & 0x80) { - ret.hours -= 0x80 - 12; - if (ret.hours == 24) - ret.hours = 0; - } ret.day_of_week = read_cmos(0x06); ret.day_of_month = read_cmos(0x07); ret.month = read_cmos(0x08); diff --git a/src/kernel/cmos.h b/src/kernel/cmos.h index 53ec398..515de1d 100644 --- a/src/kernel/cmos.h +++ b/src/kernel/cmos.h @@ -14,5 +14,6 @@ struct rtc_time { }; struct rtc_time get_rtc_time(); +void cmos_init(); #endif \ No newline at end of file diff --git a/src/kernel/main.c b/src/kernel/main.c index 7e49049..36b5fc1 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -23,6 +23,7 @@ void _start_user_mode() __attribute__ ((noreturn)); __attribute__ ((noreturn)) void main() { + cmos_init(); init_pagemap(); init_paging(); init_tasks(); diff --git a/src/user/include/knob/time.h b/src/user/include/knob/time.h new file mode 100644 index 0000000..4b84697 --- /dev/null +++ b/src/user/include/knob/time.h @@ -0,0 +1,13 @@ +#include + +struct time { + uint16_t year;//ad + uint8_t month;//jan = 1 + uint8_t day; + uint8_t hour;//24-hour, midnight = 0 + uint8_t minute; + uint8_t second; + uint32_t timestamp; +}; + +struct time get_time(); \ No newline at end of file diff --git a/src/user/knob/time.c b/src/user/knob/time.c new file mode 100644 index 0000000..e3bbb08 --- /dev/null +++ b/src/user/knob/time.c @@ -0,0 +1,57 @@ +#include +#include +#include + +uint8_t days_in_months[] = { + 31, 0, 31, 30, + 31, 30, 31, 31, + 30, 31, 30, 31 +}; + +struct time get_time() { + struct time t; + + const uint32_t ts = _get_timestamp(); + t.timestamp = ts; + + const uint32_t time_part = ts % 86400; + t.hour = time_part / 3600; + t.minute = (time_part / 60) % 60; + t.second = time_part % 60; + + uint32_t days = ts / 86400; + + uint32_t year = 2000; + while (days >= 1461) { + year += 4; + days -= 1461; + } + + days_in_months[1] = 28; + if (days >= 1096) { + t.year = year += 3; + days -= 1096; + } + else if (days >= 731) { + t.year = year += 2; + days -= 731; + } + else if (days >= 366) { + t.year = ++year; + days -= 366; + } + else { + t.year = year; + days_in_months[1] = 29; + } + + uint8_t m = 0; + while (days >= days_in_months[m]) { + days -= days_in_months[m]; + ++m; + } + + t.month = m + 1; + t.day = days + 1; + return t; +} \ No newline at end of file diff --git a/src/user/time/time.c b/src/user/time/time.c new file mode 100644 index 0000000..49f6cf5 --- /dev/null +++ b/src/user/time/time.c @@ -0,0 +1,24 @@ +#include +#include + +static const char *const month_names[] = { + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" +}; + +void main() { + const struct time t = get_time(); + term_addf("TS: 0x%8h\n", t.timestamp); + term_addf("Date: %s %u, %u\n", month_names[t.month - 1], t.day, t.year); + term_addf("Time: %u:%2u:%2u\n", t.hour, t.minute, t.second); +} \ No newline at end of file -- cgit v1.2.3