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
                      );