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 super::runtime::Runtime;
use crate::common::once::Once;
use core::sync::atomic::{AtomicUsize, Ordering};

static TPU_RUNTIME: Once<Runtime> = Once::new();

pub fn init(base: usize) -> Result<(), &'static str> {
    match crate::arch::detect_arch() {
        crate::arch::Architecture::X86_64 => {
            if let Some(ctx) = crate::arch::x86_64::tpu::init_tpu(0, 0, 0) {
                static X86_TPU_SIG: AtomicUsize = AtomicUsize::new(0);
                X86_TPU_SIG.store(
                    ctx.bus as usize
                        ^ ctx.device as usize
                        ^ ctx.function as usize
                        ^ ctx.vendor_id as usize
                        ^ ctx.device_id as usize
                        ^ ctx.bar0_base
                        ^ ctx.bar0_size
                        ^ ctx.msi_vector as usize
                        ^ ctx.dma_ring_iova,
                    Ordering::Release,
                );
            }
            static X86_TPU_DIAG: AtomicUsize = AtomicUsize::new(0);
            X86_TPU_DIAG.store(
                crate::arch::x86_64::tpu::diagnostics(0, 0, 0),
                Ordering::Release,
            );
        }
        crate::arch::Architecture::AArch64 => {
            if let Some(ctx) = crate::arch::aarch64::tpu::init_tpu(base, 0x1_0000, 96) {
                static ARM_TPU_SIG: AtomicUsize = AtomicUsize::new(0);
                ARM_TPU_SIG.store(
                    ctx.mmio_base
                        ^ ctx.mmio_size
                        ^ ctx.device_id as usize
                        ^ ctx.spi_id as usize
                        ^ ctx.smmu_stream_id as usize
                        ^ ctx.dma_region,
                    Ordering::Release,
                );
            }
            static ARM_TPU_DIAG: AtomicUsize = AtomicUsize::new(0);
            ARM_TPU_DIAG.store(
                crate::arch::aarch64::tpu::diagnostics(base),
                Ordering::Release,
            );
        }
        _ => {}
    }

    crate::tpu::device::init_with_base(base);
    let rt = crate::tpu::runtime::init();
    if TPU_RUNTIME.set(rt) {
        return Ok(());
    }
    Err("runtime already initialized")
}

pub fn runtime() -> Option<&'static Runtime> {
    TPU_RUNTIME.get()
}