Reorganize the codebase

This commit is contained in:
Jianfeng Jiang
2023-04-09 23:12:42 -04:00
committed by Tate, Hongliang Tian
parent 888853a6de
commit 271a16d492
416 changed files with 67 additions and 53 deletions

View File

@ -0,0 +1,97 @@
//! The system time of jinux
#![no_std]
#![forbid(unsafe_code)]
use component::{init_component, ComponentInitError};
use core::sync::atomic::Ordering::Relaxed;
use rtc::{get_cmos, is_updating, read, CENTURY_REGISTER};
mod rtc;
#[init_component]
fn time_init() -> Result<(), ComponentInitError> {
rtc::init();
Ok(())
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct SystemTime {
century: u8,
pub year: u16,
pub month: u8,
pub day: u8,
pub hour: u8,
pub minute: u8,
pub second: u8,
}
impl SystemTime {
pub(crate) const fn zero() -> Self {
Self {
century: 0,
year: 0,
month: 0,
day: 0,
hour: 0,
minute: 0,
second: 0,
}
}
pub(crate) fn update_from_rtc(&mut self) {
while is_updating() {}
self.second = get_cmos(0x00);
self.minute = get_cmos(0x02);
self.hour = get_cmos(0x04);
self.day = get_cmos(0x07);
self.month = get_cmos(0x08);
self.year = get_cmos(0x09) as u16;
let century_register = CENTURY_REGISTER.load(Relaxed);
if century_register != 0 {
self.century = get_cmos(century_register);
}
}
/// convert BCD to binary values
/// ref:https://wiki.osdev.org/CMOS#Reading_All_RTC_Time_and_Date_Registers
pub(crate) fn convert_bcd_to_binary(&mut self, register_b: u8) {
if register_b & 0x04 == 0 {
let century_register = CENTURY_REGISTER.load(Relaxed);
self.second = (self.second & 0x0F) + ((self.second / 16) * 10);
self.minute = (self.minute & 0x0F) + ((self.minute / 16) * 10);
self.hour =
((self.hour & 0x0F) + (((self.hour & 0x70) / 16) * 10)) | (self.hour & 0x80);
self.day = (self.day & 0x0F) + ((self.day / 16) * 10);
self.month = (self.month & 0x0F) + ((self.month / 16) * 10);
self.year = (self.year & 0x0F) + ((self.year / 16) * 10);
if century_register != 0 {
self.century = (self.century & 0x0F) + ((self.century / 16) * 10);
}
}
}
/// convert 12 hour clock to 24 hour clock
pub(crate) fn convert_12_hour_to_24_hour(&mut self, register_b: u8) {
// bit1 in register_b is not set if 12 hour format is enable
// if highest bit in hour is set, then it is pm
if ((register_b & 0x02) == 0) && ((self.hour & 0x80) != 0) {
self.hour = ((self.hour & 0x7F) + 12) % 24;
}
}
/// convert raw year (10, 20 etc.) to real year (2010, 2020 etc.)
pub(crate) fn modify_year(&mut self) {
let century_register = CENTURY_REGISTER.load(Relaxed);
if century_register != 0 {
self.year += self.century as u16 * 100;
} else {
panic!("century register not exists");
}
}
}
/// get real time
pub fn get_real_time() -> SystemTime {
read()
}

View File

@ -0,0 +1,58 @@
use core::sync::atomic::AtomicU8;
use core::sync::atomic::Ordering::Relaxed;
use spin::Mutex;
use crate::SystemTime;
use jinux_frame::arch::x86::device::cmos::{get_century, CMOS_ADDRESS, CMOS_DATA};
pub(crate) static CENTURY_REGISTER: AtomicU8 = AtomicU8::new(0);
static READ_TIME: Mutex<SystemTime> = Mutex::new(SystemTime::zero());
pub fn init() {
CENTURY_REGISTER.store(get_century(), Relaxed);
}
pub fn get_cmos(reg: u8) -> u8 {
CMOS_ADDRESS.write(reg);
CMOS_DATA.read()
}
pub fn is_updating() -> bool {
CMOS_ADDRESS.write(0x0A);
CMOS_DATA.read() & 0x80 != 0
}
pub fn read() -> SystemTime {
update_time();
READ_TIME.lock().clone()
}
/// read year,month,day and other data
/// ref: https://wiki.osdev.org/CMOS#Reading_All_RTC_Time_and_Date_Registers
fn update_time() {
let mut last_time: SystemTime;
let register_b: u8;
let mut lock = READ_TIME.lock();
lock.update_from_rtc();
last_time = lock.clone();
lock.update_from_rtc();
while *lock != last_time {
last_time = lock.clone();
lock.update_from_rtc();
}
register_b = get_cmos(0x0B);
lock.convert_bcd_to_binary(register_b);
lock.convert_12_hour_to_24_hour(register_b);
lock.modify_year();
}