blob: 5b3e708fa8fa18b9e8a44371f0eec5af3b080bdf [file] [log] [blame]
/** @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;
}