Allow arch to provide higher precision time

This commit is contained in:
Jeremy Soller
2022-11-14 11:12:44 -07:00
parent 31868077f0
commit 2052cc8cdc
11 changed files with 93 additions and 43 deletions

View File

@@ -33,4 +33,6 @@ pub mod vectors;
/// Early init support
pub mod init;
pub mod time;
pub use ::rmm::AArch64Arch as CurrentRmmArch;

4
src/arch/aarch64/time.rs Normal file
View File

@@ -0,0 +1,4 @@
pub fn counter() -> u128 {
//TODO: aarch64 generic timer counter
0
}

View File

@@ -1,22 +1,22 @@
use crate::acpi::hpet::Hpet;
static LEG_RT_CNF: u64 = 2;
static ENABLE_CNF: u64 = 1;
const LEG_RT_CNF: u64 = 2;
const ENABLE_CNF: u64 = 1;
static TN_VAL_SET_CNF: u64 = 0x40;
static TN_TYPE_CNF: u64 = 0x08;
static TN_INT_ENB_CNF: u64 = 0x04;
const TN_VAL_SET_CNF: u64 = 0x40;
const TN_TYPE_CNF: u64 = 0x08;
const 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;
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;
static PER_INT_CAP: u64 = 0x10;
const PER_INT_CAP: u64 = 0x10;
pub unsafe fn init(hpet: &mut Hpet) -> bool {
println!("HPET Before Init");

View File

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

View File

@@ -40,6 +40,8 @@ pub mod start;
/// Stop function
pub mod stop;
pub mod time;
pub use ::rmm::X86Arch as CurrentRmmArch;
// Flags

16
src/arch/x86/time.rs Normal file
View File

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

View File

@@ -1,22 +1,22 @@
use crate::acpi::hpet::Hpet;
static LEG_RT_CNF: u64 = 2;
static ENABLE_CNF: u64 = 1;
const LEG_RT_CNF: u64 = 2;
const ENABLE_CNF: u64 = 1;
static TN_VAL_SET_CNF: u64 = 0x40;
static TN_TYPE_CNF: u64 = 0x08;
static TN_INT_ENB_CNF: u64 = 0x04;
const TN_VAL_SET_CNF: u64 = 0x40;
const TN_TYPE_CNF: u64 = 0x08;
const 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;
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;
static PER_INT_CAP: u64 = 0x10;
const PER_INT_CAP: u64 = 0x10;
pub unsafe fn init(hpet: &mut Hpet) -> bool {
println!("HPET Before Init");

View File

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

View File

@@ -40,6 +40,8 @@ pub mod start;
/// Stop function
pub mod stop;
pub mod time;
pub use ::rmm::X8664Arch as CurrentRmmArch;
// Flags

16
src/arch/x86_64/time.rs Normal file
View File

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

View File

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