diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c | 708 |
1 files changed, 708 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c b/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c new file mode 100644 index 00000000..a0c4a7fa --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c @@ -0,0 +1,708 @@ +/** @file + SSDT CMN-600 AML Table Generator. + + Copyright (c) 2020, Arm Limited. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Arm CoreLink CMN-600 Coherent Mesh Network Technical Reference Manual r3p0 + - Generic ACPI for Arm Components 1.0 Platform Design Document +**/ + +#include <IndustryStandard/DebugPort2Table.h> +#include <Library/AcpiLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Protocol/AcpiTable.h> + +// Module specific include files. +#include <AcpiTableGenerator.h> +#include <ConfigurationManagerObject.h> +#include <ConfigurationManagerHelper.h> +#include <Library/AmlLib/AmlLib.h> +#include <Library/TableHelperLib.h> +#include <Protocol/ConfigurationManagerProtocol.h> +#include "SsdtCmn600Generator.h" + +/** C array containing the compiled AML template. + This symbol is defined in the auto generated C file + containing the AML bytecode array. +*/ +extern CHAR8 ssdtcmn600template_aml_code[]; + +/** SSDT CMN-600 Table Generator. + + Requirements: + The following Configuration Manager Object(s) are required by + this Generator: + - EArmObjCmn600Info +*/ + +/** This macro expands to a function that retrieves the CMN-600 + Information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjCmn600Info, + CM_ARM_CMN_600_INFO + ); + +/** Check the CMN-600 Information. + + @param [in] Cmn600InfoList Array of CMN-600 information structure. + @param [in] Cmn600Count Count of CMN-600 information structure. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +ValidateCmn600Info ( + IN CONST CM_ARM_CMN_600_INFO * Cmn600InfoList, + IN CONST UINT32 Cmn600Count + ) +{ + UINT32 Index; + UINT32 DtcIndex; + CONST CM_ARM_CMN_600_INFO * Cmn600Info; + CONST CM_ARM_GENERIC_INTERRUPT * DtcInterrupt; + + if ((Cmn600InfoList == NULL) || + (Cmn600Count == 0)) { + return EFI_INVALID_PARAMETER; + } + + // Validate each Cmn600Info structure. + for (Index = 0; Index < Cmn600Count; Index++) { + Cmn600Info = &Cmn600InfoList[Index]; + + // At least one DTC is required. + if ((Cmn600Info->DtcCount == 0) || + (Cmn600Info->DtcCount > MAX_DTC_COUNT)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Invalid DTC configuration:\n" + )); + goto error_handler; + } + + // Check PERIPHBASE and ROOTNODEBASE address spaces are initialized. + if ((Cmn600Info->PeriphBaseAddress == 0) || + (Cmn600Info->RootNodeBaseAddress == 0)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Invalid PERIPHBASE or ROOTNODEBASE.\n" + )); + goto error_handler; + } + + // The PERIPHBASE address must be 64MB aligned for a (X < 4) && (Y < 4) + // dimension mesh, and 256MB aligned otherwise. + // Check it is a least 64MB aligned. + if ((Cmn600Info->PeriphBaseAddress & + (PERIPHBASE_MIN_ADDRESS_LENGTH - 1)) != 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: PERIPHBASE address must be 64MB aligned.\n" + )); + goto error_handler; + } + + // The PERIPHBASE address is at most 64MB for a (X < 4) && (Y < 4) + // dimension mesh, and 256MB otherwise. Check it is not more than 256MB. + if (Cmn600Info->PeriphBaseAddressLength > PERIPHBASE_MAX_ADDRESS_LENGTH) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: PERIPHBASE address range must be < 256MB.\n" + )); + goto error_handler; + } + + // Check the 16 KB alignment of the ROOTNODEBASE address. + if ((Cmn600Info->PeriphBaseAddress & + (ROOTNODEBASE_ADDRESS_LENGTH - 1)) != 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Root base address must be 16KB aligned.\n" + )); + goto error_handler; + } + + // The ROOTNODEBASE address space should be included in the PERIPHBASE + // address space. + if ((Cmn600Info->PeriphBaseAddress > Cmn600Info->RootNodeBaseAddress) || + ((Cmn600Info->PeriphBaseAddress + Cmn600Info->PeriphBaseAddressLength) < + (Cmn600Info->RootNodeBaseAddress + ROOTNODEBASE_ADDRESS_LENGTH))) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600:" + " ROOTNODEBASE address space not in PERIPHBASE address space.\n" + )); + goto error_handler; + } + + for (DtcIndex = 0; DtcIndex < Cmn600Info->DtcCount; DtcIndex++) { + DtcInterrupt = &Cmn600Info->DtcInterrupt[DtcIndex]; + if (((DtcInterrupt->Flags & + EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) == 0)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: DTC Interrupt must be consumer.\n" + )); + goto error_handler; + } + } // for DTC Interrupt + + } //for Cmn600InfoList + + return EFI_SUCCESS; + +error_handler: + + DEBUG (( + DEBUG_ERROR, + "PeriphBaseAddress = 0x%llx\n" + "PeriphBaseAddressLength = 0x%llx\n" + "RootNodeBaseAddress = 0x%llx\n" + "DtcCount = %u\n", + Cmn600Info->PeriphBaseAddress, + Cmn600Info->PeriphBaseAddressLength, + Cmn600Info->RootNodeBaseAddress, + Cmn600Info->DtcCount + )); + + DEBUG_CODE ( + for (DtcIndex = 0; DtcIndex < Cmn600Info->DtcCount; DtcIndex++) { + DtcInterrupt = &Cmn600Info->DtcInterrupt[DtcIndex]; + DEBUG (( + DEBUG_ERROR, + " DTC[%d]:\n", + DtcIndex + )); + DEBUG (( + DEBUG_ERROR, + " Interrupt = 0x%lx\n", + DtcInterrupt->Interrupt + )); + DEBUG (( + DEBUG_ERROR, + " Flags = 0x%lx\n", + DtcInterrupt->Flags + )); + } // for + ); + + return EFI_INVALID_PARAMETER; +} + +/** Build a SSDT table describing the CMN-600 device. + + The table created by this function must be freed by FreeSsdtCmn600Table. + + @param [in] Cmn600Info Pointer to a Cmn600 structure. + @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 CMN600 device. + @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. +**/ +STATIC +EFI_STATUS +EFIAPI +FixupCmn600Info ( + IN CONST CM_ARM_CMN_600_INFO * Cmn600Info, + IN CONST CHAR8 * Name, + IN CONST UINT64 Uid, + OUT EFI_ACPI_DESCRIPTION_HEADER ** Table + ) +{ + EFI_STATUS Status; + EFI_STATUS Status1; + UINT8 Index; + CONST CM_ARM_GENERIC_INTERRUPT * DtcInt; + + EFI_ACPI_DESCRIPTION_HEADER * SsdtCmn600Template; + AML_ROOT_NODE_HANDLE RootNodeHandle; + AML_OBJECT_NODE_HANDLE NameOpIdNode; + AML_OBJECT_NODE_HANDLE NameOpCrsNode; + AML_DATA_NODE_HANDLE CmnPeriphBaseRdNode; + AML_DATA_NODE_HANDLE CmnRootNodeBaseRdNode; + AML_OBJECT_NODE_HANDLE DeviceNode; + + // Parse the Ssdt CMN-600 Template. + SsdtCmn600Template = (EFI_ACPI_DESCRIPTION_HEADER*) + ssdtcmn600template_aml_code; + + RootNodeHandle = NULL; + Status = AmlParseDefinitionBlock ( + SsdtCmn600Template, + &RootNodeHandle + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to parse SSDT CMN-600 Template." + " Status = %r\n", + Status + )); + return Status; + } + + // Get the _UID NameOp object defined by the "Name ()" statement, + // and update its value. + Status = AmlFindNode ( + RootNodeHandle, + "\\_SB_.CMN0._UID", + &NameOpIdNode + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + Status = AmlNameOpUpdateInteger (NameOpIdNode, (UINT64)Uid); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Get the _CRS object defined by the "Name ()" statement. + Status = AmlFindNode ( + RootNodeHandle, + "\\_SB.CMN0._CRS", + &NameOpCrsNode + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Get the first Rd node in the "_CRS" object. + // This is the PERIPHBASE node. + Status = AmlNameOpCrsGetFirstRdNode (NameOpCrsNode, &CmnPeriphBaseRdNode); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + if (CmnPeriphBaseRdNode == NULL) { + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + + // Update the PERIPHBASE base address and length. + Status = AmlUpdateRdQWord ( + CmnPeriphBaseRdNode, + Cmn600Info->PeriphBaseAddress, + Cmn600Info->PeriphBaseAddressLength + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Get the QWord node corresponding to the ROOTNODEBASE. + // It is the second Resource Data element in the BufferNode's + // variable list of arguments. + Status = AmlNameOpCrsGetNextRdNode ( + CmnPeriphBaseRdNode, + &CmnRootNodeBaseRdNode + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + if (CmnRootNodeBaseRdNode == NULL) { + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + + // Update the ROOTNODEBASE base address and length. + Status = AmlUpdateRdQWord ( + CmnRootNodeBaseRdNode, + Cmn600Info->RootNodeBaseAddress, + ROOTNODEBASE_ADDRESS_LENGTH + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Add the Interrupt node(s). + // Generate Resource Data node(s) corresponding to the "Interrupt ()" + // ASL function and add it at the last position in the list of + // Resource Data nodes. + for (Index = 0; Index < Cmn600Info->DtcCount; Index++) { + DtcInt = &Cmn600Info->DtcInterrupt[Index]; + Status = AmlCodeGenCrsAddRdInterrupt ( + NameOpCrsNode, + ((DtcInt->Flags & + EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) != 0), + ((DtcInt->Flags & + EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK) != 0), + ((DtcInt->Flags & + EFI_ACPI_EXTENDED_INTERRUPT_FLAG_POLARITY_MASK) != 0), + ((DtcInt->Flags & + EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK) != 0), + (UINT32*)&DtcInt->Interrupt, + 1 + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + } // for + + // Fixup the CMN600 device name. + // This MUST be done at the end, otherwise AML paths won't be valid anymore. + // Get the CMN0 variable defined by the "Device ()" statement. + Status = AmlFindNode (RootNodeHandle, "\\_SB_.CMN0", &DeviceNode); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Update the CMN600 Device's name. + Status = AmlDeviceOpUpdateName (DeviceNode, (CHAR8*)Name); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Serialise the definition block + Status = AmlSerializeDefinitionBlock ( + RootNodeHandle, + Table + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to Serialize SSDT Table Data." + " Status = %r\n", + Status + )); + } + +error_handler: + // Cleanup + if (RootNodeHandle != NULL) { + Status1 = AmlDeleteTree (RootNodeHandle); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to cleanup AML tree." + " Status = %r\n", + Status1 + )); + // If Status was success but we failed to delete the AML Tree + // return Status1 else return the original error code, i.e. Status. + if (!EFI_ERROR (Status)) { + return Status1; + } + } + } + + return Status; +} + +/** Free any resources allocated for constructing the SSDT tables for CMN-600. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to an array of pointers + to ACPI Table(s). + @param [in] TableCount Number of ACPI table(s). + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +FreeSsdtCmn600TableResourcesEx ( + IN CONST ACPI_TABLE_GENERATOR * CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER *** CONST Table, + IN CONST UINTN TableCount + ) +{ + EFI_ACPI_DESCRIPTION_HEADER ** TableList; + UINTN Index; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + if ((Table == NULL) || + (*Table == NULL) || + (TableCount == 0)) { + DEBUG ((DEBUG_ERROR, "ERROR: SSDT-CMN-600: Invalid Table Pointer\n")); + return EFI_INVALID_PARAMETER; + } + + TableList = *Table; + + for (Index = 0; Index < TableCount; Index++) { + if ((TableList[Index] != NULL) && + (TableList[Index]->Signature == + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) { + FreePool (TableList[Index]); + } else { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Could not free SSDT table at index %d." + " Status = %r\n", + Index, + EFI_INVALID_PARAMETER + )); + return EFI_INVALID_PARAMETER; + } + } //for + + // Free the table list. + FreePool (*Table); + *Table = NULL; + return EFI_SUCCESS; +} + +/** Construct SSDT tables for describing CMN-600 meshes. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResourcesEx function. + + @param [in] This Pointer to the ACPI table generator. + @param [in] AcpiTableInfo Pointer to the ACPI table information. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [out] Table Pointer to a list of generated ACPI table(s). + @param [out] TableCount Number of generated ACPI table(s). + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for + the requested object. + @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. + @retval EFI_UNSUPPORTED Unsupported configuration. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildSsdtCmn600TableEx ( + IN CONST ACPI_TABLE_GENERATOR * This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER *** Table, + OUT UINTN * CONST TableCount + ) +{ + EFI_STATUS Status; + UINT64 Index; + CM_ARM_CMN_600_INFO * Cmn600Info; + UINT32 Cmn600Count; + CHAR8 NewName[5]; + EFI_ACPI_DESCRIPTION_HEADER ** TableList; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (TableCount != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + *Table = NULL; + + // Get CMN-600 information. + Status = GetEArmObjCmn600Info ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &Cmn600Info, + &Cmn600Count + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to get the CMN-600 information." + " Status = %r\n", + Status + )); + return Status; + } + + if ((Cmn600Count == 0) || (Cmn600Count > MAX_CMN600_DEVICES_SUPPORTED)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: CMN600 peripheral count = %d." + " This must be between 1 to 16.\n", + Cmn600Count + )); + return EFI_INVALID_PARAMETER; + } + + // Validate the CMN-600 Info. + Status = ValidateCmn600Info (Cmn600Info, Cmn600Count); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Invalid CMN600 information. Status = %r\n", + Status + )); + return Status; + } + + // Allocate a table to store pointers to the SSDT tables. + TableList = (EFI_ACPI_DESCRIPTION_HEADER**) + AllocateZeroPool ( + (sizeof (EFI_ACPI_DESCRIPTION_HEADER*) * Cmn600Count) + ); + if (TableList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to allocate memory for Table List." + " Status = %r\n", + Status + )); + return Status; + } + + // Setup the table list early so that that appropriate cleanup + // can be done in case of failure. + *Table = TableList; + + NewName[0] = 'C'; + NewName[1] = 'M'; + NewName[2] = 'N'; + NewName[4] = '\0'; + for (Index = 0; Index < Cmn600Count; Index++) { + NewName[3] = AsciiFromHex ((UINT8)(Index)); + + // Build a SSDT table describing the CMN600 device. + Status = FixupCmn600Info ( + &Cmn600Info[Index], + NewName, + Index, + &TableList[Index] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-CMN-600: Failed to build associated SSDT table." + " Status = %r\n", + Status + )); + break; + } + + // Increment the table count here so that appropriate clean-up + // can be done in case of failure. + *TableCount += 1; + } // for + + // Note: Table list and CMN600 device count has been setup. The + // framework will invoke FreeSsdtCmn600TableResourcesEx() even + // on failure, so appropriate clean-up will be done. + return Status; +} + +/** This macro defines the Raw Generator revision. +*/ +#define SSDT_CMN_600_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the Raw Table Generator. +*/ +STATIC +CONST +ACPI_TABLE_GENERATOR SsdtCmn600Generator = { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtCmn600), + // Generator Description + L"ACPI.STD.SSDT.CMN600.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + // ACPI Table Revision - Unused + 0, + // Minimum ACPI Table Revision - Unused + 0, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + SSDT_CMN_600_GENERATOR_REVISION, + // Build table function. Use the extended version instead. + NULL, + // Free table function. Use the extended version instead. + NULL, + // Build Table function + BuildSsdtCmn600TableEx, + // Free Resource function + FreeSsdtCmn600TableResourcesEx +}; + +/** Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiSsdtCmn600LibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&SsdtCmn600Generator); + DEBUG (( + DEBUG_INFO, + "SSDT-CMN-600: Register Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiSsdtCmn600LibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&SsdtCmn600Generator); + DEBUG (( + DEBUG_INFO, + "SSDT-CMN-600: Deregister Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; +} |