diff --git a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c index f4077c04a7..e056cdb9ed 100644 --- a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c +++ b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c @@ -8,23 +8,29 @@ **/ #include +#include #include #include #include #include -STATIC -VOID * +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + +EFI_STATUS EFIAPI -InternalAllocatePages ( - IN UINTN Pages, - IN EFI_MEMORY_TYPE MemoryType +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { EFI_PEI_HOB_POINTERS Hob; EFI_PHYSICAL_ADDRESS NewTop; + ASSERT (Type == AllocateAnyPages); + Hob.Raw = GetHobList (); NewTop = Hob.HandoffInformationTable->EfiFreeMemoryTop & ~(EFI_PHYSICAL_ADDRESS)EFI_PAGE_MASK; @@ -34,7 +40,7 @@ InternalAllocatePages ( // Verify that there is sufficient memory to satisfy the allocation // if (NewTop < (Hob.HandoffInformationTable->EfiFreeMemoryBottom + sizeof (EFI_HOB_MEMORY_ALLOCATION))) { - return NULL; + return EFI_OUT_OF_RESOURCES; } // @@ -51,131 +57,41 @@ InternalAllocatePages ( MemoryType ); - return (VOID *)(UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of MemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (Pages, EfiBootServicesData); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (Pages, EfiRuntimeServicesData); -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData 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(). - - @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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Memory; - UINTN AlignmentMask; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment))); - // - // We would rather waste some memory to save PEI code size. - // - Memory = (VOID *)(UINTN)AllocatePages (Pages + EFI_SIZE_TO_PAGES (Alignment)); - if (Alignment == 0) { - AlignmentMask = Alignment; - } else { - AlignmentMask = Alignment - 1; - } - - return (VOID *)(UINTN)(((UINTN)Memory + AlignmentMask) & ~AlignmentMask); + *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop; + return EFI_SUCCESS; } /** Frees one or more 4KB pages that were previously allocated with one of the 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 page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + 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 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 a page allocation function in the Memory Allocation Library, - then ASSERT(). + If Buffer was not allocated with a 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 Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { // For now, we do not support the ability to free pages in the PrePei Memory Allocator. // The allocated memory is lost. + return EFI_SUCCESS; } /** @@ -192,8 +108,9 @@ FreePages ( **/ VOID * EFIAPI -AllocatePool ( - IN UINTN AllocationSize +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { EFI_HOB_MEMORY_POOL *Hob; @@ -216,37 +133,6 @@ AllocatePool ( } } -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = AllocatePool (AllocationSize); - if (Buffer == NULL) { - return NULL; - } - - ZeroMem (Buffer, AllocationSize); - - return Buffer; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -263,7 +149,7 @@ AllocateZeroPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf index 9491af9f24..4513a1d0fd 100644 --- a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf +++ b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf @@ -30,4 +30,5 @@ BaseMemoryLib PrePiLib #PeiServicesLib + CommonMemoryAllocationLib diff --git a/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf b/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf index 95038a64de..5ddc9299c6 100644 --- a/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf +++ b/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf @@ -35,3 +35,4 @@ BaseMemoryLib UefiBootServicesTableLib EmuThunkLib + CommonMemoryAllocationLib diff --git a/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c b/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c index 515ef1a59b..23aa0b1b7b 100644 --- a/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c +++ b/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c @@ -17,337 +17,95 @@ #include -#include +#include #include #include #include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; + VOID *Buffer; + + ASSERT (Type == AllocateAnyPages); if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } - return gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); -} + Buffer = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiBootServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiReservedMemoryType, Pages); + *Memory = (UINTN)Buffer; + return EFI_SUCCESS; } /** Frees one or more 4KB pages that were previously allocated with one of the 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 page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + 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 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 a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - if (!gEmuThunk->Free (Buffer)) { - // The Free thunk will not free memory allocated in emulated EFI memory. - // The assmuption is this was allocated directly by EFI. We need this as some - // times protocols or EFI BootServices can return dynamically allocated buffers. - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - 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(). - - @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; - VOID *Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Caculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); - if (Memory != NULL) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - FreePages (Memory, UnalignedPages); - } - - Memory = (VOID *)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - FreePages (Memory, UnalignedPages); - } - } else { - // - // Do not over-allocate pages in this case. - // - Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); - if (Memory != NULL) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData 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(). - - @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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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(). - - @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 * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType 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(). - - @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 * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, 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 + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - FreePages (Buffer, Pages); + ASSERT (Pages != 0); + if (!gEmuThunk->Free ((VOID *)(UINTN)Memory)) { + // The Free thunk will not free memory allocated in emulated EFI memory. + // The assmuption is this was allocated directly by EFI. We need this as some + // times protocols or EFI BootServices can return dynamically allocated buffers. + return gBS->FreePages (Memory, Pages); + } + + return EFI_SUCCESS; } /** @@ -364,7 +122,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -372,420 +131,6 @@ InternalAllocatePool ( return gEmuThunk->Malloc (AllocationSize); } -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiBootServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiReservedMemoryType, AllocationSize); -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -802,7 +147,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c b/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c index b81d637aef..66f075531e 100644 --- a/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c +++ b/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c @@ -18,7 +18,7 @@ #include -#include +#include #include #include #include @@ -27,6 +27,8 @@ #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; + EFI_SMRAM_DESCRIPTOR *mSmmCoreMemoryAllocLibSmramRanges = NULL; UINTN mSmmCoreMemoryAllocLibSmramRangeCount = 0; @@ -41,14 +43,14 @@ UINTN mSmmCoreMemoryAllocLibSmramRangeCount = 0; BOOLEAN EFIAPI BufferInSmram ( - IN VOID *Buffer + IN EFI_PHYSICAL_ADDRESS Buffer ) { UINTN Index; for (Index = 0; Index < mSmmCoreMemoryAllocLibSmramRangeCount; Index++) { - if (((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer >= mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart) && - ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer < (mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart + mSmmCoreMemoryAllocLibSmramRanges[Index].PhysicalSize))) + if ((Buffer >= mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart) && + (Buffer < (mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart + mSmmCoreMemoryAllocLibSmramRanges[Index].PhysicalSize))) { return TRUE; } @@ -60,420 +62,83 @@ BufferInSmram ( /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } - Status = SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return NULL; + return SmmAllocatePages (Type, MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the 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 page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + 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 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 a 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 -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - if (BufferInSmram (Buffer)) { - // - // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service. - // So, SmmFreePages() service is used to free it. - // - Status = SmmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } else { - // - // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service. - // So, gBS->FreePages() service is used to free it. - // - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } - - 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. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = SmmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = SmmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = SmmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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 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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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 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 * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType 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 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 * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return NULL; -} - -/** - 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 + If Buffer was not allocated with a 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 Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { EFI_STATUS Status; ASSERT (Pages != 0); - if (BufferInSmram (Buffer)) { + if (BufferInSmram (Memory)) { // // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service. // So, SmmFreePages() service is used to free it. // - Status = SmmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); + Status = SmmFreePages (Memory, Pages); } else { // // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service. // So, gBS->FreePages() service is used to free it. // - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); + Status = gBS->FreePages (Memory, Pages); } - ASSERT_EFI_ERROR (Status); + return Status; } /** @@ -490,7 +155,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -508,532 +174,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return NULL; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, - EfiRuntimeServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return NULL; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -1050,13 +190,13 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { EFI_STATUS Status; - if (BufferInSmram (Buffer)) { + if (BufferInSmram ((UINTN)Buffer)) { // // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePool() service. // So, SmmFreePool() service is used to free it. diff --git a/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c b/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c index 3061ec6cd0..bd661ca428 100644 --- a/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c +++ b/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c @@ -7,231 +7,84 @@ **/ -#include +#include #include -#include +#include + +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; /** - Allocates one or more 4KB pages of type EfiBootServicesData. + Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * +EFI_STATUS EFIAPI -AllocatePages ( - IN UINTN Pages +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { ASSERT (FALSE); - return NULL; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - ASSERT (FALSE); - return NULL; + return EFI_OUT_OF_RESOURCES; } /** Frees one or more 4KB pages that were previously allocated with one of the 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 page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + 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 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 a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - ASSERT (FALSE); -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData 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 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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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 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 * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType 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 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 * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - 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 + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { ASSERT (FALSE); + return EFI_NOT_FOUND; } /** - Allocates a buffer of type EfiBootServicesData. + Allocates a buffer of a certain pool type. - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + @param MemoryType The type of memory to allocate. @param AllocationSize The number of bytes to allocate. @return A pointer to the allocated buffer or NULL if allocation fails. @@ -239,304 +92,9 @@ FreeAlignedPages ( **/ VOID * EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { ASSERT (FALSE); @@ -559,7 +117,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf b/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf index 00a2b78093..3a89dfa0f9 100644 --- a/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf +++ b/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf @@ -31,3 +31,4 @@ [LibraryClasses] DebugLib + CommonMemoryAllocationLib diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c new file mode 100644 index 0000000000..6eed53cfc8 --- /dev/null +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c @@ -0,0 +1,978 @@ +/** @file + Common code for the Memory Allocation Library based on + PhaseMemoryAllocationLib. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include + +#include + +/** + Allocates one or more 4KB pages of type EfiBootServicesData. + + Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + VOID *Buffer; + + Status = PhaseAllocatePages (AllocateAnyPages, gPhaseDefaultDataType, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + + Buffer = (VOID *)(UINTN)Memory; + + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, + gPhaseDefaultDataType, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + + return Buffer; +} + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimePages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + VOID *Buffer; + + Status = PhaseAllocatePages (AllocateAnyPages, EfiRuntimeServicesData, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + + Buffer = (VOID *)(UINTN)Memory; + + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, + EfiRuntimeServicesData, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + + return Buffer; +} + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType. + + Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedPages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + VOID *Buffer; + + Status = PhaseAllocatePages (AllocateAnyPages, EfiReservedMemoryType, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + + Buffer = (VOID *)(UINTN)Memory; + + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES, + EfiReservedMemoryType, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + + return Buffer; +} + +/** + Frees one or more 4KB pages that were previously allocated with one of the 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 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 a 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 +EFIAPI +FreePages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + + Status = PhaseFreePages ((UINTN)Buffer, Pages); + 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 the number of 4KB pages specified by Pages of type EfiBootServicesData 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 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 * +EFIAPI +AllocateAlignedPages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateAlignedPages (gPhaseDefaultDataType, Pages, Alignment); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, + gPhaseDefaultDataType, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + } + + return Buffer; +} + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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 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 * +EFIAPI +AllocateAlignedRuntimePages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, + EfiRuntimeServicesData, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + } + + return Buffer; +} + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType 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 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 * +EFIAPI +AllocateAlignedReservedPages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES, + EfiReservedMemoryType, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + } + + return Buffer; +} + +/** + 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 +EFIAPI +FreeAlignedPages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + FreePages (Buffer, Pages); +} + +/** + Allocates a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = PhaseAllocatePool (gPhaseDefaultDataType, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, + gPhaseDefaultDataType, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Allocates a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimePool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = PhaseAllocatePool (EfiRuntimeServicesData, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, + EfiRuntimeServicesData, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Allocates a buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = PhaseAllocatePool (EfiReservedMemoryType, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL, + EfiReservedMemoryType, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Allocates and zeros a buffer of a certain pool type. + + Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer + with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid + buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, + then NULL is returned. + + @param PoolType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +STATIC +VOID * +InternalAllocateZeroPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize + ) +{ + VOID *Memory; + + Memory = PhaseAllocatePool (PoolType, AllocationSize); + if (Memory != NULL) { + Memory = ZeroMem (Memory, AllocationSize); + } + + return Memory; +} + +/** + Allocates and zeros a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateZeroPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateZeroPool (gPhaseDefaultDataType, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, + gPhaseDefaultDataType, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Allocates and zeros a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimeZeroPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, + EfiRuntimeServicesData, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Allocates and zeros a buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedZeroPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL, + EfiReservedMemoryType, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Copies a buffer to an allocated buffer of a certain pool type. + + Allocates the number bytes specified by AllocationSize of a certain pool type, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param PoolType The type of pool to allocate. + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +STATIC +VOID * +InternalAllocateCopyPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *Memory; + + ASSERT (Buffer != NULL); + ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); + + Memory = PhaseAllocatePool (PoolType, AllocationSize); + if (Memory != NULL) { + Memory = CopyMem (Memory, Buffer, AllocationSize); + } + + return Memory; +} + +/** + Copies a buffer to an allocated buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *NewBuffer; + + NewBuffer = InternalAllocateCopyPool (gPhaseDefaultDataType, AllocationSize, Buffer); + if (NewBuffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, + gPhaseDefaultDataType, + NewBuffer, + AllocationSize, + NULL + ); + } + + return NewBuffer; +} + +/** + Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimeCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *NewBuffer; + + NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); + if (NewBuffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, + EfiRuntimeServicesData, + NewBuffer, + AllocationSize, + NULL + ); + } + + return NewBuffer; +} + +/** + Copies a buffer to an allocated buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *NewBuffer; + + NewBuffer = InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); + if (NewBuffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL, + EfiRuntimeServicesData, + NewBuffer, + AllocationSize, + NULL + ); + } + + return NewBuffer; +} + +/** + Reallocates a buffer of a specified memory type. + + Allocates and zeros the number bytes specified by NewSize from memory of the type + specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param PoolType The type of pool to allocate. + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +STATIC +VOID * +InternalReallocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *NewBuffer; + + NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); + if ((NewBuffer != NULL) && (OldBuffer != NULL)) { + CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); + FreePool (OldBuffer); + } + + return NewBuffer; +} + +/** + Reallocates a buffer of type EfiBootServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocatePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *Buffer; + + Buffer = InternalReallocatePool (gPhaseDefaultDataType, OldSize, NewSize, OldBuffer); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, + gPhaseDefaultDataType, + Buffer, + NewSize, + NULL + ); + } + + return Buffer; +} + +/** + Reallocates a buffer of type EfiRuntimeServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocateRuntimePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *Buffer; + + Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, + EfiRuntimeServicesData, + Buffer, + NewSize, + NULL + ); + } + + return Buffer; +} + +/** + Reallocates a buffer of type EfiReservedMemoryType. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocateReservedPool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *Buffer; + + Buffer = InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL, + EfiReservedMemoryType, + Buffer, + NewSize, + NULL + ); + } + + return Buffer; +} + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer Pointer to the buffer to free. + +**/ +VOID +EFIAPI +FreePool ( + IN VOID *Buffer + ) +{ + PhaseFreePool (Buffer); +} diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf new file mode 100644 index 0000000000..8c806dc642 --- /dev/null +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf @@ -0,0 +1,37 @@ +## @file +# Common code for the Memory Allocation Library based on +# PhaseMemoryAllocationLib. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CommonMemoryAllocationLib + MODULE_UNI_FILE = CommonMemoryAllocationLib.uni + FILE_GUID = 020172f8-f96d-479b-9f29-c4d2f204573d + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = CommonMemoryAllocationLib + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + CommonMemoryAllocationLib.c + CommonMemoryAllocationLibEx.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + DebugLib + BaseMemoryLib + MemoryProfileLib + diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.uni b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.uni new file mode 100644 index 0000000000..4ed987566c --- /dev/null +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.uni @@ -0,0 +1,15 @@ +// /** @file +// Common code for the Memory Allocation Library based on +// PhaseMemoryAllocationLib. +// +// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Common code for the Memory Allocation Library based on PhaseMemoryAllocationLib" + +#string STR_MODULE_DESCRIPTION #language en-US "Common code for the Memory Allocation Library based on PhaseMemoryAllocationLib." + diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLibEx.c b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLibEx.c new file mode 100644 index 0000000000..b378193421 --- /dev/null +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLibEx.c @@ -0,0 +1,150 @@ +/** @file + Implementation of MemoryAllocationLibEx based on PhaseMemoryAllocationLib. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include + +/** + Allocates one or more 4KB pages of a certain memory type. + + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. + +**/ +EFI_STATUS +EFIAPI +AllocatePagesEx ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + return PhaseAllocatePages (Type, MemoryType, Pages, Memory); +} + +/** + 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. + 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 Type The type of allocation to perform. + @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. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. + +**/ +EFI_STATUS +EFIAPI +AllocateAlignedPagesEx ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN UINTN Alignment, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + EFI_PHYSICAL_ADDRESS AlignedMemory; + UINTN AlignmentMask; + UINTN UnalignedPages; + UINTN RealPages; + + // + // Alignment must be a power of two or zero. + // + ASSERT ((Alignment & (Alignment - 1)) == 0); + + // + // Reserving a specific address does not require guaranteeing alignment + // constraints. + // + ASSERT (Type != AllocateAddress); + + if (Pages == 0) { + return EFI_INVALID_PARAMETER; + } + + if (Alignment > EFI_PAGE_SIZE) { + // + // Calculate the total number of pages since alignment is larger than page size. + // + AlignmentMask = Alignment - 1; + RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); + // + // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. + // + ASSERT (RealPages > Pages); + + Status = AllocatePagesEx (Type, MemoryType, RealPages, Memory); + if (EFI_ERROR (Status)) { + return Status; + } + + Address = *Memory; + + AlignedMemory = (Address + AlignmentMask) & ~(EFI_PHYSICAL_ADDRESS)AlignmentMask; + UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN)(AlignedMemory - Address)); + if (UnalignedPages > 0) { + // + // Free first unaligned page(s). + // + Status = PhaseFreePages (Address, UnalignedPages); + ASSERT_EFI_ERROR (Status); + } + + Address = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); + UnalignedPages = RealPages - Pages - UnalignedPages; + if (UnalignedPages > 0) { + // + // Free last unaligned page(s). + // + Status = PhaseFreePages (Address, UnalignedPages); + ASSERT_EFI_ERROR (Status); + } + + *Memory = AlignedMemory; + } else { + // + // Do not over-allocate pages in this case. + // + Status = AllocatePagesEx (Type, MemoryType, Pages, Memory); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf index cd5515ee52..de8c565352 100644 --- a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf +++ b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf @@ -38,3 +38,4 @@ DebugLib BaseMemoryLib MemoryProfileLib + CommonMemoryAllocationLib diff --git a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c index e813e87f24..1d8a263947 100644 --- a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c @@ -10,432 +10,77 @@ #include -#include +#include #include #include #include "DxeCoreMemoryAllocationServices.h" -#include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } - Status = CoreAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiBootServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, - EfiBootServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiReservedMemoryType, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES, - EfiReservedMemoryType, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; + return CoreAllocatePages (Type, MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the 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 page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + 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 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 a 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 -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - 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. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = CoreAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = CoreFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = CoreFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = CoreAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData 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 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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, - EfiBootServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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 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 * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType 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 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 * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES, - EfiReservedMemoryType, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - 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 + If Buffer was not allocated with a 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 Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - Status = CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); + return CoreFreePages (Memory, Pages); } /** @@ -452,7 +97,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -470,588 +116,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiBootServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, - EfiBootServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiReservedMemoryType, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL, - EfiReservedMemoryType, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiBootServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, - EfiBootServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL, - EfiReservedMemoryType, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, - EfiBootServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, - EfiBootServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL, - EfiReservedMemoryType, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -1068,7 +132,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf index 9bb3aaef02..c56c4aef42 100644 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf +++ b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf @@ -37,4 +37,4 @@ MdePkg/MdePkg.dec [LibraryClasses] - MemoryProfileLib + CommonMemoryAllocationLib diff --git a/MdePkg/Include/Library/MemoryAllocationLibEx.h b/MdePkg/Include/Library/MemoryAllocationLibEx.h new file mode 100644 index 0000000000..079d823a78 --- /dev/null +++ b/MdePkg/Include/Library/MemoryAllocationLibEx.h @@ -0,0 +1,75 @@ +/** @file + Provides extended services to allocate and free memory buffers of various memory types and alignments. + This header is part of the MemoryAllocationLib library class. Every instance + of MemoryAllocationLib must also implement the functions declared by this + header. The separation is due to the newly-introduced dependency on + MdePkg/Uefi/UefiSpec.h. + +Copyright (c) 2023, Marvin Häuser. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __MEMORY_ALLOCATION_LIB_EX_H__ +#define __MEMORY_ALLOCATION_LIB_EX_H__ + +/** + Allocates one or more 4KB pages of a certain memory type. + + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. + +**/ +EFI_STATUS +EFIAPI +AllocatePagesEx ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +/** + 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. + 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 Type The type of allocation to perform. + @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. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. + +**/ +EFI_STATUS +EFIAPI +AllocateAlignedPagesEx ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN UINTN Alignment, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +#endif diff --git a/MdePkg/Include/Library/PhaseMemoryAllocationLib.h b/MdePkg/Include/Library/PhaseMemoryAllocationLib.h new file mode 100644 index 0000000000..fbe1ad6e1f --- /dev/null +++ b/MdePkg/Include/Library/PhaseMemoryAllocationLib.h @@ -0,0 +1,117 @@ +/** @file + Provides primitives to allocate and free memory buffers of various memory types and alignments. + + The Phase Memory Allocation Library abstracts primitive memory allocation operations. This library + allows code to be written in a phase-independent manner because the allocation of memory in PEI, DXE, + and SMM (for example) is done via a different mechanism. Using a common library interface makes it + much easier to port algorithms from phase to phase. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PHASE_MEMORY_ALLOCATION_LIB_H__ +#define __PHASE_MEMORY_ALLOCATION_LIB_H__ + +/** + Allocates one or more 4KB pages of a certain memory type. + + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. + +**/ +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +/** + Frees one or more 4KB pages that were previously allocated with one of the 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 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 a page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Memory The base physical address of the pages to be freed. + @param Pages The number of 4 KB pages to free. + + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + +**/ +EFI_STATUS +EFIAPI +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages + ); + +/** + Allocates a buffer of a certain pool type. + + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param MemoryType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize + ); + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer The pointer to the buffer to free. + +**/ +VOID +EFIAPI +PhaseFreePool ( + IN VOID *Buffer + ); + +/// +/// The memory type to allocate for calls to AllocatePages(). +/// +extern CONST EFI_MEMORY_TYPE gPhaseDefaultDataType; + +#endif diff --git a/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c index e540e06e00..619a3664f7 100644 --- a/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c @@ -8,352 +8,82 @@ **/ #include +#include -#include +#include #include #include #include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; + ASSERT (Type == AllocateAnyPages); if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } - Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiBootServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiReservedMemoryType, Pages); + return PeiServicesAllocatePages (MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the 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 page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + 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 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 a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = PeiServicesFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - 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. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = PeiServicesAllocatePages (MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = PeiServicesFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = PeiServicesFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData 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 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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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 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 * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType 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 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 * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, 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 + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - Status = PeiServicesFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); + return PeiServicesFreePages (Memory, Pages); } /** @@ -370,458 +100,43 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) { - // - // If we need lots of small runtime/reserved memory type from PEI in the future, - // we can consider providing a more complex algorithm that allocates runtime pages and - // provide pool allocations from those pages. - // - return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize)); -} + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + VOID *Buffer; -/** - Allocates a buffer of type EfiBootServicesData. + if (MemoryType != EfiBootServicesData) { + // + // If we need lots of small runtime/reserved memory type from PEI in the future, + // we can consider providing a more complex algorithm that allocates runtime pages and + // provide pool allocations from those pages. + // + Status = PhaseAllocatePages ( + AllocateAnyPages, + MemoryType, + EFI_SIZE_TO_PAGES (AllocationSize), + &Memory + ); + if (EFI_ERROR (Status)) { + return NULL; + } - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - EFI_STATUS Status; - VOID *Buffer; - - Status = PeiServicesAllocatePool (AllocationSize, &Buffer); - if (EFI_ERROR (Status)) { - Buffer = NULL; + Buffer = (VOID *)(UINTN)Memory; + } else { + Status = PeiServicesAllocatePool (AllocationSize, &Buffer); + if (EFI_ERROR (Status)) { + return NULL; + } } return Buffer; } -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiReservedMemoryType, AllocationSize); -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = AllocatePool (AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = AllocatePool (AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -838,7 +153,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf b/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf index f6a670871e..8f6d8cf37b 100644 --- a/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf +++ b/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf @@ -37,4 +37,5 @@ BaseMemoryLib PeiServicesLib HobLib + CommonMemoryAllocationLib diff --git a/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c index 99a8259325..0dfd86bedd 100644 --- a/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c @@ -21,11 +21,14 @@ #include #include +#include #include #include #include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; + EFI_SMRAM_DESCRIPTOR *mSmramRanges; UINTN mSmramRangeCount; @@ -114,14 +117,14 @@ SmmMemoryAllocationLibDestructor ( BOOLEAN EFIAPI BufferInSmram ( - IN VOID *Buffer + IN EFI_PHYSICAL_ADDRESS Buffer ) { UINTN Index; for (Index = 0; Index < mSmramRangeCount; Index++) { - if (((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer >= mSmramRanges[Index].CpuStart) && - ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer < (mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize))) + if ((Buffer >= mSmramRanges[Index].CpuStart) && + (Buffer < (mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize))) { return TRUE; } @@ -134,101 +137,34 @@ BufferInSmram ( Allocates one or more 4KB pages of a certain memory type. Allocates the number of 4KB pages of a certain memory type and returns a pointer - to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If - Pages is 0, then NULL is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } - Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer - to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If - Pages is 0, then NULL is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a - pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary. - If Pages is 0, then NULL is returned. If there is not enough memory remaining - to satisfy the request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a - pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary. - If Pages is 0, then NULL is returned. If there is not enough memory remaining - to satisfy the request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return NULL; + return gSmst->SmmAllocatePages (Type, MemoryType, Pages, Memory); } /** @@ -244,258 +180,39 @@ AllocateReservedPages ( Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { EFI_STATUS Status; ASSERT (Pages != 0); - if (BufferInSmram (Buffer)) { + if (BufferInSmram (Memory)) { // // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service. // So, gSmst->SmmFreePages() service is used to free it. // - Status = gSmst->SmmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); + Status = gSmst->SmmFreePages (Memory, Pages); } else { // // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service. // So, gBS->FreePages() service is used to free it. // - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); + Status = gBS->FreePages (Memory, Pages); } - 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. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment) - 1; - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = gSmst->SmmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = gSmst->SmmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData - 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 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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData - 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 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 * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType - 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 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 * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return NULL; -} - -/** - 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 The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - if (BufferInSmram (Buffer)) { - // - // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service. - // So, gSmst->SmmFreePages() service is used to free it. - // - Status = gSmst->SmmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } else { - // - // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service. - // So, gBS->FreePages() service is used to free it. - // - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } - - ASSERT_EFI_ERROR (Status); + return Status; } /** @@ -513,7 +230,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -529,426 +247,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData - and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData - and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType - and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return NULL; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize - and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize - and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return NULL; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -966,13 +264,13 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { EFI_STATUS Status; - if (BufferInSmram (Buffer)) { + if (BufferInSmram ((UINTN)Buffer)) { // // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service. // So, gSmst->SmmFreePool() service is used to free it. diff --git a/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf b/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf index 9f0ecbf663..bd652c5e9d 100644 --- a/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf +++ b/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf @@ -36,6 +36,7 @@ BaseMemoryLib SmmServicesTableLib UefiBootServicesTableLib + CommonMemoryAllocationLib [Protocols] gEfiSmmAccess2ProtocolGuid ## CONSUMES diff --git a/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c index eb1226612f..4b7e18f2e0 100644 --- a/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c @@ -9,346 +9,85 @@ #include -#include +#include #include #include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If + Pages is 0, then NULL is returned. If there is not enough memory remaining to + satisfy the request, then NULL is returned. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or + AllocateMaxAddress or AllocateAddress. + 2) MemoryType is in the range + EfiMaxMemoryType..0x6FFFFFFF. + 3) Memory is NULL. + 4) MemoryType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } - Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiBootServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiReservedMemoryType, Pages); + return gBS->AllocatePages (Type, MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the 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 page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + 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 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 a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - 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. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = gBS->FreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = gBS->FreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData 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 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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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 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 * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType 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 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 * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, 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 + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); + return gBS->FreePages (Memory, Pages); } /** @@ -365,7 +104,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -381,420 +121,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiBootServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiReservedMemoryType, AllocationSize); -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -811,7 +137,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf b/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf index 4d14a157f2..57e0740e0d 100644 --- a/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf +++ b/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf @@ -34,4 +34,5 @@ DebugLib BaseMemoryLib UefiBootServicesTableLib + CommonMemoryAllocationLib diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc index d2c65a17b4..c5ad467924 100644 --- a/MdePkg/MdeLibs.dsc.inc +++ b/MdePkg/MdeLibs.dsc.inc @@ -22,3 +22,4 @@ BaseOverflowLib|MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf MemoryProfileLib|MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.inf + CommonMemoryAllocationLib|MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c index 2246823886..ce4079fd94 100644 --- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c +++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c @@ -11,349 +11,88 @@ #include #include -#include +#include #include #include #include #include "StandaloneMmCoreMemoryAllocationServices.h" +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; + EFI_MM_SYSTEM_TABLE *gMmst = NULL; /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If + Pages is 0, then NULL is returned. If there is not enough memory remaining to + satisfy the request, then NULL is returned. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or + AllocateMaxAddress or AllocateAddress. + 2) MemoryType is in the range + EfiMaxMemoryType..0x6FFFFFFF. + 3) Memory is NULL. + 4) MemoryType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } - Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return NULL; + return gMmst->MmAllocatePages (Type, MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the 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 page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + 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 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 a 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 -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - 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. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = gMmst->MmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = (EFI_PHYSICAL_ADDRESS)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = gMmst->MmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData 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 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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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 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 * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType 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 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 * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return NULL; -} - -/** - 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 + If Buffer was not allocated with a 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 Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); + return gMmst->MmFreePages (Memory, Pages); } /** @@ -370,7 +109,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -388,420 +128,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return NULL; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return NULL; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -818,7 +144,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf index bf7530bb74..307923c87f 100644 --- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf +++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf @@ -39,6 +39,7 @@ BaseMemoryLib DebugLib HobLib + CommonMemoryAllocationLib [Guids] gEfiMmPeiMmramMemoryReserveGuid diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c index b38b32b27f..b3b38a1568 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c +++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c @@ -12,344 +12,83 @@ #include #include -#include +#include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; + /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If + Pages is 0, then NULL is returned. If there is not enough memory remaining to + satisfy the request, then NULL is returned. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or + AllocateMaxAddress or AllocateAddress. + 2) MemoryType is in the range + EfiMaxMemoryType..0x6FFFFFFF. + 3) Memory is NULL. + 4) MemoryType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } - Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return NULL; + return gMmst->MmAllocatePages (Type, MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the 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 page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + 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 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 a 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 -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - 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. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = gMmst->MmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = (EFI_PHYSICAL_ADDRESS)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = gMmst->MmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData 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 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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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 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 * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType 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 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 * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return NULL; -} - -/** - 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 + If Buffer was not allocated with a 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 Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); + return gMmst->MmFreePages (Memory, Pages); } /** @@ -366,7 +105,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -384,420 +124,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return NULL; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return NULL; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -814,7 +140,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf index f5aaff1a25..bcf7eb120d 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf +++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf @@ -35,3 +35,4 @@ BaseMemoryLib DebugLib MmServicesTableLib + CommonMemoryAllocationLib diff --git a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c index 59f9adbf1d..ae213d5da2 100755 --- a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c +++ b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c @@ -9,14 +9,17 @@ **/ #include +#include #include #include -#include +#include #include #include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + /** Add a new HOB to the HOB List. @@ -35,32 +38,49 @@ CreateHob ( ); /** - Allocates one or more pages of type EfiBootServicesData. + Allocates one or more 4KB pages of a certain memory type. - Allocates the number of pages of MemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. - If Pages is 0, then NULL is returned. - If there is not enough memory availble to satisfy the request, then NULL - is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or + AllocateMaxAddress or AllocateAddress. + 2) MemoryType is in the range + EfiMaxMemoryType..0x6FFFFFFF. + 3) Memory is NULL. + 4) MemoryType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. - @param Pages The number of 4 KB pages to allocate. - @return A pointer to the allocated buffer or NULL if allocation fails. **/ -VOID * +EFI_STATUS EFIAPI -AllocatePages ( - IN UINTN Pages +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { EFI_PEI_HOB_POINTERS Hob; EFI_PHYSICAL_ADDRESS Offset; EFI_HOB_HANDOFF_INFO_TABLE *HobTable; + ASSERT (Type == AllocateAnyPages); + Hob.Raw = GetHobList (); HobTable = Hob.HandoffInformationTable; if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } // Make sure allocation address is page alligned. @@ -73,93 +93,47 @@ AllocatePages ( // Check available memory for the allocation // if (HobTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < HobTable->EfiFreeMemoryBottom) { - return NULL; + return EFI_OUT_OF_RESOURCES; } HobTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE; - BuildMemoryAllocationHob (HobTable->EfiFreeMemoryTop, Pages * EFI_PAGE_SIZE, EfiBootServicesData); + BuildMemoryAllocationHob (HobTable->EfiFreeMemoryTop, Pages * EFI_PAGE_SIZE, MemoryType); - return (VOID *)(UINTN)HobTable->EfiFreeMemoryTop; + *Memory = HobTable->EfiFreeMemoryTop; + return EFI_SUCCESS; } /** Frees one or more 4KB pages that were previously allocated with one of the 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 page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + 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 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 a page allocation function in the Memory Allocation Library, - then ASSERT(). + If Buffer was not allocated with a 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 Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { + return EFI_SUCCESS; } -/** - Allocates one or more pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. - If Pages is 0, then NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If there is no enough memory at the specified alignment available to satisfy the - request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - - @return A pointer to the allocated buffer or NULL if allocation fails. -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Memory; - UINTN AlignmentMask; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - // - // Check overflow. - // - ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment))); - - Memory = (VOID *)(UINTN)AllocatePages (Pages + EFI_SIZE_TO_PAGES (Alignment)); - if (Memory == NULL) { - return NULL; - } - - if (Alignment == 0) { - AlignmentMask = Alignment; - } else { - AlignmentMask = Alignment - 1; - } - - return (VOID *)(UINTN)(((UINTN)Memory + AlignmentMask) & ~AlignmentMask); -} /** Allocates a buffer of type EfiBootServicesData. @@ -168,6 +142,7 @@ AllocateAlignedPages ( pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + @param MemoryType The type of memory to allocate. @param AllocationSize The number of bytes to allocate. @return A pointer to the allocated buffer or NULL if allocation fails. @@ -175,8 +150,9 @@ AllocateAlignedPages ( **/ VOID * EFIAPI -AllocatePool ( - IN UINTN AllocationSize +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { EFI_HOB_MEMORY_POOL *Hob; @@ -190,37 +166,6 @@ AllocatePool ( return (VOID *)(Hob + 1); } -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = AllocatePool (AllocationSize); - if (Buffer == NULL) { - return NULL; - } - - ZeroMem (Buffer, AllocationSize); - - return Buffer; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -237,7 +182,7 @@ AllocateZeroPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf index 46ca835552..fa9982ab2f 100755 --- a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf +++ b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf @@ -37,3 +37,4 @@ BaseMemoryLib BaseLib HobLib + CommonMemoryAllocationLib diff --git a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c index 54029283fb..b7c0076628 100644 --- a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c +++ b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include /// @@ -33,133 +33,49 @@ typedef struct { UINTN AlignedPages; } PAGE_HEAD; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + /** - Allocates one or more 4KB pages of type EfiBootServicesData. + Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. - @param Pages The number of 4 KB pages to allocate. + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or + AllocateMaxAddress or AllocateAddress. + 2) MemoryType is in the range + EfiMaxMemoryType..0x6FFFFFFF. + 3) Memory is NULL. + 4) MemoryType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * +EFI_STATUS EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return AllocateAlignedPages (Pages, SIZE_4KB); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return AllocatePages (Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return AllocatePages (Pages); -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the 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 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 a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - FreeAlignedPages (Buffer, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData 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 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 * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { PAGE_HEAD PageHead; PAGE_HEAD *PageHeadPtr; + UINTN Alignment; UINTN AlignmentMask; - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Alignment < SIZE_4KB) { - Alignment = SIZE_4KB; - } + ASSERT (Type == AllocateAnyPages); + Alignment = SIZE_4KB; AlignmentMask = Alignment - 1; // @@ -170,7 +86,7 @@ AllocateAlignedPages ( PageHead.AlignedPages = Pages; PageHead.AllocatedBufffer = malloc (EFI_PAGES_TO_SIZE (PageHead.TotalPages)); if (PageHead.AllocatedBufffer == NULL) { - return NULL; + return EFI_OUT_OF_RESOURCES; } PageHead.AlignedBuffer = (VOID *)(((UINTN)PageHead.AllocatedBufffer + AlignmentMask) & ~AlignmentMask); @@ -181,87 +97,36 @@ AllocateAlignedPages ( PageHeadPtr = (VOID *)((UINTN)PageHead.AlignedBuffer - sizeof (PAGE_HEAD)); memcpy (PageHeadPtr, &PageHead, sizeof (PAGE_HEAD)); - return PageHead.AlignedBuffer; + *Memory = (UINTN)PageHead.AlignedBuffer; + return EFI_SUCCESS; } /** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. + Frees one or more 4KB pages that were previously allocated with one of the page allocation + functions in the Memory Allocation Library. - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData 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. + 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 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 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 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 * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return AllocateAlignedPages (Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType 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 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 * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return AllocateAlignedPages (Pages, 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 + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. + @param Memory The base physical address of the pages to be freed. + @param Pages The number of 4 KB pages to free. + + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { PAGE_HEAD *PageHeadPtr; @@ -269,351 +134,43 @@ FreeAlignedPages ( // // NOTE: Partial free is not supported. Just keep it. // - PageHeadPtr = (VOID *)((UINTN)Buffer - sizeof (PAGE_HEAD)); + PageHeadPtr = (VOID *)((UINTN)Memory - sizeof (PAGE_HEAD)); if (PageHeadPtr->Signature != PAGE_HEAD_PRIVATE_SIGNATURE) { - return; + return EFI_NOT_FOUND; } if (PageHeadPtr->AlignedPages != Pages) { - return; + return EFI_INVALID_PARAMETER; } PageHeadPtr->Signature = 0; free (PageHeadPtr->AllocatedBufffer); + return EFI_SUCCESS; } /** - Allocates a buffer of type EfiBootServicesData. + Allocates a buffer of a certain pool type. - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - @param AllocationSize The number of bytes to allocate. + @param MemoryType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate. - @return A pointer to the allocated buffer or NULL if allocation fails. + @return A pointer to the allocated buffer or NULL if allocation fails. -**/VOID * +**/ +VOID * EFIAPI -AllocatePool ( - IN UINTN AllocationSize +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { return malloc (AllocationSize); } -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return AllocatePool (AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return AllocatePool (AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = malloc (AllocationSize); - if (Buffer == NULL) { - return NULL; - } - - memset (Buffer, 0, AllocationSize); - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return AllocateZeroPool (AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return AllocateZeroPool (AllocationSize); -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - Memory = malloc (AllocationSize); - if (Memory == NULL) { - return NULL; - } - - memcpy (Memory, Buffer, AllocationSize); - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return AllocateCopyPool (AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return AllocateCopyPool (AllocationSize, Buffer); -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = malloc (NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - } - - if (OldBuffer != NULL) { - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return ReallocatePool (OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return ReallocatePool (OldSize, NewSize, OldBuffer); -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -630,7 +187,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf index 44ec3fd517..6d65c87146 100644 --- a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf +++ b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf @@ -25,3 +25,4 @@ [LibraryClasses] BaseLib + CommonMemoryAllocationLib