\r
BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry);\r
\r
+ //\r
+ // Make sure we are not inadvertently hitting in the caches\r
+ // when populating the page tables\r
+ //\r
+ InvalidateDataCacheRange ((VOID *)TranslationTable,\r
+ TRANSLATION_TABLE_PAGE_SIZE);\r
+\r
// Populate the new Level2 Page Table for the section\r
PageEntry = (UINT32*)TranslationTable;\r
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {\r
TranslationTable = (UINTN)AllocateAlignedPages (\r
EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_PAGE_SIZE),\r
TRANSLATION_TABLE_PAGE_ALIGNMENT);\r
+ //\r
+ // Make sure we are not inadvertently hitting in the caches\r
+ // when populating the page tables\r
+ //\r
+ InvalidateDataCacheRange ((VOID *)TranslationTable,\r
+ TRANSLATION_TABLE_PAGE_SIZE);\r
ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);\r
\r
*SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |\r
PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE;\r
}\r
\r
+ //\r
+ // Invalidate again to ensure that any line fetches that may have occurred\r
+ // [speculatively] since the previous invalidate are evicted again.\r
+ //\r
+ ArmDataMemoryBarrier ();\r
+ InvalidateDataCacheRange ((UINT32 *)TranslationTable + FirstPageOffset,\r
+ RemainLength / TT_DESCRIPTOR_PAGE_SIZE * sizeof (*PageEntry));\r
}\r
\r
STATIC\r
RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) {\r
// Case: Physical address aligned on the Section Size (1MB) && the length\r
// is greater than the Section Size\r
- *SectionEntry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;\r
+ *SectionEntry = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;\r
+\r
+ //\r
+ // Issue a DMB to ensure that the page table entry update made it to\r
+ // memory before we issue the invalidate, otherwise, a subsequent\r
+ // speculative fetch could observe the old value.\r
+ //\r
+ ArmDataMemoryBarrier ();\r
+ ArmInvalidateDataCacheEntryByMVA ((UINTN)SectionEntry++);\r
+\r
PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;\r
RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;\r
} else {\r
// Case: Physical address aligned on the Section Size (1MB) && the length\r
// does not fill a section\r
// Case: Physical address NOT aligned on the Section Size (1MB)\r
- PopulateLevel2PageTable (SectionEntry++, PhysicalBase, PageMapLength,\r
+ PopulateLevel2PageTable (SectionEntry, PhysicalBase, PageMapLength,\r
MemoryRegion->Attributes);\r
\r
+ //\r
+ // Issue a DMB to ensure that the page table entry update made it to\r
+ // memory before we issue the invalidate, otherwise, a subsequent\r
+ // speculative fetch could observe the old value.\r
+ //\r
+ ArmDataMemoryBarrier ();\r
+ ArmInvalidateDataCacheEntryByMVA ((UINTN)SectionEntry++);\r
+\r
// If it is the last entry\r
if (RemainLength < TT_DESCRIPTOR_SECTION_SIZE) {\r
break;\r
*TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;\r
}\r
\r
+ //\r
+ // Make sure we are not inadvertently hitting in the caches\r
+ // when populating the page tables\r
+ //\r
+ InvalidateDataCacheRange (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);\r
ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);\r
\r
// By default, mark the translation table as belonging to a uncached region\r
}\r
}\r
\r
- ArmCleanInvalidateDataCache ();\r
- ArmInvalidateInstructionCache ();\r
-\r
- ArmDisableDataCache ();\r
- ArmDisableInstructionCache();\r
- // TLBs are also invalidated when calling ArmDisableMmu()\r
- ArmDisableMmu ();\r
-\r
- // Make sure nothing sneaked into the cache\r
- ArmCleanInvalidateDataCache ();\r
- ArmInvalidateInstructionCache ();\r
-\r
ArmSetTTBR0 ((VOID *)(UINTN)(((UINTN)TranslationTable & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) | (TTBRAttributes & 0x7F)));\r
\r
//\r