hardware 0.0.7

A no_std bare-metal hardware abstraction layer — all port I/O, memory and swap allocations are guarded at runtime. Do not consider this dependency stable before x.1.x
Documentation
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);
}

/// # Safety
/// Must only be called with a valid MMIO fallback configured or MIDR shim set.
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
    }
}

/// # Safety
/// `addr` must be a valid virtual address with data at that cache line.
pub unsafe fn dc_civac(addr: usize) {
    if let Some(f) = DC_CIVAC_FN.get() {
        f(addr);
    }
}

/// # Safety
/// `addr` must be a valid virtual address with data at that cache line.
pub unsafe fn dc_cvau(addr: usize) {
    if let Some(f) = DC_CVAU_FN.get() {
        f(addr);
    }
}

/// # Safety
/// Issues an ISH data synchronisation barrier; only valid on aarch64.
pub unsafe fn dsb_ish() {
    if let Some(f) = DSB_ISH_FN.get() {
        f();
    }
}

/// # Safety
/// `id` must be a valid aarch64 system register encoding.
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
}