summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BaseTools/Source/Python/FMMT/core/FvHandler.py26
-rw-r--r--DynamicTablesPkg/DynamicTables.dsc.inc1
-rw-r--r--DynamicTablesPkg/DynamicTablesPkg.ci.yaml3
-rw-r--r--DynamicTablesPkg/DynamicTablesPkg.dec6
-rw-r--r--DynamicTablesPkg/DynamicTablesPkg.dsc1
-rw-r--r--DynamicTablesPkg/Include/Library/Tpm2DeviceTableLib.h50
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf5
-rw-r--r--DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c251
-rw-r--r--DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableLib.c329
-rw-r--r--DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableLib.inf33
-rw-r--r--DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableTemplate.asl44
-rw-r--r--MdeModulePkg/MdeModulePkg.dec9
-rw-r--r--UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c1
13 files changed, 701 insertions, 58 deletions
diff --git a/BaseTools/Source/Python/FMMT/core/FvHandler.py b/BaseTools/Source/Python/FMMT/core/FvHandler.py
index 6d6a9c2..12d52c1 100644
--- a/BaseTools/Source/Python/FMMT/core/FvHandler.py
+++ b/BaseTools/Source/Python/FMMT/core/FvHandler.py
@@ -237,11 +237,20 @@ class FvHandler:
Size_delta = len(CompressedData) - len(TargetTree.Data.OriData)
ChangeSize(TargetTree, -Size_delta)
if TargetTree.NextRel:
+ Original_Pad_Size = len(TargetTree.Data.PadData)
TargetTree.Data.PadData = b'\x00' * New_Pad_Size
- self.Remain_New_Free_Space = len(TargetTree.Data.OriData) + len(TargetTree.Data.PadData) - len(CompressedData) - New_Pad_Size
+ self.Remain_New_Free_Space = (
+ len(TargetTree.Data.OriData) +
+ Original_Pad_Size -
+ len(CompressedData) -
+ New_Pad_Size
+ )
else:
TargetTree.Data.PadData = b''
- self.Remain_New_Free_Space = len(TargetTree.Data.OriData) - len(CompressedData)
+ self.Remain_New_Free_Space = (
+ len(TargetTree.Data.OriData) -
+ len(CompressedData)
+ )
TargetTree.Data.OriData = CompressedData
elif len(CompressedData) == len(TargetTree.Data.OriData):
TargetTree.Data.OriData = CompressedData
@@ -347,15 +356,24 @@ class FvHandler:
ModifySectionType(ParTree)
Needed_Space += ParTree.Data.HeaderLength - OriHeaderLen
# Update needed space with Delta_Pad_Size
+ Original_Pad_Size = len(ParTree.Data.PadData)
if ParTree.NextRel:
New_Pad_Size = GetPadSize(ParTree.Data.Size, SECTION_COMMON_ALIGNMENT)
- Delta_Pad_Size = New_Pad_Size - len(ParTree.Data.PadData)
+ Delta_Pad_Size = New_Pad_Size - Original_Pad_Size
ParTree.Data.PadData = b'\x00' * New_Pad_Size
Needed_Space += Delta_Pad_Size
else:
ParTree.Data.PadData = b''
if Needed_Space < 0:
- self.Remain_New_Free_Space = len(ParTree.Data.OriData) - len(CompressedData)
+ if ParTree.NextRel:
+ self.Remain_New_Free_Space = (
+ len(ParTree.Data.OriData) + Original_Pad_Size -
+ len(CompressedData) - New_Pad_Size
+ )
+ else:
+ self.Remain_New_Free_Space = (
+ len(ParTree.Data.OriData) - len(CompressedData)
+ )
# If current section is not guided section
elif Needed_Space:
ChangeSize(ParTree, -Needed_Space)
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 95b6407..d8c92de 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -25,6 +25,7 @@
SmbiosStringTableLib|DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf
MetadataObjLib|DynamicTablesPkg/Library/Common/MetadataObjLib/MetadataObjLib.inf
MetadataHandlerLib|DynamicTablesPkg/Library/Common/MetadataHandlerLib/MetadataHandlerLib.inf
+ Tpm2DeviceTableLib|DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableLib.inf
[LibraryClasses.AARCH64]
DynamicTablesScmiInfoLib|DynamicTablesPkg/Library/DynamicTablesScmiInfoLib/DynamicTablesScmiInfoLib.inf
diff --git a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
index 5c4efb4..56069e2 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
+++ b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
@@ -54,7 +54,8 @@
"EmbeddedPkg/EmbeddedPkg.dec",
"DynamicTablesPkg/DynamicTablesPkg.dec",
"MdeModulePkg/MdeModulePkg.dec",
- "MdePkg/MdePkg.dec"
+ "MdePkg/MdePkg.dec",
+ "SecurityPkg/SecurityPkg.dec"
],
# For host based unit tests
"AcceptableDependencies-HOST_APPLICATION":[
diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec b/DynamicTablesPkg/DynamicTablesPkg.dec
index 87934c5..71e76e6 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dec
+++ b/DynamicTablesPkg/DynamicTablesPkg.dec
@@ -52,6 +52,9 @@
## @libraryclass Defines a set of APIs to a handle Metadata generation/validation.
MetadataHandlerLib|Include/Library/MetadataHandlerLib.h
+ ## @libraryclass Defines a set of methods for generating Tpm2 Device Table method.
+ Tpm2DeviceTableLib|Include/Library/Tpm2DeviceTableLib.h
+
[LibraryClasses.AARCH64]
## @libraryclass Defines a set of APIs to populate CmObj using SCMI.
DynamicTablesScmiInfoLib|Include/Library/DynamicTablesScmiInfoLib.h
@@ -84,5 +87,8 @@
# BIT0: Allow the absence of some registers in the _CPC object.
gEdkiiDynamicTablesPkgTokenSpaceGuid.PcdDevelopmentPlatformRelaxations|0|UINT64|0x4000000A
+ # Generate Tpm2 device table when generate TPM2 acpi table together.
+ gEdkiiDynamicTablesPkgTokenSpaceGuid.PcdGenTpm2DeviceTable|FALSE|BOOLEAN|0x4000000B
+
[Guids]
gEdkiiDynamicTablesPkgTokenSpaceGuid = { 0xab226e66, 0x31d8, 0x4613, { 0x87, 0x9d, 0xd2, 0xfa, 0xb6, 0x10, 0x26, 0x3c } }
diff --git a/DynamicTablesPkg/DynamicTablesPkg.dsc b/DynamicTablesPkg/DynamicTablesPkg.dsc
index 823b3fe..d8c0477 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dsc
+++ b/DynamicTablesPkg/DynamicTablesPkg.dsc
@@ -51,6 +51,7 @@
DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf
DynamicTablesPkg/Library/Common/MetadataObjLib/MetadataObjLib.inf
DynamicTablesPkg/Library/Common/MetadataHandlerLib/MetadataHandlerLib.inf
+ DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableLib.inf
[Components.ARM, Components.AARCH64]
DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf
diff --git a/DynamicTablesPkg/Include/Library/Tpm2DeviceTableLib.h b/DynamicTablesPkg/Include/Library/Tpm2DeviceTableLib.h
new file mode 100644
index 0000000..5da8117
--- /dev/null
+++ b/DynamicTablesPkg/Include/Library/Tpm2DeviceTableLib.h
@@ -0,0 +1,50 @@
+/** @file
+ Tpm2 device table generating Library
+
+ Copyright (c) 2025, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef TPM2_DEVICE_TABLE_LIB_H_
+#define TPM2_DEVICE_TABLE_LIB_H_
+
+/** Build a SSDT table describing the TPM2 device.
+
+ The table created by this function must be freed by FreeTpm2DeviceTable.
+
+ @param [in] TpmDevInfo TPM2 Device info to describe in the SSDT table.
+ @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 TPM@ 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.
+**/
+EFI_STATUS
+EFIAPI
+BuildTpm2DeviceTable (
+ IN CONST CM_ARCH_COMMON_TPM2_DEVICE_INFO *TpmDevInfo,
+ IN CONST CHAR8 *Name,
+ IN CONST UINT64 Uid,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **Table
+ );
+
+/** Free an Tpm2 device table previously created by
+ the BuildTpm2DeviceTable function.
+
+ @param [in] Table Pointer to a Tpm2 Device table allocated by
+ the BuildTpm2DeviceTable function.
+
+**/
+VOID
+EFIAPI
+FreeTpm2DeviceTable (
+ IN EFI_ACPI_DESCRIPTION_HEADER *Table
+ );
+
+#endif // TPM2_DEVICE_TABLE_LIB_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf
index ee50fc6..1623e4d 100644
--- a/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/AcpiTpm2Lib.inf
@@ -26,4 +26,9 @@
MdePkg/MdePkg.dec
[LibraryClasses]
+ AcpiHelperLib
BaseLib
+ Tpm2DeviceTableLib
+
+[FixedPcd]
+ gEdkiiDynamicTablesPkgTokenSpaceGuid.PcdGenTpm2DeviceTable
diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c
index c743e20..9e39eb5 100644
--- a/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c
+++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiTpm2Lib/Tpm2Generator.c
@@ -20,13 +20,16 @@
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
#include <Protocol/AcpiTable.h>
// Module specific include files.
#include <AcpiTableGenerator.h>
#include <ConfigurationManagerObject.h>
#include <ConfigurationManagerHelper.h>
+#include <Library/AcpiHelperLib.h>
#include <Library/TableHelperLib.h>
+#include <Library/Tpm2DeviceTableLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>
#include <IndustryStandard/Tpm2Acpi.h>
@@ -35,6 +38,9 @@
#define START_METHOD_CRB_WITH_SMC_PARAM_SIZE 12
#define START_METHOD_CRB_WITH_FFA_PARM_SIZE 12
+#define TPM2_DEVICE_UID 0
+#define MAX_TABLE_COUNT 2
+
/**
ARM standard TPM2 Generator
@@ -53,6 +59,12 @@ GET_OBJECT_LIST (
CM_ARCH_COMMON_TPM2_INTERFACE_INFO
);
+GET_OBJECT_LIST (
+ EObjNameSpaceArchCommon,
+ EArchCommonObjTpm2DeviceInfo,
+ CM_ARCH_COMMON_TPM2_DEVICE_INFO
+ );
+
/**
Sanity check Start Method Specific Parameters field
@@ -122,6 +134,73 @@ AcpiTpm2CheckStartMethodParameters (
return EFI_SUCCESS;
}
+/** Build a TPM2 ACPI table.
+
+ @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 [in] TpmInfo TpmInfo to describe TPM2 device.
+ @param [in, out] Tpm2AcpiTable Tpm2AcpiTable.
+ @param [in] TableSize Size of Tpm2AcpiTable.
+
+ @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
+BuildTpm2AcpiTable (
+ 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 CONST CM_ARCH_COMMON_TPM2_INTERFACE_INFO *TpmInfo,
+ IN OUT EFI_TPM2_ACPI_TABLE *Tpm2AcpiTable,
+ IN UINT32 TableSize
+ )
+{
+ EFI_STATUS Status;
+ UINT32 *Laml;
+ UINT64 *Lasa;
+
+ Status = AddAcpiHeader (
+ CfgMgrProtocol,
+ This,
+ &Tpm2AcpiTable->Header,
+ AcpiTableInfo,
+ TableSize
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2: Failed to add ACPI header. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ Tpm2AcpiTable->Flags = TpmInfo->PlatformClass;
+ Tpm2AcpiTable->AddressOfControlArea = TpmInfo->AddressOfControlArea;
+ Tpm2AcpiTable->StartMethod = TpmInfo->StartMethod;
+
+ CopyMem (
+ Tpm2AcpiTable + 1,
+ TpmInfo->StartMethodParameters,
+ TpmInfo->StartMethodParametersSize
+ );
+
+ if (TpmInfo->Laml > 0) {
+ Lasa = (UINT64 *)((UINT8 *)Tpm2AcpiTable + TableSize - sizeof (TpmInfo->Lasa));
+ Laml = (UINT32 *)((UINT8 *)Lasa - sizeof (TpmInfo->Laml));
+ *Laml = TpmInfo->Laml;
+ *Lasa = TpmInfo->Lasa;
+ }
+
+ return EFI_SUCCESS;
+}
+
/** Construct the TPM2 ACPI table.
Called by the Dynamic Table Manager, this function invokes the
@@ -135,7 +214,8 @@ AcpiTpm2CheckStartMethodParameters (
@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.
+ @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_INVALID_PARAMETER A parameter is invalid.
@@ -148,22 +228,24 @@ AcpiTpm2CheckStartMethodParameters (
STATIC
EFI_STATUS
EFIAPI
-BuildTpm2Table (
+BuildTpm2TableEx (
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
+ OUT EFI_ACPI_DESCRIPTION_HEADER ***Table,
+ OUT UINTN *CONST TableCount
)
{
EFI_STATUS Status;
- UINT32 TableSize;
CM_ARCH_COMMON_TPM2_INTERFACE_INFO *TpmInfo;
- EFI_TPM2_ACPI_TABLE *Tpm2;
- UINT32 *Laml;
- UINT64 *Lasa;
+ CM_ARCH_COMMON_TPM2_DEVICE_INFO *TpmDevInfo;
+ UINT32 TableSize;
UINT32 MaxParameterSize;
+ EFI_ACPI_DESCRIPTION_HEADER **TableList;
+ CHAR8 NewName[AML_NAME_SEG_SIZE + 1];
- *Table = NULL;
+ *Table = NULL;
+ *TableCount = 0;
ASSERT (
(This != NULL) &&
@@ -233,9 +315,24 @@ BuildTpm2Table (
TableSize += sizeof (TpmInfo->Laml) + sizeof (TpmInfo->Lasa);
}
+ // Allocate a table to store pointers to the TPM2 table and
+ // Ssdt table.for Tpm2 device description.
+ TableList = (EFI_ACPI_DESCRIPTION_HEADER **)
+ AllocateZeroPool (
+ (sizeof (EFI_ACPI_DESCRIPTION_HEADER *) * MAX_TABLE_COUNT)
+ );
+ if (TableList == NULL) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2: Failed to allocate memory for TableList.\n"
+ ));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
// Allocate the Buffer for TPM2 table
- *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
- if (*Table == NULL) {
+ TableList[0] = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
+ if (TableList[0] == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
DEBUG ((
DEBUG_ERROR,
"ERROR: TPM2: Failed to allocate memory for TPM2 Table, Size = %d," \
@@ -243,51 +340,85 @@ BuildTpm2Table (
TableSize,
Status
));
- return EFI_OUT_OF_RESOURCES;
+ goto ErrorHandler;
}
- Tpm2 = (EFI_TPM2_ACPI_TABLE *)*Table;
-
- Status = AddAcpiHeader (
- CfgMgrProtocol,
+ Status = BuildTpm2AcpiTable (
This,
- &Tpm2->Header,
AcpiTableInfo,
+ CfgMgrProtocol,
+ TpmInfo,
+ (EFI_TPM2_ACPI_TABLE *)TableList[0],
TableSize
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
- "ERROR: TPM2: Failed to add ACPI header. Status = %r\n",
+ "ERROR: TPM2: Failed to Build TPM2 ACPI Table, " \
+ " Status = %r\n",
Status
));
- goto error_handler;
+ goto ErrorHandler;
}
- Tpm2->Flags = TpmInfo->PlatformClass;
- Tpm2->AddressOfControlArea = TpmInfo->AddressOfControlArea;
- Tpm2->StartMethod = TpmInfo->StartMethod;
-
- CopyMem (
- Tpm2 + 1,
- TpmInfo->StartMethodParameters,
- TpmInfo->StartMethodParametersSize
- );
-
- if (TpmInfo->Laml > 0) {
- Laml = (UINT32 *)((UINT8 *)Tpm2 + sizeof (EFI_TPM2_ACPI_TABLE) + MaxParameterSize);
- Lasa = (UINT64 *)((UINT8 *)Laml + sizeof (TpmInfo->Laml));
- *Laml = TpmInfo->Laml;
- *Lasa = TpmInfo->Lasa;
+ *TableCount += 1;
+
+ // Generate TPM2 device SSDT table.
+ if (FixedPcdGetBool (PcdGenTpm2DeviceTable)) {
+ Status = GetEArchCommonObjTpm2DeviceInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &TpmDevInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a: Failed to get TPM2 Device CM Object %r\n",
+ __func__,
+ Status
+ ));
+ goto ErrorHandler;
+ }
+
+ NewName[0] = 'T';
+ NewName[1] = 'P';
+ NewName[2] = 'M';
+ NewName[3] = AsciiFromHex ((UINT8)(TPM2_DEVICE_UID));
+ NewName[4] = '\0';
+
+ Status = BuildTpm2DeviceTable (
+ TpmDevInfo,
+ NewName,
+ TPM2_DEVICE_UID,
+ &TableList[1]
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2: Failed to Build SSDT table for TPM2 device," \
+ " Status = %r\n",
+ Status
+ ));
+ goto ErrorHandler;
+ }
+
+ *TableCount += 1;
}
+ *Table = TableList;
+
return EFI_SUCCESS;
-error_handler:
+ErrorHandler:
+ *TableCount = 0;
+
+ if (TableList != NULL) {
+ if (TableList[0] != NULL) {
+ FreePool (TableList[0]);
+ }
- if (*Table != NULL) {
- FreePool (*Table);
- *Table = NULL;
+ FreePool (TableList);
}
return Status;
@@ -299,7 +430,10 @@ error_handler:
@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 the ACPI Table.
+ @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.
@@ -307,13 +441,17 @@ error_handler:
STATIC
EFI_STATUS
EFIAPI
-FreeTpm2TableResources (
- 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
+FreeTpm2TableResourcesEx (
+ 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
)
{
+ UINTN Idx;
+ EFI_ACPI_DESCRIPTION_HEADER **TableList;
+
ASSERT (
(This != NULL) &&
(AcpiTableInfo != NULL) &&
@@ -322,12 +460,27 @@ FreeTpm2TableResources (
(AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature)
);
- if ((Table == NULL) || (*Table == NULL)) {
+ if ((Table == NULL) || (*Table == NULL) || (TableCount == 0)) {
DEBUG ((DEBUG_ERROR, "ERROR: TPM2: Invalid Table Pointer\n"));
return EFI_INVALID_PARAMETER;
}
- FreePool (*Table);
+ TableList = *Table;
+
+ for (Idx = 0; Idx < TableCount; Idx++) {
+ switch (TableList[Idx]->Signature) {
+ case EFI_ACPI_6_5_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE:
+ FreePool (TableList[Idx]);
+ break;
+ case EFI_ACPI_6_5_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
+ FreeTpm2DeviceTable (TableList[Idx]);
+ break;
+ default:
+ ASSERT (0);
+ }
+ }
+
+ FreePool (TableList);
*Table = NULL;
return EFI_SUCCESS;
@@ -357,14 +510,14 @@ ACPI_TABLE_GENERATOR Tpm2Generator = {
// Creator Revision
TPM2_GENERATOR_REVISION,
// Build Table function
- BuildTpm2Table,
+ NULL,
// Free Resource function
- FreeTpm2TableResources,
- // Extended build function not needed
NULL,
+ // Extended build function not needed
+ BuildTpm2TableEx,
// Extended build function not implemented by the generator.
// Hence extended free resource function is not required.
- NULL
+ FreeTpm2TableResourcesEx
};
/** Register the Generator with the ACPI Table Factory.
diff --git a/DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableLib.c b/DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableLib.c
new file mode 100644
index 0000000..22bd001
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableLib.c
@@ -0,0 +1,329 @@
+/** @file
+ Tpm2 device table generating Library
+
+ Copyright (c) 2025, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - TCG ACPI specification.
+ (https://trustedcomputinggroup.org/resource/tcg-acpi-specification/)
+**/
+#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/PcdLib.h>
+
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/AmlLib/AmlLib.h>
+#include <Protocol/ConfigurationManagerProtocol.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 tpm2devicetabletemplate_aml_code[];
+
+/** Fixup the TPM2 device UID (_UID).
+
+ @param [in] RootNodeHandle Pointer to the root of an AML tree.
+ @param [in] Uid UID for the TPM2 device.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Could not find information.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FixupTpm2DeviceUid (
+ IN AML_ROOT_NODE_HANDLE RootNodeHandle,
+ IN CONST UINT64 Uid
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE NameOpIdNode;
+
+ // Get the _UID NameOp object defined by the "Name ()" statement,
+ // and update its value.
+ Status = AmlFindNode (
+ RootNodeHandle,
+ "\\_SB_.TPM0._UID",
+ &NameOpIdNode
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return AmlNameOpUpdateInteger (NameOpIdNode, (UINT64)Uid);
+}
+
+/** Fixup the Tpm2 device name.
+
+ @param [in] RootNodeHandle Pointer to the root of an AML tree.
+ @param [in] Name The Name to give to the Device.
+ Must be a NULL-terminated ASL NameString
+ e.g.: "DEV0", "DV15.DEV0", etc.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Could not find information.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FixupTpm2DeviceName (
+ IN AML_ROOT_NODE_HANDLE RootNodeHandle,
+ IN CONST CHAR8 *Name
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE DeviceNode;
+
+ // Get the COM0 variable defined by the "Device ()" statement.
+ Status = AmlFindNode (RootNodeHandle, "\\_SB_.TPM0", &DeviceNode);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Update the Device's name.
+ return AmlDeviceOpUpdateName (DeviceNode, Name);
+}
+
+/** Fixup the Tpm2 device _CRS values (BaseAddress, ...).
+
+ @param [in] RootNodeHandle Pointer to the root of an AML tree.
+ @param [in] TpmDevInfo Pointer to a TPM2 device Information
+ structure.
+ Get the device size Information from there.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Could not find information.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FixupTpm2DeviceCrs (
+ IN AML_ROOT_NODE_HANDLE RootNodeHandle,
+ IN CONST CM_ARCH_COMMON_TPM2_DEVICE_INFO *TpmDevInfo
+ )
+{
+ EFI_STATUS Status;
+ AML_OBJECT_NODE_HANDLE NameOpCrsNode;
+ AML_DATA_NODE_HANDLE QWordRdNode;
+
+ // Get the "_CRS" object defined by the "Name ()" statement.
+ Status = AmlFindNode (
+ RootNodeHandle,
+ "\\_SB_.TPM0._CRS",
+ &NameOpCrsNode
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Get the first Rd node in the "_CRS" object.
+ Status = AmlNameOpGetFirstRdNode (NameOpCrsNode, &QWordRdNode);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (QWordRdNode == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Update the TPM2 device's base address and length.
+ Status = AmlUpdateRdQWord (
+ QWordRdNode,
+ TpmDevInfo->Tpm2DeviceBaseAddress,
+ TpmDevInfo->Tpm2DeviceSize
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+/** Fixup the Tpm2 Device in the AML tree.
+
+ For each template value:
+ - find the node to update;
+ - update the value.
+
+ @param [in] RootNodeHandle Pointer to the root of the AML tree.
+ @param [in] TpmDevInfo Pointer to a TPM2 device Information
+ 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 TPM2 device.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_NOT_FOUND Could not find information.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FixupTpm2DeviceInfo (
+ IN AML_ROOT_NODE_HANDLE RootNodeHandle,
+ IN CONST CM_ARCH_COMMON_TPM2_DEVICE_INFO *TpmDevInfo,
+ IN CONST CHAR8 *Name,
+ IN CONST UINT64 Uid
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT (RootNodeHandle != NULL);
+ ASSERT (TpmDevInfo != NULL);
+ ASSERT (Name != NULL);
+
+ // Fixup the _UID value.
+ Status = FixupTpm2DeviceUid (RootNodeHandle, Uid);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Fixup the _CRS values.
+ Status = FixupTpm2DeviceCrs (RootNodeHandle, TpmDevInfo);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Fixup the Tpm2 device name.
+ // This MUST be done at the end, otherwise AML paths won't be valid anymore.
+ return FixupTpm2DeviceName (RootNodeHandle, Name);
+}
+
+/** Build a SSDT table describing the TPM2 device.
+
+ The table created by this function must be freed by FreeSImpleTpm2DeviceTable.
+
+ @param [in] TpmDevInfo TPM2 device info to describe in the SSDT table.
+ @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 TPM2 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.
+**/
+EFI_STATUS
+EFIAPI
+BuildTpm2DeviceTable (
+ IN CONST CM_ARCH_COMMON_TPM2_DEVICE_INFO *TpmDevInfo,
+ IN CONST CHAR8 *Name,
+ IN CONST UINT64 Uid,
+ OUT EFI_ACPI_DESCRIPTION_HEADER **Table
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ AML_ROOT_NODE_HANDLE RootNodeHandle;
+
+ ASSERT (TpmDevInfo != NULL);
+ ASSERT (Name != NULL);
+ ASSERT (Table != NULL);
+
+ // Parse the Tpm2 Device Table Template.
+ Status = AmlParseDefinitionBlock (
+ (EFI_ACPI_DESCRIPTION_HEADER *)tpm2devicetabletemplate_aml_code,
+ &RootNodeHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2-DEVICE-FIXUP:"
+ " Failed to parse SSDT TPM2 device Template. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ // Fixup the template values.
+ Status = FixupTpm2DeviceInfo (
+ RootNodeHandle,
+ TpmDevInfo,
+ Name,
+ Uid
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2-DEVICE-FIXUP: Failed to fixup SSDT TPM2 Device Table."
+ " Status = %r\n",
+ Status
+ ));
+ goto ExitHandler;
+ }
+
+ // Serialize the tree.
+ Status = AmlSerializeDefinitionBlock (
+ RootNodeHandle,
+ Table
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2-DEVICE-FIXUP: Failed to Serialize SSDT Table Data."
+ " Status = %r\n",
+ Status
+ ));
+ }
+
+ExitHandler:
+ // Cleanup
+ if (RootNodeHandle != NULL) {
+ Status1 = AmlDeleteTree (RootNodeHandle);
+ if (EFI_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: TPM2-DEVICE-FIXUP: 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 an Tpm2 device table previously created by
+ the BuildTpm2DeviceTable function.
+
+ @param [in] Table Pointer to a Tpm2 Device table allocated by
+ the BuildTpm2DeviceTable function.
+
+**/
+VOID
+EFIAPI
+FreeTpm2DeviceTable (
+ IN EFI_ACPI_DESCRIPTION_HEADER *Table
+ )
+{
+ ASSERT (Table != NULL);
+ FreePool (Table);
+}
diff --git a/DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableLib.inf b/DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableLib.inf
new file mode 100644
index 0000000..6c69a9c
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Tpm2 Device table generating library
+#
+# Copyright (c) 2025, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = DynamicTpm2DeviceTableLib
+ FILE_GUID = b09d0390-0400-11f0-a447-cfc17b482322
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = Tpm2DeviceTableLib
+
+[Sources]
+ Tpm2DeviceTableLib.c
+ Tpm2DeviceTableTemplate.asl
+
+[Packages.common]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[Packages.ARM, Packages.AARCH64]
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ AcpiHelperLib
+ AmlLib
+ BaseLib
diff --git a/DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableTemplate.asl b/DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableTemplate.asl
new file mode 100644
index 0000000..9b99767
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/Tpm2DeviceTableLib/Tpm2DeviceTableTemplate.asl
@@ -0,0 +1,44 @@
+/** @file
+ TPM2 Device Table Template
+
+ Copyright (c) 2025, ARM Ltd. All rights reserved.<BR>
+ All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s)
+ - TCG ACPI Specification
+ - TCG PC Client Platform Firmware Profile Specification
+
+ @par Glossary:
+ - {template} - Data fixed up using AML Fixup APIs.
+**/
+
+DefinitionBlock("Tpm2DeviceTableTemplate.aml", "SSDT", 2, "ARMLTD", "TPM2CRB", 1) {
+ Scope(_SB) {
+ Device (TPM0) { // {template}
+ Name (_HID, "MSFT0101")
+ Name (_UID, 0) // {template}
+ Name (_CRS, ResourceTemplate () {
+ QWordMemory (
+ ResourceProducer,
+ PosDecode,
+ MinFixed,
+ MaxFixed,
+ NonCacheable,
+ ReadWrite,
+ 0x0000000000000000, // Granularity
+ 0x00000000FFDFB000, // Range Minimum // {template}
+ 0x00000000FFDFFFFF, // Range Maximum // {template}
+ 0x0000000000000000, // Translation Offset
+ 0x0000000000005000, // Length // {template}
+ ,
+ ,
+ ,
+ AddressRangeReserved,
+ TypeStatic
+ ) // QWordMemory
+ }) // Name
+ } // Device
+ } // Scope(_SB)
+}
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index ed0b17e..0c0b1c6 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -1352,10 +1352,6 @@
# @Prompt Enable serial port cable detetion.
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable|FALSE|BOOLEAN|0x00020006
- ## Base address of 16550 serial port registers in MMIO or I/O space. Default is 0x3F8.
- # @Prompt Base address of serial port registers.
- gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x03F8|UINT64|0x00020002
-
## Baud rate for the 16550 serial port. Default is 115200 baud.
# @Prompt Baud rate for serial port.
# @ValidList 0x80000001 | 921600, 460800, 230400, 115200, 57600, 38400, 19200, 9600, 7200, 4800, 3600, 2400, 2000, 1800, 1200, 600, 300, 150, 134, 110, 75, 50
@@ -1790,6 +1786,11 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x20|UINT32|0x0001004c
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+
+ ## Base address of 16550 serial port registers in MMIO or I/O space. Default is 0x3F8.
+ # @Prompt Base address of serial port registers.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x03F8|UINT64|0x00020002
+
## UART clock frequency is for the baud rate configuration.
# @Prompt Serial Port Clock Rate.
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate|1843200|UINT32|0x00010066
diff --git a/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c b/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c
index 8a076e1..155ab79 100644
--- a/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c
+++ b/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c
@@ -87,6 +87,7 @@ FindContextByDispatchHandle (
**/
EFI_STATUS
+EFIAPI
SmmSwDispatcher (
IN EFI_HANDLE DispatchHandle,
IN CONST VOID *RegisterContext,