IN UINT64 RegionStart,\r
OUT UINTN *TableLevel,\r
IN OUT UINT64 *BlockEntrySize,\r
- IN OUT UINT64 **LastBlockEntry\r
+ OUT UINT64 **LastBlockEntry\r
)\r
{\r
UINTN RootTableLevel;\r
return NULL;\r
}\r
\r
- //\r
- // Calculate LastBlockEntry from T0SZ - this is the last block entry of the root Translation table\r
- //\r
T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;\r
// Get the Table info from T0SZ\r
GetRootTranslationTableInfo (T0SZ, &RootTableLevel, &RootTableEntryCount);\r
- // The last block of the root table depends on the number of entry in this table\r
- *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(RootTable, RootTableEntryCount);\r
\r
// If the start address is 0x0 then we use the size of the region to identify the alignment\r
if (RegionStart == 0) {\r
PageLevel++;\r
}\r
\r
- // Expose the found PageLevel to the caller\r
- *TableLevel = PageLevel;\r
-\r
- // Now, we have the Table Level we can get the Block Size associated to this table\r
- *BlockEntrySize = TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel);\r
-\r
//\r
// Get the Table Descriptor for the corresponding PageLevel. We need to decompose RegionStart to get appropriate entries\r
//\r
// Go to the next table\r
TranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);\r
\r
- // If we are at the last level then update the output\r
+ // If we are at the last level then update the last level to next level\r
if (IndexLevel == PageLevel) {\r
- // And get the appropriate BlockEntry at the next level\r
- BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel + 1, RegionStart);\r
-\r
- // Set the last block for this new table\r
- *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);\r
+ // Enter the next level\r
+ PageLevel++;\r
}\r
} else if ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) {\r
// If we are not at the last level then we need to split this BlockEntry\r
\r
// Fill the BlockEntry with the new TranslationTable\r
*BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY;\r
- // Update the last block entry with the newly created translation table\r
- *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);\r
-\r
- // Block Entry points at the beginning of the Translation Table\r
- BlockEntry = TranslationTable;\r
}\r
} else {\r
if (IndexLevel != PageLevel) {\r
\r
// Fill the new BlockEntry with the TranslationTable\r
*BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TT_TYPE_TABLE_ENTRY;\r
- // Update the last block entry with the newly created translation table\r
- *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);\r
- } else {\r
- //\r
- // Case when the new region is part of an existing page table\r
- //\r
- *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT);\r
}\r
}\r
}\r
\r
+ // Expose the found PageLevel to the caller\r
+ *TableLevel = PageLevel;\r
+\r
+ // Now, we have the Table Level we can get the Block Size associated to this table\r
+ *BlockEntrySize = TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel);\r
+\r
+ // The last block of the root table depends on the number of entry in this table,\r
+ // otherwise it is always the (TT_ENTRY_COUNT - 1)th entry in the table.\r
+ *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable,\r
+ (PageLevel == RootTableLevel) ? RootTableEntryCount : TT_ENTRY_COUNT);\r
+\r
return BlockEntry;\r
}\r
\r