public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Yao, Jiewen" <jiewen.yao@intel.com>
To: Achin Gupta <achin.gupta@arm.com>,
	Supreeth Venkatesh <supreeth.venkatesh@arm.com>
Cc: "ard.biesheuvel@linaro.org" <ard.biesheuvel@linaro.org>,
	"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
	"leif.lindholm@linaro.org" <leif.lindholm@linaro.org>,
	"Gao, Liming" <liming.gao@intel.com>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>,
	"nd@arm.com" <nd@arm.com>
Subject: Re: [PATCH v1 09/18] StandaloneMmPkg/MemoryAllocationLib: Add MM memory allocation library.
Date: Thu, 26 Apr 2018 13:05:53 +0000	[thread overview]
Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503AB81B6B@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <20180425143354.GO663@e104320-lin>

Same comment as previous 2.

Maybe to separate ARM specific function from generic function.

Thank you



> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Achin
> Gupta
> Sent: Wednesday, April 25, 2018 7:34 AM
> To: Supreeth Venkatesh <supreeth.venkatesh@arm.com>
> Cc: ard.biesheuvel@linaro.org; edk2-devel@lists.01.org;
> leif.lindholm@linaro.org; Yao, Jiewen <jiewen.yao@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>;
> nd@arm.com
> Subject: Re: [edk2] [PATCH v1 09/18] StandaloneMmPkg/MemoryAllocationLib:
> Add MM memory allocation library.
> 
> Hi Supreeth,
> 
> On Fri, Apr 06, 2018 at 03:42:14PM +0100, Supreeth Venkatesh wrote:
> > This patch implements management mode memory allocation services.The
> > implementation borrows the MM Core Memory Allocation services as the
> > primitive for memory allocation instead of using MM System Table
> > services.
> 
> The commit message did not really register with me. Once the MMRAM ranges
> have
> been conveyed to the MMST memory allocation services (through
> MemoryAllocationLibConstructor()), all functions in MemoryAllocationLib.c use
> the MMST services. The message seems to indicate otherwise.
> 
> On Arm, the gEfiMmPeiMmramMemoryReserveGuid HOB is used to convey the
> MMRAM
> ranges. It seems x86 uses gMmCoreDataHobGuid HOB. So it worth getting this
> reviewed by Jiewen.
> 
> The copyright years in the files need to be updated.
> 
> With that in mind..
> 
> Acked-by: Achin Gupta <achin.gupta@arm.com>
> 
> >
> > Contributed-under: TianoCore Contribution Agreement 1.1
> > Signed-off-by: Achin Gupta <achin.gupta@arm.com>
> > Signed-off-by: Supreeth Venkatesh <supreeth.venkatesh@arm.com>
> > ---
> >  StandaloneMmPkg/Include/Guid/MmCoreData.h          | 132 +++
> >  StandaloneMmPkg/Include/Guid/MmramMemoryReserve.h  |  62 ++
> >  .../MemoryAllocationLib/MemoryAllocationLib.c      | 907
> +++++++++++++++++++++
> >  .../MemoryAllocationLib/MemoryAllocationLib.inf    |  49 ++
> >  .../MemoryAllocationLib/MemoryAllocationServices.h |  38 +
> >  5 files changed, 1188 insertions(+)
> >  create mode 100644 StandaloneMmPkg/Include/Guid/MmCoreData.h
> >  create mode 100644
> StandaloneMmPkg/Include/Guid/MmramMemoryReserve.h
> >  create mode 100644
> StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationLib.c
> >  create mode 100644
> StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationLib.inf
> >  create mode 100644
> StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationServices.h
> >
> > diff --git a/StandaloneMmPkg/Include/Guid/MmCoreData.h
> b/StandaloneMmPkg/Include/Guid/MmCoreData.h
> > new file mode 100644
> > index 0000000000..c0ac772014
> > --- /dev/null
> > +++ b/StandaloneMmPkg/Include/Guid/MmCoreData.h
> > @@ -0,0 +1,132 @@
> > +/** @file
> > +  MM Core data.
> > +
> > +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> > +This program and the accompanying materials are licensed and made
> available under
> > +the terms and conditions of the BSD License that 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.
> > +
> > +**/
> > +
> > +#ifndef __MM_CORE_DATA_H__
> > +#define __MM_CORE_DATA_H__
> > +
> > +#define MM_CORE_DATA_HOB_GUID \
> > +  { 0xa160bf99, 0x2aa4, 0x4d7d, { 0x99, 0x93, 0x89, 0x9c, 0xb1, 0x2d, 0xf3,
> 0x76 }}
> > +
> > +extern EFI_GUID gMmCoreDataHobGuid;
> > +
> > +typedef struct {
> > +  //
> > +  // Address pointer to MM_CORE_PRIVATE_DATA
> > +  //
> > +  EFI_PHYSICAL_ADDRESS   Address;
> > +} MM_CORE_DATA_HOB_DATA;
> > +
> > +
> > +///
> > +/// Define values for the communications buffer used when
> gEfiEventDxeDispatchGuid is
> > +/// event signaled.  This event is signaled by the DXE Core each time the DXE
> Core
> > +/// dispatcher has completed its work.  When this event is signaled, the MM
> Core
> > +/// if notified, so the MM Core can dispatch MM drivers.  If
> COMM_BUFFER_MM_DISPATCH_ERROR
> > +/// is returned in the communication buffer, then an error occurred
> dispatching MM
> > +/// Drivers.  If COMM_BUFFER_MM_DISPATCH_SUCCESS is returned, then
> the MM Core
> > +/// dispatched all the drivers it could.  If
> COMM_BUFFER_MM_DISPATCH_RESTART is
> > +/// returned, then the MM Core just dispatched the MM Driver that
> registered
> > +/// the MM Entry Point enabling the use of MM Mode.  In this case, the MM
> Core
> > +/// should be notified again to dispatch more MM Drivers using MM Mode.
> > +///
> > +#define COMM_BUFFER_MM_DISPATCH_ERROR    0x00
> > +#define COMM_BUFFER_MM_DISPATCH_SUCCESS  0x01
> > +#define COMM_BUFFER_MM_DISPATCH_RESTART  0x02
> > +
> > +///
> > +/// Signature for the private structure shared between the MM IPL and the
> MM Core
> > +///
> > +#define MM_CORE_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('m', 'm', 'i',
> 'c')
> > +
> > +///
> > +/// Private structure that is used to share information between the MM IPL
> and
> > +/// the MM Core.  This structure is allocated from memory of type
> EfiRuntimeServicesData.
> > +/// Since runtime memory types are converted to available memory when a
> legacy boot
> > +/// is performed, the MM Core must not access any fields of this structure if a
> legacy
> > +/// boot is performed.  As a result, the MM IPL must create an event
> notification
> > +/// for the Legacy Boot event and notify the MM Core that a legacy boot is
> being
> > +/// performed.  The MM Core can then use this information to filter accesses
> to
> > +/// thos structure.
> > +///
> > +typedef struct {
> > +  UINT64                          Signature;
> > +
> > +  ///
> > +  /// The number of MMRAM ranges passed from the MM IPL to the MM
> Core.  The MM
> > +  /// Core uses these ranges of MMRAM to initialize the MM Core memory
> manager.
> > +  ///
> > +  UINT64                          MmramRangeCount;
> > +
> > +  ///
> > +  /// A table of MMRAM ranges passed from the MM IPL to the MM Core.
> The MM
> > +  /// Core uses these ranges of MMRAM to initialize the MM Core memory
> manager.
> > +  ///
> > +  EFI_PHYSICAL_ADDRESS            MmramRanges;
> > +
> > +  ///
> > +  /// The MM Foundation Entry Point.  The MM Core fills in this field when
> the
> > +  /// MM Core is initialized.  The MM IPL is responsbile for registering this
> entry
> > +  /// point with the MM Configuration Protocol.  The MM Configuration
> Protocol may
> > +  /// not be available at the time the MM IPL and MM Core are started, so the
> MM IPL
> > +  /// sets up a protocol notification on the MM Configuration Protocol and
> registers
> > +  /// the MM Foundation Entry Point as soon as the MM Configuration
> Protocol is
> > +  /// available.
> > +  ///
> > +  EFI_PHYSICAL_ADDRESS            MmEntryPoint;
> > +
> > +  ///
> > +  /// Boolean flag set to TRUE while an MMI is being processed by the MM
> Core.
> > +  ///
> > +  BOOLEAN                         MmEntryPointRegistered;
> > +
> > +  ///
> > +  /// Boolean flag set to TRUE while an MMI is being processed by the MM
> Core.
> > +  ///
> > +  BOOLEAN                         InMm;
> > +
> > +  ///
> > +  /// This field is set by the MM Core then the MM Core is initialized.  This
> field is
> > +  /// used by the MM Base 2 Protocol and MM Communication Protocol
> implementations in
> > +  /// the MM IPL.
> > +  ///
> > +  EFI_PHYSICAL_ADDRESS            Mmst;
> > +
> > +  ///
> > +  /// This field is used by the MM Communicatioon Protocol to pass a buffer
> into
> > +  /// a software MMI handler and for the software MMI handler to pass a
> buffer back to
> > +  /// the caller of the MM Communication Protocol.
> > +  ///
> > +  EFI_PHYSICAL_ADDRESS            CommunicationBuffer;
> > +
> > +  ///
> > +  /// This field is used by the MM Communicatioon Protocol to pass the size
> of a buffer,
> > +  /// in bytes, into a software MMI handler and for the software MMI
> handler to pass the
> > +  /// size, in bytes, of a buffer back to the caller of the MM Communication
> Protocol.
> > +  ///
> > +  UINT64                          BufferSize;
> > +
> > +  ///
> > +  /// This field is used by the MM Communication Protocol to pass the return
> status from
> > +  /// a software MMI handler back to the caller of the MM Communication
> Protocol.
> > +  ///
> > +  UINT64                          ReturnStatus;
> > +
> > +  EFI_PHYSICAL_ADDRESS            MmCoreImageBase;
> > +  UINT64                          MmCoreImageSize;
> > +  EFI_PHYSICAL_ADDRESS            MmCoreEntryPoint;
> > +
> > +  EFI_PHYSICAL_ADDRESS            StandaloneBfvAddress;
> > +} MM_CORE_PRIVATE_DATA;
> > +
> > +#endif
> > diff --git a/StandaloneMmPkg/Include/Guid/MmramMemoryReserve.h
> b/StandaloneMmPkg/Include/Guid/MmramMemoryReserve.h
> > new file mode 100644
> > index 0000000000..c4104b755d
> > --- /dev/null
> > +++ b/StandaloneMmPkg/Include/Guid/MmramMemoryReserve.h
> > @@ -0,0 +1,62 @@
> > +/** @file
> > +  Definition of GUIDed HOB for reserving MMRAM regions.
> > +
> > +  This file defines:
> > +  * the GUID used to identify the GUID HOB for reserving MMRAM regions.
> > +  * the data structure of MMRAM descriptor to describe MMRAM candidate
> regions
> > +  * values of state of MMRAM candidate regions
> > +  * the GUID specific data structure of HOB for reserving MMRAM regions.
> > +  This GUIDed HOB can be used to convey the existence of the T-SEG
> reservation and H-SEG usage
> > +
> > +Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
> > +Copyright (c) 2016 - 2017, 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 that 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.
> > +
> > +  @par Revision Reference:
> > +  GUIDs defined in MmCis spec version 0.9.
> > +
> > +**/
> > +
> > +#ifndef _EFI_MM_PEI_MMRAM_MEMORY_RESERVE_H_
> > +#define _EFI_MM_PEI_MMRAM_MEMORY_RESERVE_H_
> > +
> > +#define EFI_MM_PEI_MMRAM_MEMORY_RESERVE \
> > +  { \
> > +    0x0703f912, 0xbf8d, 0x4e2a, {0xbe, 0x07, 0xab, 0x27, 0x25, 0x25, 0xc5,
> 0x92 } \
> > +  }
> > +
> > +/**
> > +* GUID specific data structure of HOB for reserving MMRAM regions.
> > +*
> > +* Inconsistent with specification here:
> > +* EFI_HOB_MMRAM_DESCRIPTOR_BLOCK has been changed to
> EFI_MMRAM_HOB_DESCRIPTOR_BLOCK.
> > +* This inconsistency is kept in code in order for backward compatibility.
> > +**/
> > +typedef struct {
> > +  ///
> > +  /// Designates the number of possible regions in the system
> > +  /// that can be usable for MMRAM.
> > +  ///
> > +  /// Inconsistent with specification here:
> > +  /// In Framework MM CIS 0.91 specification, it defines the field type as
> UINTN.
> > +  /// However, HOBs are supposed to be CPU neutral, so UINT32 should be
> used instead.
> > +  ///
> > +  UINT32                NumberOfMmReservedRegions;
> > +  ///
> > +  /// Used throughout this protocol to describe the candidate
> > +  /// regions for MMRAM that are supported by this platform.
> > +  ///
> > +  EFI_MMRAM_DESCRIPTOR  Descriptor[1];
> > +} EFI_MMRAM_HOB_DESCRIPTOR_BLOCK;
> > +
> > +extern EFI_GUID gEfiMmPeiSmramMemoryReserveGuid;
> > +
> > +#endif
> > +
> > diff --git
> a/StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationLib.c
> b/StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationLib.c
> > new file mode 100644
> > index 0000000000..c177a8f538
> > --- /dev/null
> > +++
> b/StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationLib.c
> > @@ -0,0 +1,907 @@
> > +/** @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 - 2017, 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 <Guid/MmramMemoryReserve.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/HobLib.h>
> > +#include "MemoryAllocationServices.h"
> > +
> > +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.
> > +
> > +  @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);
> > +}
> > +
> > +/**
> > +  The constructor function calls MmInitializeMemoryServices to initialize
> > +  memory in MMRAM and caches EFI_MM_SYSTEM_TABLE pointer.
> > +
> > +  @param  ImageHandle   The firmware allocated handle for the EFI
> image.
> > +  @param  SystemTable   A pointer to the Management mode System
> Table.
> > +
> > +  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +MemoryAllocationLibConstructor (
> > +  IN EFI_HANDLE             ImageHandle,
> > +  IN EFI_MM_SYSTEM_TABLE    *MmSystemTable
> > +  )
> > +{
> > +  MM_CORE_PRIVATE_DATA           *MmCorePrivate;
> > +  EFI_HOB_GUID_TYPE               *GuidHob;
> > +  MM_CORE_DATA_HOB_DATA          *DataInHob;
> > +  VOID                            *HobStart;
> > +  EFI_MMRAM_HOB_DESCRIPTOR_BLOCK  *MmramRangesHobData;
> > +  EFI_MMRAM_DESCRIPTOR            *MmramRanges;
> > +  UINT32                           MmramRangeCount;
> > +  EFI_HOB_GUID_TYPE               *MmramRangesHob;
> > +
> > +  HobStart = GetHobList ();
> > +  DEBUG ((DEBUG_INFO,
> "StandaloneMmCoreMemoryAllocationLibConstructor - 0x%x\n", HobStart));
> > +
> > +  //
> > +  // Extract MM Core Private context from the Hob. If absent search for
> > +  // a Hob containing the MMRAM ranges
> > +  //
> > +  GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart);
> > +  if (GuidHob == NULL) {
> > +    MmramRangesHob = GetNextGuidHob
> (&gEfiMmPeiMmramMemoryReserveGuid, HobStart);
> > +    if (MmramRangesHob == NULL) {
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
> > +    if (MmramRangesHobData == NULL) {
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    MmramRanges = MmramRangesHobData->Descriptor;
> > +    if (MmramRanges == NULL) {
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    MmramRangeCount =
> MmramRangesHobData->NumberOfMmReservedRegions;
> > +    if (MmramRanges == NULL) {
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +  } else {
> > +    DataInHob      = GET_GUID_HOB_DATA (GuidHob);
> > +    MmCorePrivate = (MM_CORE_PRIVATE_DATA
> *)(UINTN)DataInHob->Address;
> > +    MmramRanges     = (EFI_MMRAM_DESCRIPTOR
> *)(UINTN)MmCorePrivate->MmramRanges;
> > +    MmramRangeCount = MmCorePrivate->MmramRangeCount;
> > +  }
> > +
> > +  {
> > +    UINTN                Index;
> > +
> > +    DEBUG ((DEBUG_INFO, "MmramRangeCount - 0x%x\n",
> MmramRangeCount));
> > +    for (Index = 0; Index < MmramRangeCount; Index++) {
> > +      DEBUG ((DEBUG_INFO, "MmramRanges[%d]: 0x%016lx -
> 0x%016lx\n", Index, MmramRanges[Index].CpuStart,
> MmramRanges[Index].PhysicalSize));
> > +    }
> > +  }
> > +
> > +  //
> > +  // Initialize memory service using free MMRAM
> > +  //
> > +  DEBUG ((DEBUG_INFO, "MmInitializeMemoryServices\n"));
> > +  MmInitializeMemoryServices ((UINTN)MmramRangeCount, (VOID
> *)(UINTN)MmramRanges);
> > +
> > +  // Initialize MM Services Table
> > +  gMmst = MmSystemTable;
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> a/StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationLib.inf
> b/StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationLib.inf
> > new file mode 100644
> > index 0000000000..068607f90e
> > --- /dev/null
> > +++
> b/StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationLib.inf
> > @@ -0,0 +1,49 @@
> > +## @file
> > +# Memory Allocation Library instance dedicated to MM Core.
> > +# The implementation borrows the MM Core Memory Allocation services as
> the primitive
> > +# for memory allocation instead of using MM System Table servces in an
> indirect way.
> > +# It is assumed that this library instance must be linked with MM Core in this
> package.
> > +#
> > +# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
> > +# Copyright (c) 2016 - 2017, 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.
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x0001001A
> > +  BASE_NAME                      = MemoryAllocationLib
> > +  FILE_GUID                      =
> DCDCBE1D-E760-4E1D-85B4-96E3F0439C41
> > +  MODULE_TYPE                    = MM_CORE_STANDALONE
> > +  VERSION_STRING                 = 1.0
> > +  PI_SPECIFICATION_VERSION       = 0x00010032
> > +  LIBRARY_CLASS                  =
> MemoryAllocationLib|MM_CORE_STANDALONE
> > +  CONSTRUCTOR                    = MemoryAllocationLibConstructor
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> > +[Sources]
> > +  MemoryAllocationLib.c
> > +  MemoryAllocationServices.h
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  StandaloneMmPkg/StandaloneMmPkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseMemoryLib
> > +  DebugLib
> > +  HobLib
> > +
> > +[Guids]
> > +  gEfiMmPeiMmramMemoryReserveGuid
> > diff --git
> a/StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationServices.
> h
> b/StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationServices.
> h
> > new file mode 100644
> > index 0000000000..eb4f4c3984
> > --- /dev/null
> > +++
> b/StandaloneMmPkg/Library/MemoryAllocationLib/MemoryAllocationServices.
> h
> > @@ -0,0 +1,38 @@
> > +/** @file
> > +  Contains function prototypes for Memory Services in the MM Core.
> > +
> > +  This header file borrows the StandaloneMmCore Memory Allocation
> services as the primitive
> > +  for memory allocation.
> > +
> > +  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
> > +  Copyright (c) 2016 - 2017, 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.
> > +
> > +**/
> > +
> > +#ifndef _PI_MM_CORE_MEMORY_ALLOCATION_SERVICES_H_
> > +#define _PI_MM_CORE_MEMORY_ALLOCATION_SERVICES_H_
> > +
> > +#include <Guid/MmCoreData.h>
> > +
> > +/**
> > +  Called to initialize the memory service.
> > +
> > +  @param   MmramRangeCount       Number of MMRAM Regions
> > +  @param   MmramRanges           Pointer to MMRAM Descriptors
> > +
> > +**/
> > +VOID
> > +MmInitializeMemoryServices (
> > +  IN UINTN                 MmramRangeCount,
> > +  IN EFI_MMRAM_DESCRIPTOR  *MmramRanges
> > +  );
> > +
> > +#endif
> > --
> > 2.16.2
> >
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


  reply	other threads:[~2018-04-26 13:05 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-06 14:42 [PATCH v1 00/18] *** Standalone Management Mode Core Interface for AARCH64 Platforms *** Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 01/18] ArmPkg: Add PCDs needed for MM communication driver Supreeth Venkatesh
2018-04-11 14:43   ` Achin Gupta
     [not found]     ` <AM4PR0802MB23063743A3B2F5A552BE320580870@AM4PR0802MB2306.eurprd08.prod.outlook.com>
2018-05-04 23:13       ` Supreeth Venkatesh
2018-05-04 23:17     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 02/18] ArmPkg/Drivers: Add EFI_MM_COMMUNICATION_PROTOCOL DXE driver Supreeth Venkatesh
2018-04-11 14:00   ` Achin Gupta
2018-05-04 23:18     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 03/18] ArmPkg/Include: Add MM interface SVC return codes Supreeth Venkatesh
2018-04-11 14:38   ` Achin Gupta
2018-05-04 23:19     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 04/18] ArmPkg/ArmMmuLib: Add MMU Library suitable for use in S-EL0 Supreeth Venkatesh
2018-04-11 19:21   ` Achin Gupta
2018-05-04 23:19     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 05/18] ArmPkg/ArmMmuLib: Add MMU library inf file " Supreeth Venkatesh
2018-04-11 19:24   ` Achin Gupta
2018-05-04 23:19     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 06/18] StandaloneMmPkg: Add an AArch64 specific entry point library Supreeth Venkatesh
2018-04-16 14:04   ` Achin Gupta
2018-05-04 23:20     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 07/18] StandaloneMmPkg/FvLib: Add a common FV Library for management mode Supreeth Venkatesh
2018-04-16 14:44   ` Achin Gupta
2018-05-04 23:21     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 08/18] StandaloneMmPkg/MemLib: AARCH64 Specific instance of memory check library Supreeth Venkatesh
2018-04-16 15:12   ` Achin Gupta
2018-04-16 22:30     ` Yao, Jiewen
2018-04-25 10:35       ` Achin Gupta
2018-04-26 13:02         ` Yao, Jiewen
2018-05-04 23:21     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 09/18] StandaloneMmPkg/MemoryAllocationLib: Add MM memory allocation library Supreeth Venkatesh
2018-04-25 14:33   ` Achin Gupta
2018-04-26 13:05     ` Yao, Jiewen [this message]
2018-05-04 23:23       ` Supreeth Venkatesh
2018-05-04 23:21     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 10/18] StandaloneMmPkg/HobLib: Add AARCH64 Specific HOB Library for management mode Supreeth Venkatesh
2018-04-25 14:50   ` Achin Gupta
2018-04-26 13:04     ` Yao, Jiewen
2018-05-04 23:22       ` Supreeth Venkatesh
2018-05-04 23:25     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 11/18] StandaloneMmPkg: MM driver entry point library Supreeth Venkatesh
2018-04-30 14:29   ` Achin Gupta
2018-05-04 23:24     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 12/18] StandaloneMmPkg/CpuMm: Add CPU driver suitable for ARM Platforms Supreeth Venkatesh
2018-04-18 22:09   ` Daniil Egranov
2018-05-04 23:25     ` Supreeth Venkatesh
2018-04-30 15:50   ` Achin Gupta
2018-05-04 23:24     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 13/18] StandaloneMmPkg/Core: Implementation of Standalone MM Core Module Supreeth Venkatesh
2018-04-30 19:19   ` Achin Gupta
2018-04-30 19:28     ` Ard Biesheuvel
2018-04-30 20:17       ` Achin Gupta
2018-05-01  8:18       ` Laszlo Ersek
2018-05-04 23:28     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 14/18] StandaloneMmPkg: Describe the declaration, definition and fdf files Supreeth Venkatesh
2018-04-18 19:50   ` Daniil Egranov
2018-05-04 23:29     ` Supreeth Venkatesh
2018-04-30 19:32   ` Achin Gupta
2018-05-04 23:28     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 15/18] ArmPkg: Extra action to update permissions for S-ELO MM Image Supreeth Venkatesh
2018-04-30 19:49   ` Achin Gupta
2018-05-04 23:30     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 16/18] BaseTools/AutoGen: Update header file for MM modules Supreeth Venkatesh
2018-04-30 19:52   ` Achin Gupta
2018-05-04 23:30     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 17/18] StandaloneMmPkg: Add application to test MM communication protocol Supreeth Venkatesh
2018-04-30 20:02   ` Achin Gupta
2018-05-04 23:31     ` Supreeth Venkatesh
2018-04-06 14:42 ` [PATCH v1 18/18] StandaloneMmPkg: Add handler to handle event received from Normal World Supreeth Venkatesh
2018-04-08  6:01 ` [PATCH v1 00/18] *** Standalone Management Mode Core Interface for AARCH64 Platforms *** Yao, Jiewen
2018-05-04 23:15   ` Supreeth Venkatesh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=74D8A39837DF1E4DA445A8C0B3885C503AB81B6B@shsmsx102.ccr.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox