23STATIC VOID *mDeviceTreeBase;
33 OUT UINT32 *PropSize OPTIONAL
38 ASSERT (mDeviceTreeBase !=
NULL);
39 ASSERT (Prop !=
NULL);
41 *Prop = fdt_getprop (mDeviceTreeBase, Node, PropertyName, &Len);
46 if (PropSize !=
NULL) {
66 ASSERT (mDeviceTreeBase !=
NULL);
68 Ret = fdt_setprop (mDeviceTreeBase, Node, PropertyName, Prop, PropSize);
70 return EFI_DEVICE_ERROR;
82 CONST CHAR8 *NodeStatus;
90 NodeStatus = fdt_getprop (mDeviceTreeBase, Node,
"status", &Len);
91 if (NodeStatus ==
NULL) {
95 if ((Len >= 5) && (
AsciiStrCmp (NodeStatus,
"okay") == 0)) {
99 if ((Len >= 3) && (
AsciiStrCmp (NodeStatus,
"ok") == 0)) {
109FindNextCompatibleNode (
111 IN CONST CHAR8 *CompatibleString,
117 CONST CHAR8 *Type, *Compatible;
120 ASSERT (mDeviceTreeBase !=
NULL);
121 ASSERT (Node !=
NULL);
123 for (Prev = PrevNode; ; Prev = Next) {
124 Next = fdt_next_node (mDeviceTreeBase, Prev,
NULL);
129 if (!IsNodeEnabled (Next)) {
133 Type = fdt_getprop (mDeviceTreeBase, Next,
"compatible", &Len);
142 for (Compatible = Type; Compatible < Type + Len && *Compatible;
145 if (
AsciiStrCmp (CompatibleString, Compatible) == 0) {
152 return EFI_NOT_FOUND;
160 IN CONST CHAR8 *CompatibleString,
164 return FindNextCompatibleNode (This, CompatibleString, 0, Node);
170FindCompatibleNodeProperty (
172 IN CONST CHAR8 *CompatibleString,
175 OUT UINT32 *PropSize OPTIONAL
181 Status = FindCompatibleNode (This, CompatibleString, &Node);
182 if (EFI_ERROR (Status)) {
186 return GetNodeProperty (This, Node, PropertyName, Prop, PropSize);
192FindCompatibleNodeReg (
194 IN CONST CHAR8 *CompatibleString,
203 ASSERT (RegSize !=
NULL);
210 Status = FindCompatibleNodeProperty (
217 if (EFI_ERROR (Status)) {
221 if ((*RegSize % 16) != 0) {
224 "%a: '%a' compatible node has invalid 'reg' property (size == 0x%x)\n",
229 return EFI_NOT_FOUND;
241FindNextMemoryNodeReg (
252 CONST CHAR8 *DeviceType;
256 ASSERT (mDeviceTreeBase !=
NULL);
257 ASSERT (Node !=
NULL);
259 for (Prev = PrevNode; ; Prev = Next) {
260 Next = fdt_next_node (mDeviceTreeBase, Prev,
NULL);
265 if (!IsNodeEnabled (Next)) {
266 DEBUG ((DEBUG_WARN,
"%a: ignoring disabled memory node\n", __func__));
270 DeviceType = fdt_getprop (mDeviceTreeBase, Next,
"device_type", &Len);
271 if ((DeviceType !=
NULL) && (
AsciiStrCmp (DeviceType,
"memory") == 0)) {
277 Status = GetNodeProperty (This, Next,
"reg", Reg, RegSize);
278 if (EFI_ERROR (Status)) {
281 "%a: ignoring memory node with no 'reg' property\n",
287 if ((*RegSize % 16) != 0) {
290 "%a: ignoring memory node with invalid 'reg' property (size == 0x%x)\n",
304 return EFI_NOT_FOUND;
319 return FindNextMemoryNodeReg (
333GetOrInsertChosenNode (
340 ASSERT (mDeviceTreeBase !=
NULL);
341 ASSERT (Node !=
NULL);
343 NewNode = fdt_path_offset (mDeviceTreeBase,
"/chosen");
345 NewNode = fdt_add_subnode (mDeviceTreeBase, 0,
"/chosen");
349 return EFI_OUT_OF_RESOURCES;
361 FindNextCompatibleNode,
362 FindCompatibleNodeProperty,
363 FindCompatibleNodeReg,
365 FindNextMemoryNodeReg,
366 GetOrInsertChosenNode,
372OnPlatformHasDeviceTree (
379 VOID *DeviceTreeBase;
381 Status =
gBS->LocateProtocol (
382 &gEdkiiPlatformHasDeviceTreeGuid,
386 if (EFI_ERROR (Status)) {
390 DeviceTreeBase = Context;
393 "%a: exposing DTB @ 0x%p to OS\n",
397 Status =
gBS->InstallConfigurationTable (&gFdtTableGuid, DeviceTreeBase);
400 gBS->CloseEvent (Event);
405InitializeFdtClientDxe (
411 VOID *DeviceTreeBase;
417 if ((Hob ==
NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) !=
sizeof (UINT64))) {
418 return EFI_NOT_FOUND;
421 DeviceTreeBase = (VOID *)(
UINTN)*(UINT64 *)GET_GUID_HOB_DATA (Hob);
423 if (fdt_check_header (DeviceTreeBase) != 0) {
426 "%a: No DTB found @ 0x%p\n",
430 return EFI_NOT_FOUND;
433 mDeviceTreeBase = DeviceTreeBase;
435 DEBUG ((DEBUG_INFO,
"%a: DTB @ 0x%p\n", __func__, mDeviceTreeBase));
441 Status =
gBS->CreateEvent (
444 OnPlatformHasDeviceTree,
446 &PlatformHasDeviceTreeEvent
448 if (EFI_ERROR (Status)) {
449 DEBUG ((DEBUG_ERROR,
"%a: CreateEvent(): %r\n", __func__, Status));
453 Status =
gBS->RegisterProtocolNotify (
454 &gEdkiiPlatformHasDeviceTreeGuid,
455 PlatformHasDeviceTreeEvent,
458 if (EFI_ERROR (Status)) {
461 "%a: RegisterProtocolNotify(): %r\n",
471 Status =
gBS->SignalEvent (PlatformHasDeviceTreeEvent);
472 if (EFI_ERROR (Status)) {
473 DEBUG ((DEBUG_ERROR,
"%a: SignalEvent(): %r\n", __func__, Status));
477 Status =
gBS->InstallProtocolInterface (
479 &gFdtClientProtocolGuid,
483 if (EFI_ERROR (Status)) {
486 "%a: InstallProtocolInterface(): %r\n",
496 gBS->CloseEvent (PlatformHasDeviceTreeEvent);
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)