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]
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"]

View File

@ -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]

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.
pub mod cmos;
pub mod framebuffer;
pub mod io_port;
pub mod pci;

View File

@ -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())
};
}
/// RSDP information, key is the signature, value is the virtual address of the signature
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");
}

View File

@ -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();

View File

@ -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();
}

View File

@ -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);

View File

@ -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;

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};
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()
}

View File

@ -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();

View File

@ -6,16 +6,17 @@ 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"}
pod = {path = "../../../framework/pod"}
jinux-input = {path="../../comps/input"}
jinux-block = {path="../../comps/block"}
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"}
jinux-rights-proc = {path="../jinux-rights-proc"}
jinux-util = {path="../jinux-util"}
cpio-decoder = {path="../cpio-decoder"}
typeflags = { path = "../typeflags" }
typeflags-util = { path = "../typeflags-util" }
jinux-rights-proc = { path = "../jinux-rights-proc" }
jinux-util = { path = "../jinux-util" }
cpio-decoder = { path = "../cpio-decoder" }
virtio-input-decoder = "0.1.4"
ascii = { version = "1.1", default-features = false, features = ["alloc"] }
intrusive-collections = "0.9.5"
@ -31,7 +32,7 @@ ringbuffer = "0.10.0"
spin = "0.9.4"
vte = "0.10"
lru = "0.9.0"
log= "0.4"
log = "0.4"
[dependencies.lazy_static]
version = "1.0"

View File

@ -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"),

View File

@ -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 {

View File

@ -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());
}

View File

@ -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));