Working RTC access
This commit is contained in:
parent
4091148d2e
commit
e04489a8c3
2 changed files with 95 additions and 0 deletions
68
arch/i386/cmos.c
Normal file
68
arch/i386/cmos.c
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#include <kernel/cmos.h>
|
||||||
|
|
||||||
|
int _check_update_in_progress(void) {
|
||||||
|
unsigned char ret_val = 0;
|
||||||
|
__asm__ volatile("mov $0x0A, %%al\n\t" "outb %%al, $0x70\n\t" "inb $0x71, %%al\n\t" "mov %%al, %0":"=b" (ret_val)::"%al");
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char _get_rtc_reg(unsigned char reg) {
|
||||||
|
unsigned char ret_val = 0;
|
||||||
|
__asm__ volatile("mov %1, %%al\n\t" "outb %%al, $0x70\n\t" "inb $0x71, %%al\n\t" "mov %%al, %0":"=b" (ret_val):"c" (reg):"%al");
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long int read_rtc() {
|
||||||
|
unsigned char regb;
|
||||||
|
unsigned long int ret_val;
|
||||||
|
|
||||||
|
/* I might need to add this check back in, but it's fine for now. */
|
||||||
|
/* while(_check_update_in_progress()); */
|
||||||
|
|
||||||
|
cur_time.second = _get_rtc_reg(0x00);
|
||||||
|
cur_time.minute = _get_rtc_reg(0x02);
|
||||||
|
cur_time.hour = _get_rtc_reg(0x04);
|
||||||
|
cur_time.day = _get_rtc_reg(0x07);
|
||||||
|
cur_time.month = _get_rtc_reg(0x08);
|
||||||
|
cur_time.year = _get_rtc_reg(0x09);
|
||||||
|
|
||||||
|
regb = _get_rtc_reg(0x0B);
|
||||||
|
|
||||||
|
/* Convert bcd to binary if needed */
|
||||||
|
if(!(regb & 0x04)) {
|
||||||
|
cur_time.second = (cur_time.second & 0x0F) + ((cur_time.second / 16) * 10);
|
||||||
|
cur_time.minute = (cur_time.minute & 0x0F) + ((cur_time.minute / 16) * 10);
|
||||||
|
cur_time.hour = ((cur_time.hour & 0x0F) + (((cur_time.hour & 0x70) / 16) * 10)) | (cur_time.hour & 0x80);
|
||||||
|
cur_time.day = (cur_time.day & 0x0F) + ((cur_time.day / 16) * 10);
|
||||||
|
cur_time.month = (cur_time.month & 0x0F) + ((cur_time.month / 16) * 10);
|
||||||
|
cur_time.year = (cur_time.year & 0x0F) + ((cur_time.year / 16) * 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert to 24H time if needed */
|
||||||
|
if(!(regb & 0x02) && (cur_time.hour & 0x80)) {
|
||||||
|
cur_time.hour = ((cur_time.hour & 0x7F) + 12) % 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get year. TODO: Use century register for this. */
|
||||||
|
cur_time.year += (RELEASE_YEAR / 100) * 100; /* Add century of release year */
|
||||||
|
if(cur_time.year < RELEASE_YEAR) cur_time.year += 100;
|
||||||
|
|
||||||
|
ret_val = cur_time.second;
|
||||||
|
ret_val += cur_time.minute * 60;
|
||||||
|
ret_val += cur_time.hour * 3600;
|
||||||
|
unsigned int tot_days = cur_time.day;
|
||||||
|
unsigned char month_days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||||
|
for(unsigned int i = 1970; i < cur_time.year; i++) {
|
||||||
|
if(i % 400 == 0 || (i % 100 != 0 && i % 4 == 0)) {
|
||||||
|
tot_days += 366;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tot_days += 365;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < (cur_time.month - 1); i++) {
|
||||||
|
tot_days += month_days[i];
|
||||||
|
}
|
||||||
|
ret_val += tot_days * 86400;
|
||||||
|
return ret_val;
|
||||||
|
}
|
27
include/kernel/cmos.h
Normal file
27
include/kernel/cmos.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef _KERNEL_CMOS
|
||||||
|
#define _KERNEL_CMOS
|
||||||
|
|
||||||
|
/* This is kinda important, and has to be changed each year. */
|
||||||
|
#define RELEASE_YEAR 2020
|
||||||
|
|
||||||
|
struct _rtc_val {
|
||||||
|
unsigned char second;
|
||||||
|
unsigned char minute;
|
||||||
|
unsigned char hour;
|
||||||
|
unsigned char day;
|
||||||
|
unsigned char month;
|
||||||
|
unsigned int year;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct _rtc_val cur_time;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
cmos_address = 0x70,
|
||||||
|
cmos_data = 0x71
|
||||||
|
};
|
||||||
|
|
||||||
|
int _check_update_in_progress(void);
|
||||||
|
unsigned char _get_rtc_reg(unsigned char reg);
|
||||||
|
unsigned long int read_rtc();
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue