summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbdul Lateef Attar <AbdulLateef.Attar@amd.com>2024-09-25 09:45:19 +0300
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-10-03 11:58:50 +0300
commitf962adc8a089949ecc730ba17f08234b52e3952d (patch)
treef9b6c9911c84481098dcd67789a0e390aa388615
parent0958b762fb1858f9ddf8c1e55fe853a3ee7e3461 (diff)
downloadedk2-f962adc8a089949ecc730ba17f08234b52e3952d.tar.xz
DynamicTablesPkg: Adds SPMI table generator
Adds ACPI SPMI table generator library. Updates acpi standard table enum with spmi. Updates arch common namespace object and parser. Updates the Readme. Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Zhiguang Liu <zhiguang.liu@intel.com> Cc: Sami Mujawar <Sami.Mujawar@arm.com> Cc: Pierre Gondois <pierre.gondois@arm.com> Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
-rw-r--r--DynamicTablesPkg/DynamicTables.dsc.inc5
-rw-r--r--DynamicTablesPkg/DynamicTablesPkg.ci.yaml1
-rwxr-xr-x[-rw-r--r--]DynamicTablesPkg/Include/AcpiTableGenerator.h4
-rwxr-xr-x[-rw-r--r--]DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h37
-rwxr-xr-xDynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/AcpiSpmiLib.inf29
-rwxr-xr-xDynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/SpmiGenerator.c390
-rwxr-xr-x[-rw-r--r--]DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c20
-rw-r--r--DynamicTablesPkg/Readme.md2
8 files changed, 488 insertions, 0 deletions
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index c9bfa756c7..99424b0d50 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -17,6 +17,7 @@
[LibraryClasses.common]
AcpiHelperLib|DynamicTablesPkg/Library/Common/AcpiHelperLib/AcpiHelperLib.inf
AmlLib|DynamicTablesPkg/Library/Common/AmlLib/AmlLib.inf
+ IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf
SsdtPcieSupportLib|DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.inf
SsdtSerialPortFixupLib|DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf
TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
@@ -38,6 +39,7 @@
DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf
DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf
DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf
+ DynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/AcpiSpmiLib.inf
# AML Fixup (Common)
DynamicTablesPkg/Library/Acpi/Common/AcpiSsdtSerialPortLib/SsdtSerialPortLib.inf
@@ -67,6 +69,8 @@
# Generators
# Common
NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiFadtLib/AcpiFadtLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/AcpiSpmiLib.inf
+ # X64 specific
NULL|DynamicTablesPkg/Library/Acpi/X64/AcpiWsmtLib/AcpiWsmtLib.inf
NULL|DynamicTablesPkg/Library/Acpi/X64/AcpiHpetLib/AcpiHpetLib.inf
NULL|DynamicTablesPkg/Library/Acpi/X64/AcpiSsdtHpetLib/AcpiSsdtHpetLib.inf
@@ -97,6 +101,7 @@
NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiPpttLib/AcpiPpttLib.inf
NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiRawLib/AcpiRawLib.inf
NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSpcrLib/AcpiSpcrLib.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/AcpiSpmiLib.inf
NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiSratLib/AcpiSratLib.inf
NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf
# Arm specific
diff --git a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
index f7c8897fcb..5f2c6e8fb6 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
+++ b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
@@ -104,6 +104,7 @@
"CCIDX",
"CCSIDR",
"countof",
+ "deviceid",
"EArch",
"edynamic",
"EOBJECT",
diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h
index 69c012e675..6387bf3f0a 100644..100755
--- a/DynamicTablesPkg/Include/AcpiTableGenerator.h
+++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h
@@ -75,6 +75,9 @@ The Dynamic Tables Framework implements the following ACPI table generators:
SSDT table describing a Pci Express bus.
- WSMT : The WSMT generator collates the WSMT protection flag information
from the Configuration Manager and builds the WSMT table.
+ - SPMI : The SPMI generator collects the SPMI interface and
+ optionally SPMI interrupt and deviceid (or uid) information from the
+ Configuration Manager and builds the SPMI table.
*/
/** The ACPI_TABLE_GENERATOR_ID type describes ACPI table generator ID.
@@ -107,6 +110,7 @@ typedef enum StdAcpiTableId {
EStdAcpiTableIdWsmt, ///< WSMT Generator
EStdAcpiTableIdHpet, ///< HPET Generator
EStdAcpiTableIdSsdtHpet, ///< SSDT HPET Generator
+ EStdAcpiTableIdSpmi, ///< SPMI Generator
EStdAcpiTableIdMax
} ESTD_ACPI_TABLE_ID;
diff --git a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h
index 4b83e53b4d..91514ee8dd 100644..100755
--- a/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArchCommonNameSpaceObjects.h
@@ -2,6 +2,7 @@
Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.<BR>
+ Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -50,6 +51,8 @@ typedef enum ArchCommonObjectID {
EArchCommonObjPccSubspaceType5Info, ///< 24 - Pcc Subspace Type 5 Info
EArchCommonObjPsdInfo, ///< 25 - P-State Dependency (PSD) Info
EArchCommonObjTpm2InterfaceInfo, ///< 26 - TPM Interface Info
+ EArchCommonObjSpmiInterfaceInfo, ///< 27 - SPMI Interface Info
+ EArchCommonObjSpmiInterruptDeviceInfo, ///< 28 - SPMI Interrupt and Device Info
EArchCommonObjMax
} EARCH_COMMON_OBJECT_ID;
@@ -691,6 +694,40 @@ typedef struct CmArchCommonTpm2InterfaceInfo {
UINT64 Lasa;
} CM_ARCH_COMMON_TPM2_INTERFACE_INFO;
+/** A structure that describes the
+ SPMI (Service Processor Management Interface) Info.
+
+ ID: EArchCommonObjSpmiInterfaceInfo
+*/
+typedef struct CmArchCommonObjSpmiInterfaceInfo {
+ /** Interface type */
+ UINT8 InterfaceType;
+
+ /** Base address */
+ EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE BaseAddress;
+} CM_ARCH_COMMON_SPMI_INTERFACE_INFO;
+
+/** A structure that describes the
+ SPMI (Service Processor Management Interface) Interrupt and Device Info.
+
+ ID: EArchCommonObjSpmiInterruptDeviceInfo
+*/
+typedef struct CmArchCommonObjSpmiInterruptDeviceInfo {
+ /** Interrupt type */
+ UINT8 InterruptType;
+
+ /** GPE number */
+ UINT8 Gpe;
+
+ /** PCI device flag */
+ UINT8 PciDeviceFlag;
+
+ /** GSI number */
+ UINT32 GlobalSystemInterrupt;
+
+ /** Uid of the device */
+ UINT32 DeviceId;
+} CM_ARCH_COMMON_SPMI_INTERRUPT_DEVICE_INFO;
#pragma pack()
#endif // ARCH_COMMON_NAMESPACE_OBJECTS_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/AcpiSpmiLib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/AcpiSpmiLib.inf
new file mode 100755
index 0000000000..e6796dcb6f
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/AcpiSpmiLib.inf
@@ -0,0 +1,29 @@
+## @file
+# SPMI Table Generator
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.30
+ BASE_NAME = AcpiSpmiLib
+ FILE_GUID = 31307BFF-BA0E-42C3-BD73-6C482740120D
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = NULL|DXE_DRIVER
+ CONSTRUCTOR = AcpiSpmiLibConstructor
+ DESTRUCTOR = AcpiSpmiLibDestructor
+
+[Sources]
+ SpmiGenerator.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ IpmiCommandLib
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/SpmiGenerator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/SpmiGenerator.c
new file mode 100755
index 0000000000..af46bb6c1e
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiSpmiLib/SpmiGenerator.c
@@ -0,0 +1,390 @@
+/** @file
+ SPMI Table Generator
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - IPMI - Revision 2.0, April 21, 2015.
+
+**/
+
+#include <IndustryStandard/ServiceProcessorManagementInterfaceTable.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <IndustryStandard/IpmiNetFnApp.h>
+#include <Library/IpmiCommandLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** Standard SPMI Generator
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArchCommonObjSpmiInterfaceInfo
+ - EArchCommonObjSpmiInterruptDeviceInfo (OPTIONAL)
+*/
+
+/** Retrieve the SPMI interface information. */
+GET_OBJECT_LIST (
+ EObjNameSpaceArchCommon,
+ EArchCommonObjSpmiInterfaceInfo,
+ CM_ARCH_COMMON_SPMI_INTERFACE_INFO
+ );
+
+/** Retrieve the SPMI interrupt and device information. */
+GET_OBJECT_LIST (
+ EObjNameSpaceArchCommon,
+ EArchCommonObjSpmiInterruptDeviceInfo,
+ CM_ARCH_COMMON_SPMI_INTERRUPT_DEVICE_INFO
+ );
+
+STATIC
+EFI_ACPI_SERVICE_PROCESSOR_MANAGEMENT_INTERFACE_TABLE AcpiSpmi = {
+ ACPI_HEADER (
+ EFI_ACPI_6_5_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE,
+ EFI_ACPI_SERVICE_PROCESSOR_MANAGEMENT_INTERFACE_TABLE,
+ EFI_ACPI_SERVICE_PROCESSOR_MANAGEMENT_INTERFACE_5_TABLE_REVISION
+ ),
+ /// Interface Type
+ /// 0 - Reserved
+ /// 1 - KCS
+ /// 2 - SMIC
+ /// 3 - BT
+ /// 4 - SSIF
+ /// 5-255 - Reserved
+ 0x00,
+ /// Reserved1, must be 0x01 as per the IPMI specification.
+ 0x01,
+ /// Specification Revision
+ 0x0200,
+ /// Interrupt Type
+ 0x00,
+ /// GPE Number
+ 0x00,
+ /// Reserved2
+ 0x00,
+ /// PCI device flag
+ 0x00,
+ /// Global System Interrupt
+ 0x00,
+ /// Base Address
+ { 0, 0,0, 0, 0 },
+ /// Device ID
+ {
+ { 0x00 }
+ },
+ /// Reserved3
+ 0x00
+};
+
+/** Construct the SPMI ACPI table.
+
+ 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 FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildSpmiTable (
+ 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,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table
+ )
+{
+ EFI_STATUS Status;
+ CM_ARCH_COMMON_SPMI_INTERFACE_INFO *SpmiInfo;
+ CM_ARCH_COMMON_SPMI_INTERRUPT_DEVICE_INFO *SpmiIntrDeviceInfo;
+ IPMI_GET_DEVICE_ID_RESPONSE DeviceId;
+
+ ASSERT (This != NULL);
+ ASSERT (AcpiTableInfo != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Table != NULL);
+ ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+ ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+ if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
+ (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: Requested table revision = %d, is not supported."
+ "Supported table revision: Minimum = %d, Maximum = %d\n",
+ AcpiTableInfo->AcpiTableRevision,
+ This->MinAcpiTableRevision,
+ This->AcpiTableRevision
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Table = NULL;
+
+ Status = GetEArchCommonObjSpmiInterfaceInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &SpmiInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: Failed to retrieve interface type and base address.\n"
+ ));
+ return Status;
+ }
+
+ /// Validate interface type.
+ if ((SpmiInfo->InterfaceType < EFI_ACPI_SPMI_INTERFACE_TYPE_KCS) ||
+ (SpmiInfo->InterfaceType > EFI_ACPI_SPMI_INTERFACE_TYPE_SSIF))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: The Interface Type is invalid. Type = %d\n",
+ SpmiInfo->InterfaceType
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ /// If the interface type is SSIF, the Address Space ID should be SMBUS.
+ if ((SpmiInfo->InterfaceType == EFI_ACPI_SPMI_INTERFACE_TYPE_SSIF) &&
+ (SpmiInfo->BaseAddress.AddressSpaceId != EFI_ACPI_6_5_SMBUS))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: Invalid Address Space ID for SSIF. ID = %d\n",
+ SpmiInfo->BaseAddress.AddressSpaceId
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ /// For non-ssif interface types, the Address Space ID should be System Memory or System I/O.
+ if ((SpmiInfo->InterfaceType != EFI_ACPI_SPMI_INTERFACE_TYPE_SSIF) &&
+ ((SpmiInfo->BaseAddress.AddressSpaceId != EFI_ACPI_6_5_SYSTEM_MEMORY) &&
+ (SpmiInfo->BaseAddress.AddressSpaceId != EFI_ACPI_6_5_SYSTEM_IO)))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: Invalid Address Space ID. ID = %d\n",
+ SpmiInfo->BaseAddress.AddressSpaceId
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetEArchCommonObjSpmiInterruptDeviceInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &SpmiIntrDeviceInfo,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ /// Validate Interrupt Type, bit[7:2] should be zero.
+ if ((SpmiIntrDeviceInfo->InterruptType >> 2) != 0 ) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: The Interrupt Type has non-zero reserved bits. InterruptType = 0x%x\n",
+ SpmiIntrDeviceInfo->InterruptType
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (SpmiInfo->InterfaceType == EFI_ACPI_SPMI_INTERFACE_TYPE_SSIF) {
+ /// Interrupt Type bit[0] should be zero for SSIF interface type.
+ if ((SpmiIntrDeviceInfo->InterruptType & BIT0) != 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: The Interrupt Type bit0 should be zero for SSIF interface type.\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ /// PCI device flag bit0 should be zero for SSIF interface type.
+ if ((SpmiIntrDeviceInfo->PciDeviceFlag & BIT0) != 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: PCI Device Flag is invalid for SSIF interface type.\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ /// Validate SCI GPE bit if GPE number is provided.
+ if ((SpmiIntrDeviceInfo->Gpe != 0) &&
+ ((SpmiIntrDeviceInfo->InterruptType & BIT0) == 0))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: The Interrupt Type bit0 should be set if a GPE number is provided.\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ /// If GlobalSystemInterrupt is provided, the interrupt type should be GSI.
+ if ((SpmiIntrDeviceInfo->GlobalSystemInterrupt != 0) &&
+ ((SpmiIntrDeviceInfo->InterruptType & BIT1) == 0))
+ {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: Invalid interrupt type = 0x%x for GSI 0x%x\n",
+ SpmiIntrDeviceInfo->InterruptType,
+ SpmiIntrDeviceInfo->GlobalSystemInterrupt
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AcpiSpmi.InterruptType = SpmiIntrDeviceInfo->InterruptType;
+ AcpiSpmi.Gpe = SpmiIntrDeviceInfo->Gpe;
+ AcpiSpmi.PciDeviceFlag = SpmiIntrDeviceInfo->PciDeviceFlag;
+ AcpiSpmi.GlobalSystemInterrupt = SpmiIntrDeviceInfo->GlobalSystemInterrupt;
+ AcpiSpmi.DeviceId.Uid = SpmiIntrDeviceInfo->DeviceId;
+ } else {
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: SPMI: The platform does not provide interrupt and PCI device information.\n"
+ ));
+ DEBUG ((
+ DEBUG_INFO,
+ "Using default values (0) for the interrupt and PCI device information.\n"
+ ));
+ }
+
+ /// Update IPMI specification version
+ Status = IpmiGetDeviceId (&DeviceId);
+ if (!EFI_ERROR (Status) && (DeviceId.CompletionCode == IPMI_COMP_CODE_NORMAL)) {
+ AcpiSpmi.SpecificationRevision = DeviceId.SpecificationVersion & 0xF0;
+ AcpiSpmi.SpecificationRevision |= (DeviceId.SpecificationVersion & 0xF) << 8;
+ }
+
+ AcpiSpmi.InterfaceType = SpmiInfo->InterfaceType;
+ CopyMem (
+ &AcpiSpmi.BaseAddress,
+ &SpmiInfo->BaseAddress,
+ sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE)
+ );
+
+ Status = AddAcpiHeader (
+ CfgMgrProtocol,
+ This,
+ (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiSpmi,
+ AcpiTableInfo,
+ sizeof (EFI_ACPI_SERVICE_PROCESSOR_MANAGEMENT_INTERFACE_TABLE)
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPMI: Failed to add ACPI header. Status = %r\n",
+ Status
+ ));
+ }
+
+ *Table = (EFI_ACPI_DESCRIPTION_HEADER *)&AcpiSpmi;
+ return Status;
+}
+
+/** This macro defines the SPMI Table Generator revision.
+*/
+#define SPMI_GENERATOR_REVISION CREATE_REVISION (1, 0)
+
+/** The interface for the SPMI Table Generator.
+*/
+STATIC
+CONST
+ACPI_TABLE_GENERATOR SpmiGenerator = {
+ // Generator ID
+ CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpmi),
+ // Generator Description
+ L"ACPI.STD.SPMI.GENERATOR",
+ // ACPI Table Signature
+ EFI_ACPI_6_5_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE,
+ // ACPI Table Revision supported by this Generator
+ EFI_ACPI_SERVICE_PROCESSOR_MANAGEMENT_INTERFACE_5_TABLE_REVISION,
+ // Minimum supported ACPI Table Revision
+ EFI_ACPI_SERVICE_PROCESSOR_MANAGEMENT_INTERFACE_5_TABLE_REVISION,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID,
+ // Creator Revision
+ SPMI_GENERATOR_REVISION,
+ // Build Table function
+ BuildSpmiTable,
+ // Free Resource function
+ NULL,
+ // Extended build function not needed
+ NULL,
+ // Extended build function not implemented by the generator.
+ // Hence extended free resource function is not required.
+ NULL
+};
+
+/** 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
+AcpiSpmiLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = RegisterAcpiTableGenerator (&SpmiGenerator);
+ DEBUG ((DEBUG_INFO, "SPMI: 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
+AcpiSpmiLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = DeregisterAcpiTableGenerator (&SpmiGenerator);
+ DEBUG ((DEBUG_INFO, "SPMI: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
index 0f74f3d6b9..6dc48abb81 100644..100755
--- a/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/ConfigurationManagerObjectParser.c
@@ -677,6 +677,24 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonTpm2InterfaceInfo[] = {
{ "Lasa", sizeof (UINT64), "0x%llx", NULL },
};
+/** A parser for EArchCommonObjSpmiInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmArchCommonSpmiInterfaceInfoParser[] = {
+ { "InterfaceType", sizeof (UINT8), "0x%x", NULL },
+ { "BaseAddress", sizeof (EFI_ACPI_6_5_GENERIC_ADDRESS_STRUCTURE),
+ NULL, NULL, AcpiGenericAddressParser }
+};
+
+/** A parser for EArchCommonObjSpmiInterruptDeviceInfo.
+*/
+STATIC CONST CM_OBJ_PARSER CmArchCommonSpmiInterruptDeviceInfoParser[] = {
+ { "InterruptType", sizeof (UINT8), "0x%x", NULL },
+ { "GPE", sizeof (UINT8), "0x%x", NULL },
+ { "PciDeviceFlag", sizeof (UINT8), "0x%x", NULL },
+ { "GlobalSystemInterrupt", sizeof (UINT32), "0x%x", NULL },
+ { "DeviceId", sizeof (UINT32), "0x%x", NULL }
+};
+
/** A parser for Arch Common namespace objects.
*/
STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = {
@@ -707,6 +725,8 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = {
CM_PARSER_ADD_OBJECT (EArchCommonObjPccSubspaceType5Info, CmArchCommonPccSubspaceType5InfoParser),
CM_PARSER_ADD_OBJECT (EArchCommonObjPsdInfo, CmArchCommonPsdInfoParser),
CM_PARSER_ADD_OBJECT (EArchCommonObjTpm2InterfaceInfo, CmArchCommonTpm2InterfaceInfo),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjSpmiInterfaceInfo, CmArchCommonSpmiInterfaceInfoParser),
+ CM_PARSER_ADD_OBJECT (EArchCommonObjSpmiInterruptDeviceInfo, CmArchCommonSpmiInterruptDeviceInfoParser),
CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax)
};
diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md
index 7a3d499af8..3d08596963 100644
--- a/DynamicTablesPkg/Readme.md
+++ b/DynamicTablesPkg/Readme.md
@@ -498,6 +498,8 @@ The CM_OBJECT_ID type is used to identify the Configuration Manager
| 24 | Pcc Subspace Type 5 Info | |
| 25 | P-State Dependency (PSD) Info | |
| 26 | TPM Interface Info | |
+| 27 | SPMI Interface Info | |
+| 28 | SPMI Interrupt and Device/Uid Info | |
| `*` | All other values are reserved. | |
#### Object ID's in the X64 Namespace: