REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the DynamicTablesPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
		
			
				
	
	
		
			560 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			560 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   AML Tree Traversal.
 | |
| 
 | |
|   Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| **/
 | |
| 
 | |
| #include <Tree/AmlTreeTraversal.h>
 | |
| 
 | |
| #include <AmlCoreInterface.h>
 | |
| #include <Tree/AmlTree.h>
 | |
| 
 | |
| /** Get the sibling node among the nodes being in
 | |
|     the same variable argument list.
 | |
| 
 | |
|   (ParentNode)  /-i                 # Child of fixed argument b
 | |
|       \        /
 | |
|        |- [a][b][c][d]              # Fixed Arguments
 | |
|        |- {(VarArgNode)->(f)->(g)}  # Variable Arguments
 | |
|              \
 | |
|               \-h                   # Child of variable argument e
 | |
| 
 | |
|   Node must be in a variable list of arguments.
 | |
|   Traversal Order: VarArgNode, f, g, NULL
 | |
| 
 | |
|   @ingroup CoreNavigationApis
 | |
| 
 | |
|   @param  [in]  VarArgNode  Pointer to a node.
 | |
|                             Must be in a variable list of arguments.
 | |
| 
 | |
|   @return The next node after VarArgNode in the variable list of arguments.
 | |
|           Return NULL if
 | |
|           - VarArgNode is the last node of the list, or
 | |
|           - VarArgNode is not part of a variable list of arguments.
 | |
| **/
 | |
| AML_NODE_HEADER *
 | |
| EFIAPI
 | |
| AmlGetSiblingVariableArgument (
 | |
|   IN  AML_NODE_HEADER  *VarArgNode
 | |
|   )
 | |
