VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.c

Last change on this file was 108794, checked in by vboxsync, 3 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 26.2 KB
Line 
1/** @file
2 Flattened device tree utility.
3
4 Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 @par Reference(s):
8 - Device tree Specification - Release v0.3
9 - linux/Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
10 - linux//Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
11**/
12
13#include <Library/BaseLib.h>
14#include <FdtHwInfoParserInclude.h>
15#include "FdtUtility.h"
16
17/** Check whether a node has the input name.
18
19 @param [in] Fdt Pointer to a Flattened Device Tree.
20 @param [in] Node Offset of the node to check the name.
21 @param [in] SearchName Node name to search.
22 This is a NULL terminated string.
23
24 @retval True The node has the input name.
25 @retval FALSE Otherwise, or error.
26**/
27STATIC
28BOOLEAN
29EFIAPI
30FdtNodeHasName (
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
75/** Iterate through the list of strings in the Context,
76 and check whether at least one string is matching the
77 "compatible" property of the node.
78
79 @param [in] Fdt Pointer to a Flattened Device Tree.
80 @param [in] Node Offset of the node to operate the check on.
81 @param [in] CompatInfo COMPATIBILITY_INFO containing the list of compatible
82 strings to compare with the "compatible" property
83 of the node.
84
85 @retval TRUE At least one string matched, the node is compatible.
86 @retval FALSE Otherwise, or error.
87**/
88BOOLEAN
89EFIAPI
90FdtNodeIsCompatible (
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
132/** Check whether a node has a property.
133
134 @param [in] Fdt Pointer to a Flattened Device Tree.
135 @param [in] Node Offset of the node to operate the check on.
136 @param [in] PropertyName Name of the property to search.
137 This is a NULL terminated string.
138
139 @retval True The node has the property.
140 @retval FALSE Otherwise, or error.
141**/
142BOOLEAN
143EFIAPI
144FdtNodeHasProperty (
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
168/** Get the next node in the whole DT fulfilling a condition.
169
170 The condition to fulfill is checked by the NodeChecker function.
171 Context is passed to NodeChecker.
172
173 The Device tree is traversed in a depth-first search, starting from Node.
174 The input Node is skipped.
175
176 @param [in] Fdt Pointer to a Flattened Device Tree.
177 @param [in, out] Node At entry: Node offset to start the search.
178 This first node is skipped.
179 Write (-1) to search the whole tree.
180 At exit: If success, contains the offset of
181 the next node fulfilling the
182 condition.
183 @param [in, out] Depth Depth is incremented/decremented of the depth
184 difference between the input Node and the
185 output Node.
186 E.g.: If the output Node is a child node
187 of the input Node, contains (+1).
188 @param [in] NodeChecker Function called to check if the condition
189 is fulfilled.
190 @param [in] Context Context for the NodeChecker.
191
192 @retval EFI_SUCCESS The function completed successfully.
193 @retval EFI_ABORTED An error occurred.
194 @retval EFI_INVALID_PARAMETER Invalid parameter.
195 @retval EFI_NOT_FOUND No matching node found.
196**/
197STATIC
198EFI_STATUS
199EFIAPI
200FdtGetNextCondNode (
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
239/** Get the next node in a branch fulfilling a condition.
240
241 The condition to fulfill is checked by the NodeChecker function.
242 Context is passed to NodeChecker.
243
244 The Device tree is traversed in a depth-first search, starting from Node.
245 The input Node is skipped.
246
247 @param [in] Fdt Pointer to a Flattened Device Tree.
248 @param [in] FdtBranch Only search in the sub-nodes of this
249 branch.
250 Write (-1) to search the whole tree.
251 @param [in] NodeChecker Function called to check if the condition
252 is fulfilled.
253 @param [in] Context Context for the NodeChecker.
254 @param [in, out] Node At entry: Node offset to start the search.
255 This first node is skipped.
256 Write (-1) to search the whole tree.
257 At exit: If success, contains the offset
258 of the next node in the branch
259 fulfilling the condition.
260
261 @retval EFI_SUCCESS The function completed successfully.
262 @retval EFI_ABORTED An error occurred.
263 @retval EFI_INVALID_PARAMETER Invalid parameter.
264 @retval EFI_NOT_FOUND No matching node found.
265**/
266STATIC
267EFI_STATUS
268EFIAPI
269FdtGetNextCondNodeInBranch (
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
334/** Get the next node in a branch having a matching name.
335
336 The Device tree is traversed in a depth-first search, starting from Node.
337 The input Node is skipped.
338
339 @param [in] Fdt Pointer to a Flattened Device Tree.
340 @param [in] FdtBranch Only search in the sub-nodes of this branch.
341 Write (-1) to search the whole tree.
342 @param [in] NodeName The node name to search.
343 This is a NULL terminated string.
344 @param [in, out] Node At entry: Node offset to start the search.
345 This first node is skipped.
346 Write (-1) to search the whole tree.
347 At exit: If success, contains the offset of
348 the next node in the branch
349 having a matching name.
350
351 @retval EFI_SUCCESS The function completed successfully.
352 @retval EFI_ABORTED An error occurred.
353 @retval EFI_INVALID_PARAMETER Invalid parameter.
354 @retval EFI_NOT_FOUND No matching node found.
355**/
356EFI_STATUS
357EFIAPI
358FdtGetNextNamedNodeInBranch (
359 IN CONST VOID *Fdt,
360 IN INT32 FdtBranch,
361 IN CONST CHAR8 *NodeName,
362 IN OUT INT32 *Node
363 )
364{
365 return FdtGetNextCondNodeInBranch (
366 Fdt,
367 FdtBranch,
368 FdtNodeHasName,
369 NodeName,
370 Node
371 );
372}
373
374/** Get the next node in a branch with at least one compatible property.
375
376 The Device tree is traversed in a depth-first search, starting from Node.
377 The input Node is skipped.
378
379 @param [in] Fdt Pointer to a Flattened Device Tree.
380 @param [in] FdtBranch Only search in the sub-nodes of this branch.
381 Write (-1) to search the whole tree.
382 @param [in] CompatNamesInfo Table of compatible strings to compare with
383 the compatible property of the node.
384 @param [in, out] Node At entry: Node offset to start the search.
385 This first node is skipped.
386 Write (-1) to search the whole tree.
387 At exit: If success, contains the offset of
388 the next node in the branch
389 being compatible.
390
391 @retval EFI_SUCCESS The function completed successfully.
392 @retval EFI_ABORTED An error occurred.
393 @retval EFI_INVALID_PARAMETER Invalid parameter.
394 @retval EFI_NOT_FOUND No matching node found.
395**/
396EFI_STATUS
397EFIAPI
398FdtGetNextCompatNodeInBranch (
399 IN CONST VOID *Fdt,
400 IN INT32 FdtBranch,
401 IN CONST COMPATIBILITY_INFO *CompatNamesInfo,
402 IN OUT INT32 *Node
403 )
404{
405 return FdtGetNextCondNodeInBranch (
406 Fdt,
407 FdtBranch,
408 FdtNodeIsCompatible,
409 (CONST VOID *)CompatNamesInfo,
410 Node
411 );
412}
413
414/** Get the next node in a branch having the PropName property.
415
416 The Device tree is traversed in a depth-first search, starting from Node.
417 The input Node is skipped.
418
419 @param [in] Fdt Pointer to a Flattened Device Tree.
420 @param [in] FdtBranch Only search in the sub-nodes of this branch.
421 Write (-1) to search the whole tree.
422 @param [in] PropName Name of the property to search.
423 This is a NULL terminated string.
424 @param [in, out] Node At entry: Node offset to start the search.
425 This first node is skipped.
426 Write (-1) to search the whole tree.
427 At exit: If success, contains the offset of
428 the next node in the branch
429 being compatible.
430
431 @retval EFI_SUCCESS The function completed successfully.
432 @retval EFI_ABORTED An error occurred.
433 @retval EFI_INVALID_PARAMETER Invalid parameter.
434 @retval EFI_NOT_FOUND No matching node found.
435**/
436EFI_STATUS
437EFIAPI
438FdtGetNextPropNodeInBranch (
439 IN CONST VOID *Fdt,
440 IN INT32 FdtBranch,
441 IN CONST CHAR8 *PropName,
442 IN OUT INT32 *Node
443 )
444{
445 return FdtGetNextCondNodeInBranch (
446 Fdt,
447 FdtBranch,
448 FdtNodeHasProperty,
449 (CONST VOID *)PropName,
450 Node
451 );
452}
453
454/** Count the number of Device Tree nodes fulfilling a condition
455 in a Device Tree branch.
456
457 The condition to fulfill is checked by the NodeChecker function.
458 Context is passed to NodeChecker.
459
460 @param [in] Fdt Pointer to a Flattened Device Tree.
461 @param [in] FdtBranch Only search in the sub-nodes of this branch.
462 Write (-1) to search the whole tree.
463 @param [in] NodeChecker Function called to check the condition is
464 fulfilled.
465 @param [in] Context Context for the NodeChecker.
466 @param [out] NodeCount If success, contains the count of nodes
467 fulfilling the condition.
468 Can be 0.
469
470 @retval EFI_SUCCESS The function completed successfully.
471 @retval EFI_ABORTED An error occurred.
472 @retval EFI_INVALID_PARAMETER Invalid parameter.
473**/
474STATIC
475EFI_STATUS
476EFIAPI
477FdtCountCondNodeInBranch (
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) {
499 Status = FdtGetNextCondNodeInBranch (
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
521/** Count the number of nodes in a branch with the input name.
522
523 @param [in] Fdt Pointer to a Flattened Device Tree.
524 @param [in] FdtBranch Only search in the sub-nodes of this branch.
525 Write (-1) to search the whole tree.
526 @param [in] NodeName Node name to search.
527 This is a NULL terminated string.
528 @param [out] NodeCount If success, contains the count of nodes
529 fulfilling the condition.
530 Can be 0.
531
532 @retval EFI_SUCCESS The function completed successfully.
533 @retval EFI_ABORTED An error occurred.
534 @retval EFI_INVALID_PARAMETER Invalid parameter.
535**/
536EFI_STATUS
537EFIAPI
538FdtCountNamedNodeInBranch (
539 IN CONST VOID *Fdt,
540 IN INT32 FdtBranch,
541 IN CONST CHAR8 *NodeName,
542 OUT UINT32 *NodeCount
543 )
544{
545 return FdtCountCondNodeInBranch (
546 Fdt,
547 FdtBranch,
548 FdtNodeHasName,
549 NodeName,
550 NodeCount
551 );
552}
553
554/** Count the number of nodes in a branch with at least
555 one compatible property.
556
557 @param [in] Fdt Pointer to a Flattened Device Tree.
558 @param [in] FdtBranch Only search in the sub-nodes of this branch.
559 Write (-1) to search the whole tree.
560 @param [in] CompatNamesInfo Table of compatible strings to
561 compare with the compatible property
562 of the node.
563 @param [out] NodeCount If success, contains the count of nodes
564 fulfilling the condition.
565 Can be 0.
566
567 @retval EFI_SUCCESS The function completed successfully.
568 @retval EFI_ABORTED An error occurred.
569 @retval EFI_INVALID_PARAMETER Invalid parameter.
570**/
571EFI_STATUS
572EFIAPI
573FdtCountCompatNodeInBranch (
574 IN CONST VOID *Fdt,
575 IN INT32 FdtBranch,
576 IN CONST COMPATIBILITY_INFO *CompatNamesInfo,
577 OUT UINT32 *NodeCount
578 )
579{
580 return FdtCountCondNodeInBranch (
581 Fdt,
582 FdtBranch,
583 FdtNodeIsCompatible,
584 CompatNamesInfo,
585 NodeCount
586 );
587}
588
589/** Count the number of nodes in a branch having the PropName property.
590
591 @param [in] Fdt Pointer to a Flattened Device Tree.
592 @param [in] FdtBranch Only search in the sub-nodes of this branch.
593 Write (-1) to search the whole tree.
594 @param [in] PropName Name of the property to search.
595 This is a NULL terminated string.
596 @param [out] NodeCount If success, contains the count of nodes
597 fulfilling the condition.
598 Can be 0.
599
600 @retval EFI_SUCCESS The function completed successfully.
601 @retval EFI_ABORTED An error occurred.
602 @retval EFI_INVALID_PARAMETER Invalid parameter.
603**/
604EFI_STATUS
605EFIAPI
606FdtCountPropNodeInBranch (
607 IN CONST VOID *Fdt,
608 IN INT32 FdtBranch,
609 IN CONST CHAR8 *PropName,
610 OUT UINT32 *NodeCount
611 )
612{
613 return FdtCountCondNodeInBranch (
614 Fdt,
615 FdtBranch,
616 FdtNodeHasProperty,
617 PropName,
618 NodeCount
619 );
620}
621
622/** Get the interrupt-controller node handling the interrupts of
623 the input node.
624
625 To do this, recursively search a node with either the "interrupt-controller"
626 or the "interrupt-parent" property in the parents of Node.
627
628 Devicetree Specification, Release v0.3,
629 2.4.1 "Properties for Interrupt Generating Devices":
630 Because the hierarchy of the nodes in the interrupt tree
631 might not match the devicetree, the interrupt-parent
632 property is available to make the definition of an
633 interrupt parent explicit. The value is the phandle to the
634 interrupt parent. If this property is missing from a
635 device, its interrupt parent is assumed to be its devicetree
636 parent.
637
638 @param [in] Fdt Pointer to a Flattened Device Tree.
639 @param [in] Node Offset of the node to start the search.
640 @param [out] IntcNode If success, contains the offset of the
641 interrupt-controller node.
642
643 @retval EFI_SUCCESS The function completed successfully.
644 @retval EFI_NOT_FOUND No interrupt-controller node found.
645 @retval EFI_ABORTED An error occurred.
646 @retval EFI_INVALID_PARAMETER Invalid parameter.
647**/
648EFI_STATUS
649EFIAPI
650FdtGetIntcParentNode (
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
709/** Get the "interrupt-cells" property value of the node.
710
711 The "interrupts" property requires to know the number of cells used
712 to encode an interrupt. This information is stored in the
713 interrupt-controller of the input Node.
714
715 @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
716 @param [in] IntcNode Offset of an interrupt-controller node.
717 @param [out] IntCells If success, contains the "interrupt-cells"
718 property of the IntcNode.
719
720 @retval EFI_SUCCESS The function completed successfully.
721 @retval EFI_INVALID_PARAMETER Invalid parameter.
722 @retval EFI_UNSUPPORTED Unsupported.
723**/
724EFI_STATUS
725EFIAPI
726FdtGetInterruptCellsInfo (
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
754/** Get the "#address-cells" and/or "#size-cells" property of the node.
755
756 According to the Device Tree specification, s2.3.5 "#address-cells and
757 #size-cells":
758 "If missing, a client program should assume a default value of 2 for
759 #address-cells, and a value of 1 for #size-cells."
760
761 @param [in] Fdt Pointer to a Flattened Device Tree.
762 @param [in] Node Offset of the node having to get the
763 "#address-cells" and "#size-cells"
764 properties from.
765 @param [out] AddressCells If success, number of address-cells.
766 If the property is not available,
767 default value is 2.
768 @param [out] SizeCells If success, number of size-cells.
769 If the property is not available,
770 default value is 1.
771
772 @retval EFI_SUCCESS The function completed successfully.
773 @retval EFI_ABORTED An error occurred.
774 @retval EFI_INVALID_PARAMETER Invalid parameter.
775**/
776EFI_STATUS
777EFIAPI
778FdtGetAddressInfo (
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
809/** Get the "#address-cells" and/or "#size-cells" property of the parent node.
810
811 According to the Device Tree specification, s2.3.5 "#address-cells and
812 #size-cells":
813 "If missing, a client program should assume a default value of 2 for
814 #address-cells, and a value of 1 for #size-cells."
815
816 @param [in] Fdt Pointer to a Flattened Device Tree.
817 @param [in] Node Offset of the node having to get the
818 "#address-cells" and "#size-cells"
819 properties from its parent.
820 @param [out] AddressCells If success, number of address-cells.
821 If the property is not available,
822 default value is 2.
823 @param [out] SizeCells If success, number of size-cells.
824 If the property is not available,
825 default value is 1.
826
827 @retval EFI_SUCCESS The function completed successfully.
828 @retval EFI_ABORTED An error occurred.
829 @retval EFI_INVALID_PARAMETER Invalid parameter.
830**/
831EFI_STATUS
832EFIAPI
833FdtGetParentAddressInfo (
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}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette