diff options
author | Michael Brown <mcb30@ipxe.org> | 2022-09-18 13:41:21 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2022-09-18 13:41:21 +0100 |
commit | 649176cd608e74ce54d20488a0618b4c6d8be71d (patch) | |
tree | f489d7722ada60a42da7ac8dfc23fe89018e0911 /src/include/ipxe/pci_io.h | |
parent | 9448ac544574dc11e1af204de39fcfddbbccb2af (diff) | |
download | ipxe-649176cd608e74ce54d20488a0618b4c6d8be71d.tar.gz |
[pci] Select PCI I/O API at runtime for cloud images
Pretty much all physical machines and off-the-shelf virtual machines
will provide a functional PCI BIOS. We therefore default to using
only the PCI BIOS, with no fallback to an alternative mechanism if the
PCI BIOS fails.
AWS EC2 provides the opportunity to experience some exceptions to this
rule. For example, the t3a.nano instances in eu-west-1 have no
functional PCI BIOS at all. As of commit 83516ba ("[cloud] Use
PCIAPI_DIRECT for cloud images") we therefore use direct Type 1
configuration space accesses in the images built and published for use
in the cloud.
Recent experience has discovered yet more variation in AWS EC2
instances. For example, some of the metal instance types have
multiple PCI host bridges and the direct Type 1 accesses therefore
see only a subset of the PCI devices.
Attempt to accommodate future such variations by making the PCI I/O
API selectable at runtime and choosing ECAM (if available), falling
back to the PCI BIOS (if available), then finally falling back to
direct Type 1 accesses.
This is implemented as a dedicated PCIAPI_CLOUD API, rather than by
having the PCI core select a suitable API at runtime (as was done for
timers in commit 302f1ee ("[time] Allow timer to be selected at
runtime"). The common case will remain that only the PCI BIOS API is
required, and we would prefer to retain the optimisations that come
from inlining the configuration space accesses in this common case.
Cloud images are (at present) disk images rather than ROM images, and
so the increased code size required for this design approach in the
PCIAPI_CLOUD case is acceptable.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/ipxe/pci_io.h')
-rw-r--r-- | src/include/ipxe/pci_io.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/include/ipxe/pci_io.h b/src/include/ipxe/pci_io.h index 35d16f95e..4c035b18b 100644 --- a/src/include/ipxe/pci_io.h +++ b/src/include/ipxe/pci_io.h @@ -15,6 +15,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <config/ioapi.h> struct pci_device; +struct pci_api; /** A PCI bus:dev.fn address range */ struct pci_range { @@ -149,4 +150,36 @@ int pci_write_config_dword ( struct pci_device *pci, unsigned int where, void * pci_ioremap ( struct pci_device *pci, unsigned long bus_addr, size_t len ); +/** A runtime selectable PCI I/O API */ +struct pci_api { + const char *name; + typeof ( pci_discover ) ( * pci_discover ); + typeof ( pci_read_config_byte ) ( * pci_read_config_byte ); + typeof ( pci_read_config_word ) ( * pci_read_config_word ); + typeof ( pci_read_config_dword ) ( * pci_read_config_dword ); + typeof ( pci_write_config_byte ) ( * pci_write_config_byte ); + typeof ( pci_write_config_word ) ( * pci_write_config_word ); + typeof ( pci_write_config_dword ) ( * pci_write_config_dword ); + typeof ( pci_ioremap ) ( * pci_ioremap ); +}; + +/** Provide a runtime selectable PCI I/O API */ +#define PCIAPI_RUNTIME( _subsys ) { \ + .name = #_subsys, \ + .pci_discover = PCIAPI_INLINE ( _subsys, pci_discover ), \ + .pci_read_config_byte = \ + PCIAPI_INLINE ( _subsys, pci_read_config_byte ), \ + .pci_read_config_word = \ + PCIAPI_INLINE ( _subsys, pci_read_config_word ), \ + .pci_read_config_dword = \ + PCIAPI_INLINE ( _subsys, pci_read_config_dword ), \ + .pci_write_config_byte = \ + PCIAPI_INLINE ( _subsys, pci_write_config_byte ), \ + .pci_write_config_word = \ + PCIAPI_INLINE ( _subsys, pci_write_config_word ), \ + .pci_write_config_dword = \ + PCIAPI_INLINE ( _subsys, pci_write_config_dword ), \ + .pci_ioremap = PCIAPI_INLINE ( _subsys, pci_ioremap ), \ + } + #endif /* _IPXE_PCI_IO_H */ |