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
break;\r
}\r
\r
- if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {\r
+ if (PreferNonshareableMemory ()) {\r
PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED;\r
}\r
\r
break;\r
}\r
\r
- if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {\r
+ if (PreferNonshareableMemory ()) {\r
Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED;\r
}\r
\r
}\r
\r
if (TTBRAttributes & TTBR_SHAREABLE) {\r
- if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {\r
+ if (PreferNonshareableMemory ()) {\r
TTBRAttributes ^= TTBR_SHAREABLE;\r
} else {\r
//\r