/** @file AML Tree Enumerator. Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include /** Enumerate all nodes of the subtree under the input Node in the AML bytestream order (i.e. in a depth first order), and call the CallBack function with the input Context. The prototype of the Callback function is EDKII_AML_TREE_ENUM_CALLBACK. @param [in] Node Enumerate nodes of the subtree under this Node. Must be a valid node. @param [in] CallBack Callback function to call on each node. @param [in, out] Context Void pointer used to pass some information to the Callback function. Optional, can be NULL. @param [out] Status Optional parameter that can be used to get the status of the Callback function. If used, need to be init to EFI_SUCCESS. @retval TRUE if the enumeration can continue or has finished without interruption. @retval FALSE if the enumeration needs to stopped or has stopped. **/ BOOLEAN EFIAPI AmlEnumTree ( IN AML_NODE_HEADER *Node, IN EDKII_AML_TREE_ENUM_CALLBACK CallBack, IN OUT VOID *Context OPTIONAL, OUT EFI_STATUS *Status OPTIONAL ) { BOOLEAN ContinueEnum; EAML_PARSE_INDEX Index; EAML_PARSE_INDEX MaxIndex; LIST_ENTRY *StartLink; LIST_ENTRY *CurrentLink; if (!IS_AML_NODE_VALID (Node) || (CallBack == NULL)) { ASSERT (0); if (Status != NULL) { *Status = EFI_INVALID_PARAMETER; } return FALSE; } ContinueEnum = (*CallBack)(Node, Context, Status); if (ContinueEnum == FALSE) { return ContinueEnum; } // Iterate through the fixed list of arguments. MaxIndex = (EAML_PARSE_INDEX)AmlGetFixedArgumentCount ( (AML_OBJECT_NODE *)Node ); for (Index = EAmlParseIndexTerm0; Index < MaxIndex; Index++) { ContinueEnum = AmlEnumTree ( AmlGetFixedArgument ((AML_OBJECT_NODE *)Node, Index), CallBack, Context, Status ); if (ContinueEnum == FALSE) { return ContinueEnum; } } // Iterate through the variable list of arguments. StartLink = AmlNodeGetVariableArgList (Node); if (StartLink != NULL) { CurrentLink = StartLink->ForwardLink; while (CurrentLink != StartLink) { ContinueEnum = AmlEnumTree ( (AML_NODE_HEADER *)CurrentLink, CallBack, Context, Status ); if (ContinueEnum == FALSE) { return ContinueEnum; } CurrentLink = CurrentLink->ForwardLink; } // while } return ContinueEnum; }