//! Real PCI header and absent-function reads, with bounded logical binding. use super::*; use os_pci_discovery::{ClaimTable, EcamWindow}; use os_pci_headers::{Error as HeaderError, Header, Inventory}; 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(|_| "k1430-dtb-host")?; let window = EcamWindow::new(host.base, host.size, host.first_bus, host.last_bus) .map_err(|_| "k1430-ecam-window")?; let mut claims = ClaimTable::<2>::new(); let attached = claims.claim(window, 0, 1, 0, 0) .map_err(|_| "k1430-attached-claim")?; let absent = claims.claim(window, 0, 31, 0, 0) .map_err(|_| "k1430-absent-claim")?; if attached.physical != host.base + 0x8000 || absent.physical != host.base + 0xf8000 || claims.count() != 2 { return Err("k1430-config-addresses"); } // SAFETY: both DTB-bounded ECAM pages were installed as Device-nGnRnE // before TTBR0. Each read is DWORD aligned and its claim remains live. let attached_id = unsafe { read_volatile(attached.physical as *const u32) }; let attached_class = unsafe { read_volatile((attached.physical + 0x0c) as *const u32) }; let absent_id = unsafe { read_volatile(absent.physical as *const u32) }; let root = Header::parse(attached_id, attached_class) .map_err(|_| "k1430-attached-header")?; if root.vendor_id != 0x1af4 || root.function_count() != 1 { return Err("k1430-attached-scope"); } let mut inventory = Inventory::<1>::new(); inventory.publish(root, 0, 1, 0, attached_id, attached_class) .map_err(|_| "k1430-attached-bind")?; let before = inventory.snapshot(); if absent_id != 0xffff_ffff || inventory.publish(root, 0, 31, 0, absent_id, 0) != Err(HeaderError::Absent) || inventory.snapshot() != before { return Err("k1430-absent-bound"); } claims.release(absent).map_err(|_| "k1430-absent-release")?; claims.release(attached).map_err(|_| "k1430-attached-release")?; if claims.count() != 0 || inventory.count() != 1 { return Err("k1430-ownership"); } write_str("TURKOS/OS/K1430-HEADERS: ATTACHED=0x"); write_hex(attached_id as usize); write_str(" HEADER=0x"); write_hex(((attached_class >> 16) & 0xff) as usize); write_str(" ABSENT=0x"); write_hex(absent_id as usize); write_line(" SINGLE=1 BOUND=1 ABSENT-BOUND=0 CLAIMS=0"); Ok(()) }