summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c226
-rw-r--r--DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFactory/DeviceTreeTableFactory.c225
-rw-r--r--DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h125
-rw-r--r--DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c90
-rw-r--r--DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf60
-rw-r--r--DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c226
-rw-r--r--DynamicTablesPkg/DynamicTables.dsc.inc6
-rw-r--r--DynamicTablesPkg/DynamicTables.fdf.inc20
-rw-r--r--DynamicTablesPkg/DynamicTablesPkg.dec11
9 files changed, 989 insertions, 0 deletions
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c
new file mode 100644
index 0000000000..3ebbcda6d3
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c
@@ -0,0 +1,226 @@
+/** @file
+ ACPI Table Factory
+
+ Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Std - Standard
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+
+#include "DynamicTableFactory.h"
+
+extern EDKII_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo;
+
+/** Return a pointer to the ACPI table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] GeneratorId The ACPI table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested ACPI table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+GetAcpiTableGenerator (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST ACPI_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST ACPI_TABLE_GENERATOR ** CONST Generator
+ )
+{
+ UINT16 TableId;
+ EDKII_DYNAMIC_TABLE_FACTORY_INFO * FactoryInfo;
+
+ ASSERT (This != NULL);
+
+ FactoryInfo = This->TableFactoryInfo;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Invalid Generator pointer\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_ACPI (GeneratorId)) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Generator Type is not ACPI\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Generator = NULL;
+ TableId = GET_TABLE_ID (GeneratorId);
+ if (IS_GENERATOR_NAMESPACE_STD (GeneratorId)) {
+ if (TableId >= EStdAcpiTableIdMax) {
+ ASSERT (TableId < EStdAcpiTableIdMax);
+ return EFI_INVALID_PARAMETER;
+ }
+ if (FactoryInfo->StdAcpiTableGeneratorList[TableId] != NULL) {
+ *Generator = FactoryInfo->StdAcpiTableGeneratorList[TableId];
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomACPIGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomACPIGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (FactoryInfo->CustomAcpiTableGeneratorList[TableId] != NULL) {
+ *Generator = FactoryInfo->CustomAcpiTableGeneratorList[TableId];
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/** Register ACPI table factory generator.
+
+ The ACPI table factory maintains a list of the Standard and OEM ACPI
+ table generators.
+
+ @param [in] Generator Pointer to the ACPI table generator.
+
+ @retval EFI_SUCCESS The Generator was registered
+ successfully.
+ @retval EFI_INVALID_PARAMETER The Generator ID is invalid or
+ the Generator pointer is NULL.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID is
+ already registered.
+**/
+EFI_STATUS
+EFIAPI
+RegisterAcpiTableGenerator (
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator
+ )
+{
+ UINT16 TableId;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: ACPI register - Invalid Generator\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_ACPI (Generator->GeneratorID)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: ACPI register - Generator" \
+ " Type is not ACPI\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((DEBUG_INFO, "Registering %s\n", Generator->Description));
+
+ TableId = GET_TABLE_ID (Generator->GeneratorID);
+ if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) {
+ if (TableId >= EStdAcpiTableIdMax) {
+ ASSERT (TableId < EStdAcpiTableIdMax);
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.StdAcpiTableGeneratorList[TableId] == NULL) {
+ TableFactoryInfo.StdAcpiTableGeneratorList[TableId] = Generator;
+ } else {
+ return EFI_ALREADY_STARTED;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomACPIGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomACPIGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] == NULL) {
+ TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] = Generator;
+ } else {
+ return EFI_ALREADY_STARTED;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/** Deregister ACPI generator.
+
+ This function is called by the ACPI table generator to deregister itself
+ from the ACPI table factory.
+
+ @param [in] Generator Pointer to the ACPI table generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER The generator is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+DeregisterAcpiTableGenerator (
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator
+ )
+{
+ UINT16 TableId;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: ACPI deregister - Invalid Generator\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_ACPI (Generator->GeneratorID)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: ACPI deregister - Generator" \
+ " Type is not ACPI\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TableId = GET_TABLE_ID (Generator->GeneratorID);
+ if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) {
+ if (TableId >= EStdAcpiTableIdMax) {
+ ASSERT (TableId < EStdAcpiTableIdMax);
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.StdAcpiTableGeneratorList[TableId] != NULL) {
+ if (Generator != TableFactoryInfo.StdAcpiTableGeneratorList[TableId]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ TableFactoryInfo.StdAcpiTableGeneratorList[TableId] = NULL;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomACPIGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomACPIGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] != NULL) {
+ if (Generator !=
+ TableFactoryInfo.CustomAcpiTableGeneratorList[TableId]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] = NULL;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "Deregistering %s\n", Generator->Description));
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFactory/DeviceTreeTableFactory.c b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFactory/DeviceTreeTableFactory.c
new file mode 100644
index 0000000000..98b7e70fc1
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFactory/DeviceTreeTableFactory.c
@@ -0,0 +1,225 @@
+/** @file
+ Device Tree Table Factory
+
+ Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Std - Standard
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+// Module specific include files.
+#include <DeviceTreeTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+
+#include "DynamicTableFactory.h"
+
+extern EDKII_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo;
+
+/** Return a pointer to the DT table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] GeneratorId The DT table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested DT table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+GetDtTableGenerator (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST DT_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST DT_TABLE_GENERATOR ** CONST Generator
+ )
+{
+ UINT16 TableId;
+ EDKII_DYNAMIC_TABLE_FACTORY_INFO * FactoryInfo;
+
+ ASSERT (This != NULL);
+
+ FactoryInfo = This->TableFactoryInfo;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Invalid Generator pointer\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_DT (GeneratorId)) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Generator Type is not DT\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Generator = NULL;
+ TableId = GET_TABLE_ID (GeneratorId);
+ if (IS_GENERATOR_NAMESPACE_STD (GeneratorId)) {
+ if (TableId >= EStdDtTableIdMax) {
+ ASSERT (TableId < EStdDtTableIdMax);
+ return EFI_INVALID_PARAMETER;
+ }
+ if (FactoryInfo->StdDtTableGeneratorList[TableId] != NULL) {
+ *Generator = FactoryInfo->StdDtTableGeneratorList[TableId];
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomDTGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomDTGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (FactoryInfo->CustomDtTableGeneratorList[TableId] != NULL) {
+ *Generator = FactoryInfo->CustomDtTableGeneratorList[TableId];
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/** Register DT table factory generator.
+
+ The DT table factory maintains a list of the Standard and OEM DT
+ table generators.
+
+ @param [in] Generator Pointer to the DT table generator.
+
+ @retval EFI_SUCCESS The Generator was registered
+ successfully.
+ @retval EFI_INVALID_PARAMETER The Generator ID is invalid or
+ the Generator pointer is NULL.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID is
+ already registered.
+**/
+EFI_STATUS
+EFIAPI
+RegisterDtTableGenerator (
+ IN CONST DT_TABLE_GENERATOR * CONST Generator
+ )
+{
+ UINT16 TableId;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: DT register - Invalid Generator\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_DT (Generator->GeneratorID)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: DT register - Generator" \
+ " Type is not DT\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((DEBUG_INFO, "Registering %s\n", Generator->Description));
+
+ TableId = GET_TABLE_ID (Generator->GeneratorID);
+ if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) {
+ if (TableId >= EStdDtTableIdMax) {
+ ASSERT (TableId < EStdDtTableIdMax);
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.StdDtTableGeneratorList[TableId] == NULL) {
+ TableFactoryInfo.StdDtTableGeneratorList[TableId] = Generator;
+ } else {
+ return EFI_ALREADY_STARTED;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomDTGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomDTGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.CustomDtTableGeneratorList[TableId] == NULL) {
+ TableFactoryInfo.CustomDtTableGeneratorList[TableId] = Generator;
+ } else {
+ return EFI_ALREADY_STARTED;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/** Deregister DT generator.
+
+ This function is called by the DT table generator to deregister itself
+ from the DT table factory.
+
+ @param [in] Generator Pointer to the DT table generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER The generator is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+DeregisterDtTableGenerator (
+ IN CONST DT_TABLE_GENERATOR * CONST Generator
+ )
+{
+ UINT16 TableId;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: DT deregister - Invalid Generator\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_DT (Generator->GeneratorID)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: DT deregister - Generator" \
+ " Type is not DT\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TableId = GET_TABLE_ID (Generator->GeneratorID);
+ if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) {
+ if (TableId >= EStdDtTableIdMax) {
+ ASSERT (TableId < EStdDtTableIdMax);
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.StdDtTableGeneratorList[TableId] != NULL) {
+ if (Generator != TableFactoryInfo.StdDtTableGeneratorList[TableId]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ TableFactoryInfo.StdDtTableGeneratorList[TableId] = NULL;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomDTGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomDTGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.CustomDtTableGeneratorList[TableId] != NULL) {
+ if (Generator !=
+ TableFactoryInfo.CustomDtTableGeneratorList[TableId]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ TableFactoryInfo.CustomDtTableGeneratorList[TableId] = NULL;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "Deregistering %s\n", Generator->Description));
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h
new file mode 100644
index 0000000000..100a87c312
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h
@@ -0,0 +1,125 @@
+/** @file
+
+ Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Std - Standard
+ - ACPI - Advanced Configuration and Power Interface
+ - SMBIOS - System Management BIOS
+ - DT - Device Tree
+**/
+
+#ifndef DYNAMIC_TABLE_FACTORY_H_
+#define DYNAMIC_TABLE_FACTORY_H_
+
+#pragma pack(1)
+
+/** A structure that holds the list of registered ACPI and
+ SMBIOS table generators.
+*/
+typedef struct DynamicTableFactoryInfo {
+ /// An array for holding the list of Standard ACPI Table Generators.
+ CONST ACPI_TABLE_GENERATOR *
+ StdAcpiTableGeneratorList[EStdAcpiTableIdMax];
+
+ /// An array for holding the list of Custom ACPI Table Generators.
+ CONST ACPI_TABLE_GENERATOR *
+ CustomAcpiTableGeneratorList[FixedPcdGet16 (
+ PcdMaxCustomACPIGenerators
+ )];
+
+ /// An array for holding the list of Standard SMBIOS Table Generators.
+ CONST SMBIOS_TABLE_GENERATOR *
+ StdSmbiosTableGeneratorList[EStdSmbiosTableIdMax];
+
+ /// An array for holding the list of Custom SMBIOS Table Generators.
+ CONST SMBIOS_TABLE_GENERATOR *
+ CustomSmbiosTableGeneratorList[FixedPcdGet16 (
+ PcdMaxCustomSMBIOSGenerators
+ )];
+
+ /// An array for holding the list of Standard DT Table Generators.
+ CONST DT_TABLE_GENERATOR *
+ StdDtTableGeneratorList[EStdDtTableIdMax];
+
+ /// An array for holding the list of Custom DT Table Generators.
+ CONST DT_TABLE_GENERATOR *
+ CustomDtTableGeneratorList[FixedPcdGet16 (
+ PcdMaxCustomDTGenerators
+ )];
+} EDKII_DYNAMIC_TABLE_FACTORY_INFO;
+
+/** Return a pointer to the ACPI table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] GeneratorId The ACPI table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested ACPI table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+GetAcpiTableGenerator (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST ACPI_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST ACPI_TABLE_GENERATOR ** CONST Generator
+ );
+
+/** Return a pointer to the SMBIOS table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] GeneratorId The SMBIOS table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested SMBIOS table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+GetSmbiosTableGenerator (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST SMBIOS_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST SMBIOS_TABLE_GENERATOR ** CONST Generator
+ );
+
+/** Return a pointer to the DT table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] GeneratorId The DT table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested DT table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+GetDtTableGenerator (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST DT_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST DT_TABLE_GENERATOR ** CONST Generator
+ );
+
+#pragma pack()
+
+#endif // DYNAMIC_TABLE_FACTORY_H_
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c
new file mode 100644
index 0000000000..4915d379e8
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c
@@ -0,0 +1,90 @@
+/** @file
+ Dynamic Table Factory Dxe
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <DeviceTreeTableGenerator.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+#include <SmbiosTableGenerator.h>
+
+#include "DynamicTableFactory.h"
+
+/** The Dynamic Table Factory protocol structure that holds the
+ list of registered ACPI and SMBIOS table generators.
+*/
+EDKII_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo;
+
+/** A structure describing the Dynamic Table Factory protocol.
+*/
+STATIC
+CONST
+EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL DynamicTableFactoryProtocol = {
+ CREATE_REVISION (1, 0),
+ GetAcpiTableGenerator,
+ RegisterAcpiTableGenerator,
+ DeregisterAcpiTableGenerator,
+ GetSmbiosTableGenerator,
+ RegisterSmbiosTableGenerator,
+ DeregisterSmbiosTableGenerator,
+ GetDtTableGenerator,
+ RegisterDtTableGenerator,
+ DeregisterDtTableGenerator,
+ &TableFactoryInfo
+};
+
+/** Entrypoint for Dynamic Table Factory Dxe.
+
+ @param ImageHandle
+ @param SystemTable
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+ @retval EFI_NOT_FOUND Required interface/object was not found.
+ @retval EFI_INVALID_PARAMETER Some parameter is incorrect/invalid.
+**/
+EFI_STATUS
+EFIAPI
+DynamicTableFactoryDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gEdkiiDynamicTableFactoryProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID*)&DynamicTableFactoryProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to install the Dynamic Table Factory Protocol." \
+ " Status = %r\n",
+ Status
+ ));
+ }
+ return Status;
+}
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
new file mode 100644
index 0000000000..740811d0fc
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
@@ -0,0 +1,60 @@
+## @file
+# Module to manage the list of available table factories.
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = DynamicTableFactoryDxe
+ FILE_GUID = FE846898-7403-4932-B8AD-A0491F0C2CBA
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = DynamicTableFactoryDxeInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = ARM AARCH64
+#
+
+[Sources]
+ AcpiTableFactory/AcpiTableFactory.c
+ DeviceTreeTableFactory/DeviceTreeTableFactory.c
+ DynamicTableFactoryDxe.c
+ SmbiosTableFactory/SmbiosTableFactory.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ PrintLib
+ TableHelperLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[FixedPcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomACPIGenerators
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomSMBIOSGenerators
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomDTGenerators
+
+[Protocols]
+ gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEdkiiConfigurationManagerProtocolGuid
+ gEdkiiDynamicTableFactoryProtocolGuid
+
+[Depex]
+ TRUE
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c
new file mode 100644
index 0000000000..798cde4860
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c
@@ -0,0 +1,226 @@
+/** @file
+ SMBIOS Table Factory
+
+ Copyright (c) 2017 - 2019, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Std - Standard
+**/
+
+#include <IndustryStandard/SmBios.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+// Module specific include files.
+#include <SmbiosTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+
+#include "DynamicTableFactory.h"
+
+extern EDKII_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo;
+
+/** Return a pointer to the SMBIOS table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] GeneratorId The SMBIOS table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested SMBIOS table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+GetSmbiosTableGenerator (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST SMBIOS_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST SMBIOS_TABLE_GENERATOR ** CONST Generator
+ )
+{
+ UINT16 TableId;
+ EDKII_DYNAMIC_TABLE_FACTORY_INFO * FactoryInfo;
+
+ ASSERT (This != NULL);
+
+ FactoryInfo = This->TableFactoryInfo;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Invalid Generator pointer\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_SMBIOS (GeneratorId)) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Generator Type is not SMBIOS\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Generator = NULL;
+ TableId = GET_TABLE_ID (GeneratorId);
+ if (IS_GENERATOR_NAMESPACE_STD (GeneratorId)) {
+ if (TableId >= EStdSmbiosTableIdMax) {
+ ASSERT (TableId < EStdSmbiosTableIdMax);
+ return EFI_INVALID_PARAMETER;
+ }
+ if (FactoryInfo->StdSmbiosTableGeneratorList[TableId] != NULL) {
+ *Generator = FactoryInfo->StdSmbiosTableGeneratorList[TableId];
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (FactoryInfo->CustomSmbiosTableGeneratorList[TableId] != NULL) {
+ *Generator = FactoryInfo->CustomSmbiosTableGeneratorList[TableId];
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/** Register SMBIOS table factory generator.
+
+ The SMBIOS table factory maintains a list of the Standard and OEM SMBIOS
+ table generators.
+
+ @param [in] Generator Pointer to the SMBIOS table generator.
+
+ @retval EFI_SUCCESS The Generator was registered
+ successfully.
+ @retval EFI_INVALID_PARAMETER The Generator ID is invalid or
+ the Generator pointer is NULL.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID is
+ already registered.
+**/
+EFI_STATUS
+EFIAPI
+RegisterSmbiosTableGenerator (
+ IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator
+ )
+{
+ UINT16 TableId;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: SMBIOS register - Invalid Generator\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_SMBIOS (Generator->GeneratorID)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SMBIOS register - Generator" \
+ " Type is not SMBIOS\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((DEBUG_INFO, "Registering %s\n", Generator->Description));
+
+ TableId = GET_TABLE_ID (Generator->GeneratorID);
+ if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) {
+ if (TableId >= EStdSmbiosTableIdMax) {
+ ASSERT (TableId < EStdSmbiosTableIdMax);
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] == NULL) {
+ TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] = Generator;
+ } else {
+ return EFI_ALREADY_STARTED;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] == NULL) {
+ TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] = Generator;
+ } else {
+ return EFI_ALREADY_STARTED;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/** Deregister SMBIOS generator.
+
+ This function is called by the SMBIOS table generator to deregister itself
+ from the SMBIOS table factory.
+
+ @param [in] Generator Pointer to the SMBIOS table generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER The generator is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+DeregisterSmbiosTableGenerator (
+ IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator
+ )
+{
+ UINT16 TableId;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: SMBIOS deregister - Invalid Generator\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_SMBIOS (Generator->GeneratorID)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SMBIOS deregister - Generator" \
+ " Type is not SMBIOS\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TableId = GET_TABLE_ID (Generator->GeneratorID);
+ if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) {
+ if (TableId >= EStdSmbiosTableIdMax) {
+ ASSERT (TableId < EStdSmbiosTableIdMax);
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] != NULL) {
+ if (Generator != TableFactoryInfo.StdSmbiosTableGeneratorList[TableId]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] = NULL;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] != NULL) {
+ if (Generator !=
+ TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] = NULL;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "Deregistering %s\n", Generator->Description));
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 1cac3e649a..9803b345c6 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -18,3 +18,9 @@
[LibraryClasses.common]
TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
+[Components.common]
+ #
+ # Dynamic Table Factory Dxe
+ #
+ DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
+
diff --git a/DynamicTablesPkg/DynamicTables.fdf.inc b/DynamicTablesPkg/DynamicTables.fdf.inc
new file mode 100644
index 0000000000..4123c6a8b7
--- /dev/null
+++ b/DynamicTablesPkg/DynamicTables.fdf.inc
@@ -0,0 +1,20 @@
+## @file
+# fdf include file for Dynamic Tables Framework.
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+ #
+ # Dynamic Table Factory Dxe
+ #
+ INF DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
+
diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec b/DynamicTablesPkg/DynamicTablesPkg.dec
index 3137c14247..21e904ce1e 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dec
+++ b/DynamicTablesPkg/DynamicTablesPkg.dec
@@ -30,3 +30,14 @@
# Dynamic Table Factory Protocol GUID
gEdkiiDynamicTableFactoryProtocolGuid = { 0x91d1e327, 0xfe5a, 0x49b8, { 0xab, 0x65, 0xe, 0xce, 0x2d, 0xdb, 0x45, 0xec } }
+[PcdsFixedAtBuild]
+
+ # Maximum number of Custom ACPI Generators
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomACPIGenerators|1|UINT16|0xC0000001
+
+ # Maximum number of Custom SMBIOS Generators
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomSMBIOSGenerators|1|UINT16|0xC0000002
+
+ # Maximum number of Custom DT Generators
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomDTGenerators|1|UINT16|0xC0000003
+