mirror of
https://github.com/ipxe/ipxe
synced 2025-12-20 12:00:19 +03:00
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 commit83516ba("[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 commit302f1ee("[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>
58 lines
1.9 KiB
C
58 lines
1.9 KiB
C
/*
|
|
* Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*
|
|
* You can also choose to distribute this program under the terms of
|
|
* the Unmodified Binary Distribution Licence (as given in the file
|
|
* COPYING.UBDL), provided that you have satisfied its requirements.
|
|
*/
|
|
|
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|
|
|
#include <ipxe/io.h>
|
|
#include <ipxe/pci.h>
|
|
|
|
/** @file
|
|
*
|
|
* PCI configuration space access via Type 1 accesses
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Prepare for Type 1 PCI configuration space access
|
|
*
|
|
* @v pci PCI device
|
|
* @v where Location within PCI configuration space
|
|
*/
|
|
void pcidirect_prepare ( struct pci_device *pci, int where ) {
|
|
uint16_t busdevfn = ( pci->busdevfn & 0xffff );
|
|
|
|
outl ( ( 0x80000000 | ( busdevfn << 8 ) | ( where & ~3 ) ),
|
|
PCIDIRECT_CONFIG_ADDRESS );
|
|
}
|
|
|
|
PROVIDE_PCIAPI_INLINE ( direct, pci_discover );
|
|
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_byte );
|
|
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word );
|
|
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_dword );
|
|
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_byte );
|
|
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_word );
|
|
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword );
|
|
PROVIDE_PCIAPI_INLINE ( direct, pci_ioremap );
|
|
|
|
struct pci_api pcidirect_api = PCIAPI_RUNTIME ( direct );
|