ArmPkg/CpuDxe: Add support for LPA2 page table entry format

Add support for decoding the output address format in page table entries
when LPA2 is in use.

Signed-off-by: Sarah Walker <Sarah.Walker2@arm.com>
This commit is contained in:
Sarah Walker
2025-09-29 15:01:28 +01:00
committed by mergify[bot]
parent 6e01bfcca2
commit 5ec21149a7

View File

@ -18,6 +18,20 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define MIN_T0SZ 16
#define BITS_PER_LEVEL 9
STATIC
UINT64
GetOutputAddress (
IN UINT64 Entry,
IN BOOLEAN Lpa2Enabled
)
{
if (Lpa2Enabled) {
return (Entry & TT_ADDRESS_MASK_DESCRIPTION_TABLE_LPA2) | ((Entry & TT_UPPER_ADDRESS_MASK) << (50 - 8));
} else {
return Entry & TT_ADDRESS_MASK_DESCRIPTION_TABLE;
}
}
/**
Parses T0SZ to determine the level and number of entries at the root
of the translation table.
@ -126,8 +140,9 @@ RegionAttributeToGcdAttribute (
STATIC
UINT64
GetFirstPageAttribute (
IN UINT64 *FirstLevelTableAddress,
IN UINTN TableLevel
IN UINT64 *FirstLevelTableAddress,
IN UINTN TableLevel,
IN BOOLEAN Lpa2Enabled
)
{
UINT64 FirstEntry;
@ -139,7 +154,7 @@ GetFirstPageAttribute (
// Only valid for Levels 0, 1 and 2
// Get the attribute of the subsequent table
return GetFirstPageAttribute ((UINT64 *)(FirstEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE), TableLevel + 1);
return GetFirstPageAttribute ((UINT64 *)GetOutputAddress (FirstEntry, Lpa2Enabled), TableLevel + 1, Lpa2Enabled);
} else if (((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) ||
((TableLevel == 3) && ((FirstEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3)))
{
@ -226,7 +241,7 @@ GetNextEntryAttribute (
// Increase the level number and scan the sub-level table
GetNextEntryAttribute (
(UINT64 *)(Entry & TT_ADDRESS_MASK_DESCRIPTION_TABLE),
(UINT64 *)GetOutputAddress (Entry, ArmGetTCR () & TCR_DS),
TT_ENTRY_COUNT,
TableLevel + 1,
(BaseAddress + (Index * TT_ADDRESS_AT_LEVEL (TableLevel))),
@ -314,7 +329,7 @@ SyncCacheConfig (
GetRootTranslationTableInfo (T0SZ, &TableLevel, &TableCount);
// First Attribute of the Page Tables
PageAttribute = GetFirstPageAttribute (FirstLevelTableAddress, TableLevel);
PageAttribute = GetFirstPageAttribute (FirstLevelTableAddress, TableLevel, ArmGetTCR () & TCR_DS);
// We scan from the start of the memory map (ie: at the address 0x0)
BaseAddressGcdRegion = 0x0;
@ -443,7 +458,7 @@ GetMemoryRegionRec (
EntryType = *BlockEntry & TT_TYPE_MASK;
if ((TableLevel < 3) && (EntryType == TT_TYPE_TABLE_ENTRY)) {
NextTranslationTable = (UINT64 *)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
NextTranslationTable = (UINT64 *)GetOutputAddress (*BlockEntry, ArmGetTCR () & TCR_DS);
// The entry is a page table, so we go to the next level
Status = GetMemoryRegionRec (