18.6.5 PCI I/O MMIO Buffer Operations

The following examples demonstrate how writing to a PCI memory-mapped I/O buffer can dramatically affect the performance of a UEFI Driver. In the first example, a loop is used with 8-bit operations. In the second, the same operation is done with a single call. This example is based on writing to a 1MB frame buffer by a UEFI Driver for a graphics controller.


Note: The examples shown here apply equally well to reading a bitmap from the frame buffer of a PCI video controller using the PciIo->Mem.Read() function.


Example 193-Write 1MB Frame Buffer using a loop
#include <Uefi.h>
#include <Protocol/PciIo.h>
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT8 gBitMap[SIZE_1MB];
UINTN Index;
//
// Loop writing a 1 MB bitmap to the frame buffer 8 bits at a time.
//
for (Index = 0; Index < sizeof (gBitMap); Index++) {
  Status = PciIo->Mem.Write (
                        PciIo, // This
                        EfiPciIoWidthUint8, // Width
                        0, // BarIndex
                        Index, // Offset
                        1, // Count
                        &gBitMap[Index] // Buffer
                        );
}
Example 194-Write 1MB Frame Buffer with no loop
#include <Uefi.h>
#include <Protocol/PciIo.h>
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
UINT8 gBitMap[SIZE_1MB];
//
// Faster method that removes the loop and writes 32 bits at a time.
//
Status = PciIo->Mem.Write (
                      PciIo, // This
                      EfiPciIoWidthUint32, // Width
                      0, // BarIndex
                      0,
                      // Offset sizeof (gBitMap) / sizeof (UINT32),
                      // Count gBitMap
                      // Buffer
                      );