summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2022-07-02 15:14:28 +0200
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2022-10-19 09:07:13 +0000
commit999c53e2caf4a97538c7960f8c2862098541ffb8 (patch)
treea768276e9b8e34ad11ba90436a013f19a9e6728c
parent0487cac09f23f2f3e3258b903937dc1d45426096 (diff)
downloadedk2-999c53e2caf4a97538c7960f8c2862098541ffb8.tar.gz
edk2-999c53e2caf4a97538c7960f8c2862098541ffb8.tar.bz2
edk2-999c53e2caf4a97538c7960f8c2862098541ffb8.zip
ArmPkg/ArmMmuLib: permit initial configuration with MMU enabled
Permit the use of this library with the MMU and caches already enabled. This removes the need for any cache maintenance for coherency, and is generally better for robustness and performance, especially when running under virtualization. Note that this means we have to defer assignment of TTBR0 until the page tables are ready to be used, and so UpdateRegionMapping() can no longer read back TTBR0 directly to discover the root table address. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Acked-by: Leif Lindholm <quic_llindhol@quicinc.com>
-rw-r--r--ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
index 4d75788ed2..ae59e9a7d0 100644
--- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
+++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
@@ -357,6 +357,7 @@ UpdateRegionMapping (
IN UINT64 RegionLength,
IN UINT64 AttributeSetMask,
IN UINT64 AttributeClearMask,
+ IN UINT64 *RootTable,
IN BOOLEAN TableIsLive
)
{
@@ -373,7 +374,7 @@ UpdateRegionMapping (
RegionStart + RegionLength,
AttributeSetMask,
AttributeClearMask,
- ArmGetTTBR0BaseAddress (),
+ RootTable,
GetRootTableLevel (T0SZ),
TableIsLive
);
@@ -391,6 +392,7 @@ FillTranslationTable (
MemoryRegion->Length,
ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF,
0,
+ RootTable,
FALSE
);
}
@@ -466,6 +468,7 @@ ArmSetMemoryAttributes (
Length,
PageAttributes,
PageAttributeMask,
+ ArmGetTTBR0BaseAddress (),
TRUE
);
}
@@ -484,6 +487,7 @@ SetMemoryRegionAttribute (
Length,
Attributes,
BlockEntryMask,
+ ArmGetTTBR0BaseAddress (),
TRUE
);
}
@@ -675,14 +679,6 @@ ArmConfigureMmu (
return EFI_OUT_OF_RESOURCES;
}
- //
- // We set TTBR0 just after allocating the table to retrieve its location from
- // the subsequent functions without needing to pass this value across the
- // functions. The MMU is only enabled after the translation tables are
- // populated.
- //
- ArmSetTTBR0 (TranslationTable);
-
if (TranslationTableBase != NULL) {
*TranslationTableBase = TranslationTable;
}
@@ -691,14 +687,17 @@ ArmConfigureMmu (
*TranslationTableSize = RootTableEntryCount * sizeof (UINT64);
}
- //
- // Make sure we are not inadvertently hitting in the caches
- // when populating the page tables.
- //
- InvalidateDataCacheRange (
- TranslationTable,
- RootTableEntryCount * sizeof (UINT64)
- );
+ if (!ArmMmuEnabled ()) {
+ //
+ // Make sure we are not inadvertently hitting in the caches
+ // when populating the page tables.
+ //
+ InvalidateDataCacheRange (
+ TranslationTable,
+ RootTableEntryCount * sizeof (UINT64)
+ );
+ }
+
ZeroMem (TranslationTable, RootTableEntryCount * sizeof (UINT64));
while (MemoryTable->Length != 0) {
@@ -723,12 +722,17 @@ ArmConfigureMmu (
MAIR_ATTR (TT_ATTR_INDX_MEMORY_WRITE_BACK, MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK)
);
- ArmDisableAlignmentCheck ();
- ArmEnableStackAlignmentCheck ();
- ArmEnableInstructionCache ();
- ArmEnableDataCache ();
+ ArmSetTTBR0 (TranslationTable);
+
+ if (!ArmMmuEnabled ()) {
+ ArmDisableAlignmentCheck ();
+ ArmEnableStackAlignmentCheck ();
+ ArmEnableInstructionCache ();
+ ArmEnableDataCache ();
+
+ ArmEnableMmu ();
+ }
- ArmEnableMmu ();
return EFI_SUCCESS;
FreeTranslationTable: