]> git.proxmox.com Git - mirror_edk2.git/commitdiff
DynamicTablesPkg: Arm DBG2 Table Generator
authorSami Mujawar <sami.mujawar@arm.com>
Sat, 15 Dec 2018 12:28:23 +0000 (12:28 +0000)
committerSami Mujawar <sami.mujawar@arm.com>
Tue, 19 Feb 2019 10:37:31 +0000 (10:37 +0000)
The DBG2 generator uses the configuration manager protocol
to obtain the debug serial port information from the platform
configuration manager. It then updates a template DBG2 table
structure. This table data is used by the Table Manager to
install the DBG2 table.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Reviewed-by: Alexei Fedorov <alexei.fedorov@arm.com>
DynamicTablesPkg/DynamicTables.dsc.inc
DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf [new file with mode: 0644]
DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c [new file with mode: 0644]

index 069ce635e5150b5914b3d7ef58d9bcfef229879f..4a9e42728da2c211183be974215c04fdffd31fc4 100644 (file)
@@ -27,6 +27,7 @@
   #\r
   DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf {\r
     <LibraryClasses>\r
+      NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf\r
       NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf\r
       NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf\r
       NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf\r
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf
new file mode 100644 (file)
index 0000000..4075862
--- /dev/null
@@ -0,0 +1,48 @@
+## @file\r
+# DBG2 Table Generator\r
+#\r
+#  Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION    = 0x00010019\r
+  BASE_NAME      = AcpiDbg2LibArm\r
+  FILE_GUID      = A17BA4F0-3DEB-4FE5-BD27-EC008E541B22\r
+  VERSION_STRING = 1.0\r
+  MODULE_TYPE    = DXE_DRIVER\r
+  LIBRARY_CLASS  = NULL|DXE_DRIVER\r
+  CONSTRUCTOR    = AcpiDbg2LibConstructor\r
+  DESTRUCTOR     = AcpiDbg2LibDestructor\r
+\r
+[Sources]\r
+  Dbg2Generator.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  EmbeddedPkg/EmbeddedPkg.dec\r
+  ArmPlatformPkg/ArmPlatformPkg.dec\r
+  DynamicTablesPkg/DynamicTablesPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  SerialPortLib\r
+\r
+[FixedPcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate\r
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits\r
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity\r
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits\r
+\r
+[Protocols]\r
+\r
+[Guids]\r
+\r
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c
new file mode 100644 (file)
index 0000000..e21e2b6
--- /dev/null
@@ -0,0 +1,463 @@
+/** @file\r
+  DBG2 Table Generator\r
+\r
+  Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  @par Reference(s):\r
+  - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.\r
+\r
+**/\r
+\r
+#include <IndustryStandard/DebugPort2Table.h>\r
+#include <Library/AcpiLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PL011UartLib.h>\r
+#include <Protocol/AcpiTable.h>\r
+#include <Protocol/SerialIo.h>\r
+\r
+// Module specific include files.\r
+#include <AcpiTableGenerator.h>\r
+#include <ConfigurationManagerObject.h>\r
+#include <ConfigurationManagerHelper.h>\r
+#include <Library/TableHelperLib.h>\r
+#include <Protocol/ConfigurationManagerProtocol.h>\r
+\r
+/** ARM standard DBG2 Table Generator\r
+\r
+  Constructs the DBG2 table for PL011 or SBSA UART peripherals.\r
+\r
+Requirements:\r
+  The following Configuration Manager Object(s) are required by\r
+  this Generator:\r
+  - EArmObjSerialDebugPortInfo\r
+*/\r
+\r
+#pragma pack(1)\r
+\r
+/** The number of debug ports represented by the Table.\r
+*/\r
+#define DBG2_NUM_DEBUG_PORTS                       1\r
+\r
+/** The number of Generic Address Registers\r
+    presented in the debug device information.\r
+*/\r
+#define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS   1\r
+\r
+/** The index for the debug port 1 in the Debug port information list.\r
+*/\r
+#define DBG_PORT_INDEX_PORT1                       0\r
+\r
+/** A string representing the name of the debug port 1.\r
+*/\r
+#define NAME_STR_PORT1                            "COM1"\r
+\r
+/** The length of the namespace string.\r
+*/\r
+#define DBG2_NAMESPACESTRING_FIELD_SIZE            sizeof (NAME_STR_PORT1)\r
+\r
+/** The PL011 UART address range length.\r
+*/\r
+#define PL011_UART_LENGTH                          0x1000\r
+\r
+/** A structure that provides the OS with the required information\r
+    for initializing a debugger connection.\r
+*/\r
+typedef struct {\r
+  /// The debug device information for the platform\r
+  EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device;\r
+\r
+  /// The base address register for the serial port\r
+  EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE        BaseAddressRegister;\r
+\r
+  /// The address size\r
+  UINT32 AddressSize;\r
+\r
+  /// The debug port name string\r
+  UINT8  NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE];\r
+} DBG2_DEBUG_DEVICE_INFORMATION;\r
+\r
+/** A structure representing the information about the debug port(s)\r
+    available on the platform.\r
+*/\r
+typedef struct {\r
+  /// The DBG2 table header\r
+  EFI_ACPI_DEBUG_PORT_2_DESCRIPTION_TABLE Description;\r
+\r
+  /// Debug port information list\r
+  DBG2_DEBUG_DEVICE_INFORMATION       Dbg2DeviceInfo[DBG2_NUM_DEBUG_PORTS];\r
+} DBG2_TABLE;\r
+\r
+/** A helper macro used for initializing the debug port device\r
+    information structure.\r
+\r
+  @param [in]  NumReg       The number of generic address registers.\r
+  @param [in]  SubType      The DBG Port SubType.\r
+  @param [in]  UartBase     The UART port base address.\r
+  @param [in]  UartAddrLen  The UART port address range length.\r
+  @param [in]  UartNameStr  The UART port name string.\r
+**/\r
+#define DBG2_DEBUG_PORT_DDI(                                          \\r
+          NumReg,                                                     \\r
+          SubType,                                                    \\r
+          UartBase,                                                   \\r
+          UartAddrLen,                                                \\r
+          UartNameStr                                                 \\r
+          ) {                                                         \\r
+    {                                                                 \\r
+      /* UINT8     Revision */                                        \\r
+      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,         \\r
+      /* UINT16    Length */                                          \\r
+      sizeof (DBG2_DEBUG_DEVICE_INFORMATION),                         \\r
+      /* UINT8     NumberofGenericAddressRegisters */                 \\r
+      NumReg,                                                         \\r
+      /* UINT16    NameSpaceStringLength */                           \\r
+      DBG2_NAMESPACESTRING_FIELD_SIZE,                                \\r
+      /* UINT16    NameSpaceStringOffset */                           \\r
+      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString),     \\r
+      /* UINT16    OemDataLength */                                   \\r
+      0,                                                              \\r
+      /* UINT16    OemDataOffset */                                   \\r
+      0,                                                              \\r
+      /* UINT16    Port Type */                                       \\r
+      EFI_ACPI_DBG2_PORT_TYPE_SERIAL,                                 \\r
+      /* UINT16    Port Subtype */                                    \\r
+      SubType,                                                        \\r
+      /* UINT8     Reserved[2] */                                     \\r
+      {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE},               \\r
+      /* UINT16    BaseAddressRegister Offset */                      \\r
+      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), \\r
+      /* UINT16    AddressSize Offset */                              \\r
+      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize)          \\r
+    },                                                                \\r
+    /* EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */  \\r
+    ARM_GAS32 (UartBase),                                             \\r
+    /* UINT32  AddressSize */                                         \\r
+    UartAddrLen,                                                      \\r
+    /* UINT8   NameSpaceString[MAX_DBG2_NAME_LEN] */                  \\r
+    UartNameStr                                                       \\r
+  }\r
+\r
+/** The DBG2 Table template definition.\r
+\r
+  Note: fields marked with "{Template}" will be set dynamically\r
+*/\r
+STATIC\r
+DBG2_TABLE AcpiDbg2 = {\r
+  {\r
+    ACPI_HEADER (\r
+      EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE,\r
+      DBG2_TABLE,\r
+      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION\r
+      ),\r
+    OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo),\r
+    DBG2_NUM_DEBUG_PORTS\r
+  },\r
+  {\r
+    /*\r
+     * Debug port 1\r
+     */\r
+    DBG2_DEBUG_PORT_DDI (\r
+      DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS,\r
+      0,                    // {Template}: Serial Port Subtype\r
+      0,                    // {Template}: Serial Port Base Address\r
+      PL011_UART_LENGTH,\r
+      NAME_STR_PORT1\r
+      )\r
+  }\r
+};\r
+\r
+#pragma pack()\r
+\r
+/** This macro expands to a function that retrieves the Serial\r
+    debug port information from the Configuration Manager\r
+*/\r
+GET_OBJECT_LIST (\r
+  EObjNameSpaceArm,\r
+  EArmObjSerialDebugPortInfo,\r
+  CM_ARM_SERIAL_PORT_INFO\r
+  );\r
+\r
+/** Initialize the PL011 UART with the parameters obtained from\r
+    the Configuration Manager.\r
+\r
+  @param [in]  SerialPortInfo Pointer to the Serial Port Information.\r
+\r
+  @retval EFI_SUCCESS           Success.\r
+  @retval EFI_INVALID_PARAMETER The parameters for serial port initialization\r
+                                are invalid.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+SetupDebugUart (\r
+  IN  CONST CM_ARM_SERIAL_PORT_INFO  * CONST SerialPortInfo\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  UINT64              BaudRate;\r
+  UINT32              ReceiveFifoDepth;\r
+  EFI_PARITY_TYPE     Parity;\r
+  UINT8               DataBits;\r
+  EFI_STOP_BITS_TYPE  StopBits;\r
+\r
+  ASSERT (SerialPortInfo != NULL);\r
+\r
+  // Initialize the Serial Debug UART\r
+  DEBUG ((DEBUG_INFO, "Initializing Serial Debug UART...\n"));\r
+  ReceiveFifoDepth = 0; // Use the default value for FIFO depth\r
+  Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);\r
+  DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);\r
+  StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);\r
+\r
+  BaudRate = SerialPortInfo->BaudRate;\r
+  Status = PL011UartInitializePort (\r
+             (UINTN)SerialPortInfo->BaseAddress,\r
+             SerialPortInfo->Clock,\r
+             &BaudRate,\r
+             &ReceiveFifoDepth,\r
+             &Parity,\r
+             &DataBits,\r
+             &StopBits\r
+             );\r
+\r
+  DEBUG ((DEBUG_INFO, "Debug UART Configuration:\n"));\r
+  DEBUG ((DEBUG_INFO, "UART Base  = 0x%lx\n", SerialPortInfo->BaseAddress));\r
+  DEBUG ((DEBUG_INFO, "Clock      = %d\n", SerialPortInfo->Clock));\r
+  DEBUG ((DEBUG_INFO, "Baudrate   = %ld\n", BaudRate));\r
+  DEBUG ((DEBUG_INFO, "Configuring Debug UART. Status = %r\n", Status));\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+  return Status;\r
+}\r
+\r
+/** Construct the DBG2 ACPI table\r
+\r
+    The BuildDbg2Table function is called by the Dynamic Table Manager\r
+    to construct the DBG2 ACPI table.\r
+\r
+  This function invokes the Configuration Manager protocol interface\r
+  to get the required hardware information for generating the ACPI\r
+  table.\r
+\r
+  If this function allocates any resources then they must be freed\r
+  in the FreeXXXXTableResources function.\r
+\r
+  @param [in]  This           Pointer to the table generator.\r
+  @param [in]  AcpiTableInfo  Pointer to the ACPI Table Info.\r
+  @param [in]  CfgMgrProtocol Pointer to the Configuration Manager\r
+                              Protocol Interface.\r
+  @param [out] Table          Pointer to the constructed ACPI Table.\r
+\r
+  @retval EFI_SUCCESS           Table generated successfully.\r
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+  @retval EFI_NOT_FOUND         The required object was not found.\r
+  @retval EFI_BAD_BUFFER_SIZE   The size returned by the Configuration\r
+                                Manager is less than the Object size for the\r
+                                requested object.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+BuildDbg2Table (\r
+  IN  CONST ACPI_TABLE_GENERATOR                  * CONST This,\r
+  IN  CONST CM_STD_OBJ_ACPI_TABLE_INFO            * CONST AcpiTableInfo,\r
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,\r
+  OUT       EFI_ACPI_DESCRIPTION_HEADER          ** CONST Table\r
+  )\r
+{\r
+  EFI_STATUS                 Status;\r
+  CM_ARM_SERIAL_PORT_INFO  * SerialPortInfo;\r
+\r
+  ASSERT (This != NULL);\r
+  ASSERT (AcpiTableInfo != NULL);\r
+  ASSERT (CfgMgrProtocol != NULL);\r
+  ASSERT (Table != NULL);\r
+  ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);\r
+  ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);\r
+\r
+  if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||\r
+      (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ERROR: DBG2: Requested table revision = %d, is not supported."\r
+      "Supported table revision: Minimum = %d, Maximum = %d\n",\r
+      AcpiTableInfo->AcpiTableRevision,\r
+      This->MinAcpiTableRevision,\r
+      This->AcpiTableRevision\r
+      ));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Table = NULL;\r
+\r
+  Status = GetEArmObjSerialDebugPortInfo (\r
+             CfgMgrProtocol,\r
+             CM_NULL_TOKEN,\r
+             &SerialPortInfo,\r
+             NULL\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ERROR: DBG2: Failed to get serial port information. Status = %r\n",\r
+      Status\r
+      ));\r
+    goto error_handler;\r
+  }\r
+\r
+  if (SerialPortInfo->BaseAddress == 0) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ERROR: DBG2: Uart port base address is invalid. BaseAddress = 0x%lx\n",\r
+      SerialPortInfo->BaseAddress\r
+      ));\r
+    goto error_handler;\r
+  }\r
+\r
+  if ((SerialPortInfo->PortSubtype !=\r
+      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART) &&\r
+      (SerialPortInfo->PortSubtype !=\r
+      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X) &&\r
+      (SerialPortInfo->PortSubtype !=\r
+      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART) &&\r
+      (SerialPortInfo->PortSubtype !=\r
+      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_DCC)) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ERROR: DBG2: Uart port sybtype is invalid. PortSubtype = 0x%x\n",\r
+      SerialPortInfo->PortSubtype\r
+      ));\r
+    goto error_handler;\r
+  }\r
+\r
+  Status = AddAcpiHeader (\r
+             CfgMgrProtocol,\r
+             This,\r
+             (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiDbg2,\r
+             AcpiTableInfo->AcpiTableRevision,\r
+             sizeof (DBG2_TABLE)\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ERROR: DBG2: Failed to add ACPI header. Status = %r\n",\r
+      Status\r
+      ));\r
+    goto error_handler;\r
+  }\r
+\r
+  // Update the base address\r
+  AcpiDbg2.Dbg2DeviceInfo[DBG_PORT_INDEX_PORT1].BaseAddressRegister.Address =\r
+    SerialPortInfo->BaseAddress;\r
+\r
+  // Update the serial port subtype\r
+  AcpiDbg2.Dbg2DeviceInfo[DBG_PORT_INDEX_PORT1].Dbg2Device.PortSubtype =\r
+    SerialPortInfo->PortSubtype;\r
+\r
+  // Initialize the serial port\r
+  Status = SetupDebugUart (SerialPortInfo);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ERROR: DBG2: Failed to configure debug serial port. Status = %r\n",\r
+      Status\r
+      ));\r
+    goto error_handler;\r
+  }\r
+\r
+  *Table = (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiDbg2;\r
+\r
+error_handler:\r
+  return Status;\r
+}\r
+\r
+/** This macro defines the DBG2 Table Generator revision.\r
+*/\r
+#define DBG2_GENERATOR_REVISION CREATE_REVISION (1, 0)\r
+\r
+/** The interface for the DBG2 Table Generator.\r
+*/\r
+STATIC\r
+CONST\r
+ACPI_TABLE_GENERATOR Dbg2Generator = {\r
+  // Generator ID\r
+  CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2),\r
+  // Generator Description\r
+  L"ACPI.STD.DBG2.GENERATOR",\r
+  // ACPI Table Signature\r
+  EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE,\r
+  // ACPI Table Revision supported by this Generator\r
+  EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,\r
+  // Minimum supported ACPI Table Revision\r
+  EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,\r
+  // Creator ID\r
+  TABLE_GENERATOR_CREATOR_ID_ARM,\r
+  // Creator Revision\r
+  DBG2_GENERATOR_REVISION,\r
+  // Build Table function\r
+  BuildDbg2Table,\r
+  // No additional resources are allocated by the generator.\r
+  // Hence the Free Resource function is not required.\r
+  NULL,\r
+  // Extended build function not needed\r
+  NULL,\r
+  // Extended build function not implemented by the generator.\r
+  // Hence extended free resource function is not required.\r
+  NULL\r
+};\r
+\r
+/** Register the Generator with the ACPI Table Factory.\r
+\r
+  @param [in]  ImageHandle  The handle to the image.\r
+  @param [in]  SystemTable  Pointer to the System Table.\r
+\r
+  @retval EFI_SUCCESS           The Generator is registered.\r
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+  @retval EFI_ALREADY_STARTED   The Generator for the Table ID\r
+                                is already registered.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AcpiDbg2LibConstructor (\r
+  IN CONST EFI_HANDLE                ImageHandle,\r
+  IN       EFI_SYSTEM_TABLE  * CONST SystemTable\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  Status = RegisterAcpiTableGenerator (&Dbg2Generator);\r
+  DEBUG ((DEBUG_INFO, "DBG2: Register Generator. Status = %r\n", Status));\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/** Deregister the Generator from the ACPI Table Factory.\r
+\r
+  @param [in]  ImageHandle  The handle to the image.\r
+  @param [in]  SystemTable  Pointer to the System Table.\r
+\r
+  @retval EFI_SUCCESS           The Generator is deregistered.\r
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.\r
+  @retval EFI_NOT_FOUND         The Generator is not registered.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AcpiDbg2LibDestructor (\r
+  IN CONST EFI_HANDLE                ImageHandle,\r
+  IN       EFI_SYSTEM_TABLE  * CONST SystemTable\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  Status = DeregisterAcpiTableGenerator (&Dbg2Generator);\r
+  DEBUG ((DEBUG_INFO, "DBG2: Deregister Generator. Status = %r\n", Status));\r
+  ASSERT_EFI_ERROR (Status);\r
+  return Status;\r
+}\r