//! Read a real PCI function through one DTB-bounded ECAM Device page. use super::*; use os_pci_discovery::{ClaimTable, EcamWindow, Error, BUS_BYTES}; pub fn run(boot: &BootData) -> Result<(), &'static str> { let blob = unsafe { core::slice::from_raw_parts(boot.dtb_address as *const u8, boot.dtb_size) }; let host = dtb::discover_pci_ecam(blob).map_err(|_| "k1425-dtb-host")?; let window = EcamWindow::new(host.base, host.size, host.first_bus, host.last_bus) .map_err(|_| "k1425-ecam-window")?; let mut claims = ClaimTable::<1>::new(); let config = claims.claim(window, 0, 1, 0, 0) .map_err(|_| "k1425-config-claim")?; if config.physical != host.base + 0x8000 || claims.count() != 1 { return Err("k1425-config-address"); } // SAFETY: the DTB host owns this physical ECAM resource. Boot installed // exactly this page as Device-nGnRnE before enabling TTBR0. The claim is // live and the DWORD is aligned and fully within the host's bus range. let identity = unsafe { read_volatile(config.physical as *const u32) }; let vendor = identity & 0xffff; let device = identity >> 16; if vendor != 0x1af4 || device == 0 || device == 0xffff { return Err("k1425-virtio-rng-identity"); } // This narrower fixture describes only bus zero; it tests the same // checked-address function without attempting a second physical read. let narrow = EcamWindow::new(host.base, BUS_BYTES, 0, 0) .map_err(|_| "k1425-narrow-window")?; let before = claims.snapshot(); if claims.claim(narrow, 255, 0, 0, 0) != Err(Error::BusOutOfRange) || claims.snapshot() != before { return Err("k1425-outside-bus-accepted"); } claims.release(config).map_err(|_| "k1425-config-release")?; if claims.count() != 0 { return Err("k1425-claim-leak"); } write_str("TURKOS/OS/K1425-ECAM: BASE=0x"); write_hex(host.base as usize); write_str(" SIZE=0x"); write_hex(host.size as usize); write_str(" BUS-END=0x"); write_hex(host.last_bus as usize); write_str(" CONFIG=0x"); write_hex(config.physical as usize); write_str(" ID=0x"); write_hex(identity as usize); write_line(" READS=1 OUTSIDE-BUS255=REJECTED CLAIMS=0"); Ok(()) }