| /** @file | |
| ACPI Table Factory | |
| Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| @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; | |
| } |