Reviewed-by: jiewen....@intel.com

> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheu...@linaro.org]
> Sent: Wednesday, January 16, 2019 12:22 PM
> To: edk2-devel@lists.01.org
> Cc: Ard Biesheuvel <ard.biesheu...@linaro.org>; Achin Gupta
> <achin.gu...@arm.com>; Yao, Jiewen <jiewen....@intel.com>; Supreeth
> Venkatesh <supreeth.venkat...@arm.com>; Leif Lindholm
> <leif.lindh...@linaro.org>; Jagadeesh Ujja <jagadeesh.u...@arm.com>;
> Thomas Panakamattam Abraham <thomas.abra...@arm.com>; Sami
> Mujawar <sami.muja...@arm.com>
> Subject: [PATCH v2 02/11] StandaloneMmPkg: add MM_STANDALONE
> MemoryAllocationLib implementation
> 
> This MemoryAllocationLib code is based on the staging implementation of
> StandaloneMmPkg, with the following changes:
> - use correct MODULE_TYPE
> - include MmServicesTableLib instead of declaring gMmst directly
> - update code comments referring to the MM core
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Jagadeesh Ujja <jagadeesh.u...@arm.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
> ---
> 
> StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalone
> MmMemoryAllocationLib.c   | 822 ++++++++++++++++++++
> 
> StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalone
> MmMemoryAllocationLib.inf |  42 +
>  2 files changed, 864 insertions(+)
> 
> diff --git
> a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> neMmMemoryAllocationLib.c
> b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> neMmMemoryAllocationLib.c
> new file mode 100644
> index 000000000000..c7c1282babff
> --- /dev/null
> +++
> b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> neMmMemoryAllocationLib.c
> @@ -0,0 +1,822 @@
> +/** @file
> +  Support routines for memory allocation routines based on Standalone
> MM Core internal functions.
> +
> +  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include <PiMm.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/MmServicesTableLib.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.  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.
> +
> +  @return A pointer to the allocated buffer or NULL if allocation fails.
> +
> +**/
> +VOID *
> +InternalAllocatePages (
> +  IN EFI_MEMORY_TYPE  MemoryType,
> +  IN UINTN            Pages
> +  )
> +{
> +  EFI_STATUS            Status;
> +  EFI_PHYSICAL_ADDRESS  Memory;
> +
> +  if (Pages == 0) {
> +    return NULL;
> +  }
> +
> +  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;
> +}
> +
> +/**
> +  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;
> +
> +  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
> +  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
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  ASSERT (Pages != 0);
> +  Status = gMmst->MmFreePages ((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.
> +
> +  @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 *
> +InternalAllocatePool (
> +  IN EFI_MEMORY_TYPE  MemoryType,
> +  IN UINTN            AllocationSize
> +  )
> +{
> +  EFI_STATUS  Status;
> +  VOID        *Memory;
> +
> +  Memory = NULL;
> +
> +  Status = gMmst->MmAllocatePool (MemoryType, AllocationSize,
> &Memory);
> +  if (EFI_ERROR (Status)) {
> +    Memory = NULL;
> +  }
> +  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.
> +
> +  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
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  Status = gMmst->MmFreePool (Buffer);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> diff --git
> a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> neMmMemoryAllocationLib.inf
> b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> neMmMemoryAllocationLib.inf
> new file mode 100644
> index 000000000000..8776e34e7c06
> --- /dev/null
> +++
> b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/Standalo
> neMmMemoryAllocationLib.inf
> @@ -0,0 +1,42 @@
> +## @file
> +# Memory Allocation Library instance standalone MM modules.
> +#
> +# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
> +# Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
> +#
> +#  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.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = MemoryAllocationLib
> +  FILE_GUID                      =
> 54646378-A9DC-473F-9BE1-BD027C4C76DE
> +  MODULE_TYPE                    = MM_STANDALONE
> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x00010032
> +  LIBRARY_CLASS                  =
> MemoryAllocationLib|MM_STANDALONE
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64
> +#
> +
> +[Sources]
> +  StandaloneMmMemoryAllocationLib.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  StandaloneMmPkg/StandaloneMmPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  MmServicesTableLib
> --
> 2.17.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to