use crate::common::once::OnceCopy;
use core::sync::atomic::{AtomicUsize, Ordering};
static MIDR_MMIO: AtomicUsize = AtomicUsize::new(0);
pub fn set_midr_mmio(addr: usize) {
MIDR_MMIO.store(addr, Ordering::Release);
}
type CacheOpFn = fn(usize);
type BarrierFn = fn();
static DC_CIVAC_FN: OnceCopy<CacheOpFn> = OnceCopy::new();
static DC_CVAU_FN: OnceCopy<CacheOpFn> = OnceCopy::new();
static DSB_ISH_FN: OnceCopy<BarrierFn> = OnceCopy::new();
pub fn set_dc_civac_fn(f: CacheOpFn) {
DC_CIVAC_FN.set(f);
}
pub fn set_dc_cvau_fn(f: CacheOpFn) {
DC_CVAU_FN.set(f);
}
pub fn set_dsb_ish_fn(f: BarrierFn) {
DSB_ISH_FN.set(f);
}
pub unsafe fn read_midr_el1() -> u64 {
if let Some(v) = crate::arch::shim::read_aarch64_midr() {
return v;
}
let addr = MIDR_MMIO.load(Ordering::Acquire);
if addr != 0 {
core::ptr::read_volatile(addr as *const u64)
} else {
0
}
}
pub unsafe fn dc_civac(addr: usize) {
if let Some(f) = DC_CIVAC_FN.get() {
f(addr);
}
}
pub unsafe fn dc_cvau(addr: usize) {
if let Some(f) = DC_CVAU_FN.get() {
f(addr);
}
}
pub unsafe fn dsb_ish() {
if let Some(f) = DSB_ISH_FN.get() {
f();
}
}
pub unsafe fn read_sysreg(id: u32) -> u64 {
static SYSREG_LAST: core::sync::atomic::AtomicUsize = core::sync::atomic::AtomicUsize::new(0);
SYSREG_LAST.store(id as usize, core::sync::atomic::Ordering::Release);
0u64
}