]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
ArmPkg/ArmV7Mmu: prefer non shareable memory on non-coherent hardware
[mirror_edk2.git] / ArmPkg / Library / ArmLib / ArmV7 / ArmV7Mmu.c
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