pub trait Timer {
type Tick: Copy + Ord;
fn now(&self) -> Self::Tick;
}
pub trait InterruptController {
fn enable(&mut self, id: u32);
fn disable(&mut self, id: u32);
fn acknowledge(&mut self, id: u32);
}
pub trait AddressTranslator {
fn translate(&self, virtual_address: usize) -> Option<usize>;
}
pub trait Architecture {
type Timer: Timer;
type InterruptController: InterruptController;
type AddressTranslator: AddressTranslator;
fn timer(&self) -> &Self::Timer;
fn interrupt_controller(&mut self) -> &mut Self::InterruptController;
fn address_translator(&self) -> &Self::AddressTranslator;
}
#[cfg(test)]
#[derive(Debug, Clone)]
pub struct MockTimer {
tick: u64,
}
#[cfg(test)]
impl MockTimer {
pub fn new() -> Self {
Self { tick: 0 }
}
pub fn advance(&mut self, delta: u64) -> u64 {
self.tick = self.tick.saturating_add(delta);
self.tick
}
}
#[cfg(test)]
impl Timer for MockTimer {
type Tick = u64;
fn now(&self) -> Self::Tick {
self.tick
}
}
#[cfg(test)]
#[derive(Debug, Default)]
pub struct MockInterruptController {
last_enabled: Option<u32>,
last_disabled: Option<u32>,
last_acknowledged: Option<u32>,
}
#[cfg(test)]
impl InterruptController for MockInterruptController {
fn enable(&mut self, id: u32) {
self.last_enabled = Some(id);
}
fn disable(&mut self, id: u32) {
self.last_disabled = Some(id);
}
fn acknowledge(&mut self, id: u32) {
self.last_acknowledged = Some(id);
}
}
#[cfg(test)]
#[derive(Debug, Default)]
pub struct MockAddressTranslator {
mappings: std::collections::BTreeMap<usize, usize>,
}
#[cfg(test)]
impl MockAddressTranslator {
pub fn new() -> Self {
Self {
mappings: std::collections::BTreeMap::new(),
}
}
pub fn insert(&mut self, virtual_address: usize, physical_address: usize) {
let _ = self.mappings.insert(virtual_address, physical_address);
}
}
#[cfg(test)]
impl AddressTranslator for MockAddressTranslator {
fn translate(&self, virtual_address: usize) -> Option<usize> {
self.mappings.get(&virtual_address).copied()
}
}