BaseTools/Common: Fix aligned page alloc functions

This commit is contained in:
Marvin Häuser 2023-04-10 21:09:49 +02:00
parent 5fe6994faf
commit c3f671eff1
6 changed files with 175 additions and 46 deletions

View File

@ -644,6 +644,28 @@ PhaseFreePool (
InternalAlignedFree (Buffer); InternalAlignedFree (Buffer);
} }
VOID *
InternalAllocateAlignedPages (
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
IN UINTN Alignment
)
{
UINTN BufferSize;
BufferSize = EFI_PAGES_TO_SIZE (Pages);
return InternalAlignedAlloc (MAX (Alignment, EFI_PAGE_SIZE), BufferSize);
}
VOID
InternalFreeAlignedPages (
IN VOID *Buffer,
IN UINTN Pages
)
{
InternalAlignedFree (Buffer);
}
VOID VOID
EFIAPI EFIAPI
CpuBreakpoint ( CpuBreakpoint (

View File

@ -0,0 +1,84 @@
/** @file
Common code for the Memory Allocation Library aligned page allocation code.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include <Uefi/UefiBaseType.h>
#include <Uefi/UefiSpec.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/MemoryAllocationLibEx.h>
#include "AlignedPages.h"
/**
Allocates one or more 4KB pages of a certain memory type at a specified alignment.
Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
If there is not enough memory at the specified alignment remaining to satisfy the request, then
NULL is returned.
If Alignment is not a power of two and Alignment is not zero, then ASSERT().
If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
@param MemoryType The type of memory to allocate.
@param Pages The number of 4 KB pages to allocate.
@param Alignment The requested alignment of the allocation. Must be a power of two.
If Alignment is zero, then byte alignment is used.
@return A pointer to the allocated buffer or NULL if allocation fails.
**/
VOID *
InternalAllocateAlignedPages (
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
IN UINTN Alignment
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Memory;
Status = AllocateAlignedPagesEx (
AllocateAnyPages,
MemoryType,
Pages,
Alignment,
&Memory
);
if (EFI_ERROR (Status)) {
return NULL;
}
return (VOID *)(UINTN)Memory;
}
/**
Frees one or more 4KB pages that were previously allocated with one of the aligned page
allocation functions in the Memory Allocation Library.
Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
must have been allocated on a previous call to the aligned page allocation services of the Memory
Allocation Library. If it is not possible to free allocated pages, then this function will
perform no actions.
If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
Library, then ASSERT().
If Pages is zero, then ASSERT().
@param Buffer Pointer to the buffer of pages to free.
@param Pages The number of 4 KB pages to free.
**/
VOID
InternalFreeAlignedPages (
IN VOID *Buffer,
IN UINTN Pages
)
{
FreePages (Buffer, Pages);
}

View File

@ -0,0 +1,60 @@
/** @file
Common code for the Memory Allocation Library aligned page allocation code.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef ALIGNED_PAGES_H_
#define ALIGNED_PAGES_H_
/**
Allocates one or more 4KB pages of a certain memory type at a specified alignment.
Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
If there is not enough memory at the specified alignment remaining to satisfy the request, then
NULL is returned.
If Alignment is not a power of two and Alignment is not zero, then ASSERT().
If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
@param MemoryType The type of memory to allocate.
@param Pages The number of 4 KB pages to allocate.
@param Alignment The requested alignment of the allocation. Must be a power of two.
If Alignment is zero, then byte alignment is used.
@return A pointer to the allocated buffer or NULL if allocation fails.
**/
VOID *
InternalAllocateAlignedPages (
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
IN UINTN Alignment
);
/**
Frees one or more 4KB pages that were previously allocated with one of the aligned page
allocation functions in the Memory Allocation Library.
Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
must have been allocated on a previous call to the aligned page allocation services of the Memory
Allocation Library. If it is not possible to free allocated pages, then this function will
perform no actions.
If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
Library, then ASSERT().
If Pages is zero, then ASSERT().
@param Buffer Pointer to the buffer of pages to free.
@param Pages The number of 4 KB pages to free.
**/
VOID
InternalFreeAlignedPages (
IN VOID *Buffer,
IN UINTN Pages
);
#endif // ALIGNED_PAGES_H_

View File

@ -7,7 +7,9 @@
**/ **/
#include <PiDxe.h> #include <Base.h>
#include <Uefi/UefiBaseType.h>
#include <Uefi/UefiSpec.h>
#include <Library/MemoryAllocationLib.h> #include <Library/MemoryAllocationLib.h>
#include <Library/MemoryAllocationLibEx.h> #include <Library/MemoryAllocationLibEx.h>
@ -17,6 +19,8 @@
#include <Library/MemoryProfileLib.h> #include <Library/MemoryProfileLib.h>
#include "AlignedPages.h"
/** /**
Allocates one or more 4KB pages of type EfiBootServicesData. Allocates one or more 4KB pages of type EfiBootServicesData.
@ -203,49 +207,6 @@ FreePages (
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
} }
/**
Allocates one or more 4KB pages of a certain memory type at a specified alignment.
Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment
specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.
If there is not enough memory at the specified alignment remaining to satisfy the request, then
NULL is returned.
If Alignment is not a power of two and Alignment is not zero, then ASSERT().
If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
@param MemoryType The type of memory to allocate.
@param Pages The number of 4 KB pages to allocate.
@param Alignment The requested alignment of the allocation. Must be a power of two.
If Alignment is zero, then byte alignment is used.
@return A pointer to the allocated buffer or NULL if allocation fails.
**/
STATIC
VOID *
InternalAllocateAlignedPages (
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
IN UINTN Alignment
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Memory;
Status = AllocateAlignedPagesEx (
AllocateAnyPages,
MemoryType,
Pages,
Alignment,
&Memory
);
if (EFI_ERROR (Status)) {
return NULL;
}
return (VOID *)(UINTN)Memory;
}
/** /**
Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
@ -406,7 +367,7 @@ FreeAlignedPages (
IN UINTN Pages IN UINTN Pages
) )
{ {
FreePages (Buffer, Pages); InternalFreeAlignedPages (Buffer, Pages);
} }
/** /**

View File

@ -23,6 +23,8 @@
# #
[Sources] [Sources]
AlignedPages.h
AlignedPages.c
CommonMemoryAllocationLib.c CommonMemoryAllocationLib.c
CommonMemoryAllocationLibEx.c CommonMemoryAllocationLibEx.c

@ -1 +1 @@
Subproject commit cda8a58595f933a7ab5c5f8e883ad52f187a5525 Subproject commit 997ef4ae8f53a4b7f67e12b8d19a05368e6c2728