diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2019-03-27 13:40:13 +0100 |
---|---|---|
committer | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2019-03-27 13:50:14 +0100 |
commit | 790173efa32cf9c81fed510b94529e6eeea5972e (patch) | |
tree | 77d103b3f9584dfc6f6c6d1191c0eedfd4b6bde1 | |
parent | dce175303201825f57a0bb2f62eead9d5d4c5670 (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.c | 16 |
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;
}
|