extern crate alloc;
use alloc::{sync::Arc, vec, vec::Vec};
use axdevice_base::Device;
mod cntp_timer;
pub use cntp_timer::CntpTimerState as VtimerState;
mod cntp_cval_el0;
pub use cntp_cval_el0::SysCntpCvalEl0;
mod cntp_ctl_el0;
pub use cntp_ctl_el0::SysCntpCtlEl0;
mod cntpct_el0;
pub use cntpct_el0::SysCntpctEl0;
mod cntp_tval_el0;
pub use cntp_tval_el0::SysCntpTvalEl0;
pub fn new_sysreg_devices() -> (SysCntpCvalEl0, SysCntpCtlEl0, SysCntpctEl0, SysCntpTvalEl0) {
let (_timer, cval, ctl, counter, tval) = new_sysreg_devices_with_state();
(cval, ctl, counter, tval)
}
pub fn new_sysreg_devices_with_state() -> (
Arc<VtimerState>,
SysCntpCvalEl0,
SysCntpCtlEl0,
SysCntpctEl0,
SysCntpTvalEl0,
) {
let timer = Arc::new(VtimerState::new());
(
Arc::clone(&timer),
SysCntpCvalEl0::from_state(Arc::clone(&timer)),
SysCntpCtlEl0::from_state(Arc::clone(&timer)),
SysCntpctEl0::new(),
SysCntpTvalEl0::from_state(timer),
)
}
pub fn get_sysreg_device() -> Vec<Arc<dyn Device>> {
let (_timer, devices) = get_sysreg_device_with_state();
devices
}
pub fn get_sysreg_device_with_state() -> (Arc<VtimerState>, Vec<Arc<dyn Device>>) {
let (timer, cval, ctl, counter, tval) = new_sysreg_devices_with_state();
(
timer,
vec![
Arc::new(cval),
Arc::new(ctl),
Arc::new(counter),
Arc::new(tval),
],
)
}
#[cfg(test)]
mod tests {
use axdevice_base::AccessWidth;
use super::*;
#[test]
fn concrete_devices_isolate_timer_state_per_vcpu() {
let (timer, cval, ctl, _counter, tval) = new_sysreg_devices_with_state();
timer.set_test_current_identity(7, 0);
cval.write_register(AccessWidth::Qword, 0x1111).unwrap();
ctl.write_register(AccessWidth::Dword, 0x3).unwrap();
timer.set_test_current_identity(7, 1);
cval.write_register(AccessWidth::Qword, 0x2222).unwrap();
ctl.write_register(AccessWidth::Dword, 0x1).unwrap();
timer.set_test_current_identity(7, 0);
assert_eq!(cval.read_register(AccessWidth::Qword).unwrap(), 0x1111);
assert_eq!(tval.read_register(AccessWidth::Dword).unwrap(), 0x1111);
assert_eq!(ctl.read_register(AccessWidth::Dword).unwrap() & 0x3, 0x3);
timer.set_test_current_identity(7, 1);
assert_eq!(cval.read_register(AccessWidth::Qword).unwrap(), 0x2222);
assert_eq!(tval.read_register(AccessWidth::Dword).unwrap(), 0x2222);
assert_eq!(ctl.read_register(AccessWidth::Dword).unwrap() & 0x3, 0x1);
}
}