diff --git a/src/Cargo.toml b/src/Cargo.toml index 8d4ed281d..94cf5d4f9 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -11,6 +11,7 @@ component = { path = "services/comp-sys/component" } [dev-dependencies] x86_64 = "0.14.2" +jinux-time = { path = "services/comps/time" } [workspace] @@ -23,6 +24,7 @@ members = [ "services/comps/virtio", "services/comps/input", "services/comps/block", + "services/comps/time", "services/libs/jinux-std", "services/libs/jinux-rights-proc", "services/libs/typeflags", @@ -32,4 +34,3 @@ members = [ ] exclude = ["services/comp-sys/controlled", "services/comp-sys/cargo-component"] - diff --git a/src/Components.toml b/src/Components.toml index 312b03114..1f40a2be3 100644 --- a/src/Components.toml +++ b/src/Components.toml @@ -2,9 +2,10 @@ [components] std = { name = "jinux-std" } pci = { name = "jinux-pci" } -virtio = { name = "jinux-virtio"} -input = { name = "jinux-input"} -block = { name = "jinux-block"} +virtio = { name = "jinux-virtio" } +input = { name = "jinux-input" } +block = { name = "jinux-block" } +time = { name = "jinux-time" } main = { name = "jinux" } [whitelist] diff --git a/src/framework/jinux-frame/src/device/cmos.rs b/src/framework/jinux-frame/src/device/cmos.rs new file mode 100644 index 000000000..02ec84ce7 --- /dev/null +++ b/src/framework/jinux-frame/src/device/cmos.rs @@ -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 = unsafe { IoPort::new(0x70) }; +pub static CMOS_DATA: IoPort = unsafe { IoPort::new(0x71) }; + +pub fn get_century() -> u8 { + unsafe { + let a = ACPI_TABLES + .get() + .unwrap() + .lock() + .get_sdt::(Signature::FADT) + .unwrap() + .expect("not found FACP in ACPI table"); + a.century + } +} diff --git a/src/framework/jinux-frame/src/device/mod.rs b/src/framework/jinux-frame/src/device/mod.rs index 289c57613..04f161e5b 100644 --- a/src/framework/jinux-frame/src/device/mod.rs +++ b/src/framework/jinux-frame/src/device/mod.rs @@ -1,5 +1,6 @@ //! Device-related APIs. +pub mod cmos; pub mod framebuffer; pub mod io_port; pub mod pci; diff --git a/src/framework/jinux-frame/src/driver/acpi.rs b/src/framework/jinux-frame/src/driver/acpi.rs index b2a1cb87d..47bcdeede 100644 --- a/src/framework/jinux-frame/src/driver/acpi.rs +++ b/src/framework/jinux-frame/src/driver/acpi.rs @@ -2,17 +2,12 @@ use core::ptr::NonNull; use crate::{config, vm::paddr_to_vaddr}; use acpi::{AcpiHandler, AcpiTables}; -use lazy_static::lazy_static; use limine::LimineRsdpRequest; 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 - pub(crate) static ref ACPI_TABLES : Mutex> = unsafe{ - Mutex::new(core::mem::MaybeUninit::zeroed().assume_init()) - }; -} +/// RSDP information, key is the signature, value is the virtual address of the signature +pub static ACPI_TABLES: Once>> = Once::new(); #[derive(Debug, Clone)] pub struct AcpiMemoryHandler {} @@ -43,12 +38,13 @@ pub fn init() { .get() .expect("Need RSDP address"); 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() }; - let lock = ACPI_TABLES.lock(); - for (signature, sdt) in lock.sdts.iter() { + for (signature, sdt) in acpi_tables.sdts.iter() { info!("ACPI found signature:{:?}", signature); } + ACPI_TABLES.call_once(|| Mutex::new(acpi_tables)); + info!("acpi init complete"); } diff --git a/src/framework/jinux-frame/src/driver/ioapic.rs b/src/framework/jinux-frame/src/driver/ioapic.rs index d2de6ea0c..052906d44 100644 --- a/src/framework/jinux-frame/src/driver/ioapic.rs +++ b/src/framework/jinux-frame/src/driver/ioapic.rs @@ -43,7 +43,7 @@ unsafe impl Sync for IoApicWrapper {} pub(crate) static IO_APIC: Once> = Once::new(); pub fn init() { - let c = ACPI_TABLES.lock(); + let c = ACPI_TABLES.get().unwrap().lock(); let platform_info = PlatformInfo::new(&*c).unwrap(); diff --git a/src/framework/jinux-frame/src/driver/mod.rs b/src/framework/jinux-frame/src/driver/mod.rs index 58099cdcf..48bc7d411 100644 --- a/src/framework/jinux-frame/src/driver/mod.rs +++ b/src/framework/jinux-frame/src/driver/mod.rs @@ -1,19 +1,19 @@ //! Driver for APIC, PIC, PIT etc. -//! This module should inaccessible by other crate such as std, virtio etc. //! mod acpi; mod ioapic; mod pic; -pub(crate) mod rtc; mod timer; mod xapic; pub(crate) use self::pic::ack as pic_ack; pub(crate) use self::pic::allocate_irq as pic_allocate_irq; pub(crate) use self::xapic::ack as xapic_ack; -use log::info; pub(crate) use timer::{add_timeout_list, TimerCallback, TICK}; +pub(crate) use self::acpi::ACPI_TABLES; + +use log::info; pub(crate) fn init() { acpi::init(); @@ -28,5 +28,4 @@ pub(crate) fn init() { } timer::init(); pic::init(); - rtc::init(); } diff --git a/src/framework/jinux-frame/src/driver/timer/hpet.rs b/src/framework/jinux-frame/src/driver/timer/hpet.rs index 8b1b1da44..299e797a3 100644 --- a/src/framework/jinux-frame/src/driver/timer/hpet.rs +++ b/src/framework/jinux-frame/src/driver/timer/hpet.rs @@ -105,9 +105,9 @@ impl Hpet { /// HPET init, need to init IOAPIC before init this function 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 let hpet = Hpet::new(hpet_info.base_address); diff --git a/src/framework/jinux-frame/src/lib.rs b/src/framework/jinux-frame/src/lib.rs index 4b7241216..2263c9f9f 100644 --- a/src/framework/jinux-frame/src/lib.rs +++ b/src/framework/jinux-frame/src/lib.rs @@ -25,7 +25,6 @@ pub mod logger; pub mod prelude; pub mod sync; pub mod task; -pub mod time; pub mod timer; pub mod trap; pub mod user; diff --git a/src/services/comps/time/Cargo.toml b/src/services/comps/time/Cargo.toml new file mode 100644 index 000000000..24cc2b9d0 --- /dev/null +++ b/src/services/comps/time/Cargo.toml @@ -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] diff --git a/src/framework/jinux-frame/src/time.rs b/src/services/comps/time/src/lib.rs similarity index 78% rename from src/framework/jinux-frame/src/time.rs rename to src/services/comps/time/src/lib.rs index 1188fc7ce..3cf2f9b02 100644 --- a/src/framework/jinux-frame/src/time.rs +++ b/src/services/comps/time/src/lib.rs @@ -1,8 +1,21 @@ -use crate::driver::rtc::{get_cmos, is_updating, read, CENTURY_REGISTER}; -use core::sync::atomic::Ordering::Relaxed; +//! The frambuffer of jinux +#![no_std] +#![forbid(unsafe_code)] -#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)] -pub struct Time { +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, @@ -12,7 +25,19 @@ pub struct Time { 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) { while is_updating() {} self.second = get_cmos(0x00); @@ -67,6 +92,6 @@ impl Time { } /// get real time -pub fn get_real_time() -> Time { +pub fn get_real_time() -> SystemTime { read() } diff --git a/src/framework/jinux-frame/src/driver/rtc.rs b/src/services/comps/time/src/rtc.rs similarity index 56% rename from src/framework/jinux-frame/src/driver/rtc.rs rename to src/services/comps/time/src/rtc.rs index f591d02da..a9ddff3a1 100644 --- a/src/framework/jinux-frame/src/driver/rtc.rs +++ b/src/services/comps/time/src/rtc.rs @@ -1,33 +1,18 @@ use core::sync::atomic::AtomicU8; use core::sync::atomic::Ordering::Relaxed; -use acpi::{fadt::Fadt, sdt::Signature}; use spin::Mutex; -use crate::device::io_port::{IoPort, ReadOnlyAccess, WriteOnlyAccess}; -use crate::time::Time; +use crate::SystemTime; -use super::acpi::ACPI_TABLES; - -static CMOS_ADDRESS: IoPort = unsafe { IoPort::new(0x70) }; -static CMOS_DATA: IoPort = unsafe { IoPort::new(0x71) }; +use jinux_frame::device::cmos::{get_century, CMOS_ADDRESS, CMOS_DATA}; pub(crate) static CENTURY_REGISTER: AtomicU8 = AtomicU8::new(0); -lazy_static::lazy_static! { - static ref READ_TIME: Mutex