Extract RTC out of framework

This commit is contained in:
Yuke Peng
2023-03-25 02:16:37 -07:00
committed by Tate, Hongliang Tian
parent b02b29dde7
commit bed56703de
17 changed files with 110 additions and 68 deletions

View File

@ -11,6 +11,7 @@ component = { path = "services/comp-sys/component" }
[dev-dependencies] [dev-dependencies]
x86_64 = "0.14.2" x86_64 = "0.14.2"
jinux-time = { path = "services/comps/time" }
[workspace] [workspace]
@ -23,6 +24,7 @@ members = [
"services/comps/virtio", "services/comps/virtio",
"services/comps/input", "services/comps/input",
"services/comps/block", "services/comps/block",
"services/comps/time",
"services/libs/jinux-std", "services/libs/jinux-std",
"services/libs/jinux-rights-proc", "services/libs/jinux-rights-proc",
"services/libs/typeflags", "services/libs/typeflags",
@ -32,4 +34,3 @@ members = [
] ]
exclude = ["services/comp-sys/controlled", "services/comp-sys/cargo-component"] exclude = ["services/comp-sys/controlled", "services/comp-sys/cargo-component"]

View File

@ -5,6 +5,7 @@ pci = { name = "jinux-pci" }
virtio = { name = "jinux-virtio" } virtio = { name = "jinux-virtio" }
input = { name = "jinux-input" } input = { name = "jinux-input" }
block = { name = "jinux-block" } block = { name = "jinux-block" }
time = { name = "jinux-time" }
main = { name = "jinux" } main = { name = "jinux" }
[whitelist] [whitelist]

View File

@ -0,0 +1,22 @@
use acpi::{fadt::Fadt, sdt::Signature};
use x86_64::instructions::port::{ReadOnlyAccess, WriteOnlyAccess};
use crate::driver::ACPI_TABLES;
use super::io_port::IoPort;
pub static CMOS_ADDRESS: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x70) };
pub static CMOS_DATA: IoPort<u8, ReadOnlyAccess> = unsafe { IoPort::new(0x71) };
pub fn get_century() -> u8 {
unsafe {
let a = ACPI_TABLES
.get()
.unwrap()
.lock()
.get_sdt::<Fadt>(Signature::FADT)
.unwrap()
.expect("not found FACP in ACPI table");
a.century
}
}

View File

@ -1,5 +1,6 @@
//! Device-related APIs. //! Device-related APIs.
pub mod cmos;
pub mod framebuffer; pub mod framebuffer;
pub mod io_port; pub mod io_port;
pub mod pci; pub mod pci;

View File

@ -2,17 +2,12 @@ use core::ptr::NonNull;
use crate::{config, vm::paddr_to_vaddr}; use crate::{config, vm::paddr_to_vaddr};
use acpi::{AcpiHandler, AcpiTables}; use acpi::{AcpiHandler, AcpiTables};
use lazy_static::lazy_static;
use limine::LimineRsdpRequest; use limine::LimineRsdpRequest;
use log::info; use log::info;
use spin::Mutex; use spin::{Mutex, Once};
lazy_static! {
/// RSDP information, key is the signature, value is the virtual address of the signature /// RSDP information, key is the signature, value is the virtual address of the signature
pub(crate) static ref ACPI_TABLES : Mutex<AcpiTables<AcpiMemoryHandler>> = unsafe{ pub static ACPI_TABLES: Once<Mutex<AcpiTables<AcpiMemoryHandler>>> = Once::new();
Mutex::new(core::mem::MaybeUninit::zeroed().assume_init())
};
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct AcpiMemoryHandler {} pub struct AcpiMemoryHandler {}
@ -43,12 +38,13 @@ pub fn init() {
.get() .get()
.expect("Need RSDP address"); .expect("Need RSDP address");
let rsdp = response.address.as_ptr().unwrap().addr() - config::PHYS_OFFSET; let rsdp = response.address.as_ptr().unwrap().addr() - config::PHYS_OFFSET;
*ACPI_TABLES.lock() = let acpi_tables =
unsafe { AcpiTables::from_rsdp(AcpiMemoryHandler {}, rsdp as usize).unwrap() }; unsafe { AcpiTables::from_rsdp(AcpiMemoryHandler {}, rsdp as usize).unwrap() };
let lock = ACPI_TABLES.lock(); for (signature, sdt) in acpi_tables.sdts.iter() {
for (signature, sdt) in lock.sdts.iter() {
info!("ACPI found signature:{:?}", signature); info!("ACPI found signature:{:?}", signature);
} }
ACPI_TABLES.call_once(|| Mutex::new(acpi_tables));
info!("acpi init complete"); info!("acpi init complete");
} }

View File

@ -43,7 +43,7 @@ unsafe impl Sync for IoApicWrapper {}
pub(crate) static IO_APIC: Once<Mutex<IoApicWrapper>> = Once::new(); pub(crate) static IO_APIC: Once<Mutex<IoApicWrapper>> = Once::new();
pub fn init() { pub fn init() {
let c = ACPI_TABLES.lock(); let c = ACPI_TABLES.get().unwrap().lock();
let platform_info = PlatformInfo::new(&*c).unwrap(); let platform_info = PlatformInfo::new(&*c).unwrap();

View File

@ -1,19 +1,19 @@
//! Driver for APIC, PIC, PIT etc. //! Driver for APIC, PIC, PIT etc.
//! This module should inaccessible by other crate such as std, virtio etc.
//! //!
mod acpi; mod acpi;
mod ioapic; mod ioapic;
mod pic; mod pic;
pub(crate) mod rtc;
mod timer; mod timer;
mod xapic; mod xapic;
pub(crate) use self::pic::ack as pic_ack; pub(crate) use self::pic::ack as pic_ack;
pub(crate) use self::pic::allocate_irq as pic_allocate_irq; pub(crate) use self::pic::allocate_irq as pic_allocate_irq;
pub(crate) use self::xapic::ack as xapic_ack; pub(crate) use self::xapic::ack as xapic_ack;
use log::info;
pub(crate) use timer::{add_timeout_list, TimerCallback, TICK}; pub(crate) use timer::{add_timeout_list, TimerCallback, TICK};
pub(crate) use self::acpi::ACPI_TABLES;
use log::info;
pub(crate) fn init() { pub(crate) fn init() {
acpi::init(); acpi::init();
@ -28,5 +28,4 @@ pub(crate) fn init() {
} }
timer::init(); timer::init();
pic::init(); pic::init();
rtc::init();
} }

View File

@ -105,9 +105,9 @@ impl Hpet {
/// HPET init, need to init IOAPIC before init this function /// HPET init, need to init IOAPIC before init this function
pub fn init() -> Result<(), AcpiError> { pub fn init() -> Result<(), AcpiError> {
let c = ACPI_TABLES.lock(); let lock = ACPI_TABLES.get().unwrap().lock();
let hpet_info = HpetInfo::new(&*c)?; let hpet_info = HpetInfo::new(&*lock)?;
// config IO APIC entry // config IO APIC entry
let hpet = Hpet::new(hpet_info.base_address); let hpet = Hpet::new(hpet_info.base_address);

View File

@ -25,7 +25,6 @@ pub mod logger;
pub mod prelude; pub mod prelude;
pub mod sync; pub mod sync;
pub mod task; pub mod task;
pub mod time;
pub mod timer; pub mod timer;
pub mod trap; pub mod trap;
pub mod user; pub mod user;

View File

@ -0,0 +1,14 @@
[package]
name = "jinux-time"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
jinux-frame = { path = "../../../framework/jinux-frame" }
component = { path = "../../comp-sys/component" }
log = "0.4"
spin = "0.9.4"
[features]

View File

@ -1,8 +1,21 @@
use crate::driver::rtc::{get_cmos, is_updating, read, CENTURY_REGISTER}; //! The frambuffer of jinux
use core::sync::atomic::Ordering::Relaxed; #![no_std]
#![forbid(unsafe_code)]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)] use component::{init_component, ComponentInitError};
pub struct Time { 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, century: u8,
pub year: u16, pub year: u16,
pub month: u8, pub month: u8,
@ -12,7 +25,19 @@ pub struct Time {
pub second: u8, pub second: u8,
} }
impl Time { 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) { pub(crate) fn update_from_rtc(&mut self) {
while is_updating() {} while is_updating() {}
self.second = get_cmos(0x00); self.second = get_cmos(0x00);
@ -67,6 +92,6 @@ impl Time {
} }
/// get real time /// get real time
pub fn get_real_time() -> Time { pub fn get_real_time() -> SystemTime {
read() read()
} }

View File

@ -1,33 +1,18 @@
use core::sync::atomic::AtomicU8; use core::sync::atomic::AtomicU8;
use core::sync::atomic::Ordering::Relaxed; use core::sync::atomic::Ordering::Relaxed;
use acpi::{fadt::Fadt, sdt::Signature};
use spin::Mutex; use spin::Mutex;
use crate::device::io_port::{IoPort, ReadOnlyAccess, WriteOnlyAccess}; use crate::SystemTime;
use crate::time::Time;
use super::acpi::ACPI_TABLES; use jinux_frame::device::cmos::{get_century, CMOS_ADDRESS, CMOS_DATA};
static CMOS_ADDRESS: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x70) };
static CMOS_DATA: IoPort<u8, ReadOnlyAccess> = unsafe { IoPort::new(0x71) };
pub(crate) static CENTURY_REGISTER: AtomicU8 = AtomicU8::new(0); pub(crate) static CENTURY_REGISTER: AtomicU8 = AtomicU8::new(0);
lazy_static::lazy_static! { static READ_TIME: Mutex<SystemTime> = Mutex::new(SystemTime::zero());
static ref READ_TIME: Mutex<Time> = Mutex::new(Time::default());
}
pub fn init() { pub fn init() {
let c = ACPI_TABLES.lock(); CENTURY_REGISTER.store(get_century(), Relaxed);
let r_century = unsafe {
let a = c
.get_sdt::<Fadt>(Signature::FADT)
.unwrap()
.expect("not found FACP in ACPI table");
a.century
};
CENTURY_REGISTER.store(r_century, Relaxed);
} }
pub fn get_cmos(reg: u8) -> u8 { pub fn get_cmos(reg: u8) -> u8 {
@ -40,7 +25,7 @@ pub fn is_updating() -> bool {
CMOS_DATA.read() & 0x80 != 0 CMOS_DATA.read() & 0x80 != 0
} }
pub fn read() -> Time { pub fn read() -> SystemTime {
update_time(); update_time();
READ_TIME.lock().clone() READ_TIME.lock().clone()
} }
@ -48,7 +33,7 @@ pub fn read() -> Time {
/// read year,month,day and other data /// read year,month,day and other data
/// ref: https://wiki.osdev.org/CMOS#Reading_All_RTC_Time_and_Date_Registers /// ref: https://wiki.osdev.org/CMOS#Reading_All_RTC_Time_and_Date_Registers
fn update_time() { fn update_time() {
let mut last_time: Time; let mut last_time: SystemTime;
let register_b: u8; let register_b: u8;
let mut lock = READ_TIME.lock(); let mut lock = READ_TIME.lock();

View File

@ -10,6 +10,7 @@ jinux-frame = {path = "../../../framework/jinux-frame"}
pod = { path = "../../../framework/pod" } pod = { path = "../../../framework/pod" }
jinux-input = { path = "../../comps/input" } jinux-input = { path = "../../comps/input" }
jinux-block = { path = "../../comps/block" } jinux-block = { path = "../../comps/block" }
jinux-time = { path = "../../comps/time" }
controlled = { path = "../../comp-sys/controlled" } controlled = { path = "../../comp-sys/controlled" }
typeflags = { path = "../typeflags" } typeflags = { path = "../typeflags" }
typeflags-util = { path = "../typeflags-util" } typeflags-util = { path = "../typeflags-util" }

View File

@ -1,7 +1,6 @@
use core::time::Duration; use core::time::Duration;
use crate::prelude::*; use crate::prelude::*;
use jinux_frame::time::get_real_time;
use time::{Date, Month, PrimitiveDateTime, Time}; use time::{Date, Month, PrimitiveDateTime, Time};
/// This struct corresponds to `SystemTime` in Rust std. /// This struct corresponds to `SystemTime` in Rust std.
@ -21,7 +20,7 @@ impl SystemTime {
/// Returns the current system time /// Returns the current system time
pub fn now() -> Self { pub fn now() -> Self {
let system_time = get_real_time(); let system_time = jinux_time::get_real_time();
// The get real time result should always be valid // The get real time result should always be valid
convert_system_time(system_time).unwrap() convert_system_time(system_time).unwrap()
} }
@ -60,7 +59,7 @@ impl SystemTime {
} }
/// convert jinux_frame::time::Time to System time /// convert jinux_frame::time::Time to System time
fn convert_system_time(system_time: jinux_frame::time::Time) -> Result<SystemTime> { fn convert_system_time(system_time: jinux_time::SystemTime) -> Result<SystemTime> {
let month = match Month::try_from(system_time.month) { let month = match Month::try_from(system_time.month) {
Ok(month) => month, Ok(month) => month,
Err(_) => return_errno_with_message!(Errno::EINVAL, "unknown month in system time"), Err(_) => return_errno_with_message!(Errno::EINVAL, "unknown month in system time"),

View File

@ -23,7 +23,7 @@ fn panic(info: &PanicInfo) -> ! {
#[test_case] #[test_case]
fn test_input() { fn test_input() {
jinux_frame::enable_interrupts(); x86_64::instructions::interrupts::enable();
println!("please input value into console to pass this test"); println!("please input value into console to pass this test");
jinux_std::driver::tty::register_serial_input_callback(input_callback); jinux_std::driver::tty::register_serial_input_callback(input_callback);
unsafe { unsafe {

View File

@ -7,11 +7,10 @@ extern crate alloc;
use core::panic::PanicInfo; use core::panic::PanicInfo;
use jinux_frame::println; use jinux_frame::println;
static mut INPUT_VALUE: u8 = 0;
#[no_mangle] #[no_mangle]
pub extern "C" fn _start() -> ! { pub extern "C" fn _start() -> ! {
jinux_frame::init(); jinux_frame::init();
component::init_all(component::parse_metadata!()).unwrap();
test_main(); test_main();
loop {} loop {}
} }
@ -23,5 +22,5 @@ fn panic(info: &PanicInfo) -> ! {
#[test_case] #[test_case]
fn test_rtc() { fn test_rtc() {
println!("real time:{:?}", jinux_frame::time::get_real_time()); println!("real time:{:?}", jinux_time::get_real_time());
} }

View File

@ -26,7 +26,7 @@ fn panic(info: &PanicInfo) -> ! {
#[test_case] #[test_case]
fn test_timer() { fn test_timer() {
jinux_frame::enable_interrupts(); x86_64::instructions::interrupts::enable();
unsafe { unsafe {
let timer = Timer::new(timer_callback).unwrap(); let timer = Timer::new(timer_callback).unwrap();
timer.set(Duration::from_secs(1)); timer.set(Duration::from_secs(1));