summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2023-11-02 17:11:38 +0100
committerMichael Brown2023-11-02 17:11:38 +0100
commit5524bb98328dd1b16037916498b0f91e0200a87c (patch)
tree52e210c00568dcf8670b9b77d42ebd78216ebf4e
parent[pci] Check that ECAM configuration space is within reachable memory (diff)
downloadipxe-5524bb98328dd1b16037916498b0f91e0200a87c.tar.gz
ipxe-5524bb98328dd1b16037916498b0f91e0200a87c.tar.xz
ipxe-5524bb98328dd1b16037916498b0f91e0200a87c.zip
[pci] Require discovery of a PCI device when determining usable PCI APIs
The PCI cloud API (PCIAPI_CLOUD) currently selects the first PCI API that successfully discovers a PCI device address range. The ECAM API may discover an address range but subsequently be unable to map the configuration space region, which would result in the selected PCI API being unusable. Fix by instead selecting the first PCI API that can be successfully used to discover a PCI device. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/arch/x86/interface/pcbios/pcicloud.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/src/arch/x86/interface/pcbios/pcicloud.c b/src/arch/x86/interface/pcbios/pcicloud.c
index 97d7cac1..98ba38b3 100644
--- a/src/arch/x86/interface/pcbios/pcicloud.c
+++ b/src/arch/x86/interface/pcbios/pcicloud.c
@@ -165,24 +165,27 @@ static void pcicloud_init ( void ) {
static struct pci_api *apis[] = {
&ecam_api, &pcibios_api, &pcidirect_api
};
- struct pci_range range;
+ struct pci_device pci;
+ uint32_t busdevfn;
unsigned int i;
+ int rc;
- /* Select first API that successfully discovers an address range */
+ /* Select first API that successfully discovers a PCI device */
for ( i = 0 ; i < ( sizeof ( apis ) / sizeof ( apis[0] ) ) ; i++ ) {
pcicloud = apis[i];
- pcicloud_discover ( 0, &range );
- if ( range.count != 0 ) {
- DBGC ( pcicloud, "PCICLOUD selected %s API\n",
- pcicloud->name );
- break;
+ busdevfn = 0;
+ if ( ( rc = pci_find_next ( &pci, &busdevfn ) ) == 0 ) {
+ DBGC ( pcicloud, "PCICLOUD selected %s API (found "
+ PCI_FMT ")\n", pcicloud->name,
+ PCI_ARGS ( &pci ) );
+ return;
}
}
- /* The PCI direct API can never fail discovery since the range
- * is hardcoded.
- */
- assert ( range.count != 0 );
+ /* Fall back to using final attempted API if no devices found */
+ pcicloud = apis[ i - 1 ];
+ DBGC ( pcicloud, "PCICLOUD selected %s API (nothing detected)\n",
+ pcicloud->name );
}
/** Cloud VM PCI configuration space access initialisation function */