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