X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdePkg%2FLibrary%2FSmmMemoryAllocationLib%2FMemoryAllocationLib.c;h=c0247a3a42374372301a6db91af58b20ee6ff5c8;hb=9344f0921518309295da89c221d10cbead8531aa;hp=3a539e36432aa6903c2fd5a398ce22a85d9819bc;hpb=2fc59a003ed9104f9feebe0e418f2a04a50f3284;p=mirror_edk2.git
diff --git a/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c
index 3a539e3643..c0247a3a42 100644
--- a/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c
+++ b/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c
@@ -1,40 +1,141 @@
/** @file
- Support routines for memory allocation routines based
+ Support routines for memory allocation routines based
on SMM Services Table services for SMM phase drivers.
-
+
The PI System Management Mode Core Interface Specification only allows the use
- of EfiRuntimeServicesCode and EfiRuntimeServicesData memory types for memory
- allocations through the SMM Services Table. The functions in the Memory
- Allocation Library use EfiBootServicesData as the default memory allocation
- type. For this SMM specific instance of the Memory Allocation Library,
- EfiRuntimeServicesData is used as the default memory type for all allocations.
- In addition, allocation for the Reserved memory types are not supported and
- will always return NULL.
-
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php.
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ of EfiRuntimeServicesCode and EfiRuntimeServicesData memory types for memory
+ allocations through the SMM Services Table as the SMRAM space should be
+ reserved after BDS phase. The functions in the Memory Allocation Library use
+ EfiBootServicesData as the default memory allocation type. For this SMM
+ specific instance of the Memory Allocation Library, EfiRuntimeServicesData
+ is used as the default memory type for all allocations. In addition,
+ allocation for the Reserved memory types are not supported and will always
+ return NULL.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
+#include
#include
+#include
#include
#include
#include
+EFI_SMRAM_DESCRIPTOR *mSmramRanges;
+UINTN mSmramRangeCount;
+
+/**
+ The constructor function caches SMRAM ranges that are present in the system.
+
+ It will ASSERT() if SMM Access2 Protocol doesn't exist.
+ It will ASSERT() if SMRAM ranges can't be got.
+ It will ASSERT() if Resource can't be allocated for cache SMRAM range.
+ It will always return EFI_SUCCESS.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+SmmMemoryAllocationLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
+ UINTN Size;
+
+ //
+ // Locate SMM Access2 Protocol
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiSmmAccess2ProtocolGuid,
+ NULL,
+ (VOID **)&SmmAccess
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get SMRAM range information
+ //
+ Size = 0;
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ mSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size);
+ ASSERT (mSmramRanges != NULL);
+
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);
+ ASSERT_EFI_ERROR (Status);
+
+ mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ If SMM driver exits with an error, it must call this routine
+ to free the allocated resource before the exiting.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The deconstructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+SmmMemoryAllocationLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ FreePool (mSmramRanges);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Check whether the start address of buffer is within any of the SMRAM ranges.
+
+ @param[in] Buffer The pointer to the buffer to be checked.
+
+ @retval TRUE The buffer is in SMRAM ranges.
+ @retval FALSE The buffer is out of SMRAM ranges.
+**/
+BOOLEAN
+EFIAPI
+BufferInSmram (
+ IN VOID *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))) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/**
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 MemoryType The type of memory to allocate.
@param Pages The number of 4 KB pages to allocate.
@@ -44,12 +145,12 @@
**/
VOID *
InternalAllocatePages (
- IN EFI_MEMORY_TYPE MemoryType,
+ IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages
)
{
EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS Memory;
+ EFI_PHYSICAL_ADDRESS Memory;
if (Pages == 0) {
return NULL;
@@ -63,12 +164,12 @@ InternalAllocatePages (
}
/**
- Allocates one or more 4KB pages of type EfiBootServicesData.
+ Allocates one or more 4KB pages of type EfiRuntimeServicesData.
- 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 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.
@@ -87,10 +188,10 @@ AllocatePages (
/**
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.
+ 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.
@@ -109,10 +210,10 @@ AllocateRuntimePages (
/**
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.
+ 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.
@@ -132,15 +233,15 @@ AllocateReservedPages (
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().
+ 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.
@@ -155,22 +256,36 @@ FreePages (
EFI_STATUS Status;
ASSERT (Pages != 0);
- Status = gSmst->SmmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
+ 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);
}
/**
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.
+ 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.
+ @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.
@@ -178,7 +293,7 @@ FreePages (
**/
VOID *
InternalAllocateAlignedPages (
- IN EFI_MEMORY_TYPE MemoryType,
+ IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
IN UINTN Alignment
)
@@ -194,13 +309,13 @@ InternalAllocateAlignedPages (
// 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.
+ // Calculate the total number of pages since alignment is larger than page size.
//
AlignmentMask = Alignment - 1;
RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
@@ -208,7 +323,7 @@ InternalAllocateAlignedPages (
// 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;
@@ -222,7 +337,7 @@ InternalAllocateAlignedPages (
Status = gSmst->SmmFreePages (Memory, UnalignedPages);
ASSERT_EFI_ERROR (Status);
}
- Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
+ Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);
UnalignedPages = RealPages - Pages - UnalignedPages;
if (UnalignedPages > 0) {
//
@@ -245,17 +360,19 @@ InternalAllocateAlignedPages (
}
/**
- Allocates one or more 4KB pages of type EfiBootServicesData at a specified 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.
- 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.
+ @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.
@@ -274,15 +391,17 @@ AllocateAlignedPages (
/**
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.
-
+ 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.
+ @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.
@@ -301,15 +420,17 @@ AllocateAlignedRuntimePages (
/**
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.
-
+ 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.
+ @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.
@@ -329,15 +450,15 @@ AllocateAlignedReservedPages (
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().
+ 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.
@@ -352,16 +473,29 @@ FreeAlignedPages (
EFI_STATUS Status;
ASSERT (Pages != 0);
- Status = gSmst->SmmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
+ 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);
}
/**
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.
+ 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.
@@ -371,7 +505,7 @@ FreeAlignedPages (
**/
VOID *
InternalAllocatePool (
- IN EFI_MEMORY_TYPE MemoryType,
+ IN EFI_MEMORY_TYPE MemoryType,
IN UINTN AllocationSize
)
{
@@ -386,11 +520,12 @@ InternalAllocatePool (
}
/**
- Allocates a buffer of type EfiBootServicesData.
+ Allocates a buffer of type EfiRuntimeServicesData.
- 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.
+ 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.
@@ -409,9 +544,10 @@ AllocatePool (
/**
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.
+ 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.
@@ -430,9 +566,10 @@ AllocateRuntimePool (
/**
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.
+ 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.
@@ -451,10 +588,10 @@ AllocateReservedPool (
/**
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.
+ 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.
@@ -464,9 +601,9 @@ AllocateReservedPool (
**/
VOID *
InternalAllocateZeroPool (
- IN EFI_MEMORY_TYPE PoolType,
+ IN EFI_MEMORY_TYPE PoolType,
IN UINTN AllocationSize
- )
+ )
{
VOID *Memory;
@@ -478,12 +615,12 @@ InternalAllocateZeroPool (
}
/**
- Allocates and zeros a buffer of type EfiBootServicesData.
+ Allocates and zeros a buffer of type EfiRuntimeServicesData.
- 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.
+ 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.
@@ -502,10 +639,10 @@ AllocateZeroPool (
/**
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.
+ 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.
@@ -524,10 +661,10 @@ AllocateRuntimeZeroPool (
/**
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.
+ 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.
@@ -546,12 +683,12 @@ AllocateReservedZeroPool (
/**
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().
+ 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.
@@ -562,10 +699,10 @@ AllocateReservedZeroPool (
**/
VOID *
InternalAllocateCopyPool (
- IN EFI_MEMORY_TYPE PoolType,
+ IN EFI_MEMORY_TYPE PoolType,
IN UINTN AllocationSize,
IN CONST VOID *Buffer
- )
+ )
{
VOID *Memory;
@@ -577,18 +714,19 @@ InternalAllocateCopyPool (
Memory = CopyMem (Memory, Buffer, AllocationSize);
}
return Memory;
-}
+}
/**
- Copies a buffer to an allocated buffer of type EfiBootServicesData.
+ 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.
- 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().
+ 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.
@@ -609,13 +747,14 @@ AllocateCopyPool (
/**
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.
-
+ 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().
+ 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.
@@ -636,13 +775,14 @@ AllocateRuntimeCopyPool (
/**
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.
-
+ 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().
+ 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.
@@ -664,27 +804,27 @@ AllocateReservedCopyPool (
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
+ 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().
+
+ 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.
+ @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 EFI_MEMORY_TYPE PoolType,
IN UINTN OldSize,
IN UINTN NewSize,
IN VOID *OldBuffer OPTIONAL
@@ -701,22 +841,22 @@ InternalReallocatePool (
}
/**
- Reallocates a buffer of type EfiBootServicesData.
+ Reallocates a buffer of type EfiRuntimeServicesData.
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
+ 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().
+
+ 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.
+ @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.
@@ -736,19 +876,19 @@ ReallocatePool (
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
+ 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().
+ 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.
+ @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.
@@ -768,19 +908,19 @@ ReallocateRuntimePool (
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
+ 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().
+ 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.
+ @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.
@@ -797,15 +937,16 @@ ReallocateReservedPool (
}
/**
- Frees a buffer that was previously allocated with one of the pool allocation functions in the
- Memory Allocation Library.
+ 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.
- 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().
+ 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.
@@ -818,6 +959,18 @@ FreePool (
{
EFI_STATUS Status;
- Status = gSmst->SmmFreePool (Buffer);
+ if (BufferInSmram (Buffer)) {
+ //
+ // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service.
+ // So, gSmst->SmmFreePool() service is used to free it.
+ //
+ Status = gSmst->SmmFreePool (Buffer);
+ } else {
+ //
+ // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
+ // So, gBS->FreePool() service is used to free it.
+ //
+ Status = gBS->FreePool (Buffer);
+ }
ASSERT_EFI_ERROR (Status);
}