use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Mutex;
use ax_memory_addr::{PhysAddr, VirtAddr};
use lazy_static::lazy_static;
pub const BASE_PADDR: usize = 0x1000;
pub static NEXT_PADDR: AtomicUsize = AtomicUsize::new(BASE_PADDR);
pub const MEMORY_LEN: usize = 0x10000;
#[repr(align(4096))]
pub struct AlignedMemory([u8; MEMORY_LEN]);
impl Default for AlignedMemory {
fn default() -> Self {
Self([0; MEMORY_LEN])
}
}
lazy_static! {
pub static ref MEMORY: Mutex<AlignedMemory> = Mutex::new(AlignedMemory::default());
pub static ref TEST_MUTEX: Mutex<()> = Mutex::new(());
}
pub static ALLOC_COUNT: AtomicUsize = AtomicUsize::new(0);
pub static DEALLOC_COUNT: AtomicUsize = AtomicUsize::new(0);
pub static ALLOC_SHOULD_FAIL: AtomicBool = AtomicBool::new(false);
#[derive(Debug)]
pub struct MockHal {}
pub fn mock_hal_test<F, R>(test_fn: F) -> R
where
F: FnOnce() -> R,
{
let _guard = TEST_MUTEX.lock().unwrap();
MockHal::reset_state();
test_fn()
}
impl MockHal {
pub fn mock_phys_to_virt(paddr: PhysAddr) -> VirtAddr {
let paddr_usize = paddr.as_usize();
assert!(
paddr_usize >= BASE_PADDR && paddr_usize < BASE_PADDR + MEMORY_LEN,
"Physical address {:#x} out of bounds",
paddr_usize
);
let offset = paddr_usize - BASE_PADDR;
VirtAddr::from_usize(MEMORY.lock().unwrap().0.as_ptr() as usize + offset)
}
pub fn reset_state() {
NEXT_PADDR.store(BASE_PADDR, Ordering::SeqCst);
ALLOC_SHOULD_FAIL.store(false, Ordering::SeqCst);
ALLOC_COUNT.store(0, Ordering::SeqCst);
DEALLOC_COUNT.store(0, Ordering::SeqCst);
MEMORY.lock().unwrap().0.fill(0); }
}