X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ArmVirtPkg%2FFdtClientDxe%2FFdtClientDxe.c;h=5bfde381ecd0d53996272771bdee6ebe5d5ada96;hp=4cf79f70cb2ae857797fb0452c8bd7427078b231;hb=32f5975770c309723ebb17642f89bbf9670955fd;hpb=18f6d4df9ece8b91b86511bcdd1cf7da478c3627 diff --git a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c index 4cf79f70cb..5bfde381ec 100644 --- a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c +++ b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c @@ -20,9 +20,9 @@ #include #include -#include #include #include +#include #include @@ -78,6 +78,33 @@ SetNodeProperty ( return EFI_SUCCESS; } +STATIC +BOOLEAN +IsNodeEnabled ( + INT32 Node + ) +{ + CONST CHAR8 *NodeStatus; + INT32 Len; + + // + // A missing status property implies 'ok' so ignore any errors that + // may occur here. If the status property is present, check whether + // it is set to 'ok' or 'okay', anything else is treated as 'disabled'. + // + NodeStatus = fdt_getprop (mDeviceTreeBase, Node, "status", &Len); + if (NodeStatus == NULL) { + return TRUE; + } + if (Len >= 5 && AsciiStrCmp (NodeStatus, "okay") == 0) { + return TRUE; + } + if (Len >= 3 && AsciiStrCmp (NodeStatus, "ok") == 0) { + return TRUE; + } + return FALSE; +} + STATIC EFI_STATUS EFIAPI @@ -101,6 +128,10 @@ FindNextCompatibleNode ( break; } + if (!IsNodeEnabled (Next)) { + continue; + } + Type = fdt_getprop (mDeviceTreeBase, Next, "compatible", &Len); if (Type == NULL) { continue; @@ -222,6 +253,11 @@ FindNextMemoryNodeReg ( break; } + if (!IsNodeEnabled (Next)) { + DEBUG ((DEBUG_WARN, "%a: ignoring disabled memory node\n", __FUNCTION__)); + continue; + } + DeviceType = fdt_getprop (mDeviceTreeBase, Next, "device_type", &Len); if (DeviceType != NULL && AsciiStrCmp (DeviceType, "memory") == 0) { // @@ -310,27 +346,37 @@ STATIC FDT_CLIENT_PROTOCOL mFdtClientProtocol = { STATIC VOID EFIAPI -OnReadyToBoot ( - EFI_EVENT Event, - VOID *Context +OnPlatformHasDeviceTree ( + IN EFI_EVENT Event, + IN VOID *Context ) { - EFI_STATUS Status; + EFI_STATUS Status; + VOID *Interface; + VOID *DeviceTreeBase; - if (!FeaturePcdGet (PcdPureAcpiBoot)) { - // - // Only install the FDT as a configuration table if we want to leave it up - // to the OS to decide whether it prefers ACPI over DT. - // - Status = gBS->InstallConfigurationTable (&gFdtTableGuid, mDeviceTreeBase); - ASSERT_EFI_ERROR (Status); + Status = gBS->LocateProtocol ( + &gEdkiiPlatformHasDeviceTreeGuid, + NULL, // Registration + &Interface + ); + if (EFI_ERROR (Status)) { + return; } + DeviceTreeBase = Context; + DEBUG (( + DEBUG_INFO, + "%a: exposing DTB @ 0x%p to OS\n", + __FUNCTION__, + DeviceTreeBase + )); + Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DeviceTreeBase); + ASSERT_EFI_ERROR (Status); + gBS->CloseEvent (Event); } -STATIC EFI_EVENT mReadyToBootEvent; - EFI_STATUS EFIAPI InitializeFdtClientDxe ( @@ -341,6 +387,8 @@ InitializeFdtClientDxe ( VOID *Hob; VOID *DeviceTreeBase; EFI_STATUS Status; + EFI_EVENT PlatformHasDeviceTreeEvent; + VOID *Registration; Hob = GetFirstGuidHob (&gFdtHobGuid); if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) { @@ -358,21 +406,65 @@ InitializeFdtClientDxe ( DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, mDeviceTreeBase)); - Status = gBS->InstallProtocolInterface (&ImageHandle, &gFdtClientProtocolGuid, - EFI_NATIVE_INTERFACE, &mFdtClientProtocol); + // + // Register a protocol notify for the EDKII Platform Has Device Tree + // Protocol. + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + OnPlatformHasDeviceTree, + DeviceTreeBase, // Context + &PlatformHasDeviceTreeEvent + ); if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: CreateEvent(): %r\n", __FUNCTION__, Status)); return Status; } - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - OnReadyToBoot, - NULL, - &gEfiEventReadyToBootGuid, - &mReadyToBootEvent + Status = gBS->RegisterProtocolNotify ( + &gEdkiiPlatformHasDeviceTreeGuid, + PlatformHasDeviceTreeEvent, + &Registration ); - ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: RegisterProtocolNotify(): %r\n", + __FUNCTION__, + Status + )); + goto CloseEvent; + } - return EFI_SUCCESS; + // + // Kick the event; the protocol could be available already. + // + Status = gBS->SignalEvent (PlatformHasDeviceTreeEvent); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: SignalEvent(): %r\n", __FUNCTION__, Status)); + goto CloseEvent; + } + + Status = gBS->InstallProtocolInterface ( + &ImageHandle, + &gFdtClientProtocolGuid, + EFI_NATIVE_INTERFACE, + &mFdtClientProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: InstallProtocolInterface(): %r\n", + __FUNCTION__, + Status + )); + goto CloseEvent; + } + + return Status; + +CloseEvent: + gBS->CloseEvent (PlatformHasDeviceTreeEvent); + return Status; }