//! K422: read six real virtio-net config bytes after DeviceID/feature gates. //! Legacy v1 config is read twice for stability; no queue is initialized. use super::*; use turkos_kernel::{net_mac, virtio_mmio}; fn read_mac(base: u64) -> [u8; 6] { let mut mac = [0u8; 6]; for (index, byte) in mac.iter_mut().enumerate() { // SAFETY: K322 mapped the validated 0x200-byte MMIO slot as Device; // config offsets 0x100..0x105 are within that slot and byte aligned. *byte = unsafe { read_volatile((base + 0x100 + index as u64) as *const u8) }; } mac } pub fn smoke_test(boot: &BootData) -> ! { let mut net_base = None; for node in boot.virtio_mmio.as_slice() { 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-MAC-ERROR: transport identity"); park(); } if virtio_mmio::require_net_device(id).is_ok() { if net_base.replace(node.base).is_some() { write_line("TURKOS/NET-MAC-ERROR: ambiguous net"); park(); } } } let Some(base) = net_base else { write_line("TURKOS/NET-MAC-ERROR: missing net"); park(); }; // SAFETY: HostFeaturesSel/HostFeatures are aligned within the selected // K322 Device-mapped network bridge. Reading does not negotiate a driver. let offered = unsafe { write_volatile((base + 0x14) as *mut u32, 0); read_volatile((base + 0x10) as *const u32) }; if offered & net_mac::VIRTIO_NET_F_MAC == 0 { write_line("TURKOS/NET-MAC-ERROR: missing feature"); park(); } let first = read_mac(base); let second = read_mac(base); if first != second { write_line("TURKOS/NET-MAC-ERROR: unstable config"); park(); } let packed = first .iter() .fold(0usize, |value, byte| (value << 8) | *byte as usize); write_str("TURKOS/NET-MAC: BASE=0x"); write_hex(base as usize); write_str(" OFFERED=0x"); write_hex(offered as usize); write_str(" VALUE=0x"); write_hex(packed); write_str(" STABLE=0x"); write_hex(1); write_str("\r\n"); match net_mac::validate(offered, first) { Ok(_) => write_line("TURKOS/NET-MAC: PASS UNICAST=1"), Err(net_mac::Error::ZeroAddress) => write_line("TURKOS/NET-MAC-ERROR: zero address"), Err(net_mac::Error::Multicast) => write_line("TURKOS/NET-MAC-ERROR: multicast address"), Err(net_mac::Error::MissingFeature) => write_line("TURKOS/NET-MAC-ERROR: missing feature"), } park() }