5.1.2 Miscellaneous Services

The SetMem() and CopyMem() UEFI Boot Services are used by UEFI drivers to initialize the contents of a buffer or copy a buffer from one location to another. The SetMem() service is most commonly used to fill the contents of a buffer with zeros after it is allocated. The CopyMem() service handles buffers of any alignment and also handles the rare case when the source and destination buffer overlap. With overlapping buffers, the requirement is that the destination buffer on exit from this service must match the contents of the source buffer on entry to this service.

The code fragments in this section also show examples that use the EDK II library class BaseMemoryLib as an alternative to using the UEFI Boot Services directly. The advantage of using this library class is that the source code can be implemented just once. The EDK II DSC file used to build a UEFI Driver can specify mappings to different implementations of the BaseMemoryLib library class that meet the requirements of a specific target. For example, the MdePkg/Library/UefiMemoryLib library instance uses the recommended UEFI Boot Services SetMem() and CopyMem()are for best performance when building a UEFI Driver for EBC. For best performance on IA32 or X64, use the SSE2 optimized MdePkg/Library/BaseMemoryLibSse2 library instance.

5.1.2.1 Code examples for SetMem()

Use the SetMem() UEFI Boot Service to initialize the contents of a buffer with a specified value. UEFI drivers most commonly use this service to zero an allocated buffer, but it can also be used to fill a buffer with other values. The following code fragment in the example below shows the same example from Example 16, but uses SetMem() UEFI Boot Service to zero the contents of the allocated buffer. The EDK II library

UefiBootServicesTableLib provides global variables for the UEFI System Table, the UEFI Boot Services Table, and the Image Handle for the currently executing driver. Here, the global variable for the UEFI Boot Services Table called gBS is used to call the UEFI Boot Services AllocatePool() and SetMem().

Example 23-Allocate and clear a buffer using UEFI Boot Services

#include <Uefi.h>
#include <Library/UefiBootServicesTableLib.h>
EFI_STATUS Status;
EXAMPLE_DEVICE *Device;
//
// Allocate a buffer for a data structure
//
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (EXAMPLE_DEVICE),
(VOID **)&Device
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Zero the contents of the allocated buffer
//
gBS->SetMem (Device, sizeof (EXAMPLE_DEVICE), 0);

The following code fragment shows the same example from Example 17, but uses the SetMem() function from the EDK II library class BaseMemoryLib to zero the contents of the allocated buffer.

Example 24-Allocate and clear a buffer using BaseMemoryLib

#include <Uefi.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
EXAMPLE_DEVICE *Device;
//
// Allocate a buffer for a data structure
//
Device = (EXAMPLE_DEVICE *)AllocatePool (sizeof (EXAMPLE_DEVICE));
if (Device == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Zero the contents of the allocated buffer
//
SetMem (Device, sizeof (EXAMPLE_DEVICE), 0);

The code fragment in Example 25, below, shows the same example from Example 17, above, but uses the ZeroMem() function from the EDK II library class BaseMemoryLib to zero the contents of the allocated buffer.

Example 25-Allocate and clear a buffer using BaseMemoryLib

#include <Uefi.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
EXAMPLE_DEVICE *Device;
//
// Allocate a buffer for a data structure
//
Device = (EXAMPLE_DEVICE *)AllocatePool (sizeof (EXAMPLE_DEVICE));
if (Device == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Zero the contents of the allocated buffer
//
ZeroMem (Device, sizeof (EXAMPLE_DEVICE));

5.1.2.2 Code examples for CopyMem()

The following code fragment shows an example of how the CopyMem() UEFI Boot Service is typically used to copy an existing buffer into a newly allocated buffer. The AllocatePool() function from the EDK II library MemoryAllocationLib is used to allocate a new buffer. The EDK II library UefiBootServicesTableLib provides global variables for the UEFI System Table, the UEFI Boot Services Table, and the Image Handle for the currently executing driver. In this example, the global variable for the UEFI Boot Services Table called gBS is used to call the UEFI Boot Service CopyMem().

Example 26-Allocate and copy buffer

#include <Uefi.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
EXAMPLE_DEVICE *SourceDevice;
EXAMPLE_DEVICE *Device;
//
// Allocate a buffer for a data structure
//
Device = (EXAMPLE_DEVICE *)AllocatePool (sizeof (EXAMPLE_DEVICE));
if (Device == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Copy contents of SourceDevice to the allocated Device
//
gBS->CopyMem (Device, SourceDevice, sizeof (EXAMPLE_DEVICE));

The code fragment in Example 27, below, shows the same example from Example 26, above, but uses the CopyMem() function from the EDK II library class BaseMemoryLib to copy the contents of an existing buffer to a newly allocated buffer.

Example 27-Allocate and clear a buffer using BaseMemoryLib

#include <Uefi.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
EXAMPLE_DEVICE *SourceDevice;
EXAMPLE_DEVICE *Device;
//
// Allocate a buffer for a data structure
//
Device = (EXAMPLE_DEVICE *)AllocatePool (sizeof (EXAMPLE_DEVICE));
if (Device == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Copy contents of SourceDevice to the allocated Device
//
CopyMem (Device, SourceDevice, sizeof (EXAMPLE_DEVICE));