]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/ArmV7Mmu: prefer non shareable memory on non-coherent hardware
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 15 Dec 2015 17:31:56 +0000 (17:31 +0000)
committerabiesheuvel <abiesheuvel@Edk2>
Tue, 15 Dec 2015 17:31:56 +0000 (17:31 +0000)
Commit SVN r18778 made all mappings of normal memory (inner) shareable,
even on hardware that implements shareability as uncached accesses.
The original concerns that prompted the change, regarding coherent DMA
and virt guests migrating between CPUs, do not apply to such hardware,
so revert to the original behavior in that case.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19285 6f19259b-4bc3-4df7-8a09-765794883524

ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c

index e138613ca548dce03b13e756f00a4142c1aee0a5..cbd3d6f654a619a8f7761b85a5eee6f12aaeb0cb 100644 (file)
 #ifndef __ARM_V7_LIB_H__\r
 #define __ARM_V7_LIB_H__\r
 \r
+#define ID_MMFR0_SHARELVL_SHIFT       12\r
+#define ID_MMFR0_SHARELVL_MASK       0xf\r
+#define ID_MMFR0_SHARELVL_ONE          0\r
+#define ID_MMFR0_SHARELVL_TWO          1\r
+\r
+#define ID_MMFR0_INNERSHR_SHIFT       28\r
+#define ID_MMFR0_INNERSHR_MASK       0xf\r
+#define ID_MMFR0_OUTERSHR_SHIFT        8\r
+#define ID_MMFR0_OUTERSHR_MASK       0xf\r
+\r
+#define ID_MMFR0_SHR_IMP_UNCACHED      0\r
+#define ID_MMFR0_SHR_IMP_HW_COHERENT   1\r
+#define ID_MMFR0_SHR_IGNORED         0xf\r
+\r
 typedef VOID (*ARM_V7_CACHE_OPERATION)(UINT32);\r
 \r
 VOID\r
index 23d2e43beba00bbcf93ff8a098aa2995f01bc329..fc8ea42843b382509b107b9e10e5268793592414 100644 (file)
@@ -41,6 +41,42 @@ ConvertSectionAttributesToPageAttributes (
   return PageAttributes;\r
 }\r
 \r
+STATIC\r
+BOOLEAN\r
+PreferNonshareableMemory (\r
+  VOID\r
+  )\r
+{\r
+  UINTN   Mmfr;\r
+  UINTN   Val;\r
+\r
+  if (FeaturePcdGet (PcdNormalMemoryNonshareableOverride)) {\r
+    return TRUE;\r
+  }\r
+\r
+  //\r
+  // Check whether the innermost level of shareability (the level we will use\r
+  // by default to map normal memory) is implemented with hardware coherency\r
+  // support. Otherwise, revert to mapping as non-shareable.\r
+  //\r
+  Mmfr = ArmReadIdMmfr0 ();\r
+  switch ((Mmfr >> ID_MMFR0_SHARELVL_SHIFT) & ID_MMFR0_SHARELVL_MASK) {\r
+  case ID_MMFR0_SHARELVL_ONE:\r
+    // one level of shareability\r
+    Val = (Mmfr >> ID_MMFR0_OUTERSHR_SHIFT) & ID_MMFR0_OUTERSHR_MASK;\r
+    break;\r
+  case ID_MMFR0_SHARELVL_TWO:\r
+    // two levels of shareability\r
+    Val = (Mmfr >> ID_MMFR0_INNERSHR_SHIFT) & ID_MMFR0_INNERSHR_MASK;\r
+    break;\r
+  default:\r
+    // unexpected value -> shareable is the safe option\r
+    ASSERT (FALSE);\r
+    return FALSE;\r
+  }\r
+  return Val != ID_MMFR0_SHR_IMP_HW_COHERENT;\r
+}\r
+\r
 STATIC\r
 VOID\r
 PopulateLevel2PageTable (\r
@@ -80,7 +116,7 @@ PopulateLevel2PageTable (
       break;\r
   }\r
 \r
-  if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {\r
+  if (PreferNonshareableMemory ()) {\r
     PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED;\r
   }\r
 \r
@@ -189,7 +225,7 @@ FillTranslationTable (
       break;\r
   }\r
 \r
-  if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {\r
+  if (PreferNonshareableMemory ()) {\r
     Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED;\r
   }\r
 \r
@@ -281,7 +317,7 @@ ArmConfigureMmu (
   }\r
 \r
   if (TTBRAttributes & TTBR_SHAREABLE) {\r
-    if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {\r
+    if (PreferNonshareableMemory ()) {\r
       TTBRAttributes ^= TTBR_SHAREABLE;\r
     } else {\r
       //\r