Allow reading PCI ROM address and size

This commit is contained in:
Jeremy Soller
2025-12-18 12:15:23 -07:00
parent 5b4a664111
commit 0fee261866
2 changed files with 48 additions and 2 deletions
+10
View File
@@ -88,6 +88,13 @@ impl From<PciAddressDef> for PciAddress {
}
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct PciRom {
pub addr: u32,
pub size: u32,
pub enabled: bool,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct PciFunction {
/// Address of the PCI function.
@@ -97,6 +104,9 @@ pub struct PciFunction {
/// PCI Base Address Registers
pub bars: [PciBar; 6],
/// PCI Option ROM
pub rom: Option<PciRom>,
/// Legacy IRQ line: It's the responsibility of pcid to make sure that it be mapped in either
/// the I/O APIC or the 8259 PIC, so that the subdriver can map the interrupt vector directly.
/// The vector to map is always this field, plus 32.
+38 -2
View File
@@ -13,7 +13,7 @@ use pci_types::{
use redox_scheme::{RequestKind, SignalBehavior};
use crate::cfg_access::Pcie;
use pcid_interface::{FullDeviceId, LegacyInterruptLine, PciBar, PciFunction};
use pcid_interface::{FullDeviceId, LegacyInterruptLine, PciBar, PciFunction, PciRom};
mod cfg_access;
mod driver_handler;
@@ -78,6 +78,41 @@ fn handle_parsed_header(
debug!(" BAR{}", string);
}
//TODO: submit to pci_types
let get_rom = |pci_address, offset| -> Option<PciRom> {
use pci_types::ConfigRegionAccess;
const ROM_ENABLED: u32 = 1;
const ROM_ADDRESS_MASK: u32 = 0xfffff800;
let data = unsafe { pcie.read(pci_address, offset) };
let enabled = (data & ROM_ENABLED) == ROM_ENABLED;
let addr = data & ROM_ADDRESS_MASK;
let size = unsafe {
pcie.write(pci_address, offset, ROM_ADDRESS_MASK | if enabled { ROM_ENABLED } else { 0 });
let mut readback = pcie.read(pci_address, offset);
pcie.write(pci_address, offset, data);
/*
* If the entire readback value is zero, the BAR is not implemented, so we return `None`.
*/
if readback == 0x0 {
return None;
}
readback &= ROM_ADDRESS_MASK;
1 << readback.trailing_zeros()
};
Some(PciRom { addr, size, enabled })
};
let rom = get_rom(endpoint_header.header().address(), 0x30);
if let Some(rom) = rom {
debug!(" ROM={:08X}", rom.addr);
}
let capabilities = if endpoint_header.status(pcie).has_capability_list() {
endpoint_header.capabilities(pcie).collect::<Vec<_>>()
} else {
@@ -91,8 +126,9 @@ fn handle_parsed_header(
let func = Func {
inner: pcid_interface::PciFunction {
bars,
addr: endpoint_header.header().address(),
bars,
rom,
legacy_interrupt_line: None, // Will be filled in when enabling the device
full_device_id: full_device_id.clone(),
},