summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2019-03-27 13:40:13 +0100
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2019-03-27 13:50:14 +0100
commit790173efa32cf9c81fed510b94529e6eeea5972e (patch)
tree77d103b3f9584dfc6f6c6d1191c0eedfd4b6bde1
parentdce175303201825f57a0bb2f62eead9d5d4c5670 (diff)
ArmPkg/ArmMmuLib AARCH64: permit non-ID mapped device mappings
The UEFI spec mandates 1:1 mapped memory at boot time only for memory, and it permits platforms to deviate from this rule for other memory mapped regions. Taking into account that ARM_MEMORY_REGION_DESCRIPTOR already caters for this by containing both VirtualBase and PhysicalBase fields, let's wire this up in the MMU code as well. Note that this only supports statically mapped regions. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-rw-r--r--ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
index 3498f520e3..93554fc65a 100644
--- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
+++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c
@@ -338,7 +338,8 @@ STATIC
EFI_STATUS
UpdateRegionMapping (
IN UINT64 *RootTable,
- IN UINT64 RegionStart,
+ IN UINT64 RegionStartVirtual,
+ IN UINT64 RegionStartPhysical,
IN UINT64 RegionLength,
IN UINT64 Attributes,
IN UINT64 BlockEntryMask
@@ -360,7 +361,7 @@ UpdateRegionMapping (
// Get the first Block Entry that matches the Virtual Address and also the information on the Table Descriptor
// such as the the size of the Block Entry and the address of the last BlockEntry of the Table Descriptor
BlockEntrySize = RegionLength;
- BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry);
+ BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStartVirtual, &TableLevel, &BlockEntrySize, &LastBlockEntry);
if (BlockEntry == NULL) {
// GetBlockEntryListFromAddress() return NULL when it fails to allocate new pages from the Translation Tables
return EFI_OUT_OF_RESOURCES;
@@ -375,12 +376,13 @@ UpdateRegionMapping (
do {
// Fill the Block Entry with attribute and output block address
*BlockEntry &= BlockEntryMask;
- *BlockEntry |= (RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type;
+ *BlockEntry |= (RegionStartPhysical & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type;
- ArmUpdateTranslationTableEntry (BlockEntry, (VOID *)RegionStart);
+ ArmUpdateTranslationTableEntry (BlockEntry, (VOID *)RegionStartVirtual);
// Go to the next BlockEntry
- RegionStart += BlockEntrySize;
+ RegionStartVirtual += BlockEntrySize;
+ RegionStartPhysical += BlockEntrySize;
RegionLength -= BlockEntrySize;
BlockEntry++;
@@ -406,6 +408,7 @@ FillTranslationTable (
return UpdateRegionMapping (
RootTable,
MemoryRegion->VirtualBase,
+ MemoryRegion->PhysicalBase,
MemoryRegion->Length,
ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF,
0
@@ -484,6 +487,7 @@ ArmSetMemoryAttributes (
Status = UpdateRegionMapping (
TranslationTable,
BaseAddress,
+ BaseAddress,
Length,
PageAttributes,
PageAttributeMask);
@@ -508,7 +512,7 @@ SetMemoryRegionAttribute (
RootTable = ArmGetTTBR0BaseAddress ();
- Status = UpdateRegionMapping (RootTable, BaseAddress, Length, Attributes, BlockEntryMask);
+ Status = UpdateRegionMapping (RootTable, BaseAddress, BaseAddress, Length, Attributes, BlockEntryMask);
if (EFI_ERROR (Status)) {
return Status;
}