EFI_STATUS GetMemoryRegion ( IN OUT UINTN *BaseAddress, OUT UINTN *RegionLength, OUT UINTN *RegionAttributes ) { EFI_STATUS Status; UINT64 *TranslationTable; UINTN TableLevel; UINTN EntryCount; UINTN T0SZ; ASSERT ((BaseAddress != NULL) && (RegionLength != NULL) && (RegionAttributes != NULL)); TranslationTable = ArmGetTTBR0BaseAddress (); T0SZ = ArmGetTCR () & TCR_T0SZ_MASK; // Get the Table info from T0SZ GetRootTranslationTableInfo (T0SZ, &TableLevel, &EntryCount); Status = GetMemoryRegionRec (TranslationTable, TableLevel, (UINTN*)TT_LAST_BLOCK_ADDRESS(TranslationTable, EntryCount), BaseAddress, RegionLength, RegionAttributes); // If the region continues up to the end of the root table then GetMemoryRegionRec() // will return EFI_NOT_FOUND if (Status == EFI_NOT_FOUND) { return EFI_SUCCESS; } else { return Status; } }
EFI_STATUS EblDumpMmu ( IN UINTN Argc, IN CHAR8 **Argv ) { UINT32 *TTEntry; MMU_ENTRY NoEntry; TTEntry = ArmGetTTBR0BaseAddress(); AsciiPrint ("\nTranslation Table:0x%X\n",TTEntry); AsciiPrint ("Address Range\t\tAttributes\n"); AsciiPrint ("____________________________________________________\n"); NoEntry.Level = (MMU_LEVEL)200; DumpMmuLevel(Level1,TTEntry,NoEntry); return EFI_SUCCESS; }
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; }