| {
 | |
|   EAML_PARSE_INDEX  Index;
 | |
|   AML_NODE_HEADER   *ParentNode;
 | |
| 
 | |
|   // VarArgNode must be an object node or a data node,
 | |
|   // and be in a variable list of arguments.
 | |
|   if ((!IS_AML_OBJECT_NODE (VarArgNode) &&
 | |
|        !IS_AML_DATA_NODE (VarArgNode))  ||
 | |
|       AmlIsNodeFixedArgument (VarArgNode, &Index))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   ParentNode = AmlGetParent (VarArgNode);
 | |
|   if (!IS_AML_NODE_VALID (ParentNode)) {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   return AmlGetNextVariableArgument (ParentNode, VarArgNode);
 | |
| }
 | |
| 
 | |
| /** Get the next variable argument.
 | |
| 
 | |
|   (Node)        /-i           # Child of fixed argument b
 | |
|       \        /
 | |
|        |- [a][b][c][d]        # Fixed Arguments
 | |
|        |- {(e)->(f)->(g)}     # Variable Arguments
 | |
|              \
 | |
|               \-h             # Child of variable argument e
 | |
| 
 | |
|   Traversal Order: e, f, g, NULL
 | |
| 
 | |
|   @param  [in]  Node        Pointer to a Root node or Object Node.
 | |
|   @param  [in]  CurrVarArg  Pointer to the Current Variable Argument.
 | |
| 
 | |
|   @return The node after the CurrVarArg in the variable list of arguments.
 | |
|           If CurrVarArg is NULL, return the first node of the
 | |
|           variable argument list.
 | |
|           Return NULL if
 | |
|           - CurrVarArg is the last node of the list, or
 | |
|           - Node does not have a variable list of arguments.
 | |
| **/
 | |
| AML_NODE_HEADER *
 | |
| EFIAPI
 | |
| AmlGetNextVariableArgument (
 | |
|   IN  AML_NODE_HEADER  *Node,
 | |
|   IN  AML_NODE_HEADER  *CurrVarArg
 | |
|   )
 | |
| {
 | |
|   CONST LIST_ENTRY  *StartLink;
 | |
|   CONST LIST_ENTRY  *NextLink;
 | |
| 
 | |
|   // Node must be a RootNode or an Object Node
 | |
|   // and the CurrVarArg must not be a Root Node.
 | |
|   if ((!IS_AML_ROOT_NODE (Node)           &&
 | |
|        !IS_AML_OBJECT_NODE (Node))        ||
 | |
|       ((CurrVarArg != NULL)               &&
 | |
|        (!IS_AML_OBJECT_NODE (CurrVarArg)  &&
 | |
|         !IS_AML_DATA_NODE (CurrVarArg))))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   StartLink = AmlNodeGetVariableArgList (Node);
 | |
|   if (StartLink == NULL) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   // Get the first child of the variable list of arguments.
 | |
|   if (CurrVarArg == NULL) {
 | |
|     NextLink = StartLink->ForwardLink;
 | |
|     if (NextLink != StartLink) {
 | |
|       return (AML_NODE_HEADER *)NextLink;
 | |
|     }
 | |
| 
 | |
|     // List is empty.
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   // Check if CurrVarArg is in the VariableArgument List.
 | |
|   if (!IsNodeInList (StartLink, &CurrVarArg->Link)) {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   // Get the node following the CurrVarArg.
 | |
|   NextLink = CurrVarArg->Link.ForwardLink;
 | |
|   if (NextLink != StartLink) {
 | |
|     return (AML_NODE_HEADER *)NextLink;
 | |
|   }
 | |
| 
 | |
|   // End of the list has been reached.
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| /** Get the previous variable argument.
 | |
| 
 | |
|   (Node)        /-i           # Child of fixed argument b
 | |
|       \        /
 | |
|        |- [a][b][c][d]        # Fixed Arguments
 | |
|        |- {(e)->(f)->(g)}     # Variable Arguments
 | |
|              \
 | |
|               \-h             # Child of variable argument e
 | |
| 
 | |
|   Traversal Order: g, f, e, NULL
 | |
| 
 | |
|   @param  [in]  Node        Pointer to a root node or an object node.
 | |
|   @param  [in]  CurrVarArg  Pointer to the Current Variable Argument.
 | |
| 
 | |
|   @return The node before the CurrVarArg in the variable list of
 | |
|           arguments.
 | |
|           If CurrVarArg is NULL, return the last node of the
 | |
|           variable list of arguments.
 | |
|           Return NULL if:
 | |
|           - CurrVarArg is the first node of the list, or
 | |
|           - Node doesn't have a variable list of arguments.
 | |
| **/
 | |
| AML_NODE_HEADER *
 | |
| EFIAPI
 | |
| AmlGetPreviousVariableArgument (
 | |
|   IN  AML_NODE_HEADER  *Node,
 | |
|   IN  AML_NODE_HEADER  *CurrVarArg
 | |
|   )
 | |
| {
 | |
|   CONST LIST_ENTRY  *StartLink;
 | |
|   CONST LIST_ENTRY  *PreviousLink;
 | |
| 
 | |
|   // Node must be a RootNode or an Object Node
 | |
|   // and the CurrVarArg must not be a Root Node.
 | |
|   if ((!IS_AML_ROOT_NODE (Node)           &&
 | |
|        !IS_AML_OBJECT_NODE (Node))        ||
 | |
|       ((CurrVarArg != NULL)               &&
 | |
|        (!IS_AML_OBJECT_NODE (CurrVarArg)  &&
 | |
|         !IS_AML_DATA_NODE (CurrVarArg))))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   StartLink = AmlNodeGetVariableArgList (Node);
 | |
|   if (StartLink == NULL) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   // Get the last child of the variable list of arguments.
 | |
|   if (CurrVarArg == NULL) {
 | |
|     PreviousLink = StartLink->BackLink;
 | |
|     if (PreviousLink != StartLink) {
 | |
|       return (AML_NODE_HEADER *)PreviousLink;
 | |
|     }
 | |
| 
 | |
|     // List is empty.
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   // Check if CurrVarArg is in the VariableArgument List.
 | |
|   if (!IsNodeInList (StartLink, &CurrVarArg->Link)) {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   // Get the node before the CurrVarArg.
 | |
|   PreviousLink = CurrVarArg->Link.BackLink;
 | |
|   if (PreviousLink != StartLink) {
 | |
|     return (AML_NODE_HEADER *)PreviousLink;
 | |
|   }
 | |
| 
 | |
|   // We have reached the beginning of the list.
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| /** Get the next sibling node among the children of the input Node.
 | |
| 
 | |
|   This function traverses the FixedArguments followed by the
 | |
|   VariableArguments at the same level in the hierarchy.
 | |
| 
 | |
|   Fixed arguments are before variable arguments.
 | |
| 
 | |
|   (Node)        /-i           # Child of fixed argument b
 | |
|       \        /
 | |
|        |- [a][b][c][d]        # Fixed Arguments
 | |
|        |- {(e)->(f)->(g)}     # Variable Arguments
 | |
|              \
 | |
|               \-h             # Child of variable argument e
 | |
| 
 | |
|   Traversal Order: a, b, c, d, e, f, g, NULL
 | |
| 
 | |
| 
 | |
|   @param  [in]  Node        Pointer to a root node or an object node.
 | |
|   @param  [in]  ChildNode   Get the node after the ChildNode.
 | |
| 
 | |
|   @return The node after the ChildNode among the children of the input Node.
 | |
|            - If ChildNode is NULL, return the first available node among
 | |
|              the fixed argument list then variable list of arguments;
 | |
|            - If ChildNode is the last node of the fixed argument list,
 | |
|              return the first argument of the variable list of arguments;
 | |
|            - If ChildNode is the last node of the variable list of arguments,
 | |
|              return NULL.
 | |
| 
 | |
| **/
 | |
| AML_NODE_HEADER *
 | |
| EFIAPI
 | |
| AmlGetNextSibling (
 | |
|   IN  CONST AML_NODE_HEADER  *Node,
 | |
|   IN  CONST AML_NODE_HEADER  *ChildNode
 | |
|   )
 | |
| {
 | |
|   EAML_PARSE_INDEX  Index;
 | |
|   AML_NODE_HEADER   *CandidateNode;
 | |
| 
 | |
|   // Node must be a RootNode or an Object Node
 | |
|   // and the CurrVarArg must not be a Root Node.
 | |
|   if ((!IS_AML_ROOT_NODE (Node)           &&
 | |
|        !IS_AML_OBJECT_NODE (Node))        ||
 | |
|       ((ChildNode != NULL)                &&
 | |
|        (!IS_AML_OBJECT_NODE (ChildNode)   &&
 | |
|         !IS_AML_DATA_NODE (ChildNode))))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   if (IS_AML_OBJECT_NODE (Node)) {
 | |
|     if (ChildNode == NULL) {
 | |
|       // Get the fixed argument at index 0 of the ChildNode.
 | |
|       CandidateNode = AmlGetFixedArgument (
 | |
|                         (AML_OBJECT_NODE *)Node,
 | |
|                         EAmlParseIndexTerm0
 | |
|                         );
 | |
|       if (CandidateNode != NULL) {
 | |
|         return CandidateNode;
 | |
|       }
 | |
|     } else {
 | |
|       // (ChildNode != NULL)
 | |
|       if (AmlIsNodeFixedArgument (ChildNode, &Index)) {
 | |
|         // Increment index to point to the next fixed argument.
 | |
|         Index++;
 | |
|         // The node is part of the list of fixed arguments.
 | |
|         if (Index == (EAML_PARSE_INDEX)AmlGetFixedArgumentCount (
 | |
|                                          (AML_OBJECT_NODE *)Node
 | |
|                                          )
 | |
|             )
 | |
|         {
 | |
|           // It is at the last argument of the fixed argument list.
 | |
|           // Get the first argument of the variable list of arguments.
 | |
|           ChildNode = NULL;
 | |
|         } else {
 | |
|           // Else return the next node in the list of fixed arguments.
 | |
|           return AmlGetFixedArgument ((AML_OBJECT_NODE *)Node, Index);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   } // IS_AML_OBJECT_NODE (Node)
 | |
| 
 | |
|   // Else, get the next node in the variable list of arguments.
 | |
|   return AmlGetNextVariableArgument (
 | |
|            (AML_NODE_HEADER *)Node,
 | |
|            (AML_NODE_HEADER *)ChildNode
 | |
|            );
 | |
| }
 | |
| 
 | |
| /** Get the previous sibling node among the children of the input Node.
 | |
| 
 | |
|   This function traverses the FixedArguments followed by the
 | |
|   VariableArguments at the same level in the hierarchy.
 | |
| 
 | |
|   Fixed arguments are before variable arguments.
 | |
| 
 | |
|   (Node)        /-i           # Child of fixed argument b
 | |
|       \        /
 | |
|        |- [a][b][c][d]        # Fixed Arguments
 | |
|        |- {(e)->(f)->(g)}     # Variable Arguments
 | |
|              \
 | |
|               \-h             # Child of variable argument e
 | |
| 
 | |
|   Traversal Order: g, f, e, d, c, b, a, NULL
 | |
| 
 | |
|   @param  [in]  Node        The node to get the fixed argument from.
 | |
|   @param  [in]  ChildNode   Get the node before the ChildNode.
 | |
| 
 | |
|   @return The node before the ChildNode among the children of the input Node.
 | |
|            - If ChildNode is NULL, return the last available node among
 | |
|              the variable list of arguments then fixed argument list;
 | |
|            - If ChildNode is the first node of the variable list of arguments,
 | |
|              return the last argument of the fixed argument list;
 | |
|            - If ChildNode is the first node of the fixed argument list,
 | |
|              return NULL.
 | |
| **/
 | |
| AML_NODE_HEADER *
 | |
| EFIAPI
 | |
| AmlGetPreviousSibling (
 | |
|   IN  CONST  AML_NODE_HEADER  *Node,
 | |
|   IN  CONST  AML_NODE_HEADER  *ChildNode
 | |
|   )
 | |
| {
 | |
|   EAML_PARSE_INDEX  Index;
 | |
|   EAML_PARSE_INDEX  MaxIndex;
 | |
| 
 | |
|   AML_NODE_HEADER  *CandidateNode;
 | |
| 
 | |
|   // Node must be a Root Node or an Object Node
 | |
|   // and the ChildNode must not be a Root Node.
 | |
|   if ((!IS_AML_ROOT_NODE (Node)           &&
 | |
|        !IS_AML_OBJECT_NODE (Node))        ||
 | |
|       ((ChildNode != NULL)                &&
 | |
|        (!IS_AML_OBJECT_NODE (ChildNode)   &&
 | |
|         !IS_AML_DATA_NODE (ChildNode))))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   MaxIndex = (EAML_PARSE_INDEX)AmlGetFixedArgumentCount (
 | |
|                                  (AML_OBJECT_NODE *)Node
 | |
|                                  );
 | |
| 
 | |
|   // Get the last variable argument if no ChildNode.
 | |
|   // Otherwise the fixed argument list is checked first.
 | |
|   if ((ChildNode != NULL)         &&
 | |
|       IS_AML_OBJECT_NODE (Node)   &&
 | |
|       (MaxIndex != EAmlParseIndexTerm0))
 | |
|   {
 | |
|     if (AmlIsNodeFixedArgument (ChildNode, &Index)) {
 | |
|       // The node is part of the list of fixed arguments.
 | |
|       if (Index == EAmlParseIndexTerm0) {
 | |
|         // The node is the first fixed argument, return NULL.
 | |
|         return NULL;
 | |
|       } else {
 | |
|         // Return the previous node in the fixed argument list.
 | |
|         return AmlGetFixedArgument (
 | |
|                  (AML_OBJECT_NODE *)Node,
 | |
|                  (EAML_PARSE_INDEX)(Index - 1)
 | |
|                  );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // ChildNode is in the variable list of arguments.
 | |
|   CandidateNode = AmlGetPreviousVariableArgument (
 | |
|                     (AML_NODE_HEADER *)Node,
 | |
|                     (AML_NODE_HEADER *)ChildNode
 | |
|                     );
 | |
|   if (CandidateNode != NULL) {
 | |
|     if (!IS_AML_NODE_VALID (CandidateNode)) {
 | |
|       ASSERT (0);
 | |
|       return NULL;
 | |
|     }
 | |
| 
 | |
|     // A Node has been found
 | |
|     return CandidateNode;
 | |
|   } else if (MaxIndex != EAmlParseIndexTerm0) {
 | |
|     // ChildNode was the first node of the variable list of arguments.
 | |
|     return AmlGetFixedArgument (
 | |
|              (AML_OBJECT_NODE *)Node,
 | |
|              (EAML_PARSE_INDEX)(MaxIndex - 1)
 | |
|              );
 | |
|   } else {
 | |
|     // No fixed arguments or variable arguments.
 | |
|     return NULL;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /** Iterate through the nodes in the same order as the AML bytestream.
 | |
| 
 | |
|   The iteration is similar to a depth-first path.
 | |
| 
 | |
|   (Node)        /-i           # Child of fixed argument b
 | |
|       \        /
 | |
|        |- [a][b][c][d]        # Fixed Arguments
 | |
|        |- {(e)->(f)->(g)}     # Variable Arguments
 | |
|              \
 | |
|               \-h             # Child of variable argument e
 | |
| 
 | |
|   Traversal Order: a, b, i, c, d, e, h, f, g, NULL
 | |
|   Note: The branch i and h will be traversed if it has any children.
 | |
| 
 | |
|   @param  [in]  Node  Pointer to a node.
 | |
| 
 | |
|   @return The next node in the AML bytestream order.
 | |
|           Return NULL if Node is the Node corresponding to the last
 | |
|           bytecode of the tree.
 | |
| **/
 | |
| AML_NODE_HEADER *
 | |
| EFIAPI
 | |
| AmlGetNextNode (
 | |
|   IN  CONST AML_NODE_HEADER  *Node
 | |
|   )
 | |
| {
 | |
|   AML_NODE_HEADER  *ParentNode;
 | |
|   AML_NODE_HEADER  *CandidateNode;
 | |
| 
 | |
|   if (!IS_AML_NODE_VALID (Node)) {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   if (IS_AML_ROOT_NODE (Node) || IS_AML_OBJECT_NODE (Node)) {
 | |
|     // The node has children. Get the first child.
 | |
|     CandidateNode = AmlGetNextSibling (Node, NULL);
 | |
|     if (CandidateNode != NULL) {
 | |
|       if (!IS_AML_NODE_VALID (CandidateNode)) {
 | |
|         ASSERT (0);
 | |
|         return NULL;
 | |
|       }
 | |
| 
 | |
|       // A Node has been found
 | |
|       return CandidateNode;
 | |
|     } else if (IS_AML_ROOT_NODE (Node)) {
 | |
|       // The node is the root node and it doesn't have children.
 | |
|       return NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // We have traversed the current branch, go to the parent node
 | |
|   // and start traversing the next branch.
 | |
|   // Keep going up the tree until you reach the root node.
 | |
|   while (1) {
 | |
|     if (IS_AML_ROOT_NODE (Node)) {
 | |
|       // This is the last node of the tree.
 | |
|       return NULL;
 | |
|     }
 | |
| 
 | |
|     ParentNode = AmlGetParent ((AML_NODE_HEADER *)Node);
 | |
|     if (!IS_AML_NODE_VALID (ParentNode)) {
 | |
|       ASSERT (0);
 | |
|       return NULL;
 | |
|     }
 | |
| 
 | |
|     CandidateNode = AmlGetNextSibling (ParentNode, Node);
 | |
|     if (CandidateNode != NULL) {
 | |
|       if (!IS_AML_NODE_VALID (CandidateNode)) {
 | |
|         ASSERT (0);
 | |
|         return NULL;
 | |
|       }
 | |
| 
 | |
|       // A Node has been found
 | |
|       return CandidateNode;
 | |
|     }
 | |
| 
 | |
|     Node = ParentNode;
 | |
|   } // while
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| /** Iterate through the nodes in the reverse order of the AML bytestream.
 | |
| 
 | |
|   The iteration is similar to a depth-first path,
 | |
|   but done in a reverse order.
 | |
| 
 | |
|   (Node)        /-i           # Child of fixed argument b
 | |
|       \        /
 | |
|        |- [a][b][c][d]        # Fixed Arguments
 | |
|        |- {(e)->(f)->(g)}     # Variable Arguments
 | |
|              \
 | |
|               \-h             # Child of variable argument e
 | |
| 
 | |
|   Traversal Order: g, f, h, e, d, c, i, b, a, NULL
 | |
|   Note: The branch i and h will be traversed if it has any children.
 | |
| 
 | |
|   @param  [in]  Node  Pointer to a node.
 | |
| 
 | |
|   @return The previous node in the AML bytestream order.
 | |
|           Return NULL if Node is the Node corresponding to the last
 | |
|           bytecode of the tree.
 | |
| **/
 | |
| AML_NODE_HEADER *
 | |
| EFIAPI
 | |
| AmlGetPreviousNode (
 | |
|   IN  CONST  AML_NODE_HEADER  *Node
 | |
|   )
 | |
| {
 | |
|   AML_NODE_HEADER  *ParentNode;
 | |
|   AML_NODE_HEADER  *CandidateNode;
 | |
|   AML_NODE_HEADER  *PreviousNode;
 | |
| 
 | |
|   if (!IS_AML_NODE_VALID (Node)) {
 | |
|     ASSERT (0);
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   while (1) {
 | |
|     if (IS_AML_ROOT_NODE (Node)) {
 | |
|       // This is the root node.
 | |
|       return NULL;
 | |
|     }
 | |
| 
 | |
|     ParentNode    = AmlGetParent ((AML_NODE_HEADER *)Node);
 | |
|     CandidateNode = AmlGetPreviousSibling (ParentNode, Node);
 | |
| 
 | |
|     if (CandidateNode == NULL) {
 | |
|       // Node is the first child of its parent.
 | |
|       return ParentNode;
 | |
|     } else if (IS_AML_DATA_NODE (CandidateNode)) {
 | |
|       // CandidateNode is a data node, thus it has no children.
 | |
|       return CandidateNode;
 | |
|     } else if (IS_AML_OBJECT_NODE (CandidateNode)) {
 | |
|       // Get the previous node in the list of children of ParentNode,
 | |
|       // then get the last child of this node.
 | |
|       // If this node has children, get its last child, etc.
 | |
|       while (1) {
 | |
|         PreviousNode  = CandidateNode;
 | |
|         CandidateNode = AmlGetPreviousSibling (PreviousNode, NULL);
 | |
|         if (CandidateNode == NULL) {
 | |
|           return PreviousNode;
 | |
|         } else if (IS_AML_DATA_NODE (CandidateNode)) {
 | |
|           return CandidateNode;
 | |
|         }
 | |
|       } // while
 | |
|     } else {
 | |
|       ASSERT (0);
 | |
|       return NULL;
 | |
|     }
 | |
|   } // while
 | |
| }
 |