From 6cf6d8247acb7445486abe45f0864b56a5ce9b85 Mon Sep 17 00:00:00 2001
From: Mikhail Krichanov <mikhailkrichanov@gmail.com>
Date: Thu, 4 May 2023 15:24:56 +0300
Subject: [PATCH] MdePkg: Introduce CommonMemoryAllocationLib

---
 .../MemoryAllocationLib.c                     |  182 +--
 .../PrePiMemoryAllocationLib.inf              |    1 +
 .../GuardUefiMemoryAllocationLib.inf          |    1 +
 .../MemoryAllocationLib.c                     |  765 +------------
 .../Core/PiSmmCore/MemoryAllocation.c         |  952 +---------------
 .../BaseMemoryAllocationLibNull.c             |  530 +--------
 .../BaseMemoryAllocationLibNull.inf           |    1 +
 .../CommonMemoryAllocationLib.c               |  978 ++++++++++++++++
 .../CommonMemoryAllocationLib.inf             |   37 +
 .../CommonMemoryAllocationLib.uni             |   15 +
 .../CommonMemoryAllocationLibEx.c             |  150 +++
 .../DxeCoreMemoryAllocationLib.inf            |    1 +
 .../MemoryAllocationLib.c                     | 1012 +----------------
 .../PiSmmCoreMemoryAllocationLib.inf          |    2 +-
 .../Include/Library/MemoryAllocationLibEx.h   |   75 ++
 .../Library/PhaseMemoryAllocationLib.h        |  117 ++
 .../MemoryAllocationLib.c                     |  815 ++-----------
 .../PeiMemoryAllocationLib.inf                |    1 +
 .../MemoryAllocationLib.c                     |  782 +------------
 .../SmmMemoryAllocationLib.inf                |    1 +
 .../MemoryAllocationLib.c                     |  768 +------------
 .../UefiMemoryAllocationLib.inf               |    1 +
 MdePkg/MdeLibs.dsc.inc                        |    1 +
 .../StandaloneMmCoreMemoryAllocationLib.c     |  768 +------------
 .../StandaloneMmCoreMemoryAllocationLib.inf   |    1 +
 .../StandaloneMmMemoryAllocationLib.c         |  768 +------------
 .../StandaloneMmMemoryAllocationLib.inf       |    1 +
 .../MemoryAllocationLib.c                     |  171 +--
 .../UefiPayloadMemoryAllocationLib.inf        |    1 +
 .../MemoryAllocationLibPosix.c                |  573 ++--------
 .../MemoryAllocationLibPosix.inf              |    1 +
 31 files changed, 1971 insertions(+), 7501 deletions(-)
 create mode 100644 MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c
 create mode 100644 MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf
 create mode 100644 MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.uni
 create mode 100644 MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLibEx.c
 create mode 100644 MdePkg/Include/Library/MemoryAllocationLibEx.h
 create mode 100644 MdePkg/Include/Library/PhaseMemoryAllocationLib.h

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