ArmPkg/ArmDmaLib: implement DmaAllocateAlignedBuffer()

Implement the new DmaLib routine that returns DMA'able buffers
at a specified minimum alignment.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
This commit is contained in:
Ard Biesheuvel 2017-08-24 20:13:10 +01:00
parent deef290f95
commit 4b4104d87e
1 changed files with 39 additions and 3 deletions

View File

@ -284,6 +284,37 @@ DmaAllocateBuffer (
IN UINTN Pages, IN UINTN Pages,
OUT VOID **HostAddress OUT VOID **HostAddress
) )
{
return DmaAllocateAlignedBuffer (MemoryType, Pages, 0, HostAddress);
}
/**
Allocates pages that are suitable for an DmaMap() of type
MapOperationBusMasterCommonBuffer mapping, at the requested alignment.
@param MemoryType The type of memory to allocate, EfiBootServicesData or
EfiRuntimeServicesData.
@param Pages The number of pages to allocate.
@param Alignment Alignment in bytes of the base of the returned
buffer (must be a power of 2)
@param HostAddress A pointer to store the base system memory address of the
allocated range.
@retval EFI_SUCCESS The requested memory pages were allocated.
@retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are
MEMORY_WRITE_COMBINE and MEMORY_CACHED.
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
**/
EFI_STATUS
EFIAPI
DmaAllocateAlignedBuffer (
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
IN UINTN Alignment,
OUT VOID **HostAddress
)
{ {
EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor;
VOID *Allocation; VOID *Allocation;
@ -291,14 +322,19 @@ DmaAllocateBuffer (
UNCACHED_ALLOCATION *Alloc; UNCACHED_ALLOCATION *Alloc;
EFI_STATUS Status; EFI_STATUS Status;
if (HostAddress == NULL) { if (Alignment == 0) {
Alignment = EFI_PAGE_SIZE;
}
if (HostAddress == NULL ||
(Alignment & (Alignment - 1)) != 0) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (MemoryType == EfiBootServicesData) { if (MemoryType == EfiBootServicesData) {
Allocation = AllocatePages (Pages); Allocation = AllocateAlignedPages (Pages, Alignment);
} else if (MemoryType == EfiRuntimeServicesData) { } else if (MemoryType == EfiRuntimeServicesData) {
Allocation = AllocateRuntimePages (Pages); Allocation = AllocateAlignedRuntimePages (Pages, Alignment);
} else { } else {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }