)\r
{\r
VOID* TranslationTable;\r
+ VOID* TranslationTableBuffer;\r
UINT32 TranslationTableAttribute;\r
ARM_MEMORY_REGION_DESCRIPTOR *MemoryTableEntry;\r
UINT64 MaxAddress;\r
UINT64 TopAddress;\r
UINTN T0SZ;\r
UINTN RootTableEntryCount;\r
+ UINTN RootTableEntrySize;\r
UINT64 TCR;\r
RETURN_STATUS Status;\r
\r
// Set TCR\r
ArmSetTCR (TCR);\r
\r
- // Allocate pages for translation table\r
- TranslationTable = AllocatePages (1);\r
+ // Allocate pages for translation table. Pool allocations are 8 byte aligned,\r
+ // but we may require a higher alignment based on the size of the root table.\r
+ RootTableEntrySize = RootTableEntryCount * sizeof(UINT64);\r
+ if (RootTableEntrySize < EFI_PAGE_SIZE / 2) {\r
+ TranslationTableBuffer = AllocatePool (2 * RootTableEntrySize - 8);\r
+ //\r
+ // Naturally align the root table. Preserves possible NULL value\r
+ //\r
+ TranslationTable = (VOID *)((UINTN)(TranslationTableBuffer - 1) | (RootTableEntrySize - 1)) + 1;\r
+ } else {\r
+ TranslationTable = AllocatePages (1);\r
+ TranslationTableBuffer = NULL;\r
+ }\r
if (TranslationTable == NULL) {\r
return RETURN_OUT_OF_RESOURCES;\r
}\r
}\r
\r
if (TranslationTableSize != NULL) {\r
- *TranslationTableSize = RootTableEntryCount * sizeof(UINT64);\r
+ *TranslationTableSize = RootTableEntrySize;\r
}\r
\r
- ZeroMem (TranslationTable, RootTableEntryCount * sizeof(UINT64));\r
+ ZeroMem (TranslationTable, RootTableEntrySize);\r
\r
// Disable MMU and caches. ArmDisableMmu() also invalidates the TLBs\r
ArmDisableMmu ();\r
return RETURN_SUCCESS;\r
\r
FREE_TRANSLATION_TABLE:\r
- FreePages (TranslationTable, 1);\r
+ if (TranslationTableBuffer != NULL) {\r
+ FreePool (TranslationTableBuffer);\r
+ } else {\r
+ FreePages (TranslationTable, 1);\r
+ }\r
return Status;\r
}\r
\r