summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h631
-rw-r--r--src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h68
-rw-r--r--src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/TableHelperLib.h159
3 files changed, 858 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h b/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
new file mode 100644
index 00000000..51fbf40f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/AmlLib/AmlLib.h
@@ -0,0 +1,631 @@
+/** @file
+ AML Lib.
+
+ Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef AML_LIB_H_
+#define AML_LIB_H_
+
+/**
+ @mainpage Dynamic AML Generation
+ @{
+ @par Summary
+ @{
+ ACPI tables are categorized as data tables and definition block
+ tables. Dynamic Tables Framework currently supports generation of ACPI
+ data tables. Generation of definition block tables is difficult as these
+ tables are encoded in ACPI Machine Language (AML), which has a complex
+ grammar.
+
+ Dynamic AML Generation is an extension to the Dynamic tables Framework.
+ One of the techniques used to simplify definition block generation is to
+ fixup a template SSDT table.
+
+ Dynamic AML aims to provide a framework that allows fixing up of an ACPI
+ SSDT template with appropriate information about the hardware.
+
+ This framework consists of an:
+ - AMLLib core that implements a rich set of interfaces to parse, traverse
+ and update AML data.
+ - AMLLib library APIs that provides interfaces to search and updates nodes
+ in the AML namespace.
+ @}
+ @}
+*/
+
+#include <IndustryStandard/Acpi.h>
+
+#ifndef AML_HANDLE
+
+/** Node handle.
+*/
+typedef void* AML_NODE_HANDLE;
+
+/** Root Node handle.
+*/
+typedef void* AML_ROOT_NODE_HANDLE;
+
+/** Object Node handle.
+*/
+typedef void* AML_OBJECT_NODE_HANDLE;
+
+/** Data Node handle.
+*/
+typedef void* AML_DATA_NODE_HANDLE;
+
+#endif // AML_HANDLE
+
+/** Parse the definition block.
+
+ The function parses the whole AML blob. It starts with the ACPI DSDT/SSDT
+ header and then parses the AML bytestream.
+ A tree structure is returned via the RootPtr.
+ The tree must be deleted with the AmlDeleteTree function.
+
+ @ingroup UserApis
+
+ @param [in] DefinitionBlock Pointer to the definition block.
+ @param [out] RootPtr Pointer to the root node of the AML tree.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_BUFFER_TOO_SMALL No space left in the buffer.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlParseDefinitionBlock (
+ IN CONST EFI_ACPI_DESCRIPTION_HEADER * DefinitionBlock,
+ OUT AML_ROOT_NODE_HANDLE * RootPtr
+ );
+
+/** Serialize an AML definition block.
+
+ This functions allocates memory with the "AllocateZeroPool ()"
+ function. This memory is used to serialize the AML tree and is
+ returned in the Table.
+
+ @ingroup UserApis
+
+ @param [in] RootNode Root node of the tree.
+ @param [out] Table On return, hold the serialized
+ definition block.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlSerializeDefinitionBlock (
+ IN AML_ROOT_NODE_HANDLE RootNode,
+ OUT EFI_ACPI_DESCRIPTION_HEADER ** Table
+ );
+
+/** Clone a node and its children (clone a tree branch).
+
+ The cloned branch returned is not attached to any tree.
+
+ @ingroup UserApis
+
+ @param [in] Node Pointer to a node.
+ Node is the head of the branch to clone.
+ @param [out] ClonedNode Pointer holding the head of the created cloned
+ branch.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCloneTree (
+ IN AML_NODE_HANDLE Node,
+ OUT AML_NODE_HANDLE * ClonedNode
+ );
+
+/** Delete a Node and its children.
+
+ The Node must be removed from the tree first,
+ or must be the root node.
+
+ @ingroup UserApis
+
+ @param [in] Node Pointer to the node to delete.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlDeleteTree (
+ IN AML_NODE_HANDLE Node
+ );
+
+/** Detach the Node from the tree.
+
+ The function will fail if the Node is in its parent's fixed
+ argument list.
+ The Node is not deleted. The deletion is done separately
+ from the removal.
+
+ @ingroup UserApis
+
+ @param [in] Node Pointer to a Node.
+ Must be a data node or an object node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlDetachNode (
+ IN AML_NODE_HANDLE Node
+ );
+
+/** Find a node in the AML namespace, given an ASL path and a reference Node.
+
+ - The AslPath can be an absolute path, or a relative path from the
+ reference Node;
+ - Node must be a root node or a namespace node;
+ - A root node is expected to be at the top of the tree.
+
+ E.g.:
+ For the following AML namespace, with the ReferenceNode being the node with
+ the name "AAAA":
+ - the node with the name "BBBB" can be found by looking for the ASL
+ path "BBBB";
+ - the root node can be found by looking for the ASL relative path "^",
+ or the absolute path "\\".
+
+ AML namespace:
+ \
+ \-AAAA <- ReferenceNode
+ \-BBBB
+
+ @ingroup NameSpaceApis
+
+ @param [in] ReferenceNode Reference node.
+ If a relative path is given, the
+ search is done from this node. If
+ an absolute path is given, the
+ search is done from the root node.
+ Must be a root node or an object
+ node which is part of the
+ namespace.
+ @param [in] AslPath ASL path to the searched node in
+ the namespace. An ASL path name is
+ NULL terminated. Can be a relative
+ or absolute path.
+ E.g.: "\\_SB.CLU0.CPU0" or "^CPU0"
+ @param [out] OutNode Pointer to the found node.
+ Contains NULL if not found.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_BUFFER_TOO_SMALL No space left in the buffer.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Out of memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlFindNode (
+ IN AML_NODE_HANDLE ReferenceNode,
+ IN CHAR8 * AslPath,
+ OUT AML_NODE_HANDLE * OutNode
+ );
+
+/**
+ @defgroup UserApis User APIs
+ @{
+ User APIs are implemented to ease most common actions that might be done
+ using the AmlLib. They allow to find specific objects like "_UID" or
+ "_CRS" and to update their value. It also shows what can be done using
+ AmlLib functions.
+ @}
+*/
+
+/** Update the name of a DeviceOp object node.
+
+ @ingroup UserApis
+
+ @param [in] DeviceOpNode Object node representing a Device.
+ Must have an OpCode=AML_NAME_OP, SubOpCode=0.
+ OpCode/SubOpCode.
+ DeviceOp object nodes are defined in ASL
+ using the "Device ()" function.
+ @param [in] NewNameString The new Device's name.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "DEV0", "DV15.DEV0", etc.
+ The input string is copied.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlDeviceOpUpdateName (
+ IN AML_OBJECT_NODE_HANDLE DeviceOpNode,
+ IN CHAR8 * NewNameString
+ );
+
+/** Update an integer value defined by a NameOp object node.
+
+ For compatibility reasons, the NameOpNode must initially
+ contain an integer.
+
+ @ingroup UserApis
+
+ @param [in] NameOpNode NameOp object node.
+ Must have an OpCode=AML_NAME_OP, SubOpCode=0.
+ NameOp object nodes are defined in ASL
+ using the "Name ()" function.
+ @param [in] NewInt New Integer value to assign.
+ Must be a UINT64.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlNameOpUpdateInteger (
+ IN AML_OBJECT_NODE_HANDLE NameOpNode,
+ IN UINT64 NewInt
+ );
+
+/** Update a string value defined by a NameOp object node.
+
+ The NameOpNode must initially contain a string.
+ The EISAID ASL macro converts a string to an integer. This, it is
+ not accepted.
+
+ @ingroup UserApis
+
+ @param [in] NameOpNode NameOp object node.
+ Must have an OpCode=AML_NAME_OP, SubOpCode=0.
+ NameOp object nodes are defined in ASL
+ using the "Name ()" function.
+ @param [in] NewName New NULL terminated string to assign to
+ the NameOpNode.
+ The input string is copied.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlNameOpUpdateString (
+ IN AML_OBJECT_NODE_HANDLE NameOpNode,
+ IN CONST CHAR8 * NewName
+ );
+
+/** Get the first Resource Data element contained in a "_CRS" object.
+
+ In the following ASL code, the function will return the Resource Data
+ node corresponding to the "QWordMemory ()" ASL macro.
+ Name (_CRS, ResourceTemplate() {
+ QWordMemory (...) {...},
+ Interrupt (...) {...}
+ }
+ )
+
+ Note:
+ - The "_CRS" object must be declared using ASL "Name (Declare Named Object)".
+ - "_CRS" declared using ASL "Method (Declare Control Method)" is not
+ supported.
+
+ @ingroup UserApis
+
+ @param [in] NameOpCrsNode NameOp object node defining a "_CRS" object.
+ Must have an OpCode=AML_NAME_OP, SubOpCode=0.
+ NameOp object nodes are defined in ASL
+ using the "Name ()" function.
+ @param [out] OutRdNode Pointer to the first Resource Data element of
+ the "_CRS" object. A Resource Data element
+ is stored in a data node.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlNameOpCrsGetFirstRdNode (
+ IN AML_OBJECT_NODE_HANDLE NameOpCrsNode,
+ OUT AML_DATA_NODE_HANDLE * OutRdNode
+ );
+
+/** Get the Resource Data element following the CurrRdNode Resource Data.
+
+ In the following ASL code, if CurrRdNode corresponds to the first
+ "QWordMemory ()" ASL macro, the function will return the Resource Data
+ node corresponding to the "Interrupt ()" ASL macro.
+ Name (_CRS, ResourceTemplate() {
+ QwordMemory (...) {...},
+ Interrupt (...) {...}
+ }
+ )
+
+ The CurrRdNode Resource Data node must be defined in an object named "_CRS"
+ and defined by a "Name ()" ASL function.
+
+ @ingroup UserApis
+
+ @param [in] CurrRdNode Pointer to the current Resource Data element of
+ the "_CRS" variable.
+ @param [out] OutRdNode Pointer to the Resource Data element following
+ the CurrRdNode.
+ Contain a NULL pointer if CurrRdNode is the
+ last Resource Data element in the list.
+ The "End Tag" is not considered as a resource
+ data element and is not returned.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+AmlNameOpCrsGetNextRdNode (
+ IN AML_DATA_NODE_HANDLE CurrRdNode,
+ OUT AML_DATA_NODE_HANDLE * OutRdNode
+ );
+
+/** Update the first interrupt of an Interrupt resource data node.
+
+ The flags of the Interrupt resource data are left unchanged.
+
+ The InterruptRdNode corresponds to the Resource Data created by the
+ "Interrupt ()" ASL macro. It is an Extended Interrupt Resource Data.
+ See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor"
+ for more information about Extended Interrupt Resource Data.
+
+ @ingroup UserApis
+
+ @param [in] InterruptRdNode Pointer to the an extended interrupt
+ resource data node.
+ @param [in] Irq Interrupt value to update.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+**/
+EFI_STATUS
+EFIAPI
+AmlUpdateRdInterrupt (
+ IN AML_DATA_NODE_HANDLE InterruptRdNode,
+ IN UINT32 Irq
+ );
+
+/** Update the base address and length of a QWord resource data node.
+
+ @ingroup UserApis
+
+ @param [in] QWordRdNode Pointer a QWord resource data
+ node.
+ @param [in] BaseAddress Base address.
+ @param [in] BaseAddressLength Base address length.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+**/
+EFI_STATUS
+EFIAPI
+AmlUpdateRdQWord (
+ IN AML_DATA_NODE_HANDLE QWordRdNode,
+ IN UINT64 BaseAddress,
+ IN UINT64 BaseAddressLength
+ );
+
+/** Add an Interrupt Resource Data node.
+
+ This function creates a Resource Data element corresponding to the
+ "Interrupt ()" ASL function, stores it in an AML Data Node.
+
+ It then adds it after the input CurrRdNode in the list of resource data
+ element.
+
+ The Resource Data effectively created is an Extended Interrupt Resource
+ Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor"
+ for more information about Extended Interrupt Resource Data.
+
+ The Extended Interrupt contains one single interrupt.
+
+ This function allocates memory to create a data node. It is the caller's
+ responsibility to either:
+ - attach this node to an AML tree;
+ - delete this node.
+
+ Note: The _CRS node must be defined using the ASL Name () function.
+ e.g. Name (_CRS, ResourceTemplate () {
+ ...
+ }
+
+ @ingroup UserApis
+
+ @param [in] NameOpCrsNode NameOp object node defining a "_CRS" object.
+ Must have an OpCode=AML_NAME_OP, SubOpCode=0.
+ NameOp object nodes are defined in ASL
+ using the "Name ()" function.
+ @param [in] ResourceConsumer The device consumes the specified interrupt
+ or produces it for use by a child device.
+ @param [in] EdgeTriggered The interrupt is edge triggered or
+ level triggered.
+ @param [in] ActiveLow The interrupt is active-high or active-low.
+ @param [in] Shared The interrupt can be shared with other
+ devices or not (Exclusive).
+ @param [in] IrqList Interrupt list. Must be non-NULL.
+ @param [in] IrqCount Interrupt count. Must be non-zero.
+
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenCrsAddRdInterrupt (
+ IN AML_OBJECT_NODE_HANDLE NameOpCrsNode,
+ IN BOOLEAN ResourceConsumer,
+ IN BOOLEAN EdgeTriggered,
+ IN BOOLEAN ActiveLow,
+ IN BOOLEAN Shared,
+ IN UINT32 * IrqList,
+ IN UINT8 IrqCount
+ );
+
+/** AML code generation for DefinitionBlock.
+
+ Create a Root Node handle.
+ It is the caller's responsibility to free the allocated memory
+ with the AmlDeleteTree function.
+
+ AmlCodeGenDefinitionBlock (TableSignature, OemId, TableID, OEMRevision) is
+ equivalent to the following ASL code:
+ DefinitionBlock (AMLFileName, TableSignature, ComplianceRevision,
+ OemId, TableID, OEMRevision) {}
+ with the ComplianceRevision set to 2 and the AMLFileName is ignored.
+
+ @ingroup CodeGenApis
+
+ @param[in] TableSignature 4-character ACPI signature.
+ Must be 'DSDT' or 'SSDT'.
+ @param[in] OemId 6-character string OEM identifier.
+ @param[in] OemTableId 8-character string OEM table identifier.
+ @param[in] OemRevision OEM revision number.
+ @param[out] DefinitionBlockTerm The ASL Term handle representing a
+ Definition Block.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenDefinitionBlock (
+ IN CONST CHAR8 * TableSignature,
+ IN CONST CHAR8 * OemId,
+ IN CONST CHAR8 * OemTableId,
+ IN UINT32 OemRevision,
+ OUT AML_ROOT_NODE_HANDLE * NewRootNode
+ );
+
+/** AML code generation for a Name object node, containing a String.
+
+ AmlCodeGenNameString ("_HID", "HID0000", ParentNode, NewObjectNode) is
+ equivalent of the following ASL code:
+ Name(_HID, "HID0000")
+
+ @ingroup CodeGenApis
+
+ @param [in] NameString The new variable name.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "DEV0", "DV15.DEV0", etc.
+ The input string is copied.
+ @param [in] String NULL terminated String to associate to the
+ NameString.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewObjectNode If success, contains the created node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenNameString (
+ IN CONST CHAR8 * NameString,
+ IN CHAR8 * String,
+ IN AML_NODE_HANDLE ParentNode, OPTIONAL
+ OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
+ );
+
+/** AML code generation for a Name object node, containing an Integer.
+
+ AmlCodeGenNameInteger ("_UID", 1, ParentNode, NewObjectNode) is
+ equivalent of the following ASL code:
+ Name(_UID, One)
+
+ @ingroup CodeGenApis
+
+ @param [in] NameString The new variable name.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "DEV0", "DV15.DEV0", etc.
+ The input string is copied.
+ @param [in] Integer Integer to associate to the NameString.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewObjectNode If success, contains the created node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenNameInteger (
+ IN CONST CHAR8 * NameString,
+ IN UINT64 Integer,
+ IN AML_NODE_HANDLE ParentNode, OPTIONAL
+ OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
+ );
+
+/** AML code generation for a Device object node.
+
+ AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is
+ equivalent of the following ASL code:
+ Device(COM0) {}
+
+ @ingroup CodeGenApis
+
+ @param [in] NameString The new Device's name.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "DEV0", "DV15.DEV0", etc.
+ The input string is copied.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewObjectNode If success, contains the created node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenDevice (
+ IN CONST CHAR8 * NameString,
+ IN AML_NODE_HANDLE ParentNode, OPTIONAL
+ OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
+ );
+
+/** AML code generation for a Scope object node.
+
+ AmlCodeGenScope ("_SB", ParentNode, NewObjectNode) is
+ equivalent of the following ASL code:
+ Scope(_SB) {}
+
+ @ingroup CodeGenApis
+
+ @param [in] NameString The new Scope's name.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "DEV0", "DV15.DEV0", etc.
+ The input string is copied.
+ @param [in] ParentNode If provided, set ParentNode as the parent
+ of the node created.
+ @param [out] NewObjectNode If success, contains the created node.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenScope (
+ IN CONST CHAR8 * NameString,
+ IN AML_NODE_HANDLE ParentNode, OPTIONAL
+ OUT AML_OBJECT_NODE_HANDLE * NewObjectNode OPTIONAL
+ );
+
+#endif // AML_LIB_H_
diff --git a/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h b/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h
new file mode 100644
index 00000000..61eefdcf
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/SsdtSerialPortFixupLib.h
@@ -0,0 +1,68 @@
+/** @file
+ Ssdt Serial Port Fixup Library
+
+ Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef SSDT_SERIAL_PORT_LIB_H_
+#define SSDT_SERIAL_PORT_LIB_H_
+
+/** Build a SSDT table describing the input serial port.
+
+ The table created by this function must be freed by FreeSsdtSerialTable.
+
+ @param [in] AcpiTableInfo Pointer to the ACPI table information.
+ @param [in] SerialPortInfo Serial port to describe in the SSDT table.
+ @param [in] Name The Name to give to the Device.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "DEV0", "DV15.DEV0", etc.
+ @param [in] Uid UID for the Serial Port.
+ @param [out] Table If success, pointer to the created SSDT table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND Could not find information.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+BuildSsdtSerialPortTable (
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * AcpiTableInfo,
+ IN CONST CM_ARM_SERIAL_PORT_INFO * SerialPortInfo,
+ IN CONST CHAR8 * Name,
+ IN CONST UINT64 Uid,
+ OUT EFI_ACPI_DESCRIPTION_HEADER ** Table
+ );
+
+/** Free an SSDT table previously created by
+ the BuildSsdtSerialTable function.
+
+ @param [in] Table Pointer to a SSDT table allocated by
+ the BuildSsdtSerialTable function.
+
+ @retval EFI_SUCCESS Success.
+**/
+EFI_STATUS
+EFIAPI
+FreeSsdtSerialPortTable (
+ IN EFI_ACPI_DESCRIPTION_HEADER * Table
+ );
+
+/** Validate the Serial Port Information.
+
+ @param [in] SerialPortInfoTable Table of CM_ARM_SERIAL_PORT_INFO.
+ @param [in] SerialPortCount Count of SerialPort in the table.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+**/
+EFI_STATUS
+EFIAPI
+ValidateSerialPortInfo (
+ IN CONST CM_ARM_SERIAL_PORT_INFO * SerialPortInfoTable,
+ IN UINT32 SerialPortCount
+ );
+
+#endif // SSDT_SERIAL_PORT_LIB_H_
diff --git a/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/TableHelperLib.h b/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/TableHelperLib.h
new file mode 100644
index 00000000..80c44ef9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Include/Library/TableHelperLib.h
@@ -0,0 +1,159 @@
+/** @file
+
+ Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Glossary:
+ - PFN - Pointer to a Function
+
+**/
+
+#ifndef TABLE_HELPER_LIB_H_
+#define TABLE_HELPER_LIB_H_
+
+/** Is a character upper case
+*/
+#define IS_UPPER_CHAR(x) ((x >= 'A') && (x <= 'Z'))
+
+/** Is a character a decimal digit
+*/
+#define IS_DIGIT(x) ((x >= '0') && (x <= '9'))
+
+/** Is a character an upper case hexadecimal digit
+*/
+#define IS_UPPER_HEX(x) (((x >= 'A') && (x <= 'F')) || IS_DIGIT (x))
+
+/** The GetCgfMgrInfo function gets the CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
+ object from the Configuration Manager.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager protocol
+ interface.
+ @param [out] CfgMfrInfo Pointer to the Configuration Manager Info
+ object structure.
+
+ @retval EFI_SUCCESS The object is returned.
+ @retval EFI_INVALID_PARAMETER The Object ID is invalid.
+ @retval EFI_NOT_FOUND The requested Object is not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size.
+**/
+EFI_STATUS
+EFIAPI
+GetCgfMgrInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT CM_STD_OBJ_CONFIGURATION_MANAGER_INFO ** CfgMfrInfo
+ );
+
+/** The AddAcpiHeader function updates the ACPI header structure. It uses the
+ ACPI table Generator and the Configuration Manager protocol to obtain the
+ information required for constructing the header.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ protocol interface.
+ @param [in] Generator Pointer to the ACPI table Generator.
+ @param [in,out] AcpiHeader Pointer to the ACPI table header to be
+ updated.
+ @param [in] AcpiTableInfo Pointer to the ACPI table info structure.
+ @param [in] Length Length of the ACPI table.
+
+ @retval EFI_SUCCESS The ACPI table is updated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+EFI_STATUS
+EFIAPI
+AddAcpiHeader (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER * CONST AcpiHeader,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST UINT32 Length
+ );
+
+/**
+ Function prototype for testing if two arbitrary objects are equal.
+
+ @param [in] Object1 Pointer to the first object to compare.
+ @param [in] Object2 Pointer to the second object to compare.
+ @param [in] Index1 Index of Object1. This value is optional and
+ can be ignored by the specified implementation.
+ @param [in] Index2 Index of Object2. This value is optional and
+ can be ignored by the specified implementation.
+
+ @retval TRUE Object1 and Object2 are equal.
+ @retval FALSE Object1 and Object2 are NOT equal.
+**/
+typedef
+BOOLEAN
+(EFIAPI *PFN_IS_EQUAL)(
+ IN CONST VOID * Object1,
+ IN CONST VOID * Object2,
+ IN UINTN Index1 OPTIONAL,
+ IN UINTN Index2 OPTIONAL
+ );
+
+/**
+ Test and report if a duplicate entry exists in the given array of comparable
+ elements.
+
+ @param [in] Array Array of elements to test for duplicates.
+ @param [in] Count Number of elements in Array.
+ @param [in] ElementSize Size of an element in bytes
+ @param [in] EqualTestFunction The function to call to check if any two
+ elements are equal.
+
+ @retval TRUE A duplicate element was found or one of
+ the input arguments is invalid.
+ @retval FALSE Every element in Array is unique.
+**/
+BOOLEAN
+EFIAPI
+FindDuplicateValue (
+ IN CONST VOID * Array,
+ IN CONST UINTN Count,
+ IN CONST UINTN ElementSize,
+ IN PFN_IS_EQUAL EqualTestFunction
+ );
+
+/** Convert a hex number to its ASCII code.
+
+ @param [in] x Hex number to convert.
+ Must be 0 <= x < 16.
+
+ @return The ASCII code corresponding to x.
+**/
+UINT8
+EFIAPI
+AsciiFromHex (
+ IN UINT8 x
+ );
+
+/** Check if a HID is a valid PNP ID.
+
+ @param [in] Hid The Hid to validate.
+
+ @retval TRUE The Hid is a valid PNP ID.
+ @retval FALSE The Hid is not a valid PNP ID.
+**/
+BOOLEAN
+IsValidPnpId (
+ IN CONST CHAR8 * Hid
+ );
+
+/** Check if a HID is a valid ACPI ID.
+
+ @param [in] Hid The Hid to validate.
+
+ @retval TRUE The Hid is a valid ACPI ID.
+ @retval FALSE The Hid is not a valid ACPI ID.
+**/
+BOOLEAN
+IsValidAcpiId (
+ IN CONST CHAR8 * Hid
+ );
+
+#endif // TABLE_HELPER_LIB_H_