RETURN_STATUS EFIAPI ArmVirtPL031FdtClientLibConstructor ( VOID ) { EFI_STATUS Status; FDT_CLIENT_PROTOCOL *FdtClient; INT32 Node; CONST UINT64 *Reg; UINT32 RegSize; UINT64 RegBase; RETURN_STATUS PcdStatus; Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, (VOID **)&FdtClient); ASSERT_EFI_ERROR (Status); Status = FdtClient->FindCompatibleNode (FdtClient, "arm,pl031", &Node); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_WARN, "%a: No 'arm,pl031' compatible DT node found\n", __FUNCTION__)); return EFI_SUCCESS; } Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", (CONST VOID **)&Reg, &RegSize); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_WARN, "%a: No 'reg' property found in 'arm,pl031' compatible DT node\n", __FUNCTION__)); return EFI_SUCCESS; } ASSERT (RegSize == 16); RegBase = SwapBytes64 (Reg[0]); ASSERT (RegBase < MAX_UINT32); PcdStatus = PcdSet32S (PcdPL031RtcBase, (UINT32)RegBase); ASSERT_RETURN_ERROR (PcdStatus); DEBUG ((EFI_D_INFO, "Found PL031 RTC @ 0x%Lx\n", RegBase)); if (!FeaturePcdGet (PcdPureAcpiBoot)) { // // UEFI takes ownership of the RTC hardware, and exposes its functionality // through the UEFI Runtime Services GetTime, SetTime, etc. This means we // need to disable it in the device tree to prevent the OS from attaching // its device driver as well. // Status = FdtClient->SetNodeProperty (FdtClient, Node, "status", "disabled", sizeof ("disabled")); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_WARN, "Failed to set PL031 status to 'disabled'\n")); } } return EFI_SUCCESS; }
EFI_STATUS NorFlashPlatformGetDevices ( OUT NOR_FLASH_DESCRIPTION **NorFlashDescriptions, OUT UINT32 *Count ) { FDT_CLIENT_PROTOCOL *FdtClient; INT32 Node; EFI_STATUS Status; EFI_STATUS FindNodeStatus; CONST UINT32 *Reg; UINT32 PropSize; UINT32 Num; UINT64 Base; UINT64 Size; Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, (VOID **)&FdtClient); ASSERT_EFI_ERROR (Status); Num = 0; for (FindNodeStatus = FdtClient->FindCompatibleNode (FdtClient, "cfi-flash", &Node); !EFI_ERROR (FindNodeStatus) && Num < MAX_FLASH_BANKS; FindNodeStatus = FdtClient->FindNextCompatibleNode (FdtClient, "cfi-flash", Node, &Node)) { Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", (CONST VOID **)&Reg, &PropSize); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "%a: GetNodeProperty () failed (Status == %r)\n", __FUNCTION__, Status)); continue; } ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0); while (PropSize >= (4 * sizeof (UINT32)) && Num < MAX_FLASH_BANKS) { Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0])); Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2])); Reg += 4; PropSize -= 4 * sizeof (UINT32); // // Disregard any flash devices that overlap with the primary FV. // The firmware is not updatable from inside the guest anyway. // if ((PcdGet64 (PcdFvBaseAddress) + PcdGet32 (PcdFvSize) > Base) && (Base + Size) > PcdGet64 (PcdFvBaseAddress)) { continue; } mNorFlashDevices[Num].DeviceBaseAddress = (UINTN)Base; mNorFlashDevices[Num].RegionBaseAddress = (UINTN)Base; mNorFlashDevices[Num].Size = (UINTN)Size; mNorFlashDevices[Num].BlockSize = QEMU_NOR_BLOCK_SIZE; Num++; } } *NorFlashDescriptions = mNorFlashDevices; *Count = Num; return EFI_SUCCESS; }