TianoCore EDK2 master
Loading...
Searching...
No Matches
FdtUtility.c
Go to the documentation of this file.
1
13#include <Library/BaseLib.h>
15#include "FdtUtility.h"
16
28BOOLEAN
29EFIAPI
31 IN CONST VOID *Fdt,
32 IN INT32 Node,
33 IN CONST VOID *SearchName
34 )
35{
36 CONST CHAR8 *NodeName;
37 UINT32 Length;
38
39 if ((Fdt == NULL) ||
40 (SearchName == NULL))
41 {
42 ASSERT (0);
43 return FALSE;
44 }
45
46 // Always compare the whole string. Don't stop at the "@" char.
47 Length = (UINT32)AsciiStrLen (SearchName);
48
49 // Get the address of the node name.
50 NodeName = fdt_offset_ptr (Fdt, Node + FDT_TAGSIZE, Length + 1);
51 if (NodeName == NULL) {
52 return FALSE;
53 }
54
55 // SearchName must be longer than the node name.
56 if (Length > AsciiStrLen (NodeName)) {
57 return FALSE;
58 }
59
60 if (AsciiStrnCmp (NodeName, SearchName, Length) != 0) {
61 return FALSE;
62 }
63
64 // The name matches perfectly, or
65 // the node name is XXX@addr and the XXX matches.
66 if ((NodeName[Length] == '\0') ||
67 (NodeName[Length] == '@'))
68 {
69 return TRUE;
70 }
71
72 return FALSE;
73}
74
88BOOLEAN
89EFIAPI
91 IN CONST VOID *Fdt,
92 IN INT32 Node,
93 IN CONST VOID *CompatInfo
94 )
95{
96 UINT32 Index;
97 CONST COMPATIBILITY_STR *CompatibleTable;
98 UINT32 Count;
99 CONST VOID *Prop;
100 INT32 PropLen;
101
102 if ((Fdt == NULL) ||
103 (CompatInfo == NULL))
104 {
105 ASSERT (0);
106 return FALSE;
107 }
108
109 Count = ((COMPATIBILITY_INFO *)CompatInfo)->Count;
110 CompatibleTable = ((COMPATIBILITY_INFO *)CompatInfo)->CompatTable;
111
112 // Get the "compatible" property.
113 Prop = fdt_getprop (Fdt, Node, "compatible", &PropLen);
114 if ((Prop == NULL) || (PropLen < 0)) {
115 return FALSE;
116 }
117
118 for (Index = 0; Index < Count; Index++) {
119 if (fdt_stringlist_contains (
120 Prop,
121 PropLen,
122 CompatibleTable[Index].CompatStr
123 ))
124 {
125 return TRUE;
126 }
127 } // for
128
129 return FALSE;
130}
131
142BOOLEAN
143EFIAPI
145 IN CONST VOID *Fdt,
146 IN INT32 Node,
147 IN CONST VOID *PropertyName
148 )
149{
150 INT32 Size;
151 CONST VOID *Prop;
152
153 if ((Fdt == NULL) ||
154 (PropertyName == NULL))
155 {
156 ASSERT (0);
157 return FALSE;
158 }
159
160 Prop = fdt_getprop (Fdt, Node, PropertyName, &Size);
161 if ((Prop == NULL) || (Size < 0)) {
162 return FALSE;
163 }
164
165 return TRUE;
166}
167
197STATIC
199EFIAPI
201 IN CONST VOID *Fdt,
202 IN OUT INT32 *Node,
203 IN OUT INT32 *Depth,
204 IN NODE_CHECKER_FUNC NodeChecker,
205 IN CONST VOID *Context
206 )
207{
208 INT32 CurrNode;
209
210 if ((Fdt == NULL) ||
211 (Node == NULL) ||
212 (Depth == NULL) ||
213 (NodeChecker == NULL))
214 {
215 ASSERT (0);
216 return EFI_INVALID_PARAMETER;
217 }
218
219 CurrNode = *Node;
220 do {
221 CurrNode = fdt_next_node (Fdt, CurrNode, Depth);
222 if ((CurrNode == -FDT_ERR_NOTFOUND) ||
223 (*Depth < 0))
224 {
225 // End of the tree, no matching node found.
226 return EFI_NOT_FOUND;
227 } else if (CurrNode < 0) {
228 // An error occurred.
229 ASSERT (0);
230 return EFI_ABORTED;
231 }
232 } while (!NodeChecker (Fdt, CurrNode, Context));
233
234 // Matching node found.
235 *Node = CurrNode;
236 return EFI_SUCCESS;
237}
238
266STATIC
268EFIAPI
270 IN CONST VOID *Fdt,
271 IN INT32 FdtBranch,
272 IN NODE_CHECKER_FUNC NodeChecker,
273 IN CONST VOID *Context,
274 IN OUT INT32 *Node
275 )
276{
277 EFI_STATUS Status;
278 INT32 CurrNode;
279 INT32 Depth;
280
281 if ((Fdt == NULL) ||
282 (Node == NULL) ||
283 (NodeChecker == NULL))
284 {
285 ASSERT (0);
286 return EFI_INVALID_PARAMETER;
287 }
288
289 CurrNode = FdtBranch;
290 Depth = 0;
291
292 // First, check the Node is in the sub-nodes of the branch.
293 // This allows to find the relative depth of Node in the branch.
294 if (CurrNode != *Node) {
295 for (CurrNode = fdt_next_node (Fdt, CurrNode, &Depth);
296 (CurrNode >= 0) && (Depth > 0);
297 CurrNode = fdt_next_node (Fdt, CurrNode, &Depth))
298 {
299 if (CurrNode == *Node) {
300 // Node found.
301 break;
302 }
303 } // for
304
305 if ((CurrNode < 0) || (Depth <= 0)) {
306 // Node is not a node in the branch, or an error occurred.
307 ASSERT (0);
308 return EFI_INVALID_PARAMETER;
309 }
310 }
311
312 // Get the next node in the tree fulfilling the condition,
313 // in any branch.
314 Status = FdtGetNextCondNode (
315 Fdt,
316 Node,
317 &Depth,
318 NodeChecker,
319 Context
320 );
321 if (EFI_ERROR (Status)) {
322 ASSERT (Status == EFI_NOT_FOUND);
323 return Status;
324 }
325
326 if (Depth <= 0) {
327 // The node found is not in the right branch.
328 return EFI_NOT_FOUND;
329 }
330
331 return EFI_SUCCESS;
332}
333
357EFIAPI
359 IN CONST VOID *Fdt,
360 IN INT32 FdtBranch,
361 IN CONST CHAR8 *NodeName,
362 IN OUT INT32 *Node
363 )
364{
366 Fdt,
367 FdtBranch,
369 NodeName,
370 Node
371 );
372}
373
397EFIAPI
399 IN CONST VOID *Fdt,
400 IN INT32 FdtBranch,
401 IN CONST COMPATIBILITY_INFO *CompatNamesInfo,
402 IN OUT INT32 *Node
403 )
404{
406 Fdt,
407 FdtBranch,
409 (CONST VOID *)CompatNamesInfo,
410 Node
411 );
412}
413
437EFIAPI
439 IN CONST VOID *Fdt,
440 IN INT32 FdtBranch,
441 IN CONST CHAR8 *PropName,
442 IN OUT INT32 *Node
443 )
444{
446 Fdt,
447 FdtBranch,
449 (CONST VOID *)PropName,
450 Node
451 );
452}
453
474STATIC
476EFIAPI
478 IN CONST VOID *Fdt,
479 IN INT32 FdtBranch,
480 IN NODE_CHECKER_FUNC NodeChecker,
481 IN CONST VOID *Context,
482 OUT UINT32 *NodeCount
483 )
484{
485 EFI_STATUS Status;
486 INT32 CurrNode;
487
488 if ((Fdt == NULL) ||
489 (NodeChecker == NULL) ||
490 (NodeCount == NULL))
491 {
492 ASSERT (0);
493 return EFI_INVALID_PARAMETER;
494 }
495
496 *NodeCount = 0;
497 CurrNode = FdtBranch;
498 while (TRUE) {
500 Fdt,
501 FdtBranch,
502 NodeChecker,
503 Context,
504 &CurrNode
505 );
506 if (EFI_ERROR (Status) &&
507 (Status != EFI_NOT_FOUND))
508 {
509 ASSERT (0);
510 return Status;
511 } else if (Status == EFI_NOT_FOUND) {
512 break;
513 }
514
515 (*NodeCount)++;
516 }
517
518 return EFI_SUCCESS;
519}
520
537EFIAPI
539 IN CONST VOID *Fdt,
540 IN INT32 FdtBranch,
541 IN CONST CHAR8 *NodeName,
542 OUT UINT32 *NodeCount
543 )
544{
546 Fdt,
547 FdtBranch,
549 NodeName,
550 NodeCount
551 );
552}
553
572EFIAPI
574 IN CONST VOID *Fdt,
575 IN INT32 FdtBranch,
576 IN CONST COMPATIBILITY_INFO *CompatNamesInfo,
577 OUT UINT32 *NodeCount
578 )
579{
581 Fdt,
582 FdtBranch,
584 CompatNamesInfo,
585 NodeCount
586 );
587}
588
605EFIAPI
607 IN CONST VOID *Fdt,
608 IN INT32 FdtBranch,
609 IN CONST CHAR8 *PropName,
610 OUT UINT32 *NodeCount
611 )
612{
614 Fdt,
615 FdtBranch,
617 PropName,
618 NodeCount
619 );
620}
621
649EFIAPI
651 IN CONST VOID *Fdt,
652 IN INT32 Node,
653 OUT INT32 *IntcNode
654 )
655{
656 CONST UINT32 *PHandle;
657 INT32 Size;
658 CONST VOID *Prop;
659
660 if ((Fdt == NULL) ||
661 (IntcNode == NULL))
662 {
663 ASSERT (0);
664 return EFI_INVALID_PARAMETER;
665 }
666
667 while (TRUE) {
668 // Check whether the node has the "interrupt-controller" property.
669 Prop = fdt_getprop (Fdt, Node, "interrupt-controller", &Size);
670 if ((Prop != NULL) && (Size >= 0)) {
671 // The interrupt-controller has been found.
672 *IntcNode = Node;
673 return EFI_SUCCESS;
674 } else {
675 // Check whether the node has the "interrupt-parent" property.
676 PHandle = fdt_getprop (Fdt, Node, "interrupt-parent", &Size);
677 if ((PHandle != NULL) && (Size == sizeof (UINT32))) {
678 // The phandle of the interrupt-controller has been found.
679 // Search the node having this phandle and return it.
680 Node = fdt_node_offset_by_phandle (Fdt, fdt32_to_cpu (*PHandle));
681 if (Node < 0) {
682 ASSERT (0);
683 return EFI_ABORTED;
684 }
685
686 *IntcNode = Node;
687 return EFI_SUCCESS;
688 } else if (Size != -FDT_ERR_NOTFOUND) {
689 ASSERT (0);
690 return EFI_ABORTED;
691 }
692 }
693
694 if (Node == 0) {
695 // We are at the root of the tree. Not parent available.
696 return EFI_NOT_FOUND;
697 }
698
699 // Get the parent of the node.
700 Node = fdt_parent_offset (Fdt, Node);
701 if (Node < 0) {
702 // An error occurred.
703 ASSERT (0);
704 return EFI_ABORTED;
705 }
706 } // while
707}
708
725EFIAPI
727 IN CONST VOID *Fdt,
728 IN INT32 IntcNode,
729 OUT INT32 *IntCells
730 )
731{
732 CONST UINT32 *Data;
733 INT32 Size;
734
735 if ((Fdt == NULL) ||
736 (IntCells == NULL))
737 {
738 ASSERT (0);
739 return EFI_INVALID_PARAMETER;
740 }
741
742 Data = fdt_getprop (Fdt, IntcNode, "#interrupt-cells", &Size);
743 if ((Data == NULL) || (Size != sizeof (UINT32))) {
744 // If error or not on one UINT32 cell.
745 ASSERT (0);
746 return EFI_ABORTED;
747 }
748
749 *IntCells = fdt32_to_cpu (*Data);
750
751 return EFI_SUCCESS;
752}
753
777EFIAPI
779 IN CONST VOID *Fdt,
780 IN INT32 Node,
781 OUT INT32 *AddressCells, OPTIONAL
782 OUT INT32 *SizeCells OPTIONAL
783 )
784{
785 if (Fdt == NULL) {
786 ASSERT (0);
787 return EFI_INVALID_PARAMETER;
788 }
789
790 if (AddressCells != NULL) {
791 *AddressCells = fdt_address_cells (Fdt, Node);
792 if (*AddressCells < 0) {
793 ASSERT (0);
794 return EFI_ABORTED;
795 }
796 }
797
798 if (SizeCells != NULL) {
799 *SizeCells = fdt_size_cells (Fdt, Node);
800 if (*SizeCells < 0) {
801 ASSERT (0);
802 return EFI_ABORTED;
803 }
804 }
805
806 return EFI_SUCCESS;
807}
808
832EFIAPI
834 IN CONST VOID *Fdt,
835 IN INT32 Node,
836 OUT INT32 *AddressCells, OPTIONAL
837 OUT INT32 *SizeCells OPTIONAL
838 )
839{
840 if (Fdt == NULL) {
841 ASSERT (0);
842 return EFI_INVALID_PARAMETER;
843 }
844
845 Node = fdt_parent_offset (Fdt, Node);
846 if (Node < 0) {
847 // End of the tree, or an error occurred.
848 ASSERT (0);
849 return EFI_ABORTED;
850 }
851
852 return FdtGetAddressInfo (Fdt, Node, AddressCells, SizeCells);
853}
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
INTN EFIAPI AsciiStrnCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString, IN UINTN Length)
Definition: String.c:872
EFI_STATUS EFIAPI FdtGetNextPropNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST CHAR8 *PropName, IN OUT INT32 *Node)
Definition: FdtUtility.c:438
EFI_STATUS EFIAPI FdtCountPropNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST CHAR8 *PropName, OUT UINT32 *NodeCount)
Definition: FdtUtility.c:606
STATIC EFI_STATUS EFIAPI FdtGetNextCondNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN NODE_CHECKER_FUNC NodeChecker, IN CONST VOID *Context, IN OUT INT32 *Node)
Definition: FdtUtility.c:269
EFI_STATUS EFIAPI FdtGetNextCompatNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST COMPATIBILITY_INFO *CompatNamesInfo, IN OUT INT32 *Node)
Definition: FdtUtility.c:398
BOOLEAN EFIAPI FdtNodeIsCompatible(IN CONST VOID *Fdt, IN INT32 Node, IN CONST VOID *CompatInfo)
Definition: FdtUtility.c:90
STATIC EFI_STATUS EFIAPI FdtGetNextCondNode(IN CONST VOID *Fdt, IN OUT INT32 *Node, IN OUT INT32 *Depth, IN NODE_CHECKER_FUNC NodeChecker, IN CONST VOID *Context)
Definition: FdtUtility.c:200
EFI_STATUS EFIAPI FdtGetParentAddressInfo(IN CONST VOID *Fdt, IN INT32 Node, OUT INT32 *AddressCells, OPTIONAL OUT INT32 *SizeCells OPTIONAL)
Definition: FdtUtility.c:833
EFI_STATUS EFIAPI FdtCountCompatNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST COMPATIBILITY_INFO *CompatNamesInfo, OUT UINT32 *NodeCount)
Definition: FdtUtility.c:573
EFI_STATUS EFIAPI FdtGetIntcParentNode(IN CONST VOID *Fdt, IN INT32 Node, OUT INT32 *IntcNode)
Definition: FdtUtility.c:650
STATIC BOOLEAN EFIAPI FdtNodeHasName(IN CONST VOID *Fdt, IN INT32 Node, IN CONST VOID *SearchName)
Definition: FdtUtility.c:30
EFI_STATUS EFIAPI FdtGetAddressInfo(IN CONST VOID *Fdt, IN INT32 Node, OUT INT32 *AddressCells, OPTIONAL OUT INT32 *SizeCells OPTIONAL)
Definition: FdtUtility.c:778
STATIC EFI_STATUS EFIAPI FdtCountCondNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN NODE_CHECKER_FUNC NodeChecker, IN CONST VOID *Context, OUT UINT32 *NodeCount)
Definition: FdtUtility.c:477
EFI_STATUS EFIAPI FdtGetInterruptCellsInfo(IN CONST VOID *Fdt, IN INT32 IntcNode, OUT INT32 *IntCells)
Definition: FdtUtility.c:726
EFI_STATUS EFIAPI FdtGetNextNamedNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST CHAR8 *NodeName, IN OUT INT32 *Node)
Definition: FdtUtility.c:358
EFI_STATUS EFIAPI FdtCountNamedNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST CHAR8 *NodeName, OUT UINT32 *NodeCount)
Definition: FdtUtility.c:538
BOOLEAN EFIAPI FdtNodeHasProperty(IN CONST VOID *Fdt, IN INT32 Node, IN CONST VOID *PropertyName)
Definition: FdtUtility.c:144
BOOLEAN(EFIAPI * NODE_CHECKER_FUNC)(IN CONST VOID *Fdt, IN INT32 NodeOffset, IN CONST VOID *Context)
Definition: FdtUtility.h:127
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112