| /** @file | |
| AML Tree Enumerator. | |
| Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include <AmlNodeDefines.h> | |
| #include <AmlCoreInterface.h> | |
| #include <Tree/AmlTree.h> | |
| /** 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; | |
| } |