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]
|
[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"]
|
||||||
|
|
||||||
|
@ -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]
|
||||||
|
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.
|
//! 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;
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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();
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
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};
|
//! 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()
|
||||||
}
|
}
|
@ -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();
|
@ -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" }
|
||||||
|
@ -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"),
|
||||||
|
@ -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 {
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
Reference in New Issue
Block a user