]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
ArmPkg/ArmMmuLib AARCH64: cache-invalidate initial page table entries
[mirror_edk2.git] / ArmPkg / Library / ArmMmuLib / AArch64 / ArmMmuLibCore.c
index 8bd1c6fad95f7c57c19a5f66f963f73ce8a6eb0a..204e33c75f953ed71c26b544dea87e05a7fd68d5 100644 (file)
@@ -5,13 +5,7 @@
 *  Copyright (c) 2016, Linaro Limited. All rights reserved.\r
 *  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
 *\r
-*  This program and the accompanying materials\r
-*  are licensed and made available under the terms and conditions of the BSD License\r
-*  which accompanies this distribution.  The full text of the license may be found at\r
-*  http://opensource.org/licenses/bsd-license.php\r
-*\r
-*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 *\r
 **/\r
 \r
@@ -35,6 +29,10 @@ ArmMemoryAttributeToPageAttribute (
   )\r
 {\r
   switch (Attributes) {\r
+  case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE:\r
+  case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK_NONSHAREABLE:\r
+    return TT_ATTR_INDX_MEMORY_WRITE_BACK;\r
+\r
   case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:\r
   case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK:\r
     return TT_ATTR_INDX_MEMORY_WRITE_BACK | TT_SH_INNER_SHAREABLE;\r
@@ -125,13 +123,14 @@ STATIC
 VOID\r
 ReplaceLiveEntry (\r
   IN  UINT64  *Entry,\r
-  IN  UINT64  Value\r
+  IN  UINT64  Value,\r
+  IN  UINT64  RegionStart\r
   )\r
 {\r
   if (!ArmMmuEnabled ()) {\r
     *Entry = Value;\r
   } else {\r
-    ArmReplaceLiveTranslationEntry (Entry, Value);\r
+    ArmReplaceLiveTranslationEntry (Entry, Value, RegionStart);\r
   }\r
 }\r
 \r
@@ -292,7 +291,8 @@ GetBlockEntryListFromAddress (
 \r
         // Fill the BlockEntry with the new TranslationTable\r
         ReplaceLiveEntry (BlockEntry,\r
-          ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY);\r
+          (UINTN)TranslationTable | TableAttributes | TT_TYPE_TABLE_ENTRY,\r
+          RegionStart);\r
       }\r
     } else {\r
       if (IndexLevel != PageLevel) {\r
@@ -352,7 +352,7 @@ UpdateRegionMapping (
 \r
   do {\r
     // Get the first Block Entry that matches the Virtual Address and also the information on the Table Descriptor\r
-    // such as the the size of the Block Entry and the address of the last BlockEntry of the Table Descriptor\r
+    // such as the size of the Block Entry and the address of the last BlockEntry of the Table Descriptor\r
     BlockEntrySize = RegionLength;\r
     BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry);\r
     if (BlockEntry == NULL) {\r
@@ -371,6 +371,8 @@ UpdateRegionMapping (
       *BlockEntry &= BlockEntryMask;\r
       *BlockEntry |= (RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type;\r
 \r
+      ArmUpdateTranslationTableEntry (BlockEntry, (VOID *)RegionStart);\r
+\r
       // Go to the next BlockEntry\r
       RegionStart += BlockEntrySize;\r
       RegionLength -= BlockEntrySize;\r
@@ -378,7 +380,7 @@ UpdateRegionMapping (
 \r
       // Break the inner loop when next block is a table\r
       // Rerun GetBlockEntryListFromAddress to avoid page table memory leak\r
-      if (TableLevel != 3 &&\r
+      if (TableLevel != 3 && BlockEntry <= LastBlockEntry &&\r
           (*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {\r
             break;\r
       }\r
@@ -483,9 +485,6 @@ ArmSetMemoryAttributes (
     return Status;\r
   }\r
 \r
-  // Invalidate all TLB entries so changes are synced\r
-  ArmInvalidateTlb ();\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -508,9 +507,6 @@ SetMemoryRegionAttribute (
     return Status;\r
   }\r
 \r
-  // Invalidate all TLB entries so changes are synced\r
-  ArmInvalidateTlb ();\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -600,8 +596,15 @@ ArmConfigureMmu (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  // Cover the entire GCD memory space\r
-  MaxAddress = (1UL << PcdGet8 (PcdPrePiCpuMemorySize)) - 1;\r
+  //\r
+  // Limit the virtual address space to what we can actually use: UEFI\r
+  // mandates a 1:1 mapping, so no point in making the virtual address\r
+  // space larger than the physical address space. We also have to take\r
+  // into account the architectural limitations that result from UEFI's\r
+  // use of 4 KB pages.\r
+  //\r
+  MaxAddress = MIN (LShiftU64 (1ULL, ArmGetPhysicalAddressBits ()) - 1,\r
+                    MAX_ALLOC_ADDRESS);\r
 \r
   // Lookup the Table Level to get the information\r
   LookupAddresstoRootTable (MaxAddress, &T0SZ, &RootTableEntryCount);\r
@@ -696,15 +699,6 @@ ArmConfigureMmu (
 \r
   ZeroMem (TranslationTable, RootTableEntryCount * sizeof(UINT64));\r
 \r
-  // Disable MMU and caches. ArmDisableMmu() also invalidates the TLBs\r
-  ArmDisableMmu ();\r
-  ArmDisableDataCache ();\r
-  ArmDisableInstructionCache ();\r
-\r
-  // Make sure nothing sneaked into the cache\r
-  ArmCleanInvalidateDataCache ();\r
-  ArmInvalidateInstructionCache ();\r
-\r
   TranslationTableAttribute = TT_ATTR_INDX_INVALID;\r
   while (MemoryTable->Length != 0) {\r
 \r