FreePages (TranslationTable, 1);\r
}\r
\r
+STATIC\r
+BOOLEAN\r
+IsBlockEntry (\r
+ IN UINT64 Entry,\r
+ IN UINTN Level\r
+ )\r
+{\r
+ if (Level == 3) {\r
+ return (Entry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY_LEVEL3;\r
+ }\r
+ return (Entry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY;\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+IsTableEntry (\r
+ IN UINT64 Entry,\r
+ IN UINTN Level\r
+ )\r
+{\r
+ if (Level == 3) {\r
+ //\r
+ // TT_TYPE_TABLE_ENTRY aliases TT_TYPE_BLOCK_ENTRY_LEVEL3\r
+ // so we need to take the level into account as well.\r
+ //\r
+ return FALSE;\r
+ }\r
+ return (Entry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY;\r
+}\r
+\r
STATIC\r
EFI_STATUS\r
UpdateRegionMappingRecursive (\r
if (Level == 0 || ((RegionStart | BlockEnd) & BlockMask) != 0) {\r
ASSERT (Level < 3);\r
\r
- if ((*Entry & TT_TYPE_MASK) != TT_TYPE_TABLE_ENTRY) {\r
+ if (!IsTableEntry (*Entry, Level)) {\r
//\r
// No table entry exists yet, so we need to allocate a page table\r
// for the next level.\r
InvalidateDataCacheRange (TranslationTable, EFI_PAGE_SIZE);\r
}\r
\r
- if ((*Entry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) {\r
+ if (IsBlockEntry (*Entry, Level)) {\r
//\r
// We are splitting an existing block entry, so we have to populate\r
// the new table with the attributes of the block entry it replaces.\r
AttributeSetMask, AttributeClearMask, TranslationTable,\r
Level + 1);\r
if (EFI_ERROR (Status)) {\r
- if ((*Entry & TT_TYPE_MASK) != TT_TYPE_TABLE_ENTRY) {\r
+ if (!IsTableEntry (*Entry, Level)) {\r
//\r
// We are creating a new table entry, so on failure, we can free all\r
// allocations we made recursively, given that the whole subhierarchy\r
return Status;\r
}\r
\r
- if ((*Entry & TT_TYPE_MASK) != TT_TYPE_TABLE_ENTRY) {\r
+ if (!IsTableEntry (*Entry, Level)) {\r
EntryValue = (UINTN)TranslationTable | TT_TYPE_TABLE_ENTRY;\r
ReplaceTableEntry (Entry, EntryValue, RegionStart,\r
- (*Entry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY);\r
+ IsBlockEntry (*Entry, Level));\r
}\r
} else {\r
EntryValue = (*Entry & AttributeClearMask) | AttributeSetMask;\r