diff options
| author | Miguel <m.i@gmx.at> | 2018-08-21 19:42:33 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-08-21 19:42:33 +0200 |
| commit | 72c6e9763ca61bc9d7de5f7080ee1c8a1c7c1562 (patch) | |
| tree | 839bce03c26e96f1137d4b4d3550ad3e909d351c /driver | |
| parent | 6c926175afbf1f9ec2715fb007acc28588b36c4a (diff) | |
cleaning up a bit
Diffstat (limited to 'driver')
| -rw-r--r-- | driver/keyboard.c | 4 | ||||
| -rw-r--r-- | driver/mouse.c | 2 | ||||
| -rw-r--r-- | driver/pci.h | 1 | ||||
| -rw-r--r-- | driver/timer.c | 167 | ||||
| -rw-r--r-- | driver/timer.h | 50 |
5 files changed, 220 insertions, 4 deletions
diff --git a/driver/keyboard.c b/driver/keyboard.c index 52e6454..9377515 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -2,9 +2,9 @@ // http://www.computer-engineering.org/ps2keyboard/scancodes1.html #define FOOLOS_MODULE_NAME "keyboard" -#include <stdbool.h> #include "asm/x86.h" -#include "lib/logger/log.h" + +#include <stdbool.h> static bool ctrl_l=false; static bool shift_l=false; diff --git a/driver/mouse.c b/driver/mouse.c index f585b99..28acf53 100644 --- a/driver/mouse.c +++ b/driver/mouse.c @@ -4,7 +4,6 @@ //based on Mouse.inc by SANiK //License: Use as you wish, except to cause damage -#include "lib/logger/log.h" #include <stdint.h> #include "asm/x86.h" @@ -94,7 +93,6 @@ void mouse_init() mouse_write(0xF4); mouse_read(); //Acknowledge - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Mouse Initialized"); } void mouse_log() diff --git a/driver/pci.h b/driver/pci.h new file mode 100644 index 0000000..f02c5c7 --- /dev/null +++ b/driver/pci.h @@ -0,0 +1 @@ +//stub diff --git a/driver/timer.c b/driver/timer.c new file mode 100644 index 0000000..2d4c7ff --- /dev/null +++ b/driver/timer.c @@ -0,0 +1,167 @@ +#define FOOLOS_MODULE_NAME "timer" +#include "timer.h" + +#include "asm/x86.h" + +static volatile uint64_t task_system_clock_start=0; + +// CMOS RTC + +// read real time clock register +static unsigned char get_rtc_reg(int reg) { + x86_outb(0x70, reg); //cmos at addr 0x70 + return x86_inb(0x71); //cmos data at addr 0x71 +} + +// check if cmos rtc update in progress +static int get_rtc_update_flag() { + x86_outb(0x70, 0x0A); + return (x86_inb(0x71) & 0x80); +} + +// get real time clock rom cmos (seconds since jan) +static uint64_t get_rtc_time() +{ + int CURRENT_YEAR = 2018; // Change this each year! + + int century_register = 0x00; // Set by ACPI table parsing code if possible + + unsigned char second; + unsigned char minute; + unsigned char hour; + unsigned char day; + unsigned char month; + unsigned int year; + + unsigned char century; + unsigned char last_second; + unsigned char last_minute; + unsigned char last_hour; + unsigned char last_day; + unsigned char last_month; + unsigned char last_year; + unsigned char last_century; + unsigned char registerB; + + // Note: This uses the "read registers until you get the same values twice in a row" technique + // to avoid getting dodgy/inconsistent values due to RTC updates + + while (get_rtc_update_flag()); // Make sure an update isn't in progress + second = get_rtc_reg(0x00); + minute = get_rtc_reg(0x02); + hour = get_rtc_reg(0x04); + day = get_rtc_reg(0x07); + month = get_rtc_reg(0x08); + year = get_rtc_reg(0x09); + + if(century_register != 0) { + century = get_rtc_reg(century_register); + } + + do { + last_second = second; + last_minute = minute; + last_hour = hour; + last_day = day; + last_month = month; + last_year = year; + last_century = century; + + while (get_rtc_update_flag()); // Make sure an update isn't in progress + second = get_rtc_reg(0x00); + minute = get_rtc_reg(0x02); + hour = get_rtc_reg(0x04); + day = get_rtc_reg(0x07); + month = get_rtc_reg(0x08); + year = get_rtc_reg(0x09); + if(century_register != 0) { + century = get_rtc_reg(century_register); + } + } while( (last_second != second) || (last_minute != minute) || (last_hour != hour) || + (last_day != day) || (last_month != month) || (last_year != year) || + (last_century != century) ); + + registerB = get_rtc_reg(0x0B); + + // Convert BCD to binary values if necessary + if (!(registerB & 0x04)) { + second = (second & 0x0F) + ((second / 16) * 10); + minute = (minute & 0x0F) + ((minute / 16) * 10); + hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80); + day = (day & 0x0F) + ((day / 16) * 10); + month = (month & 0x0F) + ((month / 16) * 10); + year = (year & 0x0F) + ((year / 16) * 10); + if(century_register != 0) { + century = (century & 0x0F) + ((century / 16) * 10); + } + } + + // Convert 12 hour clock to 24 hour clock if necessary + if (!(registerB & 0x02) && (hour & 0x80)) { + hour = ((hour & 0x7F) + 12) % 24; + } + + // Calculate the full (4-digit) year + if(century_register != 0) { + year += century * 100; + } else { + year += (CURRENT_YEAR / 100) * 100; + if(year < CURRENT_YEAR) year += 100; + } + + // thank you doug16k @ #osdev + // https://github.com/doug65536/dgos/blob/eab7080e69360493381669e7ce0ff27587d3127a/kernel/lib/time.cc + int days[] = { + 31, + (year-1900) % 4 ? 28 : + (year-1900) % 100 ? 29 : + (year-1900) % 400 ? 28 : + 29, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31 + }; + + int yday = 0; + for (int m = 1; m < month; ++m) + yday += days[m-1]; + yday += day - 1; + + uint64_t epoch_seconds= ((uint64_t)(second)) + + minute * 60 + + hour * 3600 + + (yday) * 86400 + + (year-1900 - 70) * 365 * 86400 + + ((year-1900 - 69) / 4) * 86400 - + ((year-1900 - 1) / 100) * 86400 + + ((year-1900 + 299) / 400) * 86400; + + return epoch_seconds; +} + + +// PIT +uint64_t timer_init() +{ + uint64_t epoch_time=get_rtc_time(); + task_system_clock_start=epoch_time*25; // since pit ticks 25times a second + pit_init(); + return epoch_time; +} + +uint64_t timer_get_ms() +{ + return (pit_get_ticks()+task_system_clock_start)*40; +} + +uint64_t timer_get_uptime_ms() +{ + return pit_get_ticks()*40; +} diff --git a/driver/timer.h b/driver/timer.h new file mode 100644 index 0000000..1e3d066 --- /dev/null +++ b/driver/timer.h @@ -0,0 +1,50 @@ + +/** + * @file + * References + * ---------- + * * http://www.brokenthorn.com/Resources/OSDevPit.html + * * https://wiki.osdev.org/CMOS + + + vcc/gnd - voltage/ground + + D0-D7 - data lines (data bus) + wr/rd - writing / reading (system control bus) + cs - ignore wr/rd or not (address bus) + a0-a1 (address bus) + + // the three 16bit down counters/timers/channels + clk 0-2 (in) + gate 0-2 (in) + out 0-2 (out) + + //typical + out1 -> pic interrupt on every tick (system timer) + out2 - was used for genearting dram memory refresh (Do not use) + out3 -> pc speaker + + gate pins : depend on mode of operation + we do have modes 0-5. + mode0: counts down to zero , triggers interrupt and waits + mode1: + mode2: rate generator (sys timer) + .... + */ + +#include <stdint.h> + +/** + * Initilize time and PIT (trigger 25 times a second). + * Returns the number of seconds passed since 1970. + */ +uint64_t timer_init(); + +/** get number of ticks since boot */ +uint64_t timer_get_ticks(); + +/** get number of milliseconds since boot */ +uint64_t timer_get_uptime_ms(); + +/** get number of milliseconds since 1970 */ +uint64_t timer_get_ms(); |
