TianoCore EDK2 master
Loading...
Searching...
No Matches
AmlTree.c
Go to the documentation of this file.
1
9#include <Tree/AmlTree.h>
10
11#include <AmlCoreInterface.h>
12#include <Tree/AmlNode.h>
14#include <Utils/AmlUtility.h>
15
24EFIAPI
27 )
28{
29 if (IS_AML_DATA_NODE (Node) ||
30 IS_AML_OBJECT_NODE (Node))
31 {
32 return Node->Parent;
33 }
34
35 return NULL;
36}
37
47EFIAPI
50 )
51{
52 if (!IS_AML_NODE_VALID (Node)) {
53 ASSERT (0);
54 return NULL;
55 }
56
57 while (!IS_AML_ROOT_NODE (Node)) {
58 Node = Node->Parent;
59 if (!IS_AML_NODE_VALID (Node)) {
60 ASSERT (0);
61 return NULL;
62 }
63 }
64
65 return (AML_ROOT_NODE *)Node;
66}
67
80EFIAPI
82 IN AML_OBJECT_NODE *ObjectNode,
84 )
85{
86 if (IS_AML_OBJECT_NODE (ObjectNode)) {
87 if (Index < (EAML_PARSE_INDEX)AmlGetFixedArgumentCount (ObjectNode)) {
88 return ObjectNode->FixedArgs[Index];
89 }
90 }
91
92 return NULL;
93}
94
108BOOLEAN
109EFIAPI
112 OUT EAML_PARSE_INDEX *IndexPtr
113 )
114{
115 AML_NODE_HEADER *ParentNode;
116
117 EAML_PARSE_INDEX Index;
118 EAML_PARSE_INDEX MaxIndex;
119
120 if ((IndexPtr == NULL) ||
121 (!IS_AML_DATA_NODE (Node) &&
122 !IS_AML_OBJECT_NODE (Node)))
123 {
124 ASSERT (0);
125 return FALSE;
126 }
127
128 ParentNode = AmlGetParent ((AML_NODE_HEADER *)Node);
129 if (IS_AML_ROOT_NODE (ParentNode)) {
130 return FALSE;
131 } else if (IS_AML_DATA_NODE (ParentNode)) {
132 // Tree is inconsistent.
133 ASSERT (0);
134 return FALSE;
135 }
136
137 // Check whether the Node is in the fixed argument list.
139 (AML_OBJECT_NODE *)ParentNode
140 );
141 for (Index = EAmlParseIndexTerm0; Index < MaxIndex; Index++) {
142 if (AmlGetFixedArgument ((AML_OBJECT_NODE *)ParentNode, Index) == Node) {
143 *IndexPtr = Index;
144 return TRUE;
145 }
146 }
147
148 return FALSE;
149}
150
167EFIAPI
169 IN AML_OBJECT_NODE *ObjectNode,
170 IN EAML_PARSE_INDEX Index,
171 IN AML_NODE_HEADER *NewNode
172 )
173{
174 if (IS_AML_OBJECT_NODE (ObjectNode) &&
175 (Index <= (EAML_PARSE_INDEX)AmlGetFixedArgumentCount (ObjectNode)) &&
176 ((NewNode == NULL) ||
177 IS_AML_OBJECT_NODE (NewNode) ||
178 IS_AML_DATA_NODE (NewNode)))
179 {
180 ObjectNode->FixedArgs[Index] = NewNode;
181
182 // If NewNode is a data node or an object node, set its parent.
183 if (NewNode != NULL) {
184 NewNode->Parent = (AML_NODE_HEADER *)ObjectNode;
185 }
186
187 return EFI_SUCCESS;
188 }
189
190 ASSERT (0);
191 return EFI_INVALID_PARAMETER;
192}
193
204EFIAPI
207 )
208{
209 if (IS_AML_ROOT_NODE (Node)) {
210 return &(((AML_ROOT_NODE *)Node)->VariableArgs);
211 } else if (IS_AML_OBJECT_NODE (Node)) {
212 return &(((AML_OBJECT_NODE *)Node)->VariableArgs);
213 }
214
215 return NULL;
216}
217
232EFIAPI
234 IN AML_NODE_HEADER *Node
235 )
236{
237 EFI_STATUS Status;
238 AML_NODE_HEADER *ParentNode;
239 UINT32 Size;
240
241 if ((!IS_AML_DATA_NODE (Node) &&
242 !IS_AML_OBJECT_NODE (Node)))
243 {
244 ASSERT (0);
245 return EFI_INVALID_PARAMETER;
246 }
247
248 ParentNode = AmlGetParent (Node);
249 if (!IS_AML_ROOT_NODE (ParentNode) &&
250 !IS_AML_OBJECT_NODE (ParentNode))
251 {
252 ASSERT (0);
253 return EFI_INVALID_PARAMETER;
254 }
255
256 // Check the node is in its parent variable list of arguments.
257 if (!IsNodeInList (
258 AmlNodeGetVariableArgList (ParentNode),
259 &Node->Link
260 ))
261 {
262 ASSERT (0);
263 return EFI_INVALID_PARAMETER;
264 }
265
266 // Unlink Node from the tree.
267 RemoveEntryList (&Node->Link);
268 InitializeListHead (&Node->Link);
269 Node->Parent = NULL;
270
271 // Get the size of the node removed.
272 Status = AmlComputeSize (Node, &Size);
273 if (EFI_ERROR (Status)) {
274 ASSERT (0);
275 return Status;
276 }
277
278 // Propagate the information.
279 Status = AmlPropagateInformation (ParentNode, FALSE, Size, 1);
280 ASSERT_EFI_ERROR (Status);
281
282 return Status;
283}
284
299EFIAPI
301 IN AML_NODE_HEADER *Node
302 )
303{
304 return AmlRemoveNodeFromVarArgList (Node);
305}
306
318EFIAPI
320 IN AML_NODE_HEADER *ParentNode,
321 IN AML_NODE_HEADER *NewNode
322 )
323{
324 EFI_STATUS Status;
325 UINT32 NewSize;
326 LIST_ENTRY *ChildrenList;
327
328 // Check arguments and that NewNode is not already attached to a tree.
329 // ParentNode != Data Node AND NewNode != Root Node AND NewNode != attached.
330 if ((!IS_AML_ROOT_NODE (ParentNode) &&
331 !IS_AML_OBJECT_NODE (ParentNode)) ||
332 (!IS_AML_DATA_NODE (NewNode) &&
333 !IS_AML_OBJECT_NODE (NewNode)) ||
334 !AML_NODE_IS_DETACHED (NewNode))
335 {
336 ASSERT (0);
337 return EFI_INVALID_PARAMETER;
338 }
339
340 // Insert it at the head of the list.
341 ChildrenList = AmlNodeGetVariableArgList (ParentNode);
342 if (ChildrenList == NULL) {
343 ASSERT (0);
344 return EFI_INVALID_PARAMETER;
345 }
346
347 InsertHeadList (ChildrenList, &NewNode->Link);
348 NewNode->Parent = ParentNode;
349
350 // Get the size of the NewNode.
351 Status = AmlComputeSize (NewNode, &NewSize);
352 if (EFI_ERROR (Status)) {
353 ASSERT (0);
354 return Status;
355 }
356
357 // Propagate the new information.
358 Status = AmlPropagateInformation (ParentNode, TRUE, NewSize, 1);
359 ASSERT_EFI_ERROR (Status);
360
361 return Status;
362}
363
378EFIAPI
380 IN AML_NODE_HEADER *ParentNode,
381 IN AML_NODE_HEADER *NewNode
382 )
383{
384 LIST_ENTRY *ChildrenList;
385
386 // Check arguments and that NewNode is not already attached to a tree.
387 // ParentNode != Data Node AND NewNode != Root Node AND NewNode != attached.
388 if ((!IS_AML_ROOT_NODE (ParentNode) &&
389 !IS_AML_OBJECT_NODE (ParentNode)) ||
390 (!IS_AML_DATA_NODE (NewNode) &&
391 !IS_AML_OBJECT_NODE (NewNode)) ||
392 !AML_NODE_IS_DETACHED (NewNode))
393 {
394 ASSERT (0);
395 return EFI_INVALID_PARAMETER;
396 }
397
398 // Insert it at the tail of the list.
399 ChildrenList = AmlNodeGetVariableArgList (ParentNode);
400 if (ChildrenList == NULL) {
401 ASSERT (0);
402 return EFI_INVALID_PARAMETER;
403 }
404
405 InsertTailList (ChildrenList, &NewNode->Link);
406 NewNode->Parent = ParentNode;
407
408 return EFI_SUCCESS;
409}
410
422EFIAPI
424 IN AML_NODE_HEADER *ParentNode,
425 IN AML_NODE_HEADER *NewNode
426 )
427{
428 EFI_STATUS Status;
429 UINT32 NewSize;
430
431 // Add the NewNode and check arguments.
432 Status = AmlVarListAddTailInternal (ParentNode, NewNode);
433 if (EFI_ERROR (Status)) {
434 ASSERT (0);
435 return Status;
436 }
437
438 // Get the size of the NewNode.
439 Status = AmlComputeSize (NewNode, &NewSize);
440 if (EFI_ERROR (Status)) {
441 ASSERT (0);
442 return Status;
443 }
444
445 // Propagate the new information.
446 Status = AmlPropagateInformation (ParentNode, TRUE, NewSize, 1);
447 ASSERT_EFI_ERROR (Status);
448
449 return Status;
450}
451
463EFIAPI
465 IN AML_NODE_HEADER *Node,
466 IN AML_NODE_HEADER *NewNode
467 )
468{
469 EFI_STATUS Status;
470 AML_NODE_HEADER *ParentNode;
471 UINT32 NewSize;
472
473 // Check arguments and that NewNode is not already attached to a tree.
474 if ((!IS_AML_DATA_NODE (NewNode) &&
475 !IS_AML_OBJECT_NODE (NewNode)) ||
476 !AML_NODE_IS_DETACHED (NewNode))
477 {
478 ASSERT (0);
479 return EFI_INVALID_PARAMETER;
480 }
481
482 ParentNode = AmlGetParent (Node);
483 if (!IS_AML_ROOT_NODE (ParentNode) &&
484 !IS_AML_OBJECT_NODE (ParentNode))
485 {
486 ASSERT (0);
487 return EFI_INVALID_PARAMETER;
488 }
489
490 // Insert it before the input Node.
491 InsertTailList (&Node->Link, &NewNode->Link);
492 NewNode->Parent = ParentNode;
493
494 // Get the size of the NewNode.
495 Status = AmlComputeSize (NewNode, &NewSize);
496 if (EFI_ERROR (Status)) {
497 ASSERT (0);
498 return Status;
499 }
500
501 // Propagate the new information.
502 Status = AmlPropagateInformation (ParentNode, TRUE, NewSize, 1);
503 ASSERT_EFI_ERROR (Status);
504
505 return Status;
506}
507
519EFIAPI
521 IN AML_NODE_HEADER *Node,
522 IN AML_NODE_HEADER *NewNode
523 )
524{
525 EFI_STATUS Status;
526 AML_NODE_HEADER *ParentNode;
527 UINT32 NewSize;
528
529 // Check arguments and that NewNode is not already attached to a tree.
530 if ((!IS_AML_DATA_NODE (NewNode) &&
531 !IS_AML_OBJECT_NODE (NewNode)) ||
532 !AML_NODE_IS_DETACHED (NewNode))
533 {
534 ASSERT (0);
535 return EFI_INVALID_PARAMETER;
536 }
537
538 ParentNode = AmlGetParent (Node);
539 if (!IS_AML_ROOT_NODE (ParentNode) &&
540 !IS_AML_OBJECT_NODE (ParentNode))
541 {
542 ASSERT (0);
543 return EFI_INVALID_PARAMETER;
544 }
545
546 // Insert the new node after the input Node.
547 InsertHeadList (&Node->Link, &NewNode->Link);
548 NewNode->Parent = ParentNode;
549
550 // Get the size of the NewNode.
551 Status = AmlComputeSize (NewNode, &NewSize);
552 if (EFI_ERROR (Status)) {
553 ASSERT (0);
554 return Status;
555 }
556
557 // Propagate the new information.
558 Status = AmlPropagateInformation (ParentNode, TRUE, NewSize, 1);
559 ASSERT_EFI_ERROR (Status);
560
561 return Status;
562}
563
577EFIAPI
579 IN AML_OBJECT_NODE *BufferOpNode,
580 IN AML_DATA_NODE *NewRdNode
581 )
582{
583 EFI_STATUS Status;
584 AML_DATA_NODE *LastRdNode;
585
586 if (!AmlNodeCompareOpCode (BufferOpNode, AML_BUFFER_OP, 0) ||
587 !IS_AML_DATA_NODE (NewRdNode) ||
588 (NewRdNode->DataType != EAmlNodeDataTypeResourceData))
589 {
590 ASSERT (0);
591 return EFI_INVALID_PARAMETER;
592 }
593
594 // To avoid re-computing checksums, if a new resource data elements is
595 // added/removed/modified in a list of resource data elements, the AmlLib
596 // resets the checksum to 0.
597 // It is possible to have only one Resource Data in a BufferOp with
598 // no EndTag, but it should not be possible to add a new Resource Data
599 // in the list in this case.
600 Status = AmlSetRdListCheckSum (BufferOpNode, 0);
601 if (EFI_ERROR (Status)) {
602 ASSERT (0);
603 return Status;
604 }
605
606 // Get the last Resource data node in the variable list of argument of the
607 // BufferOp node. This must be an EndTag, otherwise setting the checksum
608 // would have failed.
610 (AML_NODE_HEADER *)BufferOpNode,
611 NULL
612 );
613 if ((LastRdNode == NULL) ||
614 !IS_AML_DATA_NODE (LastRdNode) ||
615 (LastRdNode->DataType != EAmlNodeDataTypeResourceData))
616 {
617 ASSERT (0);
618 return EFI_INVALID_PARAMETER;
619 }
620
621 // Add NewRdNode before the EndTag.
622 Status = AmlVarListAddBefore (
623 (AML_NODE_HEADER *)LastRdNode,
624 (AML_NODE_HEADER *)NewRdNode
625 )
626 ;
627 ASSERT_EFI_ERROR (Status);
628 return Status;
629}
630
645STATIC
647EFIAPI
649 IN AML_OBJECT_NODE *ParentNode,
650 IN EAML_PARSE_INDEX Index,
651 IN AML_NODE_HEADER *NewNode
652 )
653{
654 EFI_STATUS Status;
655
656 AML_NODE_HEADER *OldNode;
657 UINT32 NewSize;
658 UINT32 OldSize;
659 AML_PARSE_FORMAT FixedArgType;
660
661 // Check arguments and that NewNode is not already attached to a tree.
662 if (!IS_AML_OBJECT_NODE (ParentNode) ||
663 (!IS_AML_DATA_NODE (NewNode) &&
664 !IS_AML_OBJECT_NODE (NewNode)) ||
665 !AML_NODE_IS_DETACHED (NewNode))
666 {
667 ASSERT (0);
668 return EFI_INVALID_PARAMETER;
669 }
670
671 // Perform some compatibility checks between NewNode and OldNode.
672 FixedArgType = ParentNode->AmlByteEncoding->Format[Index];
673 switch (FixedArgType) {
674 case EAmlFieldPkgLen:
675 {
676 // A FieldPkgLen can only have a parent node with the
677 // AML_IS_FIELD_ELEMENT flag.
679 (AML_OBJECT_NODE *)ParentNode,
681 ))
682 {
683 ASSERT (0);
684 return EFI_INVALID_PARAMETER;
685 }
686
687 // Fall through.
688 }
689
690 case EAmlUInt8:
691 case EAmlUInt16:
692 case EAmlUInt32:
693 case EAmlUInt64:
694 case EAmlName:
695 case EAmlString:
696 {
697 // A uint, a name, a string and a FieldPkgLen can only be replaced by a
698 // data node of the same type.
699 // Note: This condition might be too strict, but safer.
700 if (!IS_AML_DATA_NODE (NewNode) ||
701 (((AML_DATA_NODE *)NewNode)->DataType !=
702 AmlTypeToNodeDataType (FixedArgType)))
703 {
704 ASSERT (0);
705 return EFI_INVALID_PARAMETER;
706 }
707
708 break;
709 }
710
711 case EAmlObject:
712 {
713 // If it's an object node, the grammar is too complex to do any check.
714 break;
715 }
716
717 case EAmlNone:
718 default:
719 {
720 ASSERT (0);
721 return EFI_INVALID_PARAMETER;
722 break;
723 }
724 } // switch
725
726 // Replace the OldNode with the NewNode.
727 OldNode = AmlGetFixedArgument (ParentNode, Index);
728 if (!IS_AML_NODE_VALID (OldNode)) {
729 ASSERT (0);
730 return EFI_INVALID_PARAMETER;
731 }
732
733 // Unlink the old node.
734 // Note: This function unlinks the OldNode from the tree. It is the callers
735 // responsibility to delete the OldNode if needed.
736 OldNode->Parent = NULL;
737
738 Status = AmlSetFixedArgument (ParentNode, Index, NewNode);
739 if (EFI_ERROR (Status)) {
740 ASSERT (0);
741 return Status;
742 }
743
744 // Get the size of the OldNode.
745 Status = AmlComputeSize (OldNode, &OldSize);
746 if (EFI_ERROR (Status)) {
747 ASSERT (0);
748 return Status;
749 }
750
751 // Get the size of the NewNode.
752 Status = AmlComputeSize (NewNode, &NewSize);
753 if (EFI_ERROR (Status)) {
754 ASSERT (0);
755 return Status;
756 }
757
758 // Propagate the new information.
759 Status = AmlPropagateInformation (
760 (AML_NODE_HEADER *)ParentNode,
761 (NewSize > OldSize) ? TRUE : FALSE,
762 (NewSize > OldSize) ? (NewSize - OldSize) : (OldSize - NewSize),
763 0
764 );
765 ASSERT_EFI_ERROR (Status);
766
767 return Status;
768}
769
785EFIAPI
787 IN AML_NODE_HEADER *OldNode,
788 IN AML_NODE_HEADER *NewNode
789 )
790{
791 EFI_STATUS Status;
792 UINT32 NewSize;
793 UINT32 OldSize;
794 EAML_PARSE_INDEX Index;
795
796 AML_DATA_NODE *NewDataNode;
797 AML_NODE_HEADER *ParentNode;
798 LIST_ENTRY *NextLink;
799
800 // Check arguments, that NewNode is not already attached to a tree,
801 // and that OldNode is attached and not in a fixed list of arguments.
802 if ((!IS_AML_DATA_NODE (OldNode) &&
803 !IS_AML_OBJECT_NODE (OldNode)) ||
804 (!IS_AML_DATA_NODE (NewNode) &&
805 !IS_AML_OBJECT_NODE (NewNode)) ||
806 !AML_NODE_IS_DETACHED (NewNode) ||
807 AML_NODE_IS_DETACHED (OldNode) ||
808 AmlIsNodeFixedArgument (OldNode, &Index))
809 {
810 ASSERT (0);
811 return EFI_INVALID_PARAMETER;
812 }
813
814 ParentNode = AmlGetParent (OldNode);
815 if (!IS_AML_ROOT_NODE (ParentNode) &&
816 !IS_AML_OBJECT_NODE (ParentNode))
817 {
818 ASSERT (0);
819 return EFI_INVALID_PARAMETER;
820 }
821
822 NewDataNode = (AML_DATA_NODE *)NewNode;
823
824 // Check attributes if the parent node is an object node.
825 if (IS_AML_OBJECT_NODE (ParentNode)) {
826 // A child node of a node with the HAS_CHILD flag must be either a
827 // data node or an object node. This has already been checked. So,
828 // check for other cases.
829
831 if (!IS_AML_DATA_NODE (NewNode) ||
832 ((NewDataNode->DataType != EAmlNodeDataTypeRaw) &&
833 (NewDataNode->DataType != EAmlNodeDataTypeResourceData)))
834 {
835 // A child node of a node with the BYTE_LIST flag must be a data node,
836 // containing raw data or a resource data.
837 ASSERT (0);
838 return EFI_INVALID_PARAMETER;
839 }
840 } else if (AmlNodeHasAttribute (
841 (AML_OBJECT_NODE *)ParentNode,
843 ))
844 {
846 (CONST AML_OBJECT_NODE *)NewNode,
848 ))
849 {
850 // A child node of a node with the FIELD_LIST flag must be an object
851 // node with AML_IS_FIELD_ELEMENT flag.
852 ASSERT (0);
853 return EFI_INVALID_PARAMETER;
854 }
855 }
856 } else {
857 // Parent node is a root node.
858 // A root node cannot have a data node as its child.
859 if (!IS_AML_DATA_NODE (NewNode)) {
860 ASSERT (0);
861 return EFI_INVALID_PARAMETER;
862 }
863 }
864
865 // Unlink OldNode from the tree.
866 NextLink = RemoveEntryList (&OldNode->Link);
867 InitializeListHead (&OldNode->Link);
868 OldNode->Parent = NULL;
869
870 // Add the NewNode.
871 InsertHeadList (NextLink, &NewNode->Link);
872 NewNode->Parent = ParentNode;
873
874 // Get the size of the OldNode.
875 Status = AmlComputeSize (OldNode, &OldSize);
876 if (EFI_ERROR (Status)) {
877 ASSERT (0);
878 return Status;
879 }
880
881 // Get the size of the NewNode.
882 Status = AmlComputeSize (NewNode, &NewSize);
883 if (EFI_ERROR (Status)) {
884 ASSERT (0);
885 return Status;
886 }
887
888 // Propagate the new information.
889 Status = AmlPropagateInformation (
890 ParentNode,
891 (NewSize > OldSize) ? TRUE : FALSE,
892 (NewSize > OldSize) ? (NewSize - OldSize) : (OldSize - NewSize),
893 0
894 );
895 ASSERT_EFI_ERROR (Status);
896
897 return Status;
898}
899
914EFIAPI
916 IN AML_NODE_HEADER *OldNode,
917 IN AML_NODE_HEADER *NewNode
918 )
919{
920 EFI_STATUS Status;
921 AML_NODE_HEADER *ParentNode;
922 EAML_PARSE_INDEX Index;
923
924 // Check arguments and that NewNode is not already attached to a tree.
925 if ((!IS_AML_DATA_NODE (OldNode) &&
926 !IS_AML_OBJECT_NODE (OldNode)) ||
927 (!IS_AML_DATA_NODE (NewNode) &&
928 !IS_AML_OBJECT_NODE (NewNode)) ||
929 !AML_NODE_IS_DETACHED (NewNode))
930 {
931 ASSERT (0);
932 return EFI_INVALID_PARAMETER;
933 }
934
935 // ParentNode can be a root node or an object node.
936 ParentNode = AmlGetParent (OldNode);
937 if (!IS_AML_ROOT_NODE (ParentNode) &&
938 !IS_AML_OBJECT_NODE (ParentNode))
939 {
940 ASSERT (0);
941 return EFI_INVALID_PARAMETER;
942 }
943
944 if (AmlIsNodeFixedArgument (OldNode, &Index)) {
945 // OldNode is in its parent's fixed argument list at the Index.
946 Status = AmlReplaceFixedArgument (
947 (AML_OBJECT_NODE *)ParentNode,
948 Index,
949 NewNode
950 );
951 if (EFI_ERROR (Status)) {
952 ASSERT (0);
953 return Status;
954 }
955 } else {
956 // OldNode is not in its parent's fixed argument list.
957 // It must be in its variable list of arguments.
958 Status = AmlReplaceVariableArgument (OldNode, NewNode);
959 ASSERT_EFI_ERROR (Status);
960 }
961
962 return Status;
963}
964
976EFIAPI
978 IN AML_NODE_HEADER *Node
979 )
980{
981 EFI_STATUS Status;
982
983 EAML_PARSE_INDEX Index;
984 EAML_PARSE_INDEX MaxIndex;
985
986 AML_NODE_HEADER *Arg;
987 LIST_ENTRY *StartLink;
988 LIST_ENTRY *CurrentLink;
989 LIST_ENTRY *NextLink;
990
991 // Check that the node being deleted is unlinked.
992 // When removing the node, its parent pointer and
993 // its lists data structure are reset with
994 // InitializeListHead. Thus it must be detached
995 // from the tree to avoid memory leaks.
996 if (!IS_AML_NODE_VALID (Node) ||
997 !AML_NODE_IS_DETACHED (Node))
998 {
999 ASSERT (0);
1000 return EFI_INVALID_PARAMETER;
1001 }
1002
1003 // 1. Recursively detach and delete the fixed arguments.
1004 // Iterate through the fixed list of arguments.
1005 if (IS_AML_OBJECT_NODE (Node)) {
1007 (AML_OBJECT_NODE *)Node
1008 );
1009 for (Index = EAmlParseIndexTerm0; Index < MaxIndex; Index++) {
1010 Arg = AmlGetFixedArgument ((AML_OBJECT_NODE *)Node, Index);
1011 if (Arg == NULL) {
1012 // A fixed argument is missing. The tree is inconsistent.
1013 // Note: During CodeGeneration, the fixed arguments should be set
1014 // with an incrementing index, and then the variable arguments
1015 // should be added. This allows to free as many nodes as
1016 // possible if a crash occurs.
1017 ASSERT (0);
1018 return EFI_INVALID_PARAMETER;
1019 }
1020
1021 // Remove the node from the fixed argument list.
1022 Arg->Parent = NULL;
1023 Status = AmlSetFixedArgument ((AML_OBJECT_NODE *)Node, Index, NULL);
1024 if (EFI_ERROR (Status)) {
1025 ASSERT (0);
1026 return Status;
1027 }
1028
1029 Status = AmlDeleteTree (Arg);
1030 if (EFI_ERROR (Status)) {
1031 ASSERT (0);
1032 return Status;
1033 }
1034 }
1035 }
1036
1037 // 2. Recursively detach and delete the variable arguments.
1038 // Iterate through the variable list of arguments.
1039 StartLink = AmlNodeGetVariableArgList (Node);
1040 if (StartLink != NULL) {
1041 NextLink = StartLink->ForwardLink;
1042 while (NextLink != StartLink) {
1043 CurrentLink = NextLink;
1044
1045 // Unlink the node from the tree.
1046 NextLink = RemoveEntryList (CurrentLink);
1047 InitializeListHead (CurrentLink);
1048 ((AML_NODE_HEADER *)CurrentLink)->Parent = NULL;
1049
1050 Status = AmlDeleteTree ((AML_NODE_HEADER *)CurrentLink);
1051 if (EFI_ERROR (Status)) {
1052 ASSERT (0);
1053 return Status;
1054 }
1055 } // while
1056 }
1057
1058 // 3. Delete the node.
1059 Status = AmlDeleteNode (Node);
1060 ASSERT_EFI_ERROR (Status);
1061
1062 return Status;
1063}
#define AML_IS_FIELD_ELEMENT
Definition: Aml.h:93
enum EAmlParseFormat AML_PARSE_FORMAT
#define AML_HAS_BYTE_LIST
Definition: Aml.h:82
#define AML_HAS_FIELD_LIST
Definition: Aml.h:88
@ EAmlUInt64
Eight byte value evaluated as a UINT64.
Definition: Aml.h:38
@ EAmlName
Definition: Aml.h:44
@ EAmlObject
Definition: Aml.h:39
@ EAmlUInt8
One byte value evaluated as a UINT8.
Definition: Aml.h:35
@ EAmlFieldPkgLen
Definition: Aml.h:47
@ EAmlString
NULL terminated string.
Definition: Aml.h:46
@ EAmlNone
No data expected.
Definition: Aml.h:34
@ EAmlUInt16
Two byte value evaluated as a UINT16.
Definition: Aml.h:36
@ EAmlUInt32
Four byte value evaluated as a UINT32.
Definition: Aml.h:37
BOOLEAN EFIAPI AmlNodeCompareOpCode(IN CONST AML_OBJECT_NODE *ObjectNode, IN UINT8 OpCode, IN UINT8 SubOpCode)
Definition: AmlNode.c:457
EFI_STATUS EFIAPI AmlDeleteNode(IN AML_NODE_HEADER *Node)
Definition: AmlNode.c:339
BOOLEAN EFIAPI AmlNodeHasAttribute(IN CONST AML_OBJECT_NODE *ObjectNode, IN AML_OP_ATTRIBUTE Attribute)
Definition: AmlNode.c:430
#define IS_AML_ROOT_NODE(Node)
#define IS_AML_OBJECT_NODE(Node)
#define IS_AML_DATA_NODE(Node)
#define IS_AML_NODE_VALID(Node)
#define AML_NODE_IS_DETACHED(Node)
EFI_STATUS EFIAPI AmlVarListAddBefore(IN AML_NODE_HEADER *Node, IN AML_NODE_HEADER *NewNode)
Definition: AmlTree.c:464
EFI_STATUS EFIAPI AmlReplaceArgument(IN AML_NODE_HEADER *OldNode, IN AML_NODE_HEADER *NewNode)
Definition: AmlTree.c:915
EFI_STATUS EFIAPI AmlVarListAddAfter(IN AML_NODE_HEADER *Node, IN AML_NODE_HEADER *NewNode)
Definition: AmlTree.c:520
EFI_STATUS EFIAPI AmlAppendRdNode(IN AML_OBJECT_NODE *BufferOpNode, IN AML_DATA_NODE *NewRdNode)
Definition: AmlTree.c:578
EFI_STATUS EFIAPI AmlVarListAddHead(IN AML_NODE_HEADER *ParentNode, IN AML_NODE_HEADER *NewNode)
Definition: AmlTree.c:319
EFI_STATUS EFIAPI AmlSetFixedArgument(IN AML_OBJECT_NODE *ObjectNode, IN EAML_PARSE_INDEX Index, IN AML_NODE_HEADER *NewNode)
Definition: AmlTree.c:168
EFI_STATUS EFIAPI AmlDeleteTree(IN AML_NODE_HEADER *Node)
Definition: AmlTree.c:977
AML_NODE_HEADER *EFIAPI AmlGetFixedArgument(IN AML_OBJECT_NODE *ObjectNode, IN EAML_PARSE_INDEX Index)
Definition: AmlTree.c:81
LIST_ENTRY *EFIAPI AmlNodeGetVariableArgList(IN CONST AML_NODE_HEADER *Node)
Definition: AmlTree.c:205
EFI_STATUS EFIAPI AmlDetachNode(IN AML_NODE_HEADER *Node)
Definition: AmlTree.c:300
EFI_STATUS EFIAPI AmlVarListAddTailInternal(IN AML_NODE_HEADER *ParentNode, IN AML_NODE_HEADER *NewNode)
Definition: AmlTree.c:379
AML_NODE_HEADER *EFIAPI AmlGetParent(IN AML_NODE_HEADER *Node)
Definition: AmlTree.c:25
EFI_STATUS EFIAPI AmlRemoveNodeFromVarArgList(IN AML_NODE_HEADER *Node)
Definition: AmlTree.c:233
EFI_STATUS EFIAPI AmlVarListAddTail(IN AML_NODE_HEADER *ParentNode, IN AML_NODE_HEADER *NewNode)
Definition: AmlTree.c:423
EFI_STATUS EFIAPI AmlReplaceVariableArgument(IN AML_NODE_HEADER *OldNode, IN AML_NODE_HEADER *NewNode)
Definition: AmlTree.c:786
STATIC EFI_STATUS EFIAPI AmlReplaceFixedArgument(IN AML_OBJECT_NODE *ParentNode, IN EAML_PARSE_INDEX Index, IN AML_NODE_HEADER *NewNode)
Definition: AmlTree.c:648
BOOLEAN EFIAPI AmlIsNodeFixedArgument(IN CONST AML_NODE_HEADER *Node, OUT EAML_PARSE_INDEX *IndexPtr)
Definition: AmlTree.c:110
AML_ROOT_NODE *EFIAPI AmlGetRootNode(IN CONST AML_NODE_HEADER *Node)
Definition: AmlTree.c:48
EFI_STATUS EFIAPI AmlSetRdListCheckSum(IN AML_OBJECT_NODE *BufferOpNode, IN UINT8 CheckSum)
Definition: AmlUtility.c:961
EFI_STATUS EFIAPI AmlPropagateInformation(IN AML_NODE_HEADER *Node, IN BOOLEAN IsIncrement, IN UINT32 Diff, IN UINT8 NodeCount)
Definition: AmlUtility.c:870
EFI_STATUS EFIAPI AmlComputeSize(IN CONST AML_NODE_HEADER *Node, IN OUT UINT32 *Size)
Definition: AmlUtility.c:169
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
BOOLEAN EFIAPI IsNodeInList(IN CONST LIST_ENTRY *FirstEntry, IN CONST LIST_ENTRY *SecondEntry)
Definition: LinkedList.c:121
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
EAML_NODE_DATA_TYPE EFIAPI AmlTypeToNodeDataType(IN AML_PARSE_FORMAT AmlType)
Definition: Aml.c:596
#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
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
AML_NODE_HANDLE EFIAPI AmlGetPreviousVariableArgument(IN AML_NODE_HANDLE Node, IN AML_NODE_HANDLE CurrVarArg)
UINT8 AmlGetFixedArgumentCount(IN AML_OBJECT_NODE_HANDLE Node)
enum EAmlParseIndex EAML_PARSE_INDEX
@ EAmlParseIndexTerm0
First fixed argument index.
Definition: AmlDefines.h:65
@ EAmlNodeDataTypeRaw
Raw bytes contained in a buffer.
Definition: AmlDefines.h:43
@ EAmlNodeDataTypeResourceData
Resource data element.
Definition: AmlDefines.h:44
EAML_NODE_DATA_TYPE DataType
struct AmlNodeHeader * Parent
Parent of this node. NULL for the root node.