]> git.proxmox.com Git - mirror_edk2.git/commitdiff
DynamicTablesPkg: AML tree enumerator
authorPierre Gondois <pierre.gondois@arm.com>
Mon, 3 Aug 2020 15:21:57 +0000 (16:21 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 13 Aug 2020 18:00:06 +0000 (18:00 +0000)
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>
DynamicTablesPkg/Library/Common/AmlLib/Tree/AmlTreeEnumerator.c [new file with mode: 0644]

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