//! K421: real MMIO DeviceID separation; no RX/TX queue or packet claim. use super::*; use turkos_kernel::virtio_mmio; pub fn smoke_test(boot: &BootData) -> ! { let nodes = boot.virtio_mmio.as_slice(); if nodes.len() != 32 { write_line("TURKOS/NET-ID-ERROR: slot count"); park(); } let mut empty = 0usize; let mut net = 0usize; let mut block = 0usize; let mut other = 0usize; let mut net_base = 0usize; let mut block_base = 0usize; for node in nodes { // SAFETY: K322's DTB page-window validation and Device mapping cover // all aligned register offsets in each 0x200-byte bridge slot. let magic = unsafe { read_volatile(node.base as *const u32) }; let version = unsafe { read_volatile((node.base + 4) as *const u32) }; let id = unsafe { read_volatile((node.base + 8) as *const u32) }; let vendor = unsafe { read_volatile((node.base + 12) as *const u32) }; if virtio_mmio::validate_magic(magic).is_err() || virtio_mmio::validate_version(version).is_err() || virtio_mmio::validate_fixture_vendor(vendor).is_err() { write_line("TURKOS/NET-ID-ERROR: transport identity"); park(); } match virtio_mmio::require_net_device(id) { Ok(()) => { if virtio_mmio::require_block_device(id) != Err(virtio_mmio::Error::WrongDevice) { write_line("TURKOS/NET-ID-ERROR: net entered block path"); park(); } net += 1; net_base = node.base as usize; } Err(virtio_mmio::Error::MissingDevice) => empty += 1, Err(virtio_mmio::Error::WrongDevice) if id == 2 => { if virtio_mmio::require_block_device(id).is_err() { write_line("TURKOS/NET-ID-ERROR: block identity"); park(); } block += 1; block_base = node.base as usize; } Err(virtio_mmio::Error::WrongDevice) => other += 1, Err(_) => { write_line("TURKOS/NET-ID-ERROR: classification"); park(); } } } write_str("TURKOS/NET-ID: EMPTY=0x"); write_hex(empty); write_str(" NET=0x"); write_hex(net); write_str(" BLOCK=0x"); write_hex(block); write_str(" OTHER=0x"); write_hex(other); write_str(" NET-BASE=0x"); write_hex(net_base); write_str(" BLOCK-BASE=0x"); write_hex(block_base); write_str("\r\n"); if net != 1 || block > 1 || other != 0 || empty + net + block != 32 || net_base == block_base { write_line("TURKOS/NET-ID-ERROR: missing or ambiguous net"); park(); } write_line("TURKOS/NET-ID: PASS NET=1 BLOCK-PATH=REJECTED"); park() }