18.6.4 PCI Configuration Header Operations

The following three examples demonstrate different methods to read a PCI configuration header from a PCI controller, ordered lowest to highest in performance. The first example uses a loop to read the header 8 bits at a time; the second uses a single call to read the entire header 8 bits at a time and the third uses a single call to read the header 32 bits at a time.

Example 190-Read PCI configuration using a loop

#include <Uefi.h>
#include <Protocol/PciIo.h>
#include <IndustryStandard/Pci.h>
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci;
UINT32 Index;
//
// Loop reading the 64-byte PCI configuration header 8 bits at a time
//
for (Index = 0; Index < sizeof (Pci); Index++) {
Status = PciIo->Pci.Read (
PciIo, // This
EfiPciIoWidthUint8, // Width
Index, // Offset
1, // Count
(UINT8 *)(&Pci) + Index // Buffer
);
}

Example 191-Read PCI configuration 32 bits at a time

#include <Uefi.h>
#include <Protocol/PciIo.h>
#include <IndustryStandard/Pci.h>
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci;
//
// This is a faster method that removes the loop and reads 8 bits at a time.
//
Status = PciIo->Pci.Read (
PciIo, // This
EfiPciIoWidthUint8, // Width
0, // Offset
sizeof (Pci), // Count
&Pci // Buffer
);

Example 192-Read PCI configuration 32 bits at a time

#include <Uefi.h>
#include <Protocol/PciIo.h>
#include <IndustryStandard/Pci.h>
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci;
//
// This is the fastest method that makes a single call to PCI I/O and reads the
// PCI configuration header 32 bits at a time.
//
Status = PciIo->Pci.Read (
PciIo, // This
EfiPciIoWidthUint32, // Width
0, // Offset
sizeof (Pci) / sizeof (UINT32), // Count
&Pci // Buffer
);