parent
1a1e39c960
commit
c6c89198cd
@ -0,0 +1,78 @@
|
||||
//! Driver for x86 CMOS RTC clock
|
||||
use crate::arch::interrupt;
|
||||
use log::*;
|
||||
use x86_64::instructions::port::Port;
|
||||
|
||||
const CMOS_ADDR: u16 = 0x70;
|
||||
const CMOS_DATA: u16 = 0x71;
|
||||
|
||||
unsafe fn check_updating() -> bool {
|
||||
let mut addr = Port::<u8>::new(CMOS_ADDR);
|
||||
let data = Port::<u8>::new(CMOS_DATA);
|
||||
|
||||
addr.write(0x0A);
|
||||
return (data.read() & 0x80) != 0;
|
||||
}
|
||||
|
||||
unsafe fn read_rtc(reg: u8) -> u8 {
|
||||
let mut addr = Port::<u8>::new(CMOS_ADDR);
|
||||
let data = Port::<u8>::new(CMOS_DATA);
|
||||
|
||||
addr.write(reg);
|
||||
return data.read();
|
||||
}
|
||||
|
||||
fn bcd2bin(num: u64) -> u64 {
|
||||
(num & 0x0f) + (num >> 4) * 10
|
||||
}
|
||||
|
||||
// read seconds since 1970-01-01
|
||||
pub fn read_epoch() -> u64 {
|
||||
unsafe {
|
||||
let flags = interrupt::disable_and_store();
|
||||
|
||||
while check_updating() {}
|
||||
|
||||
let mut second = read_rtc(0x00) as u64;
|
||||
let mut minute = read_rtc(0x02) as u64;
|
||||
let mut hour = read_rtc(0x04) as u64;
|
||||
let mut day = read_rtc(0x07) as u64;
|
||||
let mut month = read_rtc(0x08) as u64;
|
||||
let mut year = read_rtc(0x09) as u64;
|
||||
|
||||
let control = read_rtc(0x0B);
|
||||
if (control & 0x04) == 0 {
|
||||
// BCD
|
||||
second = bcd2bin(second);
|
||||
minute = bcd2bin(minute);
|
||||
hour = bcd2bin(hour);
|
||||
day = bcd2bin(day);
|
||||
month = bcd2bin(month);
|
||||
year = bcd2bin(year);
|
||||
}
|
||||
|
||||
// TODO: parse ACPI and find century register
|
||||
year += 2000;
|
||||
|
||||
// mktime64
|
||||
if month <= 2 {
|
||||
month = month + 10;
|
||||
year = year - 1;
|
||||
} else {
|
||||
month = month - 2;
|
||||
}
|
||||
|
||||
let result = ((((year / 4 - year / 100 + year / 400 + 367 * month / 12 + day) + year * 365
|
||||
- 719499)
|
||||
* 24
|
||||
+ hour)
|
||||
* 60
|
||||
+ minute)
|
||||
* 60
|
||||
+ second;
|
||||
|
||||
interrupt::restore(flags);
|
||||
|
||||
result
|
||||
}
|
||||
}
|
Loading…
Reference in new issue