summaryrefslogtreecommitdiffstats
path: root/DynamicTablesPkg/Library/Common/AmlLib/AmlNodeDefines.h
diff options
context:
space:
mode:
authorPierre Gondois <pierre.gondois@arm.com>2020-07-29 13:25:05 +0100
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2020-08-13 18:00:06 +0000
commitbcab901b7cc3b433bca5779a770ba3edbc7153f4 (patch)
treea88a884c1e3e64eadb1d30c976e4fe2ad1a60f05 /DynamicTablesPkg/Library/Common/AmlLib/AmlNodeDefines.h
parent98f2808115d0635c6bfd6019ccacbe7c1dd5a5f7 (diff)
downloadedk2-bcab901b7cc3b433bca5779a770ba3edbc7153f4.tar.gz
edk2-bcab901b7cc3b433bca5779a770ba3edbc7153f4.tar.bz2
edk2-bcab901b7cc3b433bca5779a770ba3edbc7153f4.zip
DynamicTablesPkg: AML node definitions
AML has a complex grammar, and this makes runtime modifications on an AML byte stream difficult. A solution is to parse the AML bytecode and represent it in a tree data structure, henceforth called the AML tree. The AML tree is composite in the sense it has the following node types: - A 'Root node' that represents the root of the AML tree. - An 'Object node' that contains the OP Code (AML Encoding). - A 'Data node' that contains a data buffer. The Root node contains the Definition block header (ACPI header) and a Variable Argument list. The Object node is composed of an array of Fixed Arguments and a Variable Argument list. Fixed arguments can be either Object Nodes or Data nodes. Their placement (index) in the Fixed Argument array is defined by the AML encoding of the enclosing Object Node. Variable arguments can be Object nodes or Data nodes. Following is a depiction of a typical AML tree: (/) # Root Node \ |-{(N1)->...} # Variable Argument list, N1 is \ # an Object Node \ /-i # Child of fixed argument b \ / |- [a][b][c][d] # Fixed Arguments |- {(e)->(f)->(g)} # Variable Arguments \ \-h # Child of variable argument e 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>
Diffstat (limited to 'DynamicTablesPkg/Library/Common/AmlLib/AmlNodeDefines.h')
-rw-r--r--DynamicTablesPkg/Library/Common/AmlLib/AmlNodeDefines.h183
1 files changed, 183 insertions, 0 deletions
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/AmlNodeDefines.h b/DynamicTablesPkg/Library/Common/AmlLib/AmlNodeDefines.h
new file mode 100644
index 0000000000..fffba6d54b
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/AmlLib/AmlNodeDefines.h
@@ -0,0 +1,183 @@
+/** @file
+ AML Node Definition.
+
+ Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef AML_NODE_DEFINES_H_
+#define AML_NODE_DEFINES_H_
+
+#include <AmlEncoding/Aml.h>
+#include <IndustryStandard/Acpi.h>
+
+/** AML header node.
+
+ This abstract class represents either a root/object/data node.
+ All the enumerated nodes have this same common header.
+*/
+typedef struct AmlNodeHeader {
+ /// This must be the first field in this structure.
+ LIST_ENTRY Link;
+
+ /// Parent of this node. NULL for the root node.
+ struct AmlNodeHeader * Parent;
+
+ /// Node type allowing to identify a root/object/data node.
+ EAML_NODE_TYPE NodeType;
+} AML_NODE_HEADER;
+
+/** Node handle.
+*/
+typedef AML_NODE_HEADER* AML_NODE_HANDLE;
+
+/** AML root node.
+
+ The root node is unique and at the head of of tree. It is a fake node used
+ to maintain the list of AML statements (stored as object nodes) which are
+ at the first scope level.
+*/
+typedef struct AmlRootNode {
+ /// Header information. Must be the first field of the struct.
+ AML_NODE_HEADER NodeHeader;
+
+ /// List of object nodes being at the first scope level.
+ /// These are children and can only be object nodes.
+ LIST_ENTRY VariableArgs;
+
+ /// ACPI DSDT/SSDT header.
+ EFI_ACPI_DESCRIPTION_HEADER * SdtHeader;
+} AML_ROOT_NODE;
+
+/** Root Node handle.
+*/
+typedef AML_ROOT_NODE* AML_ROOT_NODE_HANDLE;
+
+/** AML object node.
+
+ Object nodes match AML statements. They are associated with an
+ OpCode/SubOpCode, and can have children.
+*/
+typedef struct AmlObjectNode {
+ /// Header information. Must be the first field of the struct.
+ AML_NODE_HEADER NodeHeader;
+
+ /// Some object nodes have a variable list of arguments.
+ /// These are children and can only be object/data nodes.
+ /// Cf ACPI specification, s20.3.
+ LIST_ENTRY VariableArgs;
+
+ /// Fixed arguments of this object node.
+ /// These are children and can be object/data nodes.
+ /// Cf ACPI specification, s20.3.
+ AML_NODE_HEADER * FixedArgs[EAmlParseIndexMax];
+
+ /// AML byte encoding. Stores the encoding information:
+ /// (OpCode/SubOpCode/number of fixed arguments/ attributes).
+ CONST AML_BYTE_ENCODING * AmlByteEncoding;
+
+ /// Some nodes have a PkgLen following their OpCode/SubOpCode in the
+ /// AML bytestream. This field stores the decoded value of the PkgLen.
+ UINT32 PkgLen;
+} AML_OBJECT_NODE;
+
+/** Object Node handle.
+*/
+typedef AML_OBJECT_NODE* AML_OBJECT_NODE_HANDLE;
+
+/** AML data node.
+
+ Data nodes store the smallest pieces of information.
+ E.g.: UINT8, UINT64, NULL terminated string, etc.
+ Data node don't have children nodes.
+*/
+typedef struct AmlDataNode {
+ /// Header information. Must be the first field of the struct.
+ AML_NODE_HEADER NodeHeader;
+
+ /// Tag identifying what data is stored in this node.
+ /// E.g. UINT, NULL terminated string, resource data element, etc.
+ EAML_NODE_DATA_TYPE DataType;
+
+ /// Buffer containing the data stored by this node.
+ UINT8 * Buffer;
+
+ /// Size of the Buffer.
+ UINT32 Size;
+} AML_DATA_NODE;
+
+/** Data Node handle.
+*/
+typedef AML_DATA_NODE* AML_DATA_NODE_HANDLE;
+
+/** Check whether a Node has a valid NodeType.
+
+ @param [in] Node The node to check.
+
+ @retval TRUE The Node has a valid NodeType.
+ @retval FALSE Otherwise.
+*/
+#define IS_AML_NODE_VALID(Node) \
+ ((Node != NULL) && \
+ ((((CONST AML_NODE_HEADER*)Node)->NodeType > EAmlNodeUnknown) || \
+ (((CONST AML_NODE_HEADER*)Node)->NodeType < EAmlNodeMax)))
+
+/** Check whether a Node is a root node.
+
+ @param [in] Node The node to check.
+
+ @retval TRUE The Node is a root node.
+ @retval FALSE Otherwise.
+*/
+#define IS_AML_ROOT_NODE(Node) \
+ ((Node != NULL) && \
+ (((CONST AML_NODE_HEADER*)Node)->NodeType == EAmlNodeRoot))
+
+/** Check whether a Node is an object node.
+
+ @param [in] Node The node to check.
+
+ @retval TRUE The Node is an object node.
+ @retval FALSE Otherwise.
+*/
+#define IS_AML_OBJECT_NODE(Node) \
+ ((Node != NULL) && \
+ (((CONST AML_NODE_HEADER*)Node)->NodeType == EAmlNodeObject))
+
+/** Check whether a Node is a data node.
+
+ @param [in] Node The node to check.
+
+ @retval TRUE The Node is a data node.
+ @retval FALSE Otherwise.
+*/
+#define IS_AML_DATA_NODE(Node) \
+ ((Node != NULL) && \
+ (((CONST AML_NODE_HEADER*)Node)->NodeType == EAmlNodeData))
+
+/** Check whether a Node has a parent.
+
+ @param [in] Node The node to check.
+
+ @retval TRUE The Node is a data node.
+ @retval FALSE Otherwise.
+*/
+#define AML_NODE_HAS_PARENT(Node) \
+ (IS_AML_NODE_VALID (Node) && \
+ (((CONST AML_NODE_HEADER*)Node)->Parent != NULL))
+
+/** Check that the Node is not attached somewhere.
+ This doesn't mean the node cannot have children.
+
+ @param [in] Node The node to check.
+
+ @retval TRUE The Node has been detached.
+ @retval FALSE Otherwise.
+*/
+#define AML_NODE_IS_DETACHED(Node) \
+ (IS_AML_NODE_VALID (Node) && \
+ IsListEmpty ((CONST LIST_ENTRY*)Node) && \
+ (((CONST AML_NODE_HEADER*)Node)->Parent == NULL))
+
+#endif // AML_NODE_DEFINES_H_