mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-28 03:43:23 +00:00
Extract RTC out of framework
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
b02b29dde7
commit
bed56703de
@ -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"]
|
||||
|
||||
|
@ -5,6 +5,7 @@ pci = { name = "jinux-pci" }
|
||||
virtio = { name = "jinux-virtio" }
|
||||
input = { name = "jinux-input" }
|
||||
block = { name = "jinux-block" }
|
||||
time = { name = "jinux-time" }
|
||||
main = { name = "jinux" }
|
||||
|
||||
[whitelist]
|
||||
|
22
src/framework/jinux-frame/src/device/cmos.rs
Normal file
22
src/framework/jinux-frame/src/device/cmos.rs
Normal 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
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
//! Device-related APIs.
|
||||
|
||||
pub mod cmos;
|
||||
pub mod framebuffer;
|
||||
pub mod io_port;
|
||||
pub mod pci;
|
||||
|
@ -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<AcpiTables<AcpiMemoryHandler>> = unsafe{
|
||||
Mutex::new(core::mem::MaybeUninit::zeroed().assume_init())
|
||||
};
|
||||
}
|
||||
pub static ACPI_TABLES: Once<Mutex<AcpiTables<AcpiMemoryHandler>>> = 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");
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ unsafe impl Sync for IoApicWrapper {}
|
||||
pub(crate) static IO_APIC: Once<Mutex<IoApicWrapper>> = Once::new();
|
||||
|
||||
pub fn init() {
|
||||
let c = ACPI_TABLES.lock();
|
||||
let c = ACPI_TABLES.get().unwrap().lock();
|
||||
|
||||
let platform_info = PlatformInfo::new(&*c).unwrap();
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
14
src/services/comps/time/Cargo.toml
Normal file
14
src/services/comps/time/Cargo.toml
Normal 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]
|
@ -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()
|
||||
}
|
@ -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<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x70) };
|
||||
static CMOS_DATA: IoPort<u8, ReadOnlyAccess> = 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<Time> = Mutex::new(Time::default());
|
||||
}
|
||||
static READ_TIME: Mutex<SystemTime> = Mutex::new(SystemTime::zero());
|
||||
|
||||
pub fn init() {
|
||||
let c = ACPI_TABLES.lock();
|
||||
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);
|
||||
CENTURY_REGISTER.store(get_century(), Relaxed);
|
||||
}
|
||||
|
||||
pub fn get_cmos(reg: u8) -> u8 {
|
||||
@ -40,7 +25,7 @@ pub fn is_updating() -> bool {
|
||||
CMOS_DATA.read() & 0x80 != 0
|
||||
}
|
||||
|
||||
pub fn read() -> Time {
|
||||
pub fn read() -> SystemTime {
|
||||
update_time();
|
||||
READ_TIME.lock().clone()
|
||||
}
|
||||
@ -48,7 +33,7 @@ pub fn read() -> Time {
|
||||
/// 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: Time;
|
||||
let mut last_time: SystemTime;
|
||||
|
||||
let register_b: u8;
|
||||
let mut lock = READ_TIME.lock();
|
@ -10,6 +10,7 @@ jinux-frame = {path = "../../../framework/jinux-frame"}
|
||||
pod = { path = "../../../framework/pod" }
|
||||
jinux-input = { path = "../../comps/input" }
|
||||
jinux-block = { path = "../../comps/block" }
|
||||
jinux-time = { path = "../../comps/time" }
|
||||
controlled = { path = "../../comp-sys/controlled" }
|
||||
typeflags = { path = "../typeflags" }
|
||||
typeflags-util = { path = "../typeflags-util" }
|
||||
|
@ -1,7 +1,6 @@
|
||||
use core::time::Duration;
|
||||
|
||||
use crate::prelude::*;
|
||||
use jinux_frame::time::get_real_time;
|
||||
use time::{Date, Month, PrimitiveDateTime, Time};
|
||||
|
||||
/// This struct corresponds to `SystemTime` in Rust std.
|
||||
@ -21,7 +20,7 @@ impl SystemTime {
|
||||
|
||||
/// Returns the current system time
|
||||
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
|
||||
convert_system_time(system_time).unwrap()
|
||||
}
|
||||
@ -60,7 +59,7 @@ impl SystemTime {
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
Ok(month) => month,
|
||||
Err(_) => return_errno_with_message!(Errno::EINVAL, "unknown month in system time"),
|
||||
|
@ -23,7 +23,7 @@ fn panic(info: &PanicInfo) -> ! {
|
||||
|
||||
#[test_case]
|
||||
fn test_input() {
|
||||
jinux_frame::enable_interrupts();
|
||||
x86_64::instructions::interrupts::enable();
|
||||
println!("please input value into console to pass this test");
|
||||
jinux_std::driver::tty::register_serial_input_callback(input_callback);
|
||||
unsafe {
|
||||
|
@ -7,11 +7,10 @@ extern crate alloc;
|
||||
use core::panic::PanicInfo;
|
||||
use jinux_frame::println;
|
||||
|
||||
static mut INPUT_VALUE: u8 = 0;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _start() -> ! {
|
||||
jinux_frame::init();
|
||||
component::init_all(component::parse_metadata!()).unwrap();
|
||||
test_main();
|
||||
loop {}
|
||||
}
|
||||
@ -23,5 +22,5 @@ fn panic(info: &PanicInfo) -> ! {
|
||||
|
||||
#[test_case]
|
||||
fn test_rtc() {
|
||||
println!("real time:{:?}", jinux_frame::time::get_real_time());
|
||||
println!("real time:{:?}", jinux_time::get_real_time());
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ fn panic(info: &PanicInfo) -> ! {
|
||||
|
||||
#[test_case]
|
||||
fn test_timer() {
|
||||
jinux_frame::enable_interrupts();
|
||||
x86_64::instructions::interrupts::enable();
|
||||
unsafe {
|
||||
let timer = Timer::new(timer_callback).unwrap();
|
||||
timer.set(Duration::from_secs(1));
|
||||
|
Reference in New Issue
Block a user