TianoCore EDK2 master
Loading...
Searching...
No Matches
AmlTreeTraversal.c
Go to the documentation of this file.
1
10
11#include <AmlCoreInterface.h>
12#include <Tree/AmlTree.h>
13
38EFIAPI
40 IN AML_NODE_HEADER *VarArgNode
41 )
42{
43 EAML_PARSE_INDEX Index;
44 AML_NODE_HEADER *ParentNode;
45
46 // VarArgNode must be an object node or a data node,
47 // and be in a variable list of arguments.
48 if ((!IS_AML_OBJECT_NODE (VarArgNode) &&
49 !IS_AML_DATA_NODE (VarArgNode)) ||
50 AmlIsNodeFixedArgument (VarArgNode, &Index))
51 {
52 ASSERT (0);
53 return NULL;
54 }
55
56 ParentNode = AmlGetParent (VarArgNode);
57 if (!IS_AML_NODE_VALID (ParentNode)) {
58 ASSERT (0);
59 return NULL;
60 }
61
62 return AmlGetNextVariableArgument (ParentNode, VarArgNode);
63}
64
87EFIAPI
89 IN AML_NODE_HEADER *Node,
90 IN AML_NODE_HEADER *CurrVarArg
91 )
92{
93 CONST LIST_ENTRY *StartLink;
94 CONST LIST_ENTRY *NextLink;
95
96 // Node must be a RootNode or an Object Node
97 // and the CurrVarArg must not be a Root Node.
98 if ((!IS_AML_ROOT_NODE (Node) &&
99 !IS_AML_OBJECT_NODE (Node)) ||
100 ((CurrVarArg != NULL) &&
101 (!IS_AML_OBJECT_NODE (CurrVarArg) &&
102 !IS_AML_DATA_NODE (CurrVarArg))))
103 {
104 ASSERT (0);
105 return NULL;
106 }
107
108 StartLink = AmlNodeGetVariableArgList (Node);
109 if (StartLink == NULL) {
110 return NULL;
111 }
112
113 // Get the first child of the variable list of arguments.
114 if (CurrVarArg == NULL) {
115 NextLink = StartLink->ForwardLink;
116 if (NextLink != StartLink) {
117 return (AML_NODE_HEADER *)NextLink;
118 }
119
120 // List is empty.
121 return NULL;
122 }
123
124 // Check if CurrVarArg is in the VariableArgument List.
125 if (!IsNodeInList (StartLink, &CurrVarArg->Link)) {
126 ASSERT (0);
127 return NULL;
128 }
129
130 // Get the node following the CurrVarArg.
131 NextLink = CurrVarArg->Link.ForwardLink;
132 if (NextLink != StartLink) {
133 return (AML_NODE_HEADER *)NextLink;
134 }
135
136 // End of the list has been reached.
137 return NULL;
138}
139
163EFIAPI
165 IN AML_NODE_HEADER *Node,
166 IN AML_NODE_HEADER *CurrVarArg
167 )
168{
169 CONST LIST_ENTRY *StartLink;
170 CONST LIST_ENTRY *PreviousLink;
171
172 // Node must be a RootNode or an Object Node
173 // and the CurrVarArg must not be a Root Node.
174 if ((!IS_AML_ROOT_NODE (Node) &&
175 !IS_AML_OBJECT_NODE (Node)) ||
176 ((CurrVarArg != NULL) &&
177 (!IS_AML_OBJECT_NODE (CurrVarArg) &&
178 !IS_AML_DATA_NODE (CurrVarArg))))
179 {
180 ASSERT (0);
181 return NULL;
182 }
183
184 StartLink = AmlNodeGetVariableArgList (Node);
185 if (StartLink == NULL) {
186 return NULL;
187 }
188
189 // Get the last child of the variable list of arguments.
190 if (CurrVarArg == NULL) {
191 PreviousLink = StartLink->BackLink;
192 if (PreviousLink != StartLink) {
193 return (AML_NODE_HEADER *)PreviousLink;
194 }
195
196 // List is empty.
197 return NULL;
198 }
199
200 // Check if CurrVarArg is in the VariableArgument List.
201 if (!IsNodeInList (StartLink, &CurrVarArg->Link)) {
202 ASSERT (0);
203 return NULL;
204 }
205
206 // Get the node before the CurrVarArg.
207 PreviousLink = CurrVarArg->Link.BackLink;
208 if (PreviousLink != StartLink) {
209 return (AML_NODE_HEADER *)PreviousLink;
210 }
211
212 // We have reached the beginning of the list.
213 return NULL;
214}
215
246EFIAPI
249 IN CONST AML_NODE_HEADER *ChildNode
250 )
251{
252 EAML_PARSE_INDEX Index;
253 AML_NODE_HEADER *CandidateNode;
254
255 // Node must be a RootNode or an Object Node
256 // and the CurrVarArg must not be a Root Node.
257 if ((!IS_AML_ROOT_NODE (Node) &&
258 !IS_AML_OBJECT_NODE (Node)) ||
259 ((ChildNode != NULL) &&
260 (!IS_AML_OBJECT_NODE (ChildNode) &&
261 !IS_AML_DATA_NODE (ChildNode))))
262 {
263 ASSERT (0);
264 return NULL;
265 }
266
267 if (IS_AML_OBJECT_NODE (Node)) {
268 if (ChildNode == NULL) {
269 // Get the fixed argument at index 0 of the ChildNode.
270 CandidateNode = AmlGetFixedArgument (
271 (AML_OBJECT_NODE *)Node,
273 );
274 if (CandidateNode != NULL) {
275 return CandidateNode;
276 }
277 } else {
278 // (ChildNode != NULL)
279 if (AmlIsNodeFixedArgument (ChildNode, &Index)) {
280 // Increment index to point to the next fixed argument.
281 Index++;
282 // The node is part of the list of fixed arguments.
284 (AML_OBJECT_NODE *)Node
285 )
286 )
287 {
288 // It is at the last argument of the fixed argument list.
289 // Get the first argument of the variable list of arguments.
290 ChildNode = NULL;
291 } else {
292 // Else return the next node in the list of fixed arguments.
293 return AmlGetFixedArgument ((AML_OBJECT_NODE *)Node, Index);
294 }
295 }
296 }
297 } // IS_AML_OBJECT_NODE (Node)
298
299 // Else, get the next node in the variable list of arguments.
301 (AML_NODE_HEADER *)Node,
302 (AML_NODE_HEADER *)ChildNode
303 );
304}
305
334EFIAPI
337 IN CONST AML_NODE_HEADER *ChildNode
338 )
339{
340 EAML_PARSE_INDEX Index;
341 EAML_PARSE_INDEX MaxIndex;
342
343 AML_NODE_HEADER *CandidateNode;
344
345 // Node must be a Root Node or an Object Node
346 // and the ChildNode must not be a Root Node.
347 if ((!IS_AML_ROOT_NODE (Node) &&
348 !IS_AML_OBJECT_NODE (Node)) ||
349 ((ChildNode != NULL) &&
350 (!IS_AML_OBJECT_NODE (ChildNode) &&
351 !IS_AML_DATA_NODE (ChildNode))))
352 {
353 ASSERT (0);
354 return NULL;
355 }
356
358 (AML_OBJECT_NODE *)Node
359 );
360
361 // Get the last variable argument if no ChildNode.
362 // Otherwise the fixed argument list is checked first.
363 if ((ChildNode != NULL) &&
364 IS_AML_OBJECT_NODE (Node) &&
365 (MaxIndex != EAmlParseIndexTerm0))
366 {
367 if (AmlIsNodeFixedArgument (ChildNode, &Index)) {
368 // The node is part of the list of fixed arguments.
369 if (Index == EAmlParseIndexTerm0) {
370 // The node is the first fixed argument, return NULL.
371 return NULL;
372 } else {
373 // Return the previous node in the fixed argument list.
374 return AmlGetFixedArgument (
375 (AML_OBJECT_NODE *)Node,
376 (EAML_PARSE_INDEX)(Index - 1)
377 );
378 }
379 }
380 }
381
382 // ChildNode is in the variable list of arguments.
383 CandidateNode = AmlGetPreviousVariableArgument (
384 (AML_NODE_HEADER *)Node,
385 (AML_NODE_HEADER *)ChildNode
386 );
387 if (CandidateNode != NULL) {
388 if (!IS_AML_NODE_VALID (CandidateNode)) {
389 ASSERT (0);
390 return NULL;
391 }
392
393 // A Node has been found
394 return CandidateNode;
395 } else if (MaxIndex != EAmlParseIndexTerm0) {
396 // ChildNode was the first node of the variable list of arguments.
397 return AmlGetFixedArgument (
398 (AML_OBJECT_NODE *)Node,
399 (EAML_PARSE_INDEX)(MaxIndex - 1)
400 );
401 } else {
402 // No fixed arguments or variable arguments.
403 return NULL;
404 }
405}
406
428EFIAPI
431 )
432{
433 AML_NODE_HEADER *ParentNode;
434 AML_NODE_HEADER *CandidateNode;
435
436 if (!IS_AML_NODE_VALID (Node)) {
437 ASSERT (0);
438 return NULL;
439 }
440
441 if (IS_AML_ROOT_NODE (Node) || IS_AML_OBJECT_NODE (Node)) {
442 // The node has children. Get the first child.
443 CandidateNode = AmlGetNextSibling (Node, NULL);
444 if (CandidateNode != NULL) {
445 if (!IS_AML_NODE_VALID (CandidateNode)) {
446 ASSERT (0);
447 return NULL;
448 }
449
450 // A Node has been found
451 return CandidateNode;
452 } else if (IS_AML_ROOT_NODE (Node)) {
453 // The node is the root node and it doesn't have children.
454 return NULL;
455 }
456 }
457
458 // We have traversed the current branch, go to the parent node
459 // and start traversing the next branch.
460 // Keep going up the tree until you reach the root node.
461 while (1) {
462 if (IS_AML_ROOT_NODE (Node)) {
463 // This is the last node of the tree.
464 return NULL;
465 }
466
467 ParentNode = AmlGetParent ((AML_NODE_HEADER *)Node);
468 if (!IS_AML_NODE_VALID (ParentNode)) {
469 ASSERT (0);
470 return NULL;
471 }
472
473 CandidateNode = AmlGetNextSibling (ParentNode, Node);
474 if (CandidateNode != NULL) {
475 if (!IS_AML_NODE_VALID (CandidateNode)) {
476 ASSERT (0);
477 return NULL;
478 }
479
480 // A Node has been found
481 return CandidateNode;
482 }
483
484 Node = ParentNode;
485 } // while
486
487 return NULL;
488}
489
512EFIAPI
515 )
516{
517 AML_NODE_HEADER *ParentNode;
518 AML_NODE_HEADER *CandidateNode;
519 AML_NODE_HEADER *PreviousNode;
520
521 if (!IS_AML_NODE_VALID (Node)) {
522 ASSERT (0);
523 return NULL;
524 }
525
526 while (1) {
527 if (IS_AML_ROOT_NODE (Node)) {
528 // This is the root node.
529 return NULL;
530 }
531
532 ParentNode = AmlGetParent ((AML_NODE_HEADER *)Node);
533 CandidateNode = AmlGetPreviousSibling (ParentNode, Node);
534
535 if (CandidateNode == NULL) {
536 // Node is the first child of its parent.
537 return ParentNode;
538 } else if (IS_AML_DATA_NODE (CandidateNode)) {
539 // CandidateNode is a data node, thus it has no children.
540 return CandidateNode;
541 } else if (IS_AML_OBJECT_NODE (CandidateNode)) {
542 // Get the previous node in the list of children of ParentNode,
543 // then get the last child of this node.
544 // If this node has children, get its last child, etc.
545 while (1) {
546 PreviousNode = CandidateNode;
547 CandidateNode = AmlGetPreviousSibling (PreviousNode, NULL);
548 if (CandidateNode == NULL) {
549 return PreviousNode;
550 } else if (IS_AML_DATA_NODE (CandidateNode)) {
551 return CandidateNode;
552 }
553 } // while
554 } else {
555 ASSERT (0);
556 return NULL;
557 }
558 } // while
559}
#define IS_AML_ROOT_NODE(Node)
#define IS_AML_OBJECT_NODE(Node)
#define IS_AML_DATA_NODE(Node)
#define IS_AML_NODE_VALID(Node)
LIST_ENTRY *EFIAPI AmlNodeGetVariableArgList(IN CONST AML_NODE_HEADER *Node)
Definition: AmlTree.c:205
BOOLEAN EFIAPI AmlIsNodeFixedArgument(IN CONST AML_NODE_HEADER *Node, OUT EAML_PARSE_INDEX *IndexPtr)
Definition: AmlTree.c:110
AML_NODE_HEADER *EFIAPI AmlGetPreviousSibling(IN CONST AML_NODE_HEADER *Node, IN CONST AML_NODE_HEADER *ChildNode)
AML_NODE_HEADER *EFIAPI AmlGetPreviousVariableArgument(IN AML_NODE_HEADER *Node, IN AML_NODE_HEADER *CurrVarArg)
AML_NODE_HEADER *EFIAPI AmlGetPreviousNode(IN CONST AML_NODE_HEADER *Node)
AML_NODE_HEADER *EFIAPI AmlGetNextNode(IN CONST AML_NODE_HEADER *Node)
AML_NODE_HEADER *EFIAPI AmlGetNextVariableArgument(IN AML_NODE_HEADER *Node, IN AML_NODE_HEADER *CurrVarArg)
AML_NODE_HEADER *EFIAPI AmlGetNextSibling(IN CONST AML_NODE_HEADER *Node, IN CONST AML_NODE_HEADER *ChildNode)
BOOLEAN EFIAPI IsNodeInList(IN CONST LIST_ENTRY *FirstEntry, IN CONST LIST_ENTRY *SecondEntry)
Definition: LinkedList.c:121
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
AML_NODE_HEADER *EFIAPI AmlGetSiblingVariableArgument(IN AML_NODE_HEADER *VarArgNode)
AML_NODE_HANDLE EFIAPI AmlGetParent(IN AML_NODE_HANDLE Node)
AML_NODE_HANDLE EFIAPI AmlGetFixedArgument(IN AML_OBJECT_NODE_HANDLE ObjectNode, IN EAML_PARSE_INDEX Index)
UINT8 AmlGetFixedArgumentCount(IN AML_OBJECT_NODE_HANDLE Node)
enum EAmlParseIndex EAML_PARSE_INDEX
@ EAmlParseIndexTerm0
First fixed argument index.
Definition: AmlDefines.h:65