DynamicTablesPkg: AML tree enumerator

The AML tree enumerator interface allows enumeration of the
nodes in the AML tree. The enumerator interface can be useful
to search, serialise, print etc. the nodes in the AML tree.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Reviewed-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
This commit is contained in:
Pierre Gondois 2020-08-03 16:21:57 +01:00 committed by mergify[bot]
parent 9275bb82ca
commit 5764abda7c
1 changed files with 98 additions and 0 deletions

View File

@ -0,0 +1,98 @@
/** @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;
}