diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
index 21cdf319d45b..b31c994f43e2 100644
--- a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf
@@ -45,6 +45,7 @@ [Packages]
 
 [LibraryClasses]
   ArmLib
+  ArmMmuLib
   BaseMemoryLib
   CacheMaintenanceLib
   CpuLib
diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
index 4608b0cccccc..40d97e09b566 100644
--- a/ArmPkg/Include/Library/ArmLib.h
+++ b/ArmPkg/Include/Library/ArmLib.h
@@ -371,14 +371,6 @@ ArmGetTTBR0BaseAddress (
   VOID
   );
 
-RETURN_STATUS
-EFIAPI
-ArmConfigureMmu (
-  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,
-  OUT VOID                         **TranslationTableBase OPTIONAL,
-  OUT UINTN                         *TranslationTableSize  OPTIONAL
-  );
-
 BOOLEAN
 EFIAPI
 ArmMmuEnabled (
@@ -595,34 +587,4 @@ ArmUnsetCpuActlrBit (
   IN  UINTN    Bits
   );
 
-RETURN_STATUS
-ArmSetMemoryRegionNoExec (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  );
-
-RETURN_STATUS
-ArmClearMemoryRegionNoExec (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  );
-
-RETURN_STATUS
-ArmSetMemoryRegionReadOnly (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  );
-
-RETURN_STATUS
-ArmClearMemoryRegionReadOnly (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  );
-
-VOID
-ArmReplaceLiveTranslationEntry (
-  IN  UINT64  *Entry,
-  IN  UINT64  Value
-  );
-
 #endif // __ARM_LIB__
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64BaseLibConstructor.c b/ArmPkg/Library/ArmLib/AArch64/AArch64BaseLibConstructor.c
deleted file mode 100644
index d2d0d3c15ee3..000000000000
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64BaseLibConstructor.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#/* @file
-#
-#  Copyright (c) 2016, Linaro Limited. All rights reserved.
-#
-#  This program and the accompanying materials
-#  are licensed and made available under the terms and conditions of the BSD License
-#  which accompanies this distribution.  The full text of the license may be found at
-#  http://opensource.org/licenses/bsd-license.php
-#
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-#*/
-
-#include <Base.h>
-
-#include <Library/ArmLib.h>
-#include <Library/CacheMaintenanceLib.h>
-
-RETURN_STATUS
-EFIAPI
-AArch64LibConstructor (
-  VOID
-  )
-{
-  extern UINT32 ArmReplaceLiveTranslationEntrySize;
-
-  //
-  // The ArmReplaceLiveTranslationEntry () helper function may be invoked
-  // with the MMU off so we have to ensure that it gets cleaned to the PoC
-  //
-  WriteBackDataCacheRange (ArmReplaceLiveTranslationEntry,
-    ArmReplaceLiveTranslationEntrySize);
-
-  return RETURN_SUCCESS;
-}
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
index ef9d261b910d..f0de4aa7dfb4 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
@@ -20,11 +20,9 @@ [Defines]
   MODULE_TYPE                    = BASE
   VERSION_STRING                 = 1.0
   LIBRARY_CLASS                  = ArmLib
-  CONSTRUCTOR                    = AArch64LibConstructor
 
 [Sources.AARCH64]
   AArch64Lib.c
-  AArch64Mmu.c
   AArch64ArchTimer.c
   ArmLibSupportV8.S
   AArch64Support.S
@@ -32,7 +30,6 @@ [Sources.AARCH64]
 
   ../Common/AArch64/ArmLibSupport.S
   ../Common/ArmLib.c
-  AArch64BaseLibConstructor.c
 
 [Packages]
   ArmPkg/ArmPkg.dec
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf b/ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf
index 23fbe8673198..e41ef0815581 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64LibPrePi.inf
@@ -29,7 +29,6 @@ [Sources.common]
   ../Common/ArmLib.c
 
   AArch64Lib.c
-  AArch64Mmu.c
 
   AArch64ArchTimer.c
   AArch64ArchTimerSupport.S
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
deleted file mode 100644
index 07864bac28e6..000000000000
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
+++ /dev/null
@@ -1,751 +0,0 @@
-/** @file
-*  File managing the MMU for ARMv8 architecture
-*
-*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
-*
-*  This program and the accompanying materials
-*  are licensed and made available under the terms and conditions of the BSD License
-*  which accompanies this distribution.  The full text of the license may be found at
-*  http://opensource.org/licenses/bsd-license.php
-*
-*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-*
-**/
-
-#include <Uefi.h>
-#include <Chipset/AArch64.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/ArmLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include "AArch64Lib.h"
-#include "ArmLibPrivate.h"
-
-// We use this index definition to define an invalid block entry
-#define TT_ATTR_INDX_INVALID    ((UINT32)~0)
-
-INT32 HaveMmuRoutines = 1;
-
-STATIC
-UINT64
-ArmMemoryAttributeToPageAttribute (
-  IN ARM_MEMORY_REGION_ATTRIBUTES  Attributes
-  )
-{
-  switch (Attributes) {
-  case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
-  case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
-    return TT_ATTR_INDX_MEMORY_WRITE_BACK | TT_SH_INNER_SHAREABLE;
-
-  case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
-  case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
-    return TT_ATTR_INDX_MEMORY_WRITE_THROUGH | TT_SH_INNER_SHAREABLE;
-
-  // Uncached and device mappings are treated as outer shareable by default,
-  case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
-  case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
-    return TT_ATTR_INDX_MEMORY_NON_CACHEABLE;
-
-  default:
-    ASSERT(0);
-  case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
-  case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
-    if (ArmReadCurrentEL () == AARCH64_EL2)
-      return TT_ATTR_INDX_DEVICE_MEMORY | TT_XN_MASK;
-    else
-      return TT_ATTR_INDX_DEVICE_MEMORY | TT_UXN_MASK | TT_PXN_MASK;
-  }
-}
-
-UINT64
-PageAttributeToGcdAttribute (
-  IN UINT64 PageAttributes
-  )
-{
-  UINT64  GcdAttributes;
-
-  switch (PageAttributes & TT_ATTR_INDX_MASK) {
-  case TT_ATTR_INDX_DEVICE_MEMORY:
-    GcdAttributes = EFI_MEMORY_UC;
-    break;
-  case TT_ATTR_INDX_MEMORY_NON_CACHEABLE:
-    GcdAttributes = EFI_MEMORY_WC;
-    break;
-  case TT_ATTR_INDX_MEMORY_WRITE_THROUGH:
-    GcdAttributes = EFI_MEMORY_WT;
-    break;
-  case TT_ATTR_INDX_MEMORY_WRITE_BACK:
-    GcdAttributes = EFI_MEMORY_WB;
-    break;
-  default:
-    DEBUG ((EFI_D_ERROR, "PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n", PageAttributes));
-    ASSERT (0);
-    // The Global Coherency Domain (GCD) value is defined as a bit set.
-    // Returning 0 means no attribute has been set.
-    GcdAttributes = 0;
-  }
-
-  // Determine protection attributes
-  if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) || ((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) {
-    // Read only cases map to write-protect
-    GcdAttributes |= EFI_MEMORY_WP;
-  }
-
-  // Process eXecute Never attribute
-  if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) != 0 ) {
-    GcdAttributes |= EFI_MEMORY_XP;
-  }
-
-  return GcdAttributes;
-}
-
-ARM_MEMORY_REGION_ATTRIBUTES
-GcdAttributeToArmAttribute (
-  IN UINT64 GcdAttributes
-  )
-{
-  switch (GcdAttributes & 0xFF) {
-  case EFI_MEMORY_UC:
-    return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
-  case EFI_MEMORY_WC:
-    return ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
-  case EFI_MEMORY_WT:
-    return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH;
-  case EFI_MEMORY_WB:
-    return ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK;
-  default:
-    DEBUG ((EFI_D_ERROR, "GcdAttributeToArmAttribute: 0x%lX attributes is not supported.\n", GcdAttributes));
-    ASSERT (0);
-    return ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
-  }
-}
-
-// Describe the T0SZ values for each translation table level
-typedef struct {
-  UINTN     MinT0SZ;
-  UINTN     MaxT0SZ;
-  UINTN     LargestT0SZ; // Generally (MaxT0SZ == LargestT0SZ) but at the Level3 Table
-                         // the MaxT0SZ is not at the boundary of the table
-} T0SZ_DESCRIPTION_PER_LEVEL;
-
-// Map table for the corresponding Level of Table
-STATIC CONST T0SZ_DESCRIPTION_PER_LEVEL T0SZPerTableLevel[] = {
-    { 16, 24, 24 }, // Table Level 0
-    { 25, 33, 33 }, // Table Level 1
-    { 34, 39, 42 }  // Table Level 2
-};
-
-VOID
-GetRootTranslationTableInfo (
-  IN UINTN     T0SZ,
-  OUT UINTN   *TableLevel,
-  OUT UINTN   *TableEntryCount
-  )
-{
-  UINTN Index;
-
-  // Identify the level of the root table from the given T0SZ
-  for (Index = 0; Index < sizeof (T0SZPerTableLevel) / sizeof (T0SZ_DESCRIPTION_PER_LEVEL); Index++) {
-    if (T0SZ <= T0SZPerTableLevel[Index].MaxT0SZ) {
-      break;
-    }
-  }
-
-  // If we have not found the corresponding maximum T0SZ then we use the last one
-  if (Index == sizeof (T0SZPerTableLevel) / sizeof (T0SZ_DESCRIPTION_PER_LEVEL)) {
-    Index--;
-  }
-
-  // Get the level of the root table
-  if (TableLevel) {
-    *TableLevel = Index;
-  }
-
-  // The Size of the Table is 2^(T0SZ-LargestT0SZ)
-  if (TableEntryCount) {
-    *TableEntryCount = 1 << (T0SZPerTableLevel[Index].LargestT0SZ - T0SZ + 1);
-  }
-}
-
-STATIC
-VOID
-ReplaceLiveEntry (
-  IN  UINT64  *Entry,
-  IN  UINT64  Value
-  )
-{
-  if (!ArmMmuEnabled ()) {
-    *Entry = Value;
-  } else {
-    ArmReplaceLiveTranslationEntry (Entry, Value);
-  }
-}
-
-STATIC
-VOID
-LookupAddresstoRootTable (
-  IN  UINT64  MaxAddress,
-  OUT UINTN  *T0SZ,
-  OUT UINTN  *TableEntryCount
-  )
-{
-  UINTN TopBit;
-
-  // Check the parameters are not NULL
-  ASSERT ((T0SZ != NULL) && (TableEntryCount != NULL));
-
-  // Look for the highest bit set in MaxAddress
-  for (TopBit = 63; TopBit != 0; TopBit--) {
-    if ((1ULL << TopBit) & MaxAddress) {
-      // MaxAddress top bit is found
-      TopBit = TopBit + 1;
-      break;
-    }
-  }
-  ASSERT (TopBit != 0);
-
-  // Calculate T0SZ from the top bit of the MaxAddress
-  *T0SZ = 64 - TopBit;
-
-  // Get the Table info from T0SZ
-  GetRootTranslationTableInfo (*T0SZ, NULL, TableEntryCount);
-}
-
-STATIC
-UINT64*
-GetBlockEntryListFromAddress (
-  IN  UINT64       *RootTable,
-  IN  UINT64        RegionStart,
-  OUT UINTN        *TableLevel,
-  IN OUT UINT64    *BlockEntrySize,
-  OUT UINT64      **LastBlockEntry
-  )
-{
-  UINTN   RootTableLevel;
-  UINTN   RootTableEntryCount;
-  UINT64 *TranslationTable;
-  UINT64 *BlockEntry;
-  UINT64 *SubTableBlockEntry;
-  UINT64  BlockEntryAddress;
-  UINTN   BaseAddressAlignment;
-  UINTN   PageLevel;
-  UINTN   Index;
-  UINTN   IndexLevel;
-  UINTN   T0SZ;
-  UINT64  Attributes;
-  UINT64  TableAttributes;
-
-  // Initialize variable
-  BlockEntry = NULL;
-
-  // Ensure the parameters are valid
-  if (!(TableLevel && BlockEntrySize && LastBlockEntry)) {
-    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
-    return NULL;
-  }
-
-  // Ensure the Region is aligned on 4KB boundary
-  if ((RegionStart & (SIZE_4KB - 1)) != 0) {
-    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
-    return NULL;
-  }
-
-  // Ensure the required size is aligned on 4KB boundary and not 0
-  if ((*BlockEntrySize & (SIZE_4KB - 1)) != 0 || *BlockEntrySize == 0) {
-    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
-    return NULL;
-  }
-
-  T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
-  // Get the Table info from T0SZ
-  GetRootTranslationTableInfo (T0SZ, &RootTableLevel, &RootTableEntryCount);
-
-  // If the start address is 0x0 then we use the size of the region to identify the alignment
-  if (RegionStart == 0) {
-    // Identify the highest possible alignment for the Region Size
-    BaseAddressAlignment = LowBitSet64 (*BlockEntrySize);
-  } else {
-    // Identify the highest possible alignment for the Base Address
-    BaseAddressAlignment = LowBitSet64 (RegionStart);
-  }
-
-  // Identify the Page Level the RegionStart must belong to. Note that PageLevel
-  // should be at least 1 since block translations are not supported at level 0
-  PageLevel = MAX (3 - ((BaseAddressAlignment - 12) / 9), 1);
-
-  // If the required size is smaller than the current block size then we need to go to the page below.
-  // The PageLevel was calculated on the Base Address alignment but did not take in account the alignment
-  // of the allocation size
-  while (*BlockEntrySize < TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel)) {
-    // It does not fit so we need to go a page level above
-    PageLevel++;
-  }
-
-  //
-  // Get the Table Descriptor for the corresponding PageLevel. We need to decompose RegionStart to get appropriate entries
-  //
-
-  TranslationTable = RootTable;
-  for (IndexLevel = RootTableLevel; IndexLevel <= PageLevel; IndexLevel++) {
-    BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel, RegionStart);
-
-    if ((IndexLevel != 3) && ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) {
-      // Go to the next table
-      TranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
-
-      // If we are at the last level then update the last level to next level
-      if (IndexLevel == PageLevel) {
-        // Enter the next level
-        PageLevel++;
-      }
-    } else if ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) {
-      // If we are not at the last level then we need to split this BlockEntry
-      if (IndexLevel != PageLevel) {
-        // Retrieve the attributes from the block entry
-        Attributes = *BlockEntry & TT_ATTRIBUTES_MASK;
-
-        // Convert the block entry attributes into Table descriptor attributes
-        TableAttributes = TT_TABLE_AP_NO_PERMISSION;
-        if (Attributes & TT_NS) {
-          TableAttributes = TT_TABLE_NS;
-        }
-
-        // Get the address corresponding at this entry
-        BlockEntryAddress = RegionStart;
-        BlockEntryAddress = BlockEntryAddress >> TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
-        // Shift back to right to set zero before the effective address
-        BlockEntryAddress = BlockEntryAddress << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
-
-        // Set the correct entry type for the next page level
-        if ((IndexLevel + 1) == 3) {
-          Attributes |= TT_TYPE_BLOCK_ENTRY_LEVEL3;
-        } else {
-          Attributes |= TT_TYPE_BLOCK_ENTRY;
-        }
-
-        // Create a new translation table
-        TranslationTable = (UINT64*)AllocateAlignedPages (EFI_SIZE_TO_PAGES(TT_ENTRY_COUNT * sizeof(UINT64)), TT_ALIGNMENT_DESCRIPTION_TABLE);
-        if (TranslationTable == NULL) {
-          return NULL;
-        }
-
-        // Populate the newly created lower level table
-        SubTableBlockEntry = TranslationTable;
-        for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
-          *SubTableBlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1)));
-          SubTableBlockEntry++;
-        }
-
-        // Fill the BlockEntry with the new TranslationTable
-        ReplaceLiveEntry (BlockEntry,
-          ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY);
-      }
-    } else {
-      if (IndexLevel != PageLevel) {
-        //
-        // Case when we have an Invalid Entry and we are at a page level above of the one targetted.
-        //
-
-        // Create a new translation table
-        TranslationTable = (UINT64*)AllocateAlignedPages (EFI_SIZE_TO_PAGES(TT_ENTRY_COUNT * sizeof(UINT64)), TT_ALIGNMENT_DESCRIPTION_TABLE);
-        if (TranslationTable == NULL) {
-          return NULL;
-        }
-
-        ZeroMem (TranslationTable, TT_ENTRY_COUNT * sizeof(UINT64));
-
-        // Fill the new BlockEntry with the TranslationTable
-        *BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TT_TYPE_TABLE_ENTRY;
-      }
-    }
-  }
-
-  // Expose the found PageLevel to the caller
-  *TableLevel = PageLevel;
-
-  // Now, we have the Table Level we can get the Block Size associated to this table
-  *BlockEntrySize = TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel);
-
-  // The last block of the root table depends on the number of entry in this table,
-  // otherwise it is always the (TT_ENTRY_COUNT - 1)th entry in the table.
-  *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable,
-      (PageLevel == RootTableLevel) ? RootTableEntryCount : TT_ENTRY_COUNT);
-
-  return BlockEntry;
-}
-
-STATIC
-RETURN_STATUS
-UpdateRegionMapping (
-  IN  UINT64  *RootTable,
-  IN  UINT64  RegionStart,
-  IN  UINT64  RegionLength,
-  IN  UINT64  Attributes,
-  IN  UINT64  BlockEntryMask
-  )
-{
-  UINT32  Type;
-  UINT64  *BlockEntry;
-  UINT64  *LastBlockEntry;
-  UINT64  BlockEntrySize;
-  UINTN   TableLevel;
-
-  // Ensure the Length is aligned on 4KB boundary
-  if ((RegionLength == 0) || ((RegionLength & (SIZE_4KB - 1)) != 0)) {
-    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
-    return RETURN_INVALID_PARAMETER;
-  }
-
-  do {
-    // Get the first Block Entry that matches the Virtual Address and also the information on the Table Descriptor
-    // such as the the size of the Block Entry and the address of the last BlockEntry of the Table Descriptor
-    BlockEntrySize = RegionLength;
-    BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry);
-    if (BlockEntry == NULL) {
-      // GetBlockEntryListFromAddress() return NULL when it fails to allocate new pages from the Translation Tables
-      return RETURN_OUT_OF_RESOURCES;
-    }
-
-    if (TableLevel != 3) {
-      Type = TT_TYPE_BLOCK_ENTRY;
-    } else {
-      Type = TT_TYPE_BLOCK_ENTRY_LEVEL3;
-    }
-
-    do {
-      // Fill the Block Entry with attribute and output block address
-      *BlockEntry &= BlockEntryMask;
-      *BlockEntry |= (RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type;
-
-      // Go to the next BlockEntry
-      RegionStart += BlockEntrySize;
-      RegionLength -= BlockEntrySize;
-      BlockEntry++;
-
-      // Break the inner loop when next block is a table
-      // Rerun GetBlockEntryListFromAddress to avoid page table memory leak
-      if (TableLevel != 3 &&
-          (*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
-            break;
-      }
-    } while ((RegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry));
-  } while (RegionLength != 0);
-
-  return RETURN_SUCCESS;
-}
-
-STATIC
-RETURN_STATUS
-FillTranslationTable (
-  IN  UINT64                        *RootTable,
-  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryRegion
-  )
-{
-  return UpdateRegionMapping (
-           RootTable,
-           MemoryRegion->VirtualBase,
-           MemoryRegion->Length,
-           ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF,
-           0
-           );
-}
-
-RETURN_STATUS
-SetMemoryAttributes (
-  IN EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN UINT64                    Length,
-  IN UINT64                    Attributes,
-  IN EFI_PHYSICAL_ADDRESS      VirtualMask
-  )
-{
-  RETURN_STATUS                Status;
-  ARM_MEMORY_REGION_DESCRIPTOR MemoryRegion;
-  UINT64                      *TranslationTable;
-
-  MemoryRegion.PhysicalBase = BaseAddress;
-  MemoryRegion.VirtualBase = BaseAddress;
-  MemoryRegion.Length = Length;
-  MemoryRegion.Attributes = GcdAttributeToArmAttribute (Attributes);
-
-  TranslationTable = ArmGetTTBR0BaseAddress ();
-
-  Status = FillTranslationTable (TranslationTable, &MemoryRegion);
-  if (RETURN_ERROR (Status)) {
-    return Status;
-  }
-
-  // Invalidate all TLB entries so changes are synced
-  ArmInvalidateTlb ();
-
-  return RETURN_SUCCESS;
-}
-
-STATIC
-RETURN_STATUS
-SetMemoryRegionAttribute (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length,
-  IN  UINT64                    Attributes,
-  IN  UINT64                    BlockEntryMask
-  )
-{
-  RETURN_STATUS                Status;
-  UINT64                       *RootTable;
-
-  RootTable = ArmGetTTBR0BaseAddress ();
-
-  Status = UpdateRegionMapping (RootTable, BaseAddress, Length, Attributes, BlockEntryMask);
-  if (RETURN_ERROR (Status)) {
-    return Status;
-  }
-
-  // Invalidate all TLB entries so changes are synced
-  ArmInvalidateTlb ();
-
-  return RETURN_SUCCESS;
-}
-
-RETURN_STATUS
-ArmSetMemoryRegionNoExec (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  )
-{
-  UINT64    Val;
-
-  if (ArmReadCurrentEL () == AARCH64_EL1) {
-    Val = TT_PXN_MASK | TT_UXN_MASK;
-  } else {
-    Val = TT_XN_MASK;
-  }
-
-  return SetMemoryRegionAttribute (
-           BaseAddress,
-           Length,
-           Val,
-           ~TT_ADDRESS_MASK_BLOCK_ENTRY);
-}
-
-RETURN_STATUS
-ArmClearMemoryRegionNoExec (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  )
-{
-  UINT64 Mask;
-
-  // XN maps to UXN in the EL1&0 translation regime
-  Mask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_PXN_MASK | TT_XN_MASK);
-
-  return SetMemoryRegionAttribute (
-           BaseAddress,
-           Length,
-           0,
-           Mask);
-}
-
-RETURN_STATUS
-ArmSetMemoryRegionReadOnly (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  )
-{
-  return SetMemoryRegionAttribute (
-           BaseAddress,
-           Length,
-           TT_AP_RO_RO,
-           ~TT_ADDRESS_MASK_BLOCK_ENTRY);
-}
-
-RETURN_STATUS
-ArmClearMemoryRegionReadOnly (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  )
-{
-  return SetMemoryRegionAttribute (
-           BaseAddress,
-           Length,
-           TT_AP_RW_RW,
-           ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK));
-}
-
-RETURN_STATUS
-EFIAPI
-ArmConfigureMmu (
-  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,
-  OUT VOID                         **TranslationTableBase OPTIONAL,
-  OUT UINTN                         *TranslationTableSize OPTIONAL
-  )
-{
-  VOID*                         TranslationTable;
-  UINTN                         TranslationTablePageCount;
-  UINT32                        TranslationTableAttribute;
-  ARM_MEMORY_REGION_DESCRIPTOR *MemoryTableEntry;
-  UINT64                        MaxAddress;
-  UINT64                        TopAddress;
-  UINTN                         T0SZ;
-  UINTN                         RootTableEntryCount;
-  UINT64                        TCR;
-  RETURN_STATUS                 Status;
-
-  if(MemoryTable == NULL) {
-    ASSERT (MemoryTable != NULL);
-    return RETURN_INVALID_PARAMETER;
-  }
-
-  // Identify the highest address of the memory table
-  MaxAddress = MemoryTable->PhysicalBase + MemoryTable->Length - 1;
-  MemoryTableEntry = MemoryTable;
-  while (MemoryTableEntry->Length != 0) {
-    TopAddress = MemoryTableEntry->PhysicalBase + MemoryTableEntry->Length - 1;
-    if (TopAddress > MaxAddress) {
-      MaxAddress = TopAddress;
-    }
-    MemoryTableEntry++;
-  }
-
-  // Lookup the Table Level to get the information
-  LookupAddresstoRootTable (MaxAddress, &T0SZ, &RootTableEntryCount);
-
-  //
-  // Set TCR that allows us to retrieve T0SZ in the subsequent functions
-  //
-  // Ideally we will be running at EL2, but should support EL1 as well.
-  // UEFI should not run at EL3.
-  if (ArmReadCurrentEL () == AARCH64_EL2) {
-    //Note: Bits 23 and 31 are reserved(RES1) bits in TCR_EL2
-    TCR = T0SZ | (1UL << 31) | (1UL << 23) | TCR_TG0_4KB;
-
-    // Set the Physical Address Size using MaxAddress
-    if (MaxAddress < SIZE_4GB) {
-      TCR |= TCR_PS_4GB;
-    } else if (MaxAddress < SIZE_64GB) {
-      TCR |= TCR_PS_64GB;
-    } else if (MaxAddress < SIZE_1TB) {
-      TCR |= TCR_PS_1TB;
-    } else if (MaxAddress < SIZE_4TB) {
-      TCR |= TCR_PS_4TB;
-    } else if (MaxAddress < SIZE_16TB) {
-      TCR |= TCR_PS_16TB;
-    } else if (MaxAddress < SIZE_256TB) {
-      TCR |= TCR_PS_256TB;
-    } else {
-      DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress));
-      ASSERT (0); // Bigger than 48-bit memory space are not supported
-      return RETURN_UNSUPPORTED;
-    }
-  } else if (ArmReadCurrentEL () == AARCH64_EL1) {
-    // Due to Cortex-A57 erratum #822227 we must set TG1[1] == 1, regardless of EPD1.
-    TCR = T0SZ | TCR_TG0_4KB | TCR_TG1_4KB | TCR_EPD1;
-
-    // Set the Physical Address Size using MaxAddress
-    if (MaxAddress < SIZE_4GB) {
-      TCR |= TCR_IPS_4GB;
-    } else if (MaxAddress < SIZE_64GB) {
-      TCR |= TCR_IPS_64GB;
-    } else if (MaxAddress < SIZE_1TB) {
-      TCR |= TCR_IPS_1TB;
-    } else if (MaxAddress < SIZE_4TB) {
-      TCR |= TCR_IPS_4TB;
-    } else if (MaxAddress < SIZE_16TB) {
-      TCR |= TCR_IPS_16TB;
-    } else if (MaxAddress < SIZE_256TB) {
-      TCR |= TCR_IPS_256TB;
-    } else {
-      DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress));
-      ASSERT (0); // Bigger than 48-bit memory space are not supported
-      return RETURN_UNSUPPORTED;
-    }
-  } else {
-    ASSERT (0); // UEFI is only expected to run at EL2 and EL1, not EL3.
-    return RETURN_UNSUPPORTED;
-  }
-
-  // Set TCR
-  ArmSetTCR (TCR);
-
-  // Allocate pages for translation table
-  TranslationTablePageCount = EFI_SIZE_TO_PAGES(RootTableEntryCount * sizeof(UINT64));
-  TranslationTable = (UINT64*)AllocateAlignedPages (TranslationTablePageCount, TT_ALIGNMENT_DESCRIPTION_TABLE);
-  if (TranslationTable == NULL) {
-    return RETURN_OUT_OF_RESOURCES;
-  }
-  // We set TTBR0 just after allocating the table to retrieve its location from the subsequent
-  // functions without needing to pass this value across the functions. The MMU is only enabled
-  // after the translation tables are populated.
-  ArmSetTTBR0 (TranslationTable);
-
-  if (TranslationTableBase != NULL) {
-    *TranslationTableBase = TranslationTable;
-  }
-
-  if (TranslationTableSize != NULL) {
-    *TranslationTableSize = RootTableEntryCount * sizeof(UINT64);
-  }
-
-  ZeroMem (TranslationTable, RootTableEntryCount * sizeof(UINT64));
-
-  // Disable MMU and caches. ArmDisableMmu() also invalidates the TLBs
-  ArmDisableMmu ();
-  ArmDisableDataCache ();
-  ArmDisableInstructionCache ();
-
-  // Make sure nothing sneaked into the cache
-  ArmCleanInvalidateDataCache ();
-  ArmInvalidateInstructionCache ();
-
-  TranslationTableAttribute = TT_ATTR_INDX_INVALID;
-  while (MemoryTable->Length != 0) {
-    // Find the memory attribute for the Translation Table
-    if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) &&
-        ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {
-      TranslationTableAttribute = MemoryTable->Attributes;
-    }
-
-    Status = FillTranslationTable (TranslationTable, MemoryTable);
-    if (RETURN_ERROR (Status)) {
-      goto FREE_TRANSLATION_TABLE;
-    }
-    MemoryTable++;
-  }
-
-  // Translate the Memory Attributes into Translation Table Register Attributes
-  if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) ||
-      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED)) {
-    TCR |= TCR_SH_NON_SHAREABLE | TCR_RGN_OUTER_NON_CACHEABLE | TCR_RGN_INNER_NON_CACHEABLE;
-  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
-      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {
-    TCR |= TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WRITE_BACK_ALLOC | TCR_RGN_INNER_WRITE_BACK_ALLOC;
-  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) ||
-      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH)) {
-    TCR |= TCR_SH_NON_SHAREABLE | TCR_RGN_OUTER_WRITE_THROUGH | TCR_RGN_INNER_WRITE_THROUGH;
-  } else {
-    // If we failed to find a mapping that contains the root translation table then it probably means the translation table
-    // is not mapped in the given memory map.
-    ASSERT (0);
-    Status = RETURN_UNSUPPORTED;
-    goto FREE_TRANSLATION_TABLE;
-  }
-
-  // Set again TCR after getting the Translation Table attributes
-  ArmSetTCR (TCR);
-
-  ArmSetMAIR (MAIR_ATTR(TT_ATTR_INDX_DEVICE_MEMORY, MAIR_ATTR_DEVICE_MEMORY) |                      // mapped to EFI_MEMORY_UC
-              MAIR_ATTR(TT_ATTR_INDX_MEMORY_NON_CACHEABLE, MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) | // mapped to EFI_MEMORY_WC
-              MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_THROUGH, MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH) | // mapped to EFI_MEMORY_WT
-              MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_BACK, MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK));       // mapped to EFI_MEMORY_WB
-
-  ArmDisableAlignmentCheck ();
-  ArmEnableInstructionCache ();
-  ArmEnableDataCache ();
-
-  ArmEnableMmu ();
-  return RETURN_SUCCESS;
-
-FREE_TRANSLATION_TABLE:
-  FreePages (TranslationTable, TranslationTablePageCount);
-  return Status;
-}
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.S b/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.S
index d9e3c86b6907..1bd00d1b997f 100644
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.S
+++ b/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.S
@@ -45,12 +45,6 @@ ASM_PFX(ArmIsMpCore):
   movne   R0, #0
   bx      LR
 
-ASM_PFX(ArmHasMpExtensions):
-  mrc     p15,0,R0,c0,c0,5
-  // Get Multiprocessing extension (bit31)
-  lsr     R0, R0, #31
-  bx      LR
-
 ASM_PFX(ArmEnableAsynchronousAbort):
   cpsie   a
   isb
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.asm b/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.asm
index cbbe8dbe3db1..cac39e36a5d3 100644
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.asm
+++ b/ArmPkg/Library/ArmLib/ArmV7/ArmLibSupportV7.asm
@@ -30,12 +30,6 @@
   movne   R0, #0
   bx      LR
 
- RVCT_ASM_EXPORT ArmHasMpExtensions
-  mrc     p15,0,R0,c0,c0,5
-  // Get Multiprocessing extension (bit31)
-  lsr     R0, R0, #31
-  bx      LR
-
  RVCT_ASM_EXPORT ArmEnableAsynchronousAbort
   cpsie   a
   isb
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
index cbd3d6f654a6..e4595c44fdd5 100644
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
+++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
@@ -36,17 +36,5 @@ ArmV7AllDataCachesOperation (
   IN  ARM_V7_CACHE_OPERATION  DataCacheOperation
   );
 
-UINTN
-EFIAPI
-ArmReadIdMmfr0 (
-  VOID
-  );
-
-BOOLEAN
-EFIAPI
-ArmHasMpExtensions (
-  VOID
-  );
-
 #endif // __ARM_V7_LIB_H__
 
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
index d56851a1409b..024784d19e75 100644
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
+++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
@@ -33,7 +33,6 @@ [Sources.common]
   ArmV7Support.asm  | RVCT
 
   ArmV7Lib.c
-  ArmV7Mmu.c
 
   ArmV7ArchTimer.c
   ArmV7ArchTimerSupport.S    | GCC
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf b/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
index 6eaf350c7b9d..5710f5044c8c 100644
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
+++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
@@ -33,7 +33,6 @@ [Sources.common]
   ArmV7Support.asm  | RVCT
 
   ArmV7Lib.c
-  ArmV7Mmu.c
 
   ArmV7ArchTimer.c
   ArmV7ArchTimerSupport.S    | GCC
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
deleted file mode 100644
index 74a7c177df6c..000000000000
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/** @file
-*  File managing the MMU for ARMv7 architecture
-*
-*  Copyright (c) 2011-2016, ARM Limited. All rights reserved.
-*
-*  This program and the accompanying materials
-*  are licensed and made available under the terms and conditions of the BSD License
-*  which accompanies this distribution.  The full text of the license may be found at
-*  http://opensource.org/licenses/bsd-license.php
-*
-*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-*
-**/
-
-#include <Uefi.h>
-#include <Chipset/ArmV7.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/ArmLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include "ArmV7Lib.h"
-#include "ArmLibPrivate.h"
-
-UINT32
-ConvertSectionAttributesToPageAttributes (
-  IN UINT32   SectionAttributes,
-  IN BOOLEAN  IsLargePage
-  )
-{
-  UINT32 PageAttributes;
-
-  PageAttributes = 0;
-  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage);
-  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes);
-  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage);
-  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes);
-  PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes);
-
-  return PageAttributes;
-}
-
-STATIC
-BOOLEAN
-PreferNonshareableMemory (
-  VOID
-  )
-{
-  UINTN   Mmfr;
-  UINTN   Val;
-
-  if (FeaturePcdGet (PcdNormalMemoryNonshareableOverride)) {
-    return TRUE;
-  }
-
-  //
-  // Check whether the innermost level of shareability (the level we will use
-  // by default to map normal memory) is implemented with hardware coherency
-  // support. Otherwise, revert to mapping as non-shareable.
-  //
-  Mmfr = ArmReadIdMmfr0 ();
-  switch ((Mmfr >> ID_MMFR0_SHARELVL_SHIFT) & ID_MMFR0_SHARELVL_MASK) {
-  case ID_MMFR0_SHARELVL_ONE:
-    // one level of shareability
-    Val = (Mmfr >> ID_MMFR0_OUTERSHR_SHIFT) & ID_MMFR0_OUTERSHR_MASK;
-    break;
-  case ID_MMFR0_SHARELVL_TWO:
-    // two levels of shareability
-    Val = (Mmfr >> ID_MMFR0_INNERSHR_SHIFT) & ID_MMFR0_INNERSHR_MASK;
-    break;
-  default:
-    // unexpected value -> shareable is the safe option
-    ASSERT (FALSE);
-    return FALSE;
-  }
-  return Val != ID_MMFR0_SHR_IMP_HW_COHERENT;
-}
-
-STATIC
-VOID
-PopulateLevel2PageTable (
-  IN UINT32                         *SectionEntry,
-  IN UINT32                         PhysicalBase,
-  IN UINT32                         RemainLength,
-  IN ARM_MEMORY_REGION_ATTRIBUTES   Attributes
-  )
-{
-  UINT32* PageEntry;
-  UINT32  Pages;
-  UINT32  Index;
-  UINT32  PageAttributes;
-  UINT32  SectionDescriptor;
-  UINT32  TranslationTable;
-  UINT32  BaseSectionAddress;
-
-  switch (Attributes) {
-    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
-    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
-      PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_BACK;
-      break;
-    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
-    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
-      PageAttributes = TT_DESCRIPTOR_PAGE_WRITE_THROUGH;
-      break;
-    case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
-    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
-      PageAttributes = TT_DESCRIPTOR_PAGE_DEVICE;
-      break;
-    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
-    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
-      PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;
-      break;
-    default:
-      PageAttributes = TT_DESCRIPTOR_PAGE_UNCACHED;
-      break;
-  }
-
-  if (PreferNonshareableMemory ()) {
-    PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED;
-  }
-
-  // Check if the Section Entry has already been populated. Otherwise attach a
-  // Level 2 Translation Table to it
-  if (*SectionEntry != 0) {
-    // The entry must be a page table. Otherwise it exists an overlapping in the memory map
-    if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(*SectionEntry)) {
-      TranslationTable = *SectionEntry & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK;
-    } else if ((*SectionEntry & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) {
-      // Case where a virtual memory map descriptor overlapped a section entry
-
-      // Allocate a Level2 Page Table for this Section
-      TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
-      TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
-
-      // Translate the Section Descriptor into Page Descriptor
-      SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE);
-
-      BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry);
-
-      // Populate the new Level2 Page Table for the section
-      PageEntry = (UINT32*)TranslationTable;
-      for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
-        PageEntry[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseSectionAddress + (Index << 12)) | SectionDescriptor;
-      }
-
-      // Overwrite the section entry to point to the new Level2 Translation Table
-      *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
-          (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |
-          TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
-    } else {
-      // We do not support the other section type (16MB Section)
-      ASSERT(0);
-      return;
-    }
-  } else {
-    TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
-    TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
-
-    ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);
-
-    *SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
-        (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |
-        TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
-  }
-
-  PageEntry = ((UINT32 *)(TranslationTable) + ((PhysicalBase & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT));
-  Pages     = RemainLength / TT_DESCRIPTOR_PAGE_SIZE;
-
-  for (Index = 0; Index < Pages; Index++) {
-    *PageEntry++     =  TT_DESCRIPTOR_PAGE_BASE_ADDRESS(PhysicalBase) | PageAttributes;
-    PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE;
-  }
-
-}
-
-STATIC
-VOID
-FillTranslationTable (
-  IN  UINT32                        *TranslationTable,
-  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryRegion
-  )
-{
-  UINT32  *SectionEntry;
-  UINT32  Attributes;
-  UINT32  PhysicalBase;
-  UINT64  RemainLength;
-
-  ASSERT(MemoryRegion->Length > 0);
-
-  if (MemoryRegion->PhysicalBase >= SIZE_4GB) {
-    return;
-  }
-
-  PhysicalBase = MemoryRegion->PhysicalBase;
-  RemainLength = MIN(MemoryRegion->Length, SIZE_4GB - PhysicalBase);
-
-  switch (MemoryRegion->Attributes) {
-    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
-      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
-      break;
-    case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
-      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
-      break;
-    case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
-      Attributes = TT_DESCRIPTOR_SECTION_DEVICE(0);
-      break;
-    case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
-      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
-      break;
-    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:
-      Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);
-      break;
-    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH:
-      Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);
-      break;
-    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
-      Attributes = TT_DESCRIPTOR_SECTION_DEVICE(1);
-      break;
-    case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED:
-      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);
-      break;
-    default:
-      Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
-      break;
-  }
-
-  if (PreferNonshareableMemory ()) {
-    Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED;
-  }
-
-  // Get the first section entry for this mapping
-  SectionEntry    = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
-
-  while (RemainLength != 0) {
-    if (PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE == 0) {
-      if (RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) {
-        // Case: Physical address aligned on the Section Size (1MB) && the length is greater than the Section Size
-        *SectionEntry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
-        PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
-      } else {
-        // Case: Physical address aligned on the Section Size (1MB) && the length does not fill a section
-        PopulateLevel2PageTable (SectionEntry++, PhysicalBase, RemainLength, MemoryRegion->Attributes);
-
-        // It must be the last entry
-        break;
-      }
-    } else {
-      // Case: Physical address NOT aligned on the Section Size (1MB)
-      PopulateLevel2PageTable (SectionEntry++, PhysicalBase, RemainLength, MemoryRegion->Attributes);
-      // Aligned the address
-      PhysicalBase = (PhysicalBase + TT_DESCRIPTOR_SECTION_SIZE) & ~(TT_DESCRIPTOR_SECTION_SIZE-1);
-
-      // If it is the last entry
-      if (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) {
-        break;
-      }
-    }
-    RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;
-  }
-}
-
-RETURN_STATUS
-EFIAPI
-ArmConfigureMmu (
-  IN  ARM_MEMORY_REGION_DESCRIPTOR  *MemoryTable,
-  OUT VOID                         **TranslationTableBase OPTIONAL,
-  OUT UINTN                         *TranslationTableSize OPTIONAL
-  )
-{
-  VOID*                         TranslationTable;
-  ARM_MEMORY_REGION_ATTRIBUTES  TranslationTableAttribute;
-  UINT32                        TTBRAttributes;
-
-  // Allocate pages for translation table.
-  TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));
-  if (TranslationTable == NULL) {
-    return RETURN_OUT_OF_RESOURCES;
-  }
-  TranslationTable = (VOID*)(((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK);
-
-  if (TranslationTableBase != NULL) {
-    *TranslationTableBase = TranslationTable;
-  }
-
-  if (TranslationTableSize != NULL) {
-    *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;
-  }
-
-  ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
-
-  // By default, mark the translation table as belonging to a uncached region
-  TranslationTableAttribute = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
-  while (MemoryTable->Length != 0) {
-    // Find the memory attribute for the Translation Table
-    if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) && ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {
-      TranslationTableAttribute = MemoryTable->Attributes;
-    }
-
-    FillTranslationTable (TranslationTable, MemoryTable);
-    MemoryTable++;
-  }
-
-  // Translate the Memory Attributes into Translation Table Register Attributes
-  if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) ||
-      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED)) {
-    TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_NON_CACHEABLE : TTBR_NON_CACHEABLE;
-  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
-      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {
-    TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_BACK_ALLOC : TTBR_WRITE_BACK_ALLOC;
-  } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) ||
-      (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_THROUGH)) {
-    TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_THROUGH : TTBR_WRITE_THROUGH;
-  } else {
-    ASSERT (0); // No support has been found for the attributes of the memory region that the translation table belongs to.
-    return RETURN_UNSUPPORTED;
-  }
-
-  if (TTBRAttributes & TTBR_SHAREABLE) {
-    if (PreferNonshareableMemory ()) {
-      TTBRAttributes ^= TTBR_SHAREABLE;
-    } else {
-      //
-      // Unlike the S bit in the short descriptors, which implies inner shareable
-      // on an implementation that supports two levels, the meaning of the S bit
-      // in the TTBR depends on the NOS bit, which defaults to Outer Shareable.
-      // However, we should only set this bit after we have confirmed that the
-      // implementation supports multiple levels, or else the NOS bit is UNK/SBZP
-      //
-      if (((ArmReadIdMmfr0 () >> 12) & 0xf) != 0) {
-        TTBRAttributes |= TTBR_NOT_OUTER_SHAREABLE;
-      }
-    }
-  }
-
-  ArmCleanInvalidateDataCache ();
-  ArmInvalidateInstructionCache ();
-
-  ArmDisableDataCache ();
-  ArmDisableInstructionCache();
-  // TLBs are also invalidated when calling ArmDisableMmu()
-  ArmDisableMmu ();
-
-  // Make sure nothing sneaked into the cache
-  ArmCleanInvalidateDataCache ();
-  ArmInvalidateInstructionCache ();
-
-  ArmSetTTBR0 ((VOID *)(UINTN)(((UINTN)TranslationTable & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) | (TTBRAttributes & 0x7F)));
-
-  //
-  // The TTBCR register value is undefined at reset in the Non-Secure world.
-  // Writing 0 has the effect of:
-  //   Clearing EAE: Use short descriptors, as mandated by specification.
-  //   Clearing PD0 and PD1: Translation Table Walk Disable is off.
-  //   Clearing N: Perform all translation table walks through TTBR0.
-  //               (0 is the default reset value in systems not implementing
-  //               the Security Extensions.)
-  //
-  ArmSetTTBCR (0);
-
-  ArmSetDomainAccessControl (DOMAIN_ACCESS_CONTROL_NONE(15) |
-                             DOMAIN_ACCESS_CONTROL_NONE(14) |
-                             DOMAIN_ACCESS_CONTROL_NONE(13) |
-                             DOMAIN_ACCESS_CONTROL_NONE(12) |
-                             DOMAIN_ACCESS_CONTROL_NONE(11) |
-                             DOMAIN_ACCESS_CONTROL_NONE(10) |
-                             DOMAIN_ACCESS_CONTROL_NONE( 9) |
-                             DOMAIN_ACCESS_CONTROL_NONE( 8) |
-                             DOMAIN_ACCESS_CONTROL_NONE( 7) |
-                             DOMAIN_ACCESS_CONTROL_NONE( 6) |
-                             DOMAIN_ACCESS_CONTROL_NONE( 5) |
-                             DOMAIN_ACCESS_CONTROL_NONE( 4) |
-                             DOMAIN_ACCESS_CONTROL_NONE( 3) |
-                             DOMAIN_ACCESS_CONTROL_NONE( 2) |
-                             DOMAIN_ACCESS_CONTROL_NONE( 1) |
-                             DOMAIN_ACCESS_CONTROL_CLIENT(0));
-
-  ArmEnableInstructionCache();
-  ArmEnableDataCache();
-  ArmEnableMmu();
-  return RETURN_SUCCESS;
-}
-
-RETURN_STATUS
-ArmSetMemoryRegionNoExec (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  )
-{
-  return RETURN_UNSUPPORTED;
-}
-
-RETURN_STATUS
-ArmClearMemoryRegionNoExec (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  )
-{
-  return RETURN_UNSUPPORTED;
-}
-
-RETURN_STATUS
-ArmSetMemoryRegionReadOnly (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  )
-{
-  return RETURN_UNSUPPORTED;
-}
-
-RETURN_STATUS
-ArmClearMemoryRegionReadOnly (
-  IN  EFI_PHYSICAL_ADDRESS      BaseAddress,
-  IN  UINT64                    Length
-  )
-{
-  return RETURN_UNSUPPORTED;
-}
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S
index c765032c9e4d..47a4aa5e0d4e 100644
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S
+++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.S
@@ -52,7 +52,6 @@ GCC_ASM_EXPORT (ArmReadTpidrurw)
 GCC_ASM_EXPORT (ArmWriteTpidrurw)
 GCC_ASM_EXPORT (ArmIsArchTimerImplemented)
 GCC_ASM_EXPORT (ArmReadIdPfr1)
-GCC_ASM_EXPORT (ArmReadIdMmfr0)
 
 .set DC_ON, (0x1<<2)
 .set IC_ON, (0x1<<12)
@@ -340,8 +339,4 @@ ASM_PFX(ArmReadIdPfr1):
   mrc    p15, 0, r0, c0, c1, 1     @ Read ID_PFR1 Register
   bx     lr
 
-ASM_PFX(ArmReadIdMmfr0):
-  mrc    p15, 0, r0, c0, c1, 4     @ Read ID_MMFR0 Register
-  bx     lr
-
 ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm
index 2363ee457632..342d8970dc81 100644
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm
+++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Support.asm
@@ -295,8 +295,4 @@ Finished
   mrc    p15, 0, r0, c0, c1, 1     ; Read ID_PFR1 Register
   bx     lr
 
- RVCT_ASM_EXPORT ArmReadIdMmfr0
-  mrc    p15, 0, r0, c0, c1, 4     ; Read ID_MMFR0 Register
-  bx     lr
-
  END
diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
index 32a5aa977401..3decb11712ff 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -47,6 +47,8 @@ [LibraryClasses.ARM]
   ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
 
 [LibraryClasses.common]
+  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+
   # Virtio Support
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc
index 594ca6491b7a..ba7ec10db224 100644
--- a/ArmVirtPkg/ArmVirtXen.dsc
+++ b/ArmVirtPkg/ArmVirtXen.dsc
@@ -45,6 +45,8 @@ [LibraryClasses.ARM]
   ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
 
 [LibraryClasses.common]
+  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+
   # Virtio Support
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
   VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
diff --git a/ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.c b/ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.c
index f6c69152848e..251e5314e61d 100644
--- a/ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.c
+++ b/ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.c
@@ -15,6 +15,7 @@
 
 #include <PiPei.h>
 
+#include <Library/ArmMmuLib.h>
 #include <Library/ArmPlatformLib.h>
 #include <Library/DebugLib.h>
 #include <Library/HobLib.h>
diff --git a/ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.inf b/ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.inf
index 9fba16f90f1f..028d6fb5ac28 100644
--- a/ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.inf
+++ b/ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.inf
@@ -34,6 +34,7 @@ [LibraryClasses]
   DebugLib
   HobLib
   ArmLib
+  ArmMmuLib
   ArmPlatformLib
   CacheMaintenanceLib
 
diff --git a/MdeModulePkg/Core/DxeIplPeim/Arm/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Arm/DxeLoadFunc.c
index d6581a312541..dbf873769e17 100644
--- a/MdeModulePkg/Core/DxeIplPeim/Arm/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/Arm/DxeLoadFunc.c
@@ -17,6 +17,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "DxeIpl.h"
 
 #include <Library/ArmLib.h>
+#include <Library/ArmMmuLib.h>
 
 /**
    Transfers control to DxeCore.
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index 79f70d1a7c3c..500765aee910 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -81,6 +81,7 @@ [LibraryClasses]
 
 [LibraryClasses.ARM, LibraryClasses.AARCH64]
   ArmLib
+  ArmMmuLib
 
 [Ppis]
   gEfiDxeIplPpiGuid                 ## PRODUCES
