summaryrefslogtreecommitdiff
path: root/ArmPkg/Library/ArmLib/ArmV7
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPkg/Library/ArmLib/ArmV7')
-rw-r--r--ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h14
-rw-r--r--ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c42
2 files changed, 53 insertions, 3 deletions
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
index e138613ca5..cbd3d6f654 100644
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
+++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.h
@@ -15,6 +15,20 @@
#ifndef __ARM_V7_LIB_H__
#define __ARM_V7_LIB_H__
+#define ID_MMFR0_SHARELVL_SHIFT 12
+#define ID_MMFR0_SHARELVL_MASK 0xf
+#define ID_MMFR0_SHARELVL_ONE 0
+#define ID_MMFR0_SHARELVL_TWO 1
+
+#define ID_MMFR0_INNERSHR_SHIFT 28
+#define ID_MMFR0_INNERSHR_MASK 0xf
+#define ID_MMFR0_OUTERSHR_SHIFT 8
+#define ID_MMFR0_OUTERSHR_MASK 0xf
+
+#define ID_MMFR0_SHR_IMP_UNCACHED 0
+#define ID_MMFR0_SHR_IMP_HW_COHERENT 1
+#define ID_MMFR0_SHR_IGNORED 0xf
+
typedef VOID (*ARM_V7_CACHE_OPERATION)(UINT32);
VOID
diff --git a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
index 23d2e43beb..fc8ea42843 100644
--- a/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
+++ b/ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
@@ -42,6 +42,42 @@ ConvertSectionAttributesToPageAttributes (
}
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,
@@ -80,7 +116,7 @@ PopulateLevel2PageTable (
break;
}
- if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {
+ if (PreferNonshareableMemory ()) {
PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED;
}
@@ -189,7 +225,7 @@ FillTranslationTable (
break;
}
- if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {
+ if (PreferNonshareableMemory ()) {
Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED;
}
@@ -281,7 +317,7 @@ ArmConfigureMmu (
}
if (TTBRAttributes & TTBR_SHAREABLE) {
- if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {
+ if (PreferNonshareableMemory ()) {
TTBRAttributes ^= TTBR_SHAREABLE;
} else {
//