/** @file\r
- Support routines for memory allocation routines based on SMM Core internal functions.\r
+ Support routines for memory allocation routines based on SMM Core internal functions,\r
+ with memory profile support.\r
\r
The PI System Management Mode Core Interface Specification only allows the use\r
of EfiRuntimeServicesCode and EfiRuntimeServicesData memory types for memory \r
In addition, allocation for the Reserved memory types are not supported and will \r
always return NULL.\r
\r
- Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials \r
are licensed and made available under the terms and conditions of the BSD License \r
which accompanies this distribution. The full text of the license may be found at \r
\r
#include <PiSmm.h>\r
\r
-#include <Protocol/SmmAccess2.h>\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/DebugLib.h>\r
#include "PiSmmCoreMemoryAllocationServices.h"\r
\r
+#include <Library/MemoryProfileLib.h>\r
+\r
EFI_SMRAM_DESCRIPTOR *mSmmCoreMemoryAllocLibSmramRanges = NULL;\r
UINTN mSmmCoreMemoryAllocLibSmramRangeCount = 0;\r
\r
\r
@param[in] Buffer The pointer to the buffer to be checked.\r
\r
- @retval TURE The buffer is in SMRAM ranges.\r
+ @retval TRUE The buffer is in SMRAM ranges.\r
@retval FALSE The buffer is out of SMRAM ranges.\r
**/\r
BOOLEAN\r
IN UINTN Pages\r
)\r
{\r
- return InternalAllocatePages (EfiRuntimeServicesData, Pages);\r
+ VOID *Buffer;\r
+\r
+ Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages);\r
+ if (Buffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES,\r
+ EfiRuntimeServicesData,\r
+ Buffer,\r
+ EFI_PAGES_TO_SIZE(Pages),\r
+ NULL\r
+ );\r
+ }\r
+ return Buffer;\r
}\r
\r
/**\r
IN UINTN Pages\r
)\r
{\r
- return InternalAllocatePages (EfiRuntimeServicesData, Pages);\r
+ VOID *Buffer;\r
+\r
+ Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages);\r
+ if (Buffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES,\r
+ EfiRuntimeServicesData,\r
+ Buffer,\r
+ EFI_PAGES_TO_SIZE(Pages),\r
+ NULL\r
+ );\r
+ }\r
+ return Buffer;\r
}\r
\r
/**\r
Status = SmmFreePages (Memory, UnalignedPages);\r
ASSERT_EFI_ERROR (Status);\r
}\r
- Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));\r
+ Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);\r
UnalignedPages = RealPages - Pages - UnalignedPages;\r
if (UnalignedPages > 0) {\r
//\r
IN UINTN Alignment\r
)\r
{\r
- return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
+ VOID *Buffer;\r
+\r
+ Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
+ if (Buffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES,\r
+ EfiRuntimeServicesData,\r
+ Buffer,\r
+ EFI_PAGES_TO_SIZE(Pages),\r
+ NULL\r
+ );\r
+ }\r
+ return Buffer;\r
}\r
\r
/**\r
IN UINTN Alignment\r
)\r
{\r
- return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
+ VOID *Buffer;\r
+\r
+ Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
+ if (Buffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES,\r
+ EfiRuntimeServicesData,\r
+ Buffer,\r
+ EFI_PAGES_TO_SIZE(Pages),\r
+ NULL\r
+ );\r
+ }\r
+ return Buffer;\r
}\r
\r
/**\r
IN UINTN AllocationSize\r
)\r
{\r
- return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
+ VOID *Buffer;\r
+\r
+ Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
+ if (Buffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL,\r
+ EfiRuntimeServicesData,\r
+ Buffer,\r
+ AllocationSize,\r
+ NULL\r
+ );\r
+ }\r
+ return Buffer;\r
}\r
\r
/**\r
IN UINTN AllocationSize\r
)\r
{\r
- return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
+ VOID *Buffer;\r
+\r
+ Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
+ if (Buffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL,\r
+ EfiRuntimeServicesData,\r
+ Buffer,\r
+ AllocationSize,\r
+ NULL\r
+ );\r
+ }\r
+ return Buffer;\r
}\r
\r
/**\r
IN UINTN AllocationSize\r
)\r
{\r
- return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
+ VOID *Buffer;\r
+\r
+ Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
+ if (Buffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL,\r
+ EfiRuntimeServicesData,\r
+ Buffer,\r
+ AllocationSize,\r
+ NULL\r
+ );\r
+ }\r
+ return Buffer;\r
}\r
\r
/**\r
IN UINTN AllocationSize\r
)\r
{\r
- return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
+ VOID *Buffer;\r
+\r
+ Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
+ if (Buffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL,\r
+ EfiRuntimeServicesData,\r
+ Buffer,\r
+ AllocationSize,\r
+ NULL\r
+ );\r
+ }\r
+ return Buffer;\r
}\r
\r
/**\r
IN CONST VOID *Buffer\r
)\r
{\r
- return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
+ VOID *NewBuffer;\r
+\r
+ NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
+ if (NewBuffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL,\r
+ EfiRuntimeServicesData,\r
+ NewBuffer,\r
+ AllocationSize,\r
+ NULL\r
+ );\r
+ }\r
+ return NewBuffer;\r
}\r
\r
/**\r
IN CONST VOID *Buffer\r
)\r
{\r
- return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
+ VOID *NewBuffer;\r
+\r
+ NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
+ if (NewBuffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL,\r
+ EfiRuntimeServicesData,\r
+ NewBuffer,\r
+ AllocationSize,\r
+ NULL\r
+ );\r
+ }\r
+ return NewBuffer;\r
}\r
\r
/**\r
IN VOID *OldBuffer OPTIONAL\r
)\r
{\r
- return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);\r
+ VOID *Buffer;\r
+\r
+ Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);\r
+ if (Buffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL,\r
+ EfiRuntimeServicesData,\r
+ Buffer,\r
+ NewSize,\r
+ NULL\r
+ );\r
+ }\r
+ return Buffer;\r
}\r
\r
/**\r
IN VOID *OldBuffer OPTIONAL\r
)\r
{\r
- return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);\r
+ VOID *Buffer;\r
+\r
+ Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);\r
+ if (Buffer != NULL) {\r
+ MemoryProfileLibRecord (\r
+ (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
+ MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL,\r
+ EfiRuntimeServicesData,\r
+ Buffer,\r
+ NewSize,\r
+ NULL\r
+ );\r
+ }\r
+ return Buffer;\r
}\r
\r
/**\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
+ EFI_STATUS Status;\r
SMM_CORE_PRIVATE_DATA *SmmCorePrivate;\r
UINTN Size;\r
+ VOID *BootServicesData;\r
\r
SmmCorePrivate = (SMM_CORE_PRIVATE_DATA *)ImageHandle;\r
+\r
+ //\r
+ // The FreePool()/FreePages() will need use SmramRanges data to know whether\r
+ // the buffer to free is in SMRAM range or not. And there may be FreePool()/\r
+ // FreePages() indrectly during calling SmmInitializeMemoryServices(), but\r
+ // no SMRAM could be allocated before calling SmmInitializeMemoryServices(),\r
+ // so temporarily use BootServicesData to hold the SmramRanges data.\r
+ //\r
+ mSmmCoreMemoryAllocLibSmramRangeCount = SmmCorePrivate->SmramRangeCount;\r
+ Size = mSmmCoreMemoryAllocLibSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR);\r
+ Status = gBS->AllocatePool (EfiBootServicesData, Size, (VOID **) &mSmmCoreMemoryAllocLibSmramRanges);\r
+ ASSERT_EFI_ERROR (Status);\r
+ ASSERT (mSmmCoreMemoryAllocLibSmramRanges != NULL);\r
+ CopyMem (mSmmCoreMemoryAllocLibSmramRanges, SmmCorePrivate->SmramRanges, Size);\r
+\r
//\r
// Initialize memory service using free SMRAM\r
//\r
SmmInitializeMemoryServices (SmmCorePrivate->SmramRangeCount, SmmCorePrivate->SmramRanges);\r
\r
- mSmmCoreMemoryAllocLibSmramRangeCount = SmmCorePrivate->FullSmramRangeCount;\r
- Size = mSmmCoreMemoryAllocLibSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR);\r
- mSmmCoreMemoryAllocLibSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size);\r
+ //\r
+ // Move the SmramRanges data from BootServicesData to SMRAM.\r
+ //\r
+ BootServicesData = mSmmCoreMemoryAllocLibSmramRanges;\r
+ mSmmCoreMemoryAllocLibSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocateCopyPool (Size, (VOID *) BootServicesData);\r
ASSERT (mSmmCoreMemoryAllocLibSmramRanges != NULL);\r
- CopyMem (mSmmCoreMemoryAllocLibSmramRanges, SmmCorePrivate->FullSmramRanges, Size);\r
+\r
+ //\r
+ // Free the temporarily used BootServicesData.\r
+ //\r
+ Status = gBS->FreePool (BootServicesData);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
return EFI_SUCCESS;\r
}\r