STATIC VOID ReplaceLiveEntry ( IN UINT64 *Entry, IN UINT64 Value ) { if (!ArmMmuEnabled ()) { *Entry = Value; } else { ArmReplaceLiveTranslationEntry (Entry, Value); } }
EFI_STATUS SyncCacheConfig ( IN EFI_CPU_ARCH_PROTOCOL *CpuProtocol ) { EFI_STATUS Status; UINT32 PageAttribute = 0; UINT64 *FirstLevelTableAddress; UINTN TableLevel; UINTN TableCount; UINTN NumberOfDescriptors; EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; UINTN Tcr; UINTN T0SZ; UINT64 BaseAddressGcdRegion; UINT64 EndAddressGcdRegion; // This code assumes MMU is enabled and filed with section translations ASSERT (ArmMmuEnabled ()); // // Get the memory space map from GCD // MemorySpaceMap = NULL; Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap); ASSERT_EFI_ERROR (Status); // The GCD implementation maintains its own copy of the state of memory space attributes. GCD needs // to know what the initial memory space attributes are. The CPU Arch. Protocol does not provide a // GetMemoryAttributes function for GCD to get this so we must resort to calling GCD (as if we were // a client) to update its copy of the attributes. This is bad architecture and should be replaced // with a way for GCD to query the CPU Arch. driver of the existing memory space attributes instead. // Obtain page table base FirstLevelTableAddress = (UINT64*)(ArmGetTTBR0BaseAddress ()); // Get Translation Control Register value Tcr = ArmGetTCR (); // Get Address Region Size T0SZ = Tcr & TCR_T0SZ_MASK; // Get the level of the first table for the indicated Address Region Size GetRootTranslationTableInfo (T0SZ, &TableLevel, &TableCount); // First Attribute of the Page Tables PageAttribute = GetFirstPageAttribute (FirstLevelTableAddress, TableLevel); // We scan from the start of the memory map (ie: at the address 0x0) BaseAddressGcdRegion = 0x0; EndAddressGcdRegion = GetNextEntryAttribute (FirstLevelTableAddress, TableCount, TableLevel, BaseAddressGcdRegion, &PageAttribute, &BaseAddressGcdRegion); // Update GCD with the last region if valid if (PageAttribute != TT_ATTR_INDX_INVALID) { SetGcdMemorySpaceAttributes (MemorySpaceMap, NumberOfDescriptors, BaseAddressGcdRegion, EndAddressGcdRegion - BaseAddressGcdRegion, PageAttributeToGcdAttribute (PageAttribute)); } FreePool (MemorySpaceMap); return EFI_SUCCESS; }