diff --git a/src/arch/aarch64/mod.rs b/src/arch/aarch64/mod.rs index 1fd628951295cc3303b2fbffce1a9426ab6e58bb..0f353b390b2859e11c9e651d4c941c656db9365e 100644 --- a/src/arch/aarch64/mod.rs +++ b/src/arch/aarch64/mod.rs @@ -33,4 +33,6 @@ pub mod vectors; /// Early init support pub mod init; +pub mod time; + pub use ::rmm::AArch64Arch as CurrentRmmArch; diff --git a/src/arch/aarch64/time.rs b/src/arch/aarch64/time.rs new file mode 100644 index 0000000000000000000000000000000000000000..60809b40df4ad0ac6c280c03c095197c4f3fe9e4 --- /dev/null +++ b/src/arch/aarch64/time.rs @@ -0,0 +1,4 @@ +pub fn counter() -> u128 { + //TODO: aarch64 generic timer counter + 0 +} diff --git a/src/arch/x86/device/hpet.rs b/src/arch/x86/device/hpet.rs index 1ab3ce9fc6e5048a35463644fc8e7b62992bf1f8..40d7d4e03a23e52c9726343fea9e5d37971449a4 100644 --- a/src/arch/x86/device/hpet.rs +++ b/src/arch/x86/device/hpet.rs @@ -1,22 +1,22 @@ use crate::acpi::hpet::Hpet; -static LEG_RT_CNF: u64 = 2; -static ENABLE_CNF: u64 = 1; - -static TN_VAL_SET_CNF: u64 = 0x40; -static TN_TYPE_CNF: u64 = 0x08; -static TN_INT_ENB_CNF: u64 = 0x04; - -static CAPABILITY_OFFSET: usize = 0x00; -static GENERAL_CONFIG_OFFSET: usize = 0x10; -static GENERAL_INTERRUPT_OFFSET: usize = 0x20; -static MAIN_COUNTER_OFFSET: usize = 0xF0; -// static NUM_TIMER_CAP_MASK: u64 = 0x0f00; -static LEG_RT_CAP: u64 = 0x8000; -static T0_CONFIG_CAPABILITY_OFFSET: usize = 0x100; -static T0_COMPARATOR_OFFSET: usize = 0x108; - -static PER_INT_CAP: u64 = 0x10; +const LEG_RT_CNF: u64 = 2; +const ENABLE_CNF: u64 = 1; + +const TN_VAL_SET_CNF: u64 = 0x40; +const TN_TYPE_CNF: u64 = 0x08; +const TN_INT_ENB_CNF: u64 = 0x04; + +pub(crate) const CAPABILITY_OFFSET: usize = 0x00; +const GENERAL_CONFIG_OFFSET: usize = 0x10; +const GENERAL_INTERRUPT_OFFSET: usize = 0x20; +pub(crate) const MAIN_COUNTER_OFFSET: usize = 0xF0; +// const NUM_TIMER_CAP_MASK: u64 = 0x0f00; +const LEG_RT_CAP: u64 = 0x8000; +const T0_CONFIG_CAPABILITY_OFFSET: usize = 0x100; +const T0_COMPARATOR_OFFSET: usize = 0x108; + +const PER_INT_CAP: u64 = 0x10; pub unsafe fn init(hpet: &mut Hpet) -> bool { println!("HPET Before Init"); diff --git a/src/arch/x86/device/pit.rs b/src/arch/x86/device/pit.rs index 7c96be162914d7e7d53041a8e0730d12e0bc61f5..fdf54a14b239c8008cff4a82301d6693e81ddb87 100644 --- a/src/arch/x86/device/pit.rs +++ b/src/arch/x86/device/pit.rs @@ -5,20 +5,24 @@ pub static mut CHAN1: Pio<u8> = Pio::new(0x41); pub static mut CHAN2: Pio<u8> = Pio::new(0x42); pub static mut COMMAND: Pio<u8> = Pio::new(0x43); -static SELECT_CHAN0: u8 = 0; -static LOHI: u8 = 0x30; +const SELECT_CHAN0: u8 = 0b00 << 6; +const ACCESS_LATCH: u8 = 0b00 << 4; +const ACCESS_LOHI: u8 = 0b11 << 4; +const MODE_2: u8 = 0b010 << 1; -static CHAN0_DIVISOR: u16 = 2685; +const CHAN0_DIVISOR: u16 = 2685; pub unsafe fn init() { - COMMAND.write(SELECT_CHAN0 | LOHI | 5); - CHAN0.write((CHAN0_DIVISOR & 0xFF) as u8); + COMMAND.write(SELECT_CHAN0 | ACCESS_LOHI | MODE_2); + CHAN0.write(CHAN0_DIVISOR as u8); CHAN0.write((CHAN0_DIVISOR >> 8) as u8); } pub unsafe fn read() -> u16 { - COMMAND.write(SELECT_CHAN0 | 0); + COMMAND.write(SELECT_CHAN0 | ACCESS_LATCH); let low = CHAN0.read(); let high = CHAN0.read(); - ((high as u16) << 8) | (low as u16) + let counter = ((high as u16) << 8) | (low as u16); + // Counter is inverted, subtract from CHAN0_DIVISOR + CHAN0_DIVISOR.saturating_sub(counter) } diff --git a/src/arch/x86/mod.rs b/src/arch/x86/mod.rs index df27301e91be13a0ab5080403ae29b93e0cd1292..4c294ef1b33e4c1fffae8b93a0b3e05658b40cec 100644 --- a/src/arch/x86/mod.rs +++ b/src/arch/x86/mod.rs @@ -40,6 +40,8 @@ pub mod start; /// Stop function pub mod stop; +pub mod time; + pub use ::rmm::X86Arch as CurrentRmmArch; // Flags diff --git a/src/arch/x86/time.rs b/src/arch/x86/time.rs new file mode 100644 index 0000000000000000000000000000000000000000..ca1fa5ee838507687eb1cbfa7536bf89a7e79d05 --- /dev/null +++ b/src/arch/x86/time.rs @@ -0,0 +1,16 @@ +use crate::acpi::ACPI_TABLE; +use super::device::{hpet, pit}; + +pub fn counter() -> u128 { + if let Some(ref hpet) = *ACPI_TABLE.hpet.read() { + let capability = unsafe { hpet.base_address.read_u64(hpet::CAPABILITY_OFFSET) }; + let period_fs = (capability >> 32) as u128; + let counter = unsafe { hpet.base_address.read_u64(hpet::MAIN_COUNTER_OFFSET) }; + (counter as u128 * period_fs) / 1_000_000 + } else { + // 1.193182 MHz PIT is approximately 838.095 nanoseconds + let period_ns = 838; + let counter = unsafe { pit::read() }; + counter as u128 * period_ns + } +} diff --git a/src/arch/x86_64/device/hpet.rs b/src/arch/x86_64/device/hpet.rs index 1ab3ce9fc6e5048a35463644fc8e7b62992bf1f8..40d7d4e03a23e52c9726343fea9e5d37971449a4 100644 --- a/src/arch/x86_64/device/hpet.rs +++ b/src/arch/x86_64/device/hpet.rs @@ -1,22 +1,22 @@ use crate::acpi::hpet::Hpet; -static LEG_RT_CNF: u64 = 2; -static ENABLE_CNF: u64 = 1; - -static TN_VAL_SET_CNF: u64 = 0x40; -static TN_TYPE_CNF: u64 = 0x08; -static TN_INT_ENB_CNF: u64 = 0x04; - -static CAPABILITY_OFFSET: usize = 0x00; -static GENERAL_CONFIG_OFFSET: usize = 0x10; -static GENERAL_INTERRUPT_OFFSET: usize = 0x20; -static MAIN_COUNTER_OFFSET: usize = 0xF0; -// static NUM_TIMER_CAP_MASK: u64 = 0x0f00; -static LEG_RT_CAP: u64 = 0x8000; -static T0_CONFIG_CAPABILITY_OFFSET: usize = 0x100; -static T0_COMPARATOR_OFFSET: usize = 0x108; - -static PER_INT_CAP: u64 = 0x10; +const LEG_RT_CNF: u64 = 2; +const ENABLE_CNF: u64 = 1; + +const TN_VAL_SET_CNF: u64 = 0x40; +const TN_TYPE_CNF: u64 = 0x08; +const TN_INT_ENB_CNF: u64 = 0x04; + +pub(crate) const CAPABILITY_OFFSET: usize = 0x00; +const GENERAL_CONFIG_OFFSET: usize = 0x10; +const GENERAL_INTERRUPT_OFFSET: usize = 0x20; +pub(crate) const MAIN_COUNTER_OFFSET: usize = 0xF0; +// const NUM_TIMER_CAP_MASK: u64 = 0x0f00; +const LEG_RT_CAP: u64 = 0x8000; +const T0_CONFIG_CAPABILITY_OFFSET: usize = 0x100; +const T0_COMPARATOR_OFFSET: usize = 0x108; + +const PER_INT_CAP: u64 = 0x10; pub unsafe fn init(hpet: &mut Hpet) -> bool { println!("HPET Before Init"); diff --git a/src/arch/x86_64/device/pit.rs b/src/arch/x86_64/device/pit.rs index 7c96be162914d7e7d53041a8e0730d12e0bc61f5..fdf54a14b239c8008cff4a82301d6693e81ddb87 100644 --- a/src/arch/x86_64/device/pit.rs +++ b/src/arch/x86_64/device/pit.rs @@ -5,20 +5,24 @@ pub static mut CHAN1: Pio<u8> = Pio::new(0x41); pub static mut CHAN2: Pio<u8> = Pio::new(0x42); pub static mut COMMAND: Pio<u8> = Pio::new(0x43); -static SELECT_CHAN0: u8 = 0; -static LOHI: u8 = 0x30; +const SELECT_CHAN0: u8 = 0b00 << 6; +const ACCESS_LATCH: u8 = 0b00 << 4; +const ACCESS_LOHI: u8 = 0b11 << 4; +const MODE_2: u8 = 0b010 << 1; -static CHAN0_DIVISOR: u16 = 2685; +const CHAN0_DIVISOR: u16 = 2685; pub unsafe fn init() { - COMMAND.write(SELECT_CHAN0 | LOHI | 5); - CHAN0.write((CHAN0_DIVISOR & 0xFF) as u8); + COMMAND.write(SELECT_CHAN0 | ACCESS_LOHI | MODE_2); + CHAN0.write(CHAN0_DIVISOR as u8); CHAN0.write((CHAN0_DIVISOR >> 8) as u8); } pub unsafe fn read() -> u16 { - COMMAND.write(SELECT_CHAN0 | 0); + COMMAND.write(SELECT_CHAN0 | ACCESS_LATCH); let low = CHAN0.read(); let high = CHAN0.read(); - ((high as u16) << 8) | (low as u16) + let counter = ((high as u16) << 8) | (low as u16); + // Counter is inverted, subtract from CHAN0_DIVISOR + CHAN0_DIVISOR.saturating_sub(counter) } diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index 5dc0fd1a3c53b2466331b5bb7aec84d21f84bbc9..ca21bb516c759bfd4e758ca3c4920d23aad5159b 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -40,6 +40,8 @@ pub mod start; /// Stop function pub mod stop; +pub mod time; + pub use ::rmm::X8664Arch as CurrentRmmArch; // Flags diff --git a/src/arch/x86_64/time.rs b/src/arch/x86_64/time.rs new file mode 100644 index 0000000000000000000000000000000000000000..ca1fa5ee838507687eb1cbfa7536bf89a7e79d05 --- /dev/null +++ b/src/arch/x86_64/time.rs @@ -0,0 +1,16 @@ +use crate::acpi::ACPI_TABLE; +use super::device::{hpet, pit}; + +pub fn counter() -> u128 { + if let Some(ref hpet) = *ACPI_TABLE.hpet.read() { + let capability = unsafe { hpet.base_address.read_u64(hpet::CAPABILITY_OFFSET) }; + let period_fs = (capability >> 32) as u128; + let counter = unsafe { hpet.base_address.read_u64(hpet::MAIN_COUNTER_OFFSET) }; + (counter as u128 * period_fs) / 1_000_000 + } else { + // 1.193182 MHz PIT is approximately 838.095 nanoseconds + let period_ns = 838; + let counter = unsafe { pit::read() }; + counter as u128 * period_ns + } +} diff --git a/src/time.rs b/src/time.rs index 75717f2fc7748c069949916e4370dc909c7f585f..3d82c3903d22eb69b80dacf6c19de46327b58abf 100644 --- a/src/time.rs +++ b/src/time.rs @@ -8,7 +8,7 @@ pub static START: Mutex<u128> = Mutex::new(0); pub static OFFSET: Mutex<u128> = Mutex::new(0); pub fn monotonic() -> u128 { - *OFFSET.lock() + *OFFSET.lock() + crate::arch::time::counter() } pub fn realtime() -> u128 {