\r
#include <Guid/Fdt.h>\r
#include <Guid/FdtHob.h>\r
+#include <Guid/PlatformHasDeviceTree.h>\r
\r
#include <Protocol/FdtClient.h>\r
\r
return EFI_SUCCESS;\r
}\r
\r
+STATIC\r
+BOOLEAN\r
+IsNodeEnabled (\r
+ INT32 Node\r
+ )\r
+{\r
+ CONST CHAR8 *NodeStatus;\r
+ INT32 Len;\r
+\r
+ //\r
+ // A missing status property implies 'ok' so ignore any errors that\r
+ // may occur here. If the status property is present, check whether\r
+ // it is set to 'ok' or 'okay', anything else is treated as 'disabled'.\r
+ //\r
+ NodeStatus = fdt_getprop (mDeviceTreeBase, Node, "status", &Len);\r
+ if (NodeStatus == NULL) {\r
+ return TRUE;\r
+ }\r
+ if (Len >= 5 && AsciiStrCmp (NodeStatus, "okay") == 0) {\r
+ return TRUE;\r
+ }\r
+ if (Len >= 3 && AsciiStrCmp (NodeStatus, "ok") == 0) {\r
+ return TRUE;\r
+ }\r
+ return FALSE;\r
+}\r
+\r
STATIC\r
EFI_STATUS\r
EFIAPI\r
break;\r
}\r
\r
+ if (!IsNodeEnabled (Next)) {\r
+ continue;\r
+ }\r
+\r
Type = fdt_getprop (mDeviceTreeBase, Next, "compatible", &Len);\r
if (Type == NULL) {\r
continue;\r
break;\r
}\r
\r
+ if (!IsNodeEnabled (Next)) {\r
+ DEBUG ((DEBUG_WARN, "%a: ignoring disabled memory node\n", __FUNCTION__));\r
+ continue;\r
+ }\r
+\r
DeviceType = fdt_getprop (mDeviceTreeBase, Next, "device_type", &Len);\r
if (DeviceType != NULL && AsciiStrCmp (DeviceType, "memory") == 0) {\r
//\r
GetOrInsertChosenNode,\r
};\r
\r
+STATIC\r
+VOID\r
+EFIAPI\r
+OnPlatformHasDeviceTree (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VOID *Interface;\r
+ VOID *DeviceTreeBase;\r
+\r
+ Status = gBS->LocateProtocol (\r
+ &gEdkiiPlatformHasDeviceTreeGuid,\r
+ NULL, // Registration\r
+ &Interface\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return;\r
+ }\r
+\r
+ DeviceTreeBase = Context;\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: exposing DTB @ 0x%p to OS\n",\r
+ __FUNCTION__,\r
+ DeviceTreeBase\r
+ ));\r
+ Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DeviceTreeBase);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ gBS->CloseEvent (Event);\r
+}\r
+\r
EFI_STATUS\r
EFIAPI\r
InitializeFdtClientDxe (\r
VOID *Hob;\r
VOID *DeviceTreeBase;\r
EFI_STATUS Status;\r
+ EFI_EVENT PlatformHasDeviceTreeEvent;\r
+ VOID *Registration;\r
\r
Hob = GetFirstGuidHob (&gFdtHobGuid);\r
if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) {\r
\r
DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, mDeviceTreeBase));\r
\r
- if (!FeaturePcdGet (PcdPureAcpiBoot)) {\r
- //\r
- // Only install the FDT as a configuration table if we want to leave it up\r
- // to the OS to decide whether it prefers ACPI over DT.\r
- //\r
- Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DeviceTreeBase);\r
- ASSERT_EFI_ERROR (Status);\r
+ //\r
+ // Register a protocol notify for the EDKII Platform Has Device Tree\r
+ // Protocol.\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ OnPlatformHasDeviceTree,\r
+ DeviceTreeBase, // Context\r
+ &PlatformHasDeviceTreeEvent\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "%a: CreateEvent(): %r\n", __FUNCTION__, Status));\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->RegisterProtocolNotify (\r
+ &gEdkiiPlatformHasDeviceTreeGuid,\r
+ PlatformHasDeviceTreeEvent,\r
+ &Registration\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a: RegisterProtocolNotify(): %r\n",\r
+ __FUNCTION__,\r
+ Status\r
+ ));\r
+ goto CloseEvent;\r
}\r
\r
- return gBS->InstallProtocolInterface (&ImageHandle, &gFdtClientProtocolGuid,\r
- EFI_NATIVE_INTERFACE, &mFdtClientProtocol);\r
+ //\r
+ // Kick the event; the protocol could be available already.\r
+ //\r
+ Status = gBS->SignalEvent (PlatformHasDeviceTreeEvent);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "%a: SignalEvent(): %r\n", __FUNCTION__, Status));\r
+ goto CloseEvent;\r
+ }\r
+\r
+ Status = gBS->InstallProtocolInterface (\r
+ &ImageHandle,\r
+ &gFdtClientProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ &mFdtClientProtocol\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a: InstallProtocolInterface(): %r\n",\r
+ __FUNCTION__,\r
+ Status\r
+ ));\r
+ goto CloseEvent;\r
+ }\r
+\r
+ return Status;\r
+\r
+CloseEvent:\r
+ gBS->CloseEvent (PlatformHasDeviceTreeEvent);\r
+ return Status;\r
}\r