From: Duke Zhai <Duke.Zhai@amd.com>
BZ #:4640
In V3: Improve coding style follow edk2 C coding standard.
1.Remove macro definition extra underscores.
2.Putting some AMD copyright in the right place.
In V2: Improve coding style.
1.Remove the leading underscore and use double underscore at trailing in C header files.
2.Remove old tianocore licenses and redundant license description.
3.Improve coding style. For example: remove space between @param.
In V1:
This driver implements TPM 2.0 definition block in ACPI table and
registers SMI callback functions for Tcg2 physical presence and
MemoryClear to handle the requests from ACPI method.
Signed-off-by: Ken Yao <ken.yao@amd.com>
Cc: Eric Xing <eric.xing@amd.com>
Cc: Duke Zhai <duke.zhai@amd.com>
Cc: Igniculus Fu <igniculus.fu@amd.com>
Cc: Abner Chang <abner.chang@amd.com>
---
.../DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c | 113 ++
.../DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf | 48 +
.../PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c | 141 ++
.../PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf | 47 +
.../AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c | 108 ++
.../Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf | 43 +
.../Tpm2InstanceLibAmdFTpm.inf | 53 +
.../Tpm2InstanceLibAmdFTpmDxe.c | 109 ++
.../Tpm2InstanceLibAmdFTpmPei.c | 153 ++
.../DxeTcg2PhysicalPresenceLib.c | 1269 +++++++++++++++++
.../DxeTcg2PhysicalPresenceLib.inf | 68 +
.../DxeTcg2PhysicalPresenceLib.uni | 22 +
.../PhysicalPresenceStrings.uni | 57 +
.../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c | 854 +++++++++++
.../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h | 123 ++
.../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf | 92 ++
.../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni | 19 +
.../Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni | 15 +
.../Tcg/AmdFtpm/FtpmTcg2Smm/Tpm.asl | 397 ++++++
.../Tcg/Tcg2Config/Tcg2ConfigNvData.h | 124 ++
.../Tcg/Tcg2Config/Tcg2ConfigPei.inf | 77 +
.../Tcg/Tcg2Config/Tcg2ConfigPei.uni | 14 +
.../Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni | 15 +
.../Tcg/Tcg2Config/Tcg2ConfigPeim.c | 148 ++
.../SecurityPkg/Tcg/Tcg2Config/TpmDetection.c | 99 ++
25 files changed, 4208 insertions(+)
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpm.inf
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmDxe.c
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmPei.c
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tpm.asl
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c
create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/TpmDetection.c
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c
new file mode 100644
index 0000000000..fe359cdc28
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c
@@ -0,0 +1,113 @@
+/** @file
+ This library is TPM2 device router. Platform can register multi TPM2 instance to it
+ via PcdTpmInstanceGuid. Platform need make choice that which one will be final one.
+ At most one TPM2 instance can be finally registered, and other will return unsupported.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved. <BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Protocol/AmdPspFtpmProtocol.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+PSP_FTPM_PROTOCOL *PspFtpmProtocol;
+extern EFI_GUID gAmdPspFtpmProtocolGuid;
+
+/**
+ The constructor function for this library.
+
+ @param None
+
+ @retval EFI_SUCCESS This library is ready for use.
+
+**/
+EFI_STATUS
+EFIAPI
+Tpm2DeviceLibConstructor (
+ VOID
+ )
+{
+ return gBS->LocateProtocol (&gAmdPspFtpmProtocolGuid, NULL, (VOID **)&PspFtpmProtocol);
+}
+
+/**
+ This service enables the sending of commands to the TPM2.
+
+ @param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
+ @param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
+ @param[in] OutputParameterBlockSize Size of the TPM2 output parameter block.
+ @param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
+
+ @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
+ @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
+ @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2SubmitCommand (
+ IN UINT32 InputParameterBlockSize,
+ IN UINT8 *InputParameterBlock,
+ IN OUT UINT32 *OutputParameterBlockSize,
+ IN UINT8 *OutputParameterBlock
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if ((NULL == InputParameterBlock) || (NULL == OutputParameterBlock) || (0 == InputParameterBlockSize)) {
+ DEBUG ((DEBUG_ERROR, "Buffer == NULL or InputParameterBlockSize == 0\n"));
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ Status = PspFtpmProtocol->Execute (
+ PspFtpmProtocol,
+ (VOID *)InputParameterBlock,
+ InputParameterBlockSize,
+ (VOID *)OutputParameterBlock,
+ OutputParameterBlockSize
+ );
+
+ return Status;
+}
+
+/**
+ This service requests use TPM2.
+
+ @retval EFI_SUCCESS Get the control of TPM2 chip.
+ @retval EFI_NOT_FOUND TPM2 not found.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2RequestUseTpm (
+ VOID
+ )
+{
+ FTPM_INFO FtpmStatus;
+
+ return PspFtpmProtocol->GetInfo (PspFtpmProtocol, &FtpmStatus);
+}
+
+/**
+ This service register TPM2 device.
+
+ @Param Tpm2Device TPM2 device
+
+ @retval EFI_SUCCESS This TPM2 device is registered successfully.
+ @retval EFI_UNSUPPORTED System does not support register this TPM2 device.
+ @retval EFI_ALREADY_STARTED System already register this TPM2 device.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2RegisterTpm2DeviceLib (
+ IN TPM2_DEVICE_INTERFACE *Tpm2Device
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf
new file mode 100644
index 0000000000..6708abdfce
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/DxeTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf
@@ -0,0 +1,48 @@
+## @file
+# Provides TPM 2.0 TIS functions
+#
+# This library is TPM 2.0 device router. Platform can register multi TPM 2.0 instance to
+# it via PcdTpmInstanceGuid. Platform need make choice that which one will be final one.
+# At most one TPM 2.0 instance can be finally registered, and other will return unsupported.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Tpm2DeviceLibFtpm
+ FILE_GUID = E98C81D3-B90D-4D28-AB48-A207C89D44C0
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = Tpm2DeviceLib | DXE_DRIVER DXE_RUNTIME_DRIVER
+ CONSTRUCTOR = Tpm2DeviceLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources.common]
+ Tpm2DeviceLibFtpm.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ ChachaniBoardPkg/Project.dec
+ AgesaPublic/AgesaPublic.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+
+[Protocols]
+ gAmdPspFtpmProtocolGuid
+
+[Depex]
+ gAmdPspFtpmProtocolGuid
\ No newline at end of file
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c
new file mode 100644
index 0000000000..9e8cb5588d
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.c
@@ -0,0 +1,141 @@
+/** @file
+ This library is TPM2 device router. Platform can register multi TPM2 instance to it
+ via PcdTpmInstanceGuid. Platform need make choice that which one will be final one.
+ At most one TPM2 instance can be finally registered, and other will return unsupported.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved. <BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Pi/PiPeiCis.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Ppi/AmdPspFtpmPpi.h>
+
+/**
+ The constructor function for this library.
+
+ @param None
+
+ @retval EFI_SUCCESS This library is ready for use.
+
+**/
+
+extern EFI_GUID gAmdPspFtpmPpiGuid;
+
+EFI_STATUS
+EFIAPI
+Tpm2DeviceLibConstructor (
+ VOID
+ )
+{
+ PSP_FTPM_PPI *PspFtpmPpi;
+
+ return (*GetPeiServicesTablePointer ())->LocatePpi (
+ GetPeiServicesTablePointer (),
+ &gAmdPspFtpmPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&PspFtpmPpi
+ );
+}
+
+/**
+ This service enables the sending of commands to the TPM2.
+
+ @param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
+ @param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
+ @param[in] OutputParameterBlockSize Size of the TPM2 output parameter block.
+ @param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
+
+ @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
+ @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
+ @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2SubmitCommand (
+ IN UINT32 InputParameterBlockSize,
+ IN UINT8 *InputParameterBlock,
+ IN OUT UINT32 *OutputParameterBlockSize,
+ IN UINT8 *OutputParameterBlock
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if ((NULL == InputParameterBlock) || (NULL == OutputParameterBlock) || (0 == InputParameterBlockSize)) {
+ DEBUG ((DEBUG_ERROR, "Buffer == NULL or InputParameterBlockSize == 0\n"));
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ PSP_FTPM_PPI *PspFtpmPpi;
+
+ Status = (*GetPeiServicesTablePointer ())->LocatePpi (
+ GetPeiServicesTablePointer (),
+ &gAmdPspFtpmPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&PspFtpmPpi
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = PspFtpmPpi->Execute (
+ PspFtpmPpi,
+ (VOID *)InputParameterBlock,
+ InputParameterBlockSize,
+ (VOID *)OutputParameterBlock,
+ OutputParameterBlockSize
+ );
+ }
+
+ return Status;
+}
+
+/**
+ This service requests use TPM2.
+
+ @retval EFI_SUCCESS Get the control of TPM2 chip.
+ @retval EFI_NOT_FOUND TPM2 not found.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2RequestUseTpm (
+ VOID
+ )
+{
+ UINTN FtpmStatus;
+ PSP_FTPM_PPI *PspFtpmPpi;
+ EFI_STATUS Status = (*GetPeiServicesTablePointer ())->LocatePpi (
+ GetPeiServicesTablePointer (),
+ &gAmdPspFtpmPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&PspFtpmPpi
+ );
+
+ return Status || PspFtpmPpi->CheckStatus (PspFtpmPpi, &FtpmStatus);
+}
+
+/**
+ This service register TPM2 device.
+
+ @Param Tpm2Device TPM2 device
+
+ @retval EFI_SUCCESS This TPM2 device is registered successfully.
+ @retval EFI_UNSUPPORTED System does not support register this TPM2 device.
+ @retval EFI_ALREADY_STARTED System already register this TPM2 device.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2RegisterTpm2DeviceLib (
+ IN TPM2_DEVICE_INTERFACE *Tpm2Device
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf
new file mode 100644
index 0000000000..a38ada3efd
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/PeiTpm2DeviceLibFsp/Tpm2DeviceLibFtpm.inf
@@ -0,0 +1,47 @@
+## @file
+# Provides TPM 2.0 TIS functions
+#
+# This library is TPM 2.0 device router. Platform can register multi TPM 2.0 instance to
+# it via PcdTpmInstanceGuid. Platform need make choice that which one will be final one.
+# At most one TPM 2.0 instance can be finally registered, and other will return unsupported.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Tpm2DeviceLibFtpm
+ FILE_GUID = 2E230843-274F-4C14-A4B5-46B6167E7A5C
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = Tpm2DeviceLib | PEIM
+ CONSTRUCTOR = Tpm2DeviceLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources.common]
+ Tpm2DeviceLibFtpm.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ ChachaniBoardPkg/Project.dec
+ AgesaPublic/AgesaPublic.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+
+[Ppis]
+ gAmdPspFtpmPpiGuid
+
+[Depex]
+ gAmdPspFtpmPpiGuid
\ No newline at end of file
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c
new file mode 100644
index 0000000000..713c87a1ca
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.c
@@ -0,0 +1,108 @@
+/** @file
+ This library is TPM2 TCG2 protocol lib.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/AmdPspFtpmLib.h>
+
+/**
+ The constructor function for this library.
+
+ @param None
+
+ @retval EFI_SUCCESS This library is ready for use.
+
+**/
+EFI_STATUS
+EFIAPI
+Tpm2DeviceLibConstructor (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ This service enables the sending of commands to the TPM2.
+
+ @param[in] InputParameterBlockSize Size of the TPM2 input parameter block.
+ @param[in] InputParameterBlock Pointer to the TPM2 input parameter block.
+ @param[in] OutputParameterBlockSize Size of the TPM2 output parameter block.
+ @param[in] OutputParameterBlock Pointer to the TPM2 output parameter block.
+
+ @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
+ @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
+ @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2SubmitCommand (
+ IN UINT32 InputParameterBlockSize,
+ IN UINT8 *InputParameterBlock,
+ IN OUT UINT32 *OutputParameterBlockSize,
+ IN UINT8 *OutputParameterBlock
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if ((NULL == InputParameterBlock) || (NULL == OutputParameterBlock) || (0 == InputParameterBlockSize)) {
+ DEBUG ((DEBUG_ERROR, "Buffer == NULL or InputParameterBlockSize == 0\n"));
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ Status = FtpmExecuteCommand (
+ (VOID *)InputParameterBlock,
+ InputParameterBlockSize,
+ (VOID *)OutputParameterBlock,
+ OutputParameterBlockSize
+ );
+
+ return Status;
+}
+
+/**
+ This service requests use TPM2.
+
+ @retval EFI_SUCCESS Get the control of TPM2 chip.
+ @retval EFI_NOT_FOUND TPM2 not found.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2RequestUseTpm (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN FtpmStatus;
+
+ Status = FtpmGetInfo (&FtpmStatus);
+ return Status;
+}
+
+/**
+ This service register TPM2 device.
+
+ @Param Tpm2Device TPM2 device
+
+ @retval EFI_SUCCESS This TPM2 device is registered successfully.
+ @retval EFI_UNSUPPORTED System does not support register this TPM2 device.
+ @retval EFI_ALREADY_STARTED System already register this TPM2 device.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2RegisterTpm2DeviceLib (
+ IN TPM2_DEVICE_INTERFACE *Tpm2Device
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf
new file mode 100644
index 0000000000..7e42703347
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2DeviceLib/Tpm2DeviceLibFtpm.inf
@@ -0,0 +1,43 @@
+## @file
+# Provides function interfaces to communicate with TPM 2.0 device
+#
+# This library helps to use TPM 2.0 device in library function API
+# based on TPM2 protocol.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Tpm2DeviceLibFtpm
+ FILE_GUID = 1E0C813B-46F5-4578-AA2D-E0AFFD89F2F9
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = Tpm2DeviceLib
+ CONSTRUCTOR = Tpm2DeviceLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources.common]
+ Tpm2DeviceLibFtpm.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ ChachaniBoardPkg/Project.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ AmdPspFtpmLib
+
+[Depex]
+ TRUE
\ No newline at end of file
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpm.inf
new file mode 100644
index 0000000000..2b957fd942
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpm.inf
@@ -0,0 +1,53 @@
+## @file
+# AMD Ftpm 2.0 Instance Library Module INF file
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Tpm2InstanceLibAmdFtpm
+ FILE_GUID = F1FA6737-93AC-4B72-8906-3EAE247CFF8D
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL
+ CONSTRUCTOR = Tpm2InstanceLibAmdFTpmConstructor
+
+[Sources.IA32]
+ Tpm2InstanceLibAmdFTpmPei.c
+
+[Sources.X64]
+ Tpm2InstanceLibAmdFTpmDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ AgesaPublic/AgesaPublic.dec
+
+[LibraryClasses.X64]
+ UefiBootServicesTableLib
+
+[LibraryClasses.IA32]
+ PeiServicesLib
+
+[Protocols.X64]
+ gAmdPspFtpmProtocolGuid
+
+[Ppis.IA32]
+ gAmdPspFtpmPpiGuid
+ gAmdPspFtpmFactoryResetPpiGuid
+
+[Guids]
+ gEfiTpmDeviceInstanceNoneGuid
+
+[Pcd]
+ gEfiAmdAgesaModulePkgTokenSpaceGuid.PcdAmdPspSystemTpmConfig
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
+
+[Depex.IA32]
+ TRUE
+
+[Depex.X64]
+ TRUE
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmDxe.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmDxe.c
new file mode 100644
index 0000000000..af9bf81c18
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmDxe.c
@@ -0,0 +1,109 @@
+/** @file
+ Implements Tpm2InstanceLibAmdFTpmDxe.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/PcdLib.h>
+#include <Protocol/AmdPspFtpmProtocol.h>
+#include <Library/AmdPspFtpmLib.h>
+
+// gEfiTpmDeviceInstanceTpm20AmdFtpmGuid
+#define TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM \
+ {0x286bf25a, 0xc2c3, 0x408c, {0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, 0x17}}
+
+PSP_FTPM_PROTOCOL *mfTpmProtocol = NULL;
+
+/**
+ This service enables the sending of commands to the FTPM.
+
+ @param[in] InputParameterBlockSize Size of the FTPM input parameter block.
+ @param[in] InputParameterBlock Pointer to the FTPM input parameter block.
+ @param[in,out] OutputParameterBlockSize Size of the FTPM output parameter block.
+ @param[in] OutputParameterBlock Pointer to the FTPM output parameter block.
+
+ @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
+ @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
+ @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
+**/
+EFI_STATUS
+EFIAPI
+FTpmSubmitCommand (
+ IN UINT32 InputParameterBlockSize,
+ IN UINT8 *InputParameterBlock,
+ IN OUT UINT32 *OutputParameterBlockSize,
+ IN UINT8 *OutputParameterBlock
+ )
+{
+ return mfTpmProtocol->Execute (mfTpmProtocol, InputParameterBlock, InputParameterBlockSize, OutputParameterBlock, OutputParameterBlockSize);
+}
+
+/**
+ This service requests use FTPM.
+
+ @retval EFI_SUCCESS Get the control of FTPM chip.
+ @retval EFI_NOT_FOUND FTPM not found.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+FTpmRequestUseTpm (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN fTpmStatus;
+
+ if ((PcdGet8 (PcdAmdPspSystemTpmConfig) == SYSTEM_TPM_CONFIG_PSP_FTPM) ||
+ (PcdGet8 (PcdAmdPspSystemTpmConfig) == SYSTEM_TPM_CONFIG_HSP_FTPM))
+ {
+ Status = mfTpmProtocol->CheckStatus (mfTpmProtocol, &fTpmStatus);
+ DEBUG ((DEBUG_INFO, "fTPM Status = %r\n", Status));
+ return Status;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+TPM2_DEVICE_INTERFACE mFTpmInternalTpm2Device = {
+ TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM,
+ FTpmSubmitCommand,
+ FTpmRequestUseTpm,
+};
+
+/**
+ The function register FTPM instance.
+
+ @retval EFI_SUCCESS FTPM instance is registered, or system dose not surpport registr FTPM instance
+**/
+EFI_STATUS
+EFIAPI
+Tpm2InstanceLibAmdFTpmConstructor (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol (
+ &gAmdPspFtpmProtocolGuid,
+ NULL,
+ (VOID **)&mfTpmProtocol
+ );
+ if (Status == EFI_SUCCESS) {
+ Status = Tpm2RegisterTpm2DeviceLib (&mFTpmInternalTpm2Device);
+ if (Status == EFI_UNSUPPORTED) {
+ //
+ // Unsupported means platform policy does not need this instance enabled.
+ //
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmPei.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmPei.c
new file mode 100644
index 0000000000..35671644e2
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/AmdFtpm/Tpm2InstanceLibAmdFTpm/Tpm2InstanceLibAmdFTpmPei.c
@@ -0,0 +1,153 @@
+/** @file
+ Implements Tpm2InstanceLibAmdFTpmPei.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/PcdLib.h>
+#include <Ppi/AmdPspFtpmPpi.h>
+#include <Library/AmdPspFtpmLib.h>
+#include <Guid/TpmInstance.h>
+
+// gEfiTpmDeviceInstanceTpm20AmdFtpmGuid
+#define TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM \
+ {0x286bf25a, 0xc2c3, 0x408c, {0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, 0x17}}
+
+/**
+ * @brief gAmdFtpmFactoryResetPpiGuid callback, disable TPM
+ *
+ * @param PeiServices
+ * @param NotifyDesc
+ * @param InvokePpi
+ * @return EFI_STATUS
+ */
+EFI_STATUS
+EFIAPI
+AmdFtpmFactoryResetCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *InvokePpi
+ )
+{
+ UINTN Size;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "AmdFtpmFactoryResetCallback\n"));
+ // gEfiTpmDeviceInstanceNoneGuid GUID value used for PcdTpmInstanceGuid to indicate TPM is disabled.
+ Size = sizeof (gEfiTpmDeviceInstanceNoneGuid);
+ Status = PcdSetPtrS (PcdTpmInstanceGuid, &Size, &gEfiTpmDeviceInstanceNoneGuid);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+EFI_PEI_NOTIFY_DESCRIPTOR mAmdFtpmFactoryResetPpiCallback = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gAmdPspFtpmFactoryResetPpiGuid,
+ AmdFtpmFactoryResetCallback
+};
+
+/**
+ This service enables the sending of commands to the FTPM.
+
+ @param[in] InputParameterBlockSize Size of the FTPM input parameter block.
+ @param[in] InputParameterBlock Pointer to the FTPM input parameter block.
+ @param[in,out] OutputParameterBlockSize Size of the FTPM output parameter block.
+ @param[in] OutputParameterBlock Pointer to the FTPM output parameter block.
+
+ @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
+ @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
+ @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
+**/
+EFI_STATUS
+EFIAPI
+FTpmSubmitCommand (
+ IN UINT32 InputParameterBlockSize,
+ IN UINT8 *InputParameterBlock,
+ IN OUT UINT32 *OutputParameterBlockSize,
+ IN UINT8 *OutputParameterBlock
+ )
+{
+ PSP_FTPM_PPI *AmdFtpmPpi;
+ EFI_STATUS Status;
+
+ Status = PeiServicesLocatePpi (&gAmdPspFtpmPpiGuid, 0, NULL, (VOID **)&AmdFtpmPpi);
+ if (Status == EFI_SUCCESS) {
+ return AmdFtpmPpi->Execute (AmdFtpmPpi, InputParameterBlock, InputParameterBlockSize, OutputParameterBlock, OutputParameterBlockSize);
+ }
+
+ return Status;
+}
+
+/**
+ This service requests use FTPM.
+
+ @retval EFI_SUCCESS Get the control of FTPM chip.
+ @retval EFI_NOT_FOUND FTPM not found.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+FTpmRequestUseTpm (
+ VOID
+ )
+{
+ if ((PcdGet8 (PcdAmdPspSystemTpmConfig) == SYSTEM_TPM_CONFIG_PSP_FTPM) ||
+ (PcdGet8 (PcdAmdPspSystemTpmConfig) == SYSTEM_TPM_CONFIG_HSP_FTPM))
+ {
+ // @todo Test fTPM functionality
+ DEBUG ((DEBUG_INFO, "fTPM is used\n"));
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+TPM2_DEVICE_INTERFACE mFTpmInternalTpm2Device = {
+ TPM_DEVICE_INTERFACE_TPM20_AMD_FTPM,
+ FTpmSubmitCommand,
+ FTpmRequestUseTpm,
+};
+
+/**
+ The function register FTPM instance.
+
+ @retval EFI_SUCCESS FTPM instance is registered, or system dose not surpport registr FTPM instance
+**/
+EFI_STATUS
+EFIAPI
+Tpm2InstanceLibAmdFTpmConstructor (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ PSP_FTPM_PPI *AmdFtpmPpi;
+
+ if ((PcdGet8 (PcdAmdPspSystemTpmConfig) == SYSTEM_TPM_CONFIG_PSP_FTPM) ||
+ (PcdGet8 (PcdAmdPspSystemTpmConfig) == SYSTEM_TPM_CONFIG_HSP_FTPM))
+ {
+ //
+ // AMD HSP f-TPM for EDK2 Core Base, Get the HSP PSP TcgEvetLog before BIOS
+ //
+ Status = PeiServicesLocatePpi (&gAmdPspFtpmPpiGuid, 0, NULL, (VOID **)&AmdFtpmPpi);
+ if (Status == EFI_SUCCESS) {
+ Status = Tpm2RegisterTpm2DeviceLib (&mFTpmInternalTpm2Device);
+ if (Status == EFI_UNSUPPORTED) {
+ //
+ // Unsupported means platform policy does not need this instance enabled.
+ //
+ return EFI_SUCCESS;
+ }
+ }
+
+ PeiServicesNotifyPpi (&mAmdFtpmFactoryResetPpiCallback);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c
new file mode 100644
index 0000000000..28b945fbba
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.c
@@ -0,0 +1,1269 @@
+/** @file
+ Execute pending TPM2 requests from OS or BIOS.
+
+ Caution: This module requires additional review when modified.
+ This driver will have external input - variable.
+ This external input must be validated carefully to avoid security issue.
+
+ Tpm2ExecutePendingTpmRequest() will receive untrusted input and do validation.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Protocol/Tcg2Protocol.h>
+#include <Protocol/VariableLock.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/HiiLib.h>
+#include <Library/HobLib.h>
+#include <Guid/EventGroup.h>
+#include <Guid/Tcg2PhysicalPresenceData.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/Tcg2PhysicalPresenceLib.h>
+#include <Library/Tcg2PpVendorLib.h>
+
+#define CONFIRM_BUFFER_SIZE 4096
+
+EFI_HII_HANDLE mTcg2PpStringPackHandle;
+
+/**
+ Get string by string id from HII Interface.
+
+ @param[in] Id String ID.
+
+ @retval CHAR16 * String from ID.
+ @retval NULL If error occurs.
+
+**/
+CHAR16 *
+Tcg2PhysicalPresenceGetStringById (
+ IN EFI_STRING_ID Id
+ )
+{
+ return HiiGetString (mTcg2PpStringPackHandle, Id, NULL);
+}
+
+/**
+ Send ClearControl and Clear command to TPM.
+
+ @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_BUFFER_TOO_SMALL Response data buffer is too small.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+
+**/
+EFI_STATUS
+EFIAPI
+Tpm2CommandClear (
+ IN TPM2B_AUTH *PlatformAuth OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ TPMS_AUTH_COMMAND *AuthSession;
+ TPMS_AUTH_COMMAND LocalAuthSession;
+
+ if (PlatformAuth == NULL) {
+ AuthSession = NULL;
+ } else {
+ AuthSession = &LocalAuthSession;
+ ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));
+ LocalAuthSession.sessionHandle = TPM_RS_PW;
+ LocalAuthSession.hmac.size = PlatformAuth->size;
+ CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
+ }
+
+ DEBUG ((DEBUG_INFO, "Tpm2ClearControl ... \n"));
+ Status = Tpm2ClearControl (TPM_RH_PLATFORM, AuthSession, NO);
+ DEBUG ((DEBUG_INFO, "Tpm2ClearControl - %r\n", Status));
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ DEBUG ((DEBUG_INFO, "Tpm2Clear ... \n"));
+ Status = Tpm2Clear (TPM_RH_PLATFORM, AuthSession);
+ DEBUG ((DEBUG_INFO, "Tpm2Clear - %r\n", Status));
+
+Done:
+ ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));
+ return Status;
+}
+
+/**
+ Change EPS.
+
+ @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+**/
+EFI_STATUS
+Tpm2CommandChangeEps (
+ IN TPM2B_AUTH *PlatformAuth OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ TPMS_AUTH_COMMAND *AuthSession;
+ TPMS_AUTH_COMMAND LocalAuthSession;
+
+ if (PlatformAuth == NULL) {
+ AuthSession = NULL;
+ } else {
+ AuthSession = &LocalAuthSession;
+ ZeroMem (&LocalAuthSession, sizeof (LocalAuthSession));
+ LocalAuthSession.sessionHandle = TPM_RS_PW;
+ LocalAuthSession.hmac.size = PlatformAuth->size;
+ CopyMem (LocalAuthSession.hmac.buffer, PlatformAuth->buffer, PlatformAuth->size);
+ }
+
+ Status = Tpm2ChangeEPS (TPM_RH_PLATFORM, AuthSession);
+ DEBUG ((DEBUG_INFO, "Tpm2ChangeEPS - %r\n", Status));
+
+ ZeroMem (&LocalAuthSession.hmac, sizeof (LocalAuthSession.hmac));
+ return Status;
+}
+
+/**
+ Execute physical presence operation requested by the OS.
+
+ @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
+ @param[in] CommandCode Physical presence operation value.
+ @param[in] CommandParameter Physical presence operation parameter.
+ @param[in, out] PpiFlags The physical presence interface flags.
+
+ @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Unknown physical presence operation.
+ @retval TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE Error occurred during sending command to TPM or
+ receiving response from TPM.
+ @retval Others Return code from the TPM device after command execution.
+**/
+UINT32
+Tcg2ExecutePhysicalPresence (
+ IN TPM2B_AUTH *PlatformAuth, OPTIONAL
+ IN UINT32 CommandCode,
+ IN UINT32 CommandParameter,
+ IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS *PpiFlags
+ )
+{
+ EFI_STATUS Status;
+ EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap;
+ UINT32 ActivePcrBanks;
+
+ switch (CommandCode) {
+ case TCG2_PHYSICAL_PRESENCE_CLEAR:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
+ Status = Tpm2CommandClear (PlatformAuth);
+ if (EFI_ERROR (Status)) {
+ return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
+ } else {
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+ }
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
+ PpiFlags->PPFlags |= TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
+ PpiFlags->PPFlags &= ~TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR;
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
+ Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // PP spec requirements:
+ // Firmware should check that all requested (set) hashing algorithms are supported with respective PCR banks.
+ // Firmware has to ensure that at least one PCR banks is active.
+ // If not, an error is returned and no action is taken.
+ //
+ if ((CommandParameter == 0) || ((CommandParameter & (~TpmHashAlgorithmBitmap)) != 0)) {
+ DEBUG ((DEBUG_ERROR, "PCR banks %x to allocate are not supported by TPM. Skip operation\n", CommandParameter));
+ return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
+ }
+
+ Status = Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitmap, CommandParameter);
+ if (EFI_ERROR (Status)) {
+ return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
+ } else {
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+ }
+
+ case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
+ Status = Tpm2CommandChangeEps (PlatformAuth);
+ if (EFI_ERROR (Status)) {
+ return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
+ } else {
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+ }
+
+ case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
+ Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks);
+ ASSERT_EFI_ERROR (Status);
+ Status = Tpm2PcrAllocateBanks (PlatformAuth, TpmHashAlgorithmBitmap, TpmHashAlgorithmBitmap);
+ if (EFI_ERROR (Status)) {
+ return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
+ } else {
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+ }
+
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
+ PpiFlags->PPFlags |= TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID;
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+
+ case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
+ PpiFlags->PPFlags &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID;
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:
+ PpiFlags->PPFlags |= TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID;
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
+ PpiFlags->PPFlags &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID;
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:
+ PpiFlags->PPFlags |= TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID;
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
+ PpiFlags->PPFlags &= ~TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID;
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+
+ default:
+ if (CommandCode <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
+ return TCG_PP_OPERATION_RESPONSE_SUCCESS;
+ } else {
+ return TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
+ }
+ }
+}
+
+/**
+ Read the specified key for user confirmation.
+
+ @param[in] CautionKey If true, F12 is used as confirm key;
+ If false, F10 is used as confirm key.
+
+ @retval TRUE User confirmed the changes by input.
+ @retval FALSE User discarded the changes.
+**/
+BOOLEAN
+Tcg2ReadUserKey (
+ IN BOOLEAN CautionKey
+ )
+{
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Key;
+ UINT16 InputKey;
+
+ InputKey = 0;
+ do {
+ Status = gBS->CheckEvent (gST->ConIn->WaitForKey);
+ if (!EFI_ERROR (Status)) {
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ if (Key.ScanCode == SCAN_ESC) {
+ InputKey = Key.ScanCode;
+ }
+
+ if ((Key.ScanCode == SCAN_F10) && !CautionKey) {
+ InputKey = Key.ScanCode;
+ }
+
+ if ((Key.ScanCode == SCAN_F12) && CautionKey) {
+ InputKey = Key.ScanCode;
+ }
+ }
+ } while (InputKey == 0);
+
+ if (InputKey != SCAN_ESC) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Fill Buffer With BootHashAlg.
+
+ @param[in] Buffer Buffer to be filled.
+ @param[in] BufferSize Size of buffer.
+ @param[in] BootHashAlg BootHashAlg.
+
+**/
+VOID
+Tcg2FillBufferWithBootHashAlg (
+ IN UINT16 *Buffer,
+ IN UINTN BufferSize,
+ IN UINT32 BootHashAlg
+ )
+{
+ Buffer[0] = 0;
+ if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA1) != 0) {
+ if (Buffer[0] != 0) {
+ StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
+ }
+
+ StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA1", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
+ }
+
+ if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA256) != 0) {
+ if (Buffer[0] != 0) {
+ StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
+ }
+
+ StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
+ }
+
+ if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA384) != 0) {
+ if (Buffer[0] != 0) {
+ StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
+ }
+
+ StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA384", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
+ }
+
+ if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SHA512) != 0) {
+ if (Buffer[0] != 0) {
+ StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
+ }
+
+ StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SHA512", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
+ }
+
+ if ((BootHashAlg & EFI_TCG2_BOOT_HASH_ALG_SM3_256) != 0) {
+ if (Buffer[0] != 0) {
+ StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L", ", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
+ }
+
+ StrnCatS (Buffer, BufferSize / sizeof (CHAR16), L"SM3_256", (BufferSize / sizeof (CHAR16)) - StrLen (Buffer) - 1);
+ }
+}
+
+/**
+ Display the confirm text and get user confirmation.
+
+ @param[in] TpmPpCommand The requested TPM physical presence command.
+ @param[in] TpmPpCommandParameter The requested TPM physical presence command parameter.
+
+ @retval TRUE The user has confirmed the changes.
+ @retval FALSE The user doesn't confirm the changes.
+**/
+BOOLEAN
+Tcg2UserConfirm (
+ IN UINT32 TpmPpCommand,
+ IN UINT32 TpmPpCommandParameter
+ )
+{
+ CHAR16 *ConfirmText;
+ CHAR16 *TmpStr1;
+ CHAR16 *TmpStr2;
+ UINTN BufSize;
+ BOOLEAN CautionKey;
+ BOOLEAN NoPpiInfo;
+ UINT16 Index;
+ CHAR16 DstStr[81];
+ CHAR16 TempBuffer[1024];
+ CHAR16 TempBuffer2[1024];
+ EFI_TCG2_PROTOCOL *Tcg2Protocol;
+ EFI_TCG2_BOOT_SERVICE_CAPABILITY ProtocolCapability;
+ UINT32 CurrentPCRBanks;
+ EFI_STATUS Status;
+
+ TmpStr2 = NULL;
+ CautionKey = FALSE;
+ NoPpiInfo = FALSE;
+ BufSize = CONFIRM_BUFFER_SIZE;
+ ConfirmText = AllocateZeroPool (BufSize);
+ ASSERT (ConfirmText != NULL);
+
+ mTcg2PpStringPackHandle = HiiAddPackages (&gEfiTcg2PhysicalPresenceGuid, gImageHandle, DxeTcg2PhysicalPresenceLibStrings, NULL);
+ ASSERT (mTcg2PpStringPackHandle != NULL);
+
+ switch (TpmPpCommand) {
+ case TCG2_PHYSICAL_PRESENCE_CLEAR:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
+ CautionKey = TRUE;
+ TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
+ UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
+ FreePool (TmpStr1);
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
+ CautionKey = TRUE;
+ NoPpiInfo = TRUE;
+ TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CLEAR));
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_PPI_HEAD_STR));
+ UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
+ FreePool (TmpStr1);
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NOTE_CLEAR));
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CLEAR));
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n\n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
+ Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **)&Tcg2Protocol);
+ ASSERT_EFI_ERROR (Status);
+
+ ProtocolCapability.Size = sizeof (ProtocolCapability);
+ Status = Tcg2Protocol->GetCapability (
+ Tcg2Protocol,
+ &ProtocolCapability
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = Tcg2Protocol->GetActivePcrBanks (
+ Tcg2Protocol,
+ &CurrentPCRBanks
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ CautionKey = TRUE;
+ TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_SET_PCR_BANKS));
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
+ UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
+ FreePool (TmpStr1);
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_1));
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_SET_PCR_BANKS_2));
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+
+ Tcg2FillBufferWithBootHashAlg (TempBuffer, sizeof (TempBuffer), TpmPpCommandParameter);
+ Tcg2FillBufferWithBootHashAlg (TempBuffer2, sizeof (TempBuffer2), CurrentPCRBanks);
+
+ TmpStr1 = AllocateZeroPool (BufSize);
+ ASSERT (TmpStr1 != NULL);
+ UnicodeSPrint (TmpStr1, BufSize, L"Current PCRBanks is 0x%x. (%s)\nNew PCRBanks is 0x%x. (%s)\n", CurrentPCRBanks, TempBuffer2, TpmPpCommandParameter, TempBuffer);
+
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), L" \n", (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
+ CautionKey = TRUE;
+ TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CHANGE_EPS));
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_HEAD_STR));
+ UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
+ FreePool (TmpStr1);
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_1));
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_WARNING_CHANGE_EPS_2));
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
+ TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ENABLE_BLOCK_SID));
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR));
+ UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
+ FreePool (TmpStr1);
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
+ TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_DISABLE_BLOCK_SID));
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_HEAD_STR));
+ UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
+ FreePool (TmpStr1);
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
+ NoPpiInfo = TRUE;
+ TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PP_ENABLE_BLOCK_SID));
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PPI_HEAD_STR));
+ UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
+ FreePool (TmpStr1);
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
+ NoPpiInfo = TRUE;
+ TmpStr2 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PP_DISABLE_BLOCK_SID));
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_PPI_HEAD_STR));
+ UnicodeSPrint (ConfirmText, BufSize, TmpStr1, TmpStr2);
+ FreePool (TmpStr1);
+ break;
+
+ default:
+ ;
+ }
+
+ if (TmpStr2 == NULL) {
+ FreePool (ConfirmText);
+ return FALSE;
+ }
+
+ if (TpmPpCommand < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN) {
+ if (CautionKey) {
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_CAUTION_KEY));
+ } else {
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_ACCEPT_KEY));
+ }
+
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+
+ if (NoPpiInfo) {
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_NO_PPI_INFO));
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+ }
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TPM_REJECT_KEY));
+ } else {
+ if (CautionKey) {
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_CAUTION_KEY));
+ } else {
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_ACCEPT_KEY));
+ }
+
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+
+ if (NoPpiInfo) {
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_NO_PPI_INFO));
+ StrnCatS (ConfirmText, BufSize / sizeof (CHAR16), TmpStr1, (BufSize / sizeof (CHAR16)) - StrLen (ConfirmText) - 1);
+ FreePool (TmpStr1);
+ }
+
+ TmpStr1 = Tcg2PhysicalPresenceGetStringById (STRING_TOKEN (TCG_STORAGE_REJECT_KEY));
+ }
+
+ BufSize -= StrSize (ConfirmText);
+ UnicodeSPrint (ConfirmText + StrLen (ConfirmText), BufSize, TmpStr1, TmpStr2);
+
+ DstStr[80] = L'\0';
+ for (Index = 0; Index < StrLen (ConfirmText); Index += 80) {
+ StrnCpyS (DstStr, sizeof (DstStr) / sizeof (CHAR16), ConfirmText + Index, sizeof (DstStr) / sizeof (CHAR16) - 1);
+ Print (DstStr);
+ }
+
+ FreePool (TmpStr1);
+ FreePool (TmpStr2);
+ FreePool (ConfirmText);
+ HiiRemovePackages (mTcg2PpStringPackHandle);
+
+ if (Tcg2ReadUserKey (CautionKey)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Check if there is a valid physical presence command request. Also updates parameter value
+ to whether the requested physical presence command already confirmed by user
+
+ @param[in] TcgPpData EFI Tcg2 Physical Presence request data.
+ @param[in] Flags The physical presence interface flags.
+ @param[out] RequestConfirmed If the physical presence operation command required user confirm from UI.
+ True, it indicates the command doesn't require user confirm, or already confirmed
+ in last boot cycle by user.
+ False, it indicates the command need user confirm from UI.
+
+ @retval TRUE Physical Presence operation command is valid.
+ @retval FALSE Physical Presence operation command is invalid.
+
+**/
+BOOLEAN
+Tcg2HaveValidTpmRequest (
+ IN EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData,
+ IN EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags,
+ OUT BOOLEAN *RequestConfirmed
+ )
+{
+ EFI_TCG2_PROTOCOL *Tcg2Protocol;
+ EFI_STATUS Status;
+ BOOLEAN IsRequestValid;
+
+ *RequestConfirmed = FALSE;
+
+ if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
+ //
+ // Need TCG2 protocol.
+ //
+ Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **)&Tcg2Protocol);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ }
+
+ switch (TcgPpData->PPRequest) {
+ case TCG2_PHYSICAL_PRESENCE_NO_ACTION:
+ *RequestConfirmed = TRUE;
+ return TRUE;
+
+ case TCG2_PHYSICAL_PRESENCE_CLEAR:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
+ if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CLEAR) == 0) {
+ *RequestConfirmed = TRUE;
+ }
+
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_TRUE:
+ *RequestConfirmed = TRUE;
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_CLEAR_FALSE:
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
+ if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_PCRS) == 0) {
+ *RequestConfirmed = TRUE;
+ }
+
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
+ if ((Flags.PPFlags & TCG2_BIOS_TPM_MANAGEMENT_FLAG_PP_REQUIRED_FOR_CHANGE_EPS) == 0) {
+ *RequestConfirmed = TRUE;
+ }
+
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
+ *RequestConfirmed = TRUE;
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
+ if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) == 0) {
+ *RequestConfirmed = TRUE;
+ }
+
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
+ if ((Flags.PPFlags & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) == 0) {
+ *RequestConfirmed = TRUE;
+ }
+
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:
+ *RequestConfirmed = TRUE;
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
+ break;
+
+ default:
+ if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
+ IsRequestValid = Tcg2PpVendorLibHasValidRequest (TcgPpData->PPRequest, Flags.PPFlags, RequestConfirmed);
+ if (!IsRequestValid) {
+ return FALSE;
+ } else {
+ break;
+ }
+ } else {
+ //
+ // Wrong Physical Presence command
+ //
+ return FALSE;
+ }
+ }
+
+ if ((Flags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) != 0) {
+ //
+ // It had been confirmed in last boot, it doesn't need confirm again.
+ //
+ *RequestConfirmed = TRUE;
+ }
+
+ //
+ // Physical Presence command is correct
+ //
+ return TRUE;
+}
+
+/**
+ Check and execute the requested physical presence command.
+
+ Caution: This function may receive untrusted input.
+ TcgPpData variable is external input, so this function will validate
+ its data structure to be valid value.
+
+ @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
+ @param[in, out] TcgPpData Pointer to the physical presence NV variable.
+ @param[in, out] Flags Pointer to the physical presence interface flags.
+**/
+VOID
+Tcg2ExecutePendingTpmRequest (
+ IN TPM2B_AUTH *PlatformAuth, OPTIONAL
+ IN OUT EFI_TCG2_PHYSICAL_PRESENCE *TcgPpData,
+ IN OUT EFI_TCG2_PHYSICAL_PRESENCE_FLAGS *Flags
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ BOOLEAN RequestConfirmed;
+ EFI_TCG2_PHYSICAL_PRESENCE_FLAGS NewFlags;
+ BOOLEAN ResetRequired;
+ UINT32 NewPPFlags;
+
+ if (TcgPpData->PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {
+ //
+ // No operation request
+ //
+ return;
+ }
+
+ if (!Tcg2HaveValidTpmRequest (TcgPpData, *Flags, &RequestConfirmed)) {
+ //
+ // Invalid operation request.
+ //
+ if (TcgPpData->PPRequest <= TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) {
+ TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_SUCCESS;
+ } else {
+ TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_BIOS_FAILURE;
+ }
+
+ TcgPpData->LastPPRequest = TcgPpData->PPRequest;
+ TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
+ TcgPpData->PPRequestParameter = 0;
+
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->SetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize,
+ TcgPpData
+ );
+ return;
+ }
+
+ ResetRequired = FALSE;
+ if (TcgPpData->PPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
+ NewFlags = *Flags;
+ NewPPFlags = NewFlags.PPFlags;
+ TcgPpData->PPResponse = Tcg2PpVendorLibExecutePendingRequest (PlatformAuth, TcgPpData->PPRequest, &NewPPFlags, &ResetRequired);
+ NewFlags.PPFlags = NewPPFlags;
+ } else {
+ if (!RequestConfirmed) {
+ //
+ // Print confirm text and wait for approval.
+ //
+ DEBUG ((DEBUG_INFO, "Print confirm text and wait for approval.\n"));
+ RequestConfirmed = TRUE;
+ // RequestConfirmed = Tcg2UserConfirm (TcgPpData->PPRequest, TcgPpData->PPRequestParameter);
+ }
+
+ //
+ // Execute requested physical presence command
+ //
+ TcgPpData->PPResponse = TCG_PP_OPERATION_RESPONSE_USER_ABORT;
+ NewFlags = *Flags;
+ if (RequestConfirmed) {
+ TcgPpData->PPResponse = Tcg2ExecutePhysicalPresence (
+ PlatformAuth,
+ TcgPpData->PPRequest,
+ TcgPpData->PPRequestParameter,
+ &NewFlags
+ );
+ }
+ }
+
+ //
+ // Save the flags if it is updated.
+ //
+ if (CompareMem (Flags, &NewFlags, sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS)) != 0) {
+ *Flags = NewFlags;
+ Status = gRT->SetVariable (
+ TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),
+ &NewFlags
+ );
+ }
+
+ //
+ // Clear request
+ //
+ if ((NewFlags.PPFlags & TCG2_LIB_PP_FLAG_RESET_TRACK) == 0) {
+ TcgPpData->LastPPRequest = TcgPpData->PPRequest;
+ TcgPpData->PPRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
+ TcgPpData->PPRequestParameter = 0;
+ }
+
+ //
+ // Save changes
+ //
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->SetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize,
+ TcgPpData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to set variable %S, %r\n", TCG2_PHYSICAL_PRESENCE_VARIABLE, Status));
+ return;
+ }
+
+ if (TcgPpData->PPResponse == TCG_PP_OPERATION_RESPONSE_USER_ABORT) {
+ DEBUG ((DEBUG_INFO, "User abort the TPM action \n"));
+ return;
+ }
+
+ //
+ // Reset system to make new TPM settings in effect
+ //
+ switch (TcgPpData->LastPPRequest) {
+ case TCG2_PHYSICAL_PRESENCE_CLEAR:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_2:
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_CLEAR_3:
+ case TCG2_PHYSICAL_PRESENCE_SET_PCR_BANKS:
+ case TCG2_PHYSICAL_PRESENCE_CHANGE_EPS:
+ case TCG2_PHYSICAL_PRESENCE_LOG_ALL_DIGESTS:
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID:
+ case TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID:
+ break;
+
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE:
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE:
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE:
+ case TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE:
+ return;
+
+ default:
+ if (TcgPpData->LastPPRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
+ if (ResetRequired) {
+ break;
+ } else {
+ return;
+ }
+ }
+
+ if (TcgPpData->PPRequest != TCG2_PHYSICAL_PRESENCE_NO_ACTION) {
+ break;
+ }
+
+ return;
+ }
+
+ // Print (L"Rebooting system to make TPM2 settings in effect\n");
+ DEBUG ((DEBUG_INFO, "Rebooting system to make TPM2 settings in effect\n"));
+ gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
+ ASSERT (FALSE);
+}
+
+/**
+ Check and execute the pending TPM request.
+
+ The TPM request may come from OS or BIOS. This API will display request information and wait
+ for user confirmation if TPM request exists. The TPM request will be sent to TPM device after
+ the TPM request is confirmed, and one or more reset may be required to make TPM request to
+ take effect.
+
+ This API should be invoked after console in and console out are all ready as they are required
+ to display request information and get user input to confirm the request.
+
+ @param[in] PlatformAuth platform auth value. NULL means no platform auth change.
+**/
+VOID
+EFIAPI
+Tcg2PhysicalPresenceLibProcessRequest (
+ IN TPM2B_AUTH *PlatformAuth OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ EFI_TCG2_PHYSICAL_PRESENCE TcgPpData;
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
+ EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;
+
+ //
+ // This flags variable controls whether physical presence is required for TPM command.
+ // It should be protected from malicious software. We set it as read-only variable here.
+ //
+ Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
+ if (!EFI_ERROR (Status)) {
+ Status = VariableLockProtocol->RequestToLock (
+ VariableLockProtocol,
+ TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "[TPM2] Error when lock variable %s, Status = %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ // On AMD FCH, always do S4 for shutdown.
+ // Todo: Chang to PCD method for this
+ //
+ // Check S4 resume
+ //
+ // if (GetBootModeHob () == BOOT_ON_S4_RESUME) {
+ // DEBUG ((DEBUG_INFO, "S4 Resume, Skip TPM PP process!\n"));
+ // return ;
+ // }
+
+ //
+ // Initialize physical presence flags.
+ //
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
+ Status = gRT->GetVariable (
+ TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ NULL,
+ &DataSize,
+ &PpiFlags
+ );
+ if (EFI_ERROR (Status)) {
+ PpiFlags.PPFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);
+ Status = gRT->SetVariable (
+ TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS),
+ &PpiFlags
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "[TPM2] Set physical presence flag failed, Status = %r\n", Status));
+ return;
+ }
+
+ DEBUG ((DEBUG_INFO, "[TPM2] Initial physical presence flags value is 0x%x\n", PpiFlags.PPFlags));
+ }
+
+ //
+ // Initialize physical presence variable.
+ //
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->GetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ NULL,
+ &DataSize,
+ &TcgPpData
+ );
+ if (EFI_ERROR (Status)) {
+ ZeroMem ((VOID *)&TcgPpData, sizeof (TcgPpData));
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->SetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize,
+ &TcgPpData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "[TPM2] Set physical presence variable failed, Status = %r\n", Status));
+ return;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags.PPFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));
+
+ //
+ // Execute pending TPM request.
+ //
+ Tcg2ExecutePendingTpmRequest (PlatformAuth, &TcgPpData, &PpiFlags);
+ DEBUG ((DEBUG_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags.PPFlags));
+}
+
+/**
+ Check if the pending TPM request needs user input to confirm.
+
+ The TPM request may come from OS. This API will check if TPM request exists and need user
+ input to confirmation.
+
+ @retval TRUE TPM needs input to confirm user physical presence.
+ @retval FALSE TPM doesn't need input to confirm user physical presence.
+
+**/
+BOOLEAN
+EFIAPI
+Tcg2PhysicalPresenceLibNeedUserConfirm (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_TCG2_PHYSICAL_PRESENCE TcgPpData;
+ UINTN DataSize;
+ BOOLEAN RequestConfirmed;
+ EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;
+
+ // In AMD FCH, always do S4 for Shutdown.
+ // Todo: Chang to PCD method for this
+ //
+ // Check S4 resume
+ //
+ // if (GetBootModeHob () == BOOT_ON_S4_RESUME) {
+ // DEBUG ((DEBUG_INFO, "S4 Resume, Skip TPM PP process!\n"));
+ // return FALSE;
+ // }
+
+ //
+ // Check Tpm requests
+ //
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->GetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ NULL,
+ &DataSize,
+ &TcgPpData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "[TPM2] GetVariable %S, %r\n", TCG2_PHYSICAL_PRESENCE_VARIABLE, Status));
+ return FALSE;
+ }
+
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
+ Status = gRT->GetVariable (
+ TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ NULL,
+ &DataSize,
+ &PpiFlags
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "[TPM2] GetVariable %S, %r\n", TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE, Status));
+ return FALSE;
+ }
+
+ if (TcgPpData.PPRequest == TCG2_PHYSICAL_PRESENCE_NO_ACTION) {
+ //
+ // No operation request
+ //
+ return FALSE;
+ }
+
+ if (!Tcg2HaveValidTpmRequest (&TcgPpData, PpiFlags, &RequestConfirmed)) {
+ //
+ // Invalid operation request.
+ //
+ return FALSE;
+ }
+
+ if (!RequestConfirmed) {
+ //
+ // Need UI to confirm
+ //
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ The handler for TPM physical presence function:
+ Return TPM Operation Response to OS Environment.
+
+ @param[out] MostRecentRequest Most recent operation request.
+ @param[out] Response Response to the most recent operation request.
+
+ @return Return Code for Return TPM Operation Response to OS Environment.
+**/
+UINT32
+EFIAPI
+Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
+ OUT UINT32 *MostRecentRequest,
+ OUT UINT32 *Response
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ EFI_TCG2_PHYSICAL_PRESENCE PpData;
+
+ DEBUG ((DEBUG_INFO, "[TPM2] ReturnOperationResponseToOsFunction\n"));
+
+ //
+ // Get the Physical Presence variable
+ //
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->GetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ NULL,
+ &DataSize,
+ &PpData
+ );
+ if (EFI_ERROR (Status)) {
+ *MostRecentRequest = 0;
+ *Response = 0;
+ DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
+ return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;
+ }
+
+ *MostRecentRequest = PpData.LastPPRequest;
+ *Response = PpData.PPResponse;
+
+ return TCG_PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;
+}
+
+/**
+ The handler for TPM physical presence function:
+ Submit TPM Operation Request to Pre-OS Environment and
+ Submit TPM Operation Request to Pre-OS Environment 2.
+
+ Caution: This function may receive untrusted input.
+
+ @param[in] OperationRequest TPM physical presence operation request.
+ @param[in] RequestParameter TPM physical presence operation request parameter.
+
+ @return Return Code for Submit TPM Operation Request to Pre-OS Environment and
+ Submit TPM Operation Request to Pre-OS Environment 2.
+**/
+UINT32
+EFIAPI
+Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (
+ IN UINT32 OperationRequest,
+ IN UINT32 RequestParameter
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ EFI_TCG2_PHYSICAL_PRESENCE PpData;
+ EFI_TCG2_PHYSICAL_PRESENCE_FLAGS Flags;
+
+ DEBUG ((DEBUG_INFO, "[TPM2] SubmitRequestToPreOSFunction, Request = %x, %x\n", OperationRequest, RequestParameter));
+
+ //
+ // Get the Physical Presence variable
+ //
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->GetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ NULL,
+ &DataSize,
+ &PpData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));
+ return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
+ }
+
+ if ((OperationRequest > TCG2_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&
+ (OperationRequest < TCG2_PHYSICAL_PRESENCE_STORAGE_MANAGEMENT_BEGIN))
+ {
+ return TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;
+ }
+
+ if ((PpData.PPRequest != OperationRequest) ||
+ (PpData.PPRequestParameter != RequestParameter))
+ {
+ PpData.PPRequest = (UINT8)OperationRequest;
+ PpData.PPRequestParameter = RequestParameter;
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->SetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize,
+ &PpData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));
+ return TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;
+ }
+ }
+
+ if (OperationRequest >= TCG2_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
+ Status = gRT->GetVariable (
+ TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ NULL,
+ &DataSize,
+ &Flags
+ );
+ if (EFI_ERROR (Status)) {
+ Flags.PPFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);
+ }
+
+ return Tcg2PpVendorLibSubmitRequestToPreOSFunction (OperationRequest, Flags.PPFlags, RequestParameter);
+ }
+
+ return TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;
+}
+
+/**
+ Return TPM2 ManagementFlags set by PP interface.
+
+ @retval ManagementFlags TPM2 Management Flags.
+**/
+UINT32
+EFIAPI
+Tcg2PhysicalPresenceLibGetManagementFlags (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_TCG2_PHYSICAL_PRESENCE_FLAGS PpiFlags;
+ UINTN DataSize;
+
+ DEBUG ((DEBUG_INFO, "[TPM2] GetManagementFlags\n"));
+
+ DataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE_FLAGS);
+ Status = gRT->GetVariable (
+ TCG2_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ NULL,
+ &DataSize,
+ &PpiFlags
+ );
+ if (EFI_ERROR (Status)) {
+ PpiFlags.PPFlags = PcdGet32 (PcdTcg2PhysicalPresenceFlags);
+ }
+
+ return PpiFlags.PPFlags;
+}
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf
new file mode 100644
index 0000000000..2ce1133596
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf
@@ -0,0 +1,68 @@
+## @file
+# Executes TPM 2.0 requests from OS or BIOS
+#
+# This library will check and execute TPM 2.0 request from OS or BIOS. The request may
+# ask for user confirmation before execution.
+#
+# Caution: This module requires additional review when modified.
+# This driver will have external input - variable.
+# This external input must be validated carefully to avoid security issue.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeTcg2PhysicalPresenceLib
+ MODULE_UNI_FILE = DxeTcg2PhysicalPresenceLib.uni
+ FILE_GUID = 7E507A86-DE8B-4AD3-BC4C-0498389098D3
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = Tcg2PhysicalPresenceLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ DxeTcg2PhysicalPresenceLib.c
+ PhysicalPresenceStrings.uni
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiRuntimeServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PrintLib
+ HiiLib
+ HobLib
+ Tpm2CommandLib
+ Tcg2PpVendorLib
+
+[Protocols]
+ gEfiTcg2ProtocolGuid ## SOMETIMES_CONSUMES
+ gEdkiiVariableLockProtocolGuid ## SOMETIMES_CONSUMES
+
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTcg2PhysicalPresenceFlags ## SOMETIMES_CONSUMES
+
+[Guids]
+ ## SOMETIMES_CONSUMES ## HII
+ ## SOMETIMES_PRODUCES ## Variable:L"Tcg2PhysicalPresence"
+ ## SOMETIMES_CONSUMES ## Variable:L"Tcg2PhysicalPresence"
+ ## SOMETIMES_PRODUCES ## Variable:L"Tcg2PhysicalPresenceFlags"
+ ## SOMETIMES_CONSUMES ## Variable:L"Tcg2PhysicalPresenceFlags"
+ gEfiTcg2PhysicalPresenceGuid
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni
new file mode 100644
index 0000000000..d7e4af732b
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.uni
@@ -0,0 +1,22 @@
+// /** @file
+// Executes TPM 2.0 requests from OS or BIOS
+//
+// This library will check and execute TPM 2.0 request from OS or BIOS. The request may
+// ask for user confirmation before execution.
+//
+// Caution: This module requires additional review when modified.
+// This driver will have external input - variable.
+// This external input must be validated carefully to avoid security issue.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Executes TPM 2.0 requests from OS or BIOS"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This library will check and execute TPM 2.0 request from OS or BIOS. The request may ask for user confirmation before execution.\n"
+ "Caution: This module requires additional review when modified. This driver will have external input - variable. This external input must be validated carefully to avoid security issue."
+
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni
new file mode 100644
index 0000000000..70fa651455
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/PhysicalPresenceStrings.uni
@@ -0,0 +1,57 @@
+// /** @file
+// String definitions for TPM 2.0 physical presence confirm text.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#langdef en-US "English"
+
+#string TPM_HEAD_STR #language en-US "A configuration change was requested to %s this computer's TPM (Trusted Platform Module)\n\n"
+#string TPM_PPI_HEAD_STR #language en-US "A configuration change was requested to allow the Operating System to %s the computer's TPM (Trusted Platform Module) without asking for user confirmation in the future.\n\n"
+
+#string TPM_ACCEPT_KEY #language en-US "Press F10 "
+#string TPM_CAUTION_KEY #language en-US "Press F12 "
+#string TPM_REJECT_KEY #language en-US "to %s the TPM \nPress ESC to reject this change request and continue\n"
+
+#string TPM_ENABLE #language en-US "enable"
+#string TPM_DISABLE #language en-US "disable"
+#string TPM_CLEAR #language en-US "clear"
+#string TPM_SET_PCR_BANKS #language en-US "change the boot measurements to use PCR bank(s) of"
+#string TPM_CHANGE_EPS #language en-US "clear and change identity of"
+#string TPM_DISABLE_ENDORSEMENT_ENABLE_STORAGE #language en-US "disable access to some secrets stored in"
+
+#string TPM_NO_PPI_MAINTAIN #language en-US "maintain"
+#string TPM_NO_PPI_TURN_ON #language en-US "turn on"
+#string TPM_NO_PPI_TURN_OFF #language en-US "turn off"
+#string TPM_NO_PPI_INFO #language en-US "to approve future Operating System requests "
+
+#string TPM_WARNING_DISABLE #language en-US "WARNING: Doing so might prevent security applications that rely on the TPM from functioning as expected.\n\n"
+#string TPM_WARNING_CLEAR #language en-US "WARNING: Clearing erases information stored on the TPM. You will lose all created keys and access to data encrypted by these keys. "
+#string TPM_NOTE_CLEAR #language en-US "NOTE: This action does not clear the TPM, but by approving this configuration change, future actions to clear the TPM will not require user confirmation.\n\n"
+#string TPM_WARNING_SET_PCR_BANKS_1 #language en-US "WARNING: Changing the PCR bank(s) of the boot measurements may prevent the Operating System from properly processing the measurements. Please check if your Operating System supports the new PCR bank(s).\n\n"
+#string TPM_WARNING_SET_PCR_BANKS_2 #language en-US "WARNING: Secrets in the TPM that are bound to the boot state of your machine may become unusable.\n\n"
+#string TPM_WARNING_CHANGE_EPS_1 #language en-US "WARNING: Clearing erases information stored on the TPM. You will lose all created keys and access to data encrypted with these keys.\n\n"
+#string TPM_WARNING_CHANGE_EPS_2 #language en-US "WARNING: Changing the identity of the TPM may require additional steps to establish trust into the new identity.\n\n"
+#string TPM_WARNING_PP_CHANGE_PCRS_FALSE #language en-US "WARNING: Allowing future changes to format of the boot measurement log may affect the Operating System.\n\n"
+#string TPM_WARNING_PP_CHANGE_EPS_FALSE_1 #language en-US "WARNING: Allowing future changes to the TPM's firmware may affect the operation of the TPM and may erase information stored on the TPM.\n\n"
+#string TPM_WARNING_PP_CHANGE_EPS_FALSE_2 #language en-US "You may lose all created keys and access to data encrypted by these keys.\n\n"
+#string TPM_WARNING_DISABLE_ENDORSEMENT_ENABLE_STORAGE #language en-US "WARNING: Doing so might prevent security applications that rely on the TPM from functioning as expected.\n\n"
+
+#string TCG_STORAGE_HEAD_STR #language en-US "A configuration change was requested to %s on subsequent boots\n\n"
+#string TCG_STORAGE_PPI_HEAD_STR #language en-US "A configuration change was requested to allow the Operating System to %s without asking for user confirmation in the future.\n\n"
+
+#string TCG_STORAGE_ACCEPT_KEY #language en-US "Press F10 "
+#string TCG_STORAGE_CAUTION_KEY #language en-US "Press F12 "
+#string TCG_STORAGE_REJECT_KEY #language en-US "to %s\nPress ESC to reject this change request and continue\n"
+
+#string TCG_STORAGE_NO_PPI_INFO #language en-US "to approve future Operating System requests "
+
+#string TCG_STORAGE_ENABLE_BLOCK_SID #language en-US "issue a Block SID authentication command"
+#string TCG_STORAGE_DISABLE_BLOCK_SID #language en-US "disable issuing a Block SID authentication command"
+
+#string TCG_STORAGE_PP_ENABLE_BLOCK_SID #language en-US "enable blocking SID authentication"
+#string TCG_STORAGE_PP_DISABLE_BLOCK_SID #language en-US "disable blocking SID authentication"
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c
new file mode 100644
index 0000000000..62317165cb
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.c
@@ -0,0 +1,854 @@
+/** @file
+ It updates fTPM2 items in ACPI table and registers SMI2 callback
+ functions for Tcg2 physical presence, ClearMemory, and sample
+ for dTPM StartMethod.
+
+ Caution: This module requires additional review when modified.
+ This driver will have external input - variable and ACPINvs data in SMM mode.
+ This external input must be validated carefully to avoid security issue.
+
+ PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Tcg2Smm.h"
+
+TPM2_CONTROL_AREA *mFtpmControlArea = NULL;
+
+EFI_TPM2_ACPI_TABLE mTpm2AcpiTemplate = {
+ {
+ EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE,
+ sizeof (mTpm2AcpiTemplate),
+ EFI_TPM2_ACPI_TABLE_REVISION,
+ //
+ // Compiler initializes the remaining bytes to 0
+ // These fields should be filled in in production
+ //
+ },
+ 0, // BIT0~15: PlatformClass
+ // BIT16~31: Reserved
+ 0, // Control Area
+ EFI_TPM2_ACPI_TABLE_START_METHOD_TIS, // StartMethod
+};
+
+EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable;
+TCG_NVS *mTcgNvs;
+
+/**
+ Software SMI callback for TPM physical presence which is called from ACPI method.
+
+ Caution: This function may receive untrusted input.
+ Variable and ACPINvs are external input, so this function will validate
+ its data structure to be valid value.
+
+ @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
+ @param[in] Context Points to an optional handler context which was specified when the
+ handler was registered.
+ @param[in, out] CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-SMM environment into an SMM environment.
+ @param[in, out] CommBufferSize The size of the CommBuffer.
+
+ @retval EFI_SUCCESS The interrupt was handled successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PhysicalPresenceCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommBufferSize
+ )
+{
+ UINT32 MostRecentRequest;
+ UINT32 Response;
+ UINT32 OperationRequest;
+ UINT32 RequestParameter;
+
+ if (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) {
+ mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibReturnOperationResponseToOsFunction (
+ &MostRecentRequest,
+ &Response
+ );
+ mTcgNvs->PhysicalPresence.LastRequest = MostRecentRequest;
+ mTcgNvs->PhysicalPresence.Response = Response;
+ return EFI_SUCCESS;
+ } else if ( (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS)
+ || (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2))
+ {
+ OperationRequest = mTcgNvs->PhysicalPresence.Request;
+ RequestParameter = mTcgNvs->PhysicalPresence.RequestParameter;
+ mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunctionEx (
+ &OperationRequest,
+ &RequestParameter
+ );
+ mTcgNvs->PhysicalPresence.Request = OperationRequest;
+ mTcgNvs->PhysicalPresence.RequestParameter = RequestParameter;
+ } else if (mTcgNvs->PhysicalPresence.Parameter == TCG_ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {
+ mTcgNvs->PhysicalPresence.ReturnCode = Tcg2PhysicalPresenceLibGetUserConfirmationStatusFunction (mTcgNvs->PPRequestUserConfirm);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Software SMI callback for MemoryClear which is called from ACPI method.
+
+ Caution: This function may receive untrusted input.
+ Variable and ACPINvs are external input, so this function will validate
+ its data structure to be valid value.
+
+ @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
+ @param[in] Context Points to an optional handler context which was specified when the
+ handler was registered.
+ @param[in, out] CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-SMM environment into an SMM environment.
+ @param[in, out] CommBufferSize The size of the CommBuffer.
+
+ @retval EFI_SUCCESS The interrupt was handled successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+MemoryClearCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommBufferSize
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ UINT8 MorControl;
+
+ mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_SUCCESS;
+ if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) {
+ MorControl = (UINT8)mTcgNvs->MemoryClear.Request;
+ } else if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) {
+ DataSize = sizeof (UINT8);
+ Status = mSmmVariable->SmmGetVariable (
+ MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
+ &gEfiMemoryOverwriteControlDataGuid,
+ NULL,
+ &DataSize,
+ &MorControl
+ );
+ if (EFI_ERROR (Status)) {
+ mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
+ return EFI_SUCCESS;
+ }
+
+ if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {
+ return EFI_SUCCESS;
+ }
+
+ MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK;
+ }
+
+ DataSize = sizeof (UINT8);
+ Status = mSmmVariable->SmmSetVariable (
+ MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
+ &gEfiMemoryOverwriteControlDataGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize,
+ &MorControl
+ );
+ if (EFI_ERROR (Status)) {
+ mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Find the operation region in TCG ACPI table by given Name and Size,
+ and initialize it if the region is found.
+
+ @param[in, out] Table The TPM item in ACPI table.
+ @param[in] Name The name string to find in TPM table.
+ @param[in] Size The size of the region to find.
+
+ @return The allocated address for the found region.
+
+**/
+VOID *
+AssignOpRegion (
+ EFI_ACPI_DESCRIPTION_HEADER *Table,
+ UINT32 Name,
+ UINT16 Size
+ )
+{
+ EFI_STATUS Status;
+ AML_OP_REGION_32_8 *OpRegion;
+ EFI_PHYSICAL_ADDRESS MemoryAddress;
+
+ MemoryAddress = SIZE_4GB - 1;
+
+ //
+ // Patch some pointers for the ASL code before loading the SSDT.
+ //
+ for (OpRegion = (AML_OP_REGION_32_8 *)(Table + 1);
+ OpRegion <= (AML_OP_REGION_32_8 *)((UINT8 *)Table + Table->Length);
+ OpRegion = (AML_OP_REGION_32_8 *)((UINT8 *)OpRegion + 1))
+ {
+ if ((OpRegion->OpRegionOp == AML_EXT_REGION_OP) &&
+ (OpRegion->NameString == Name) &&
+ (OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&
+ (OpRegion->BytePrefix == AML_BYTE_PREFIX))
+ {
+ Status = gBS->AllocatePages (AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress);
+ ASSERT_EFI_ERROR (Status);
+ ZeroMem ((VOID *)(UINTN)MemoryAddress, Size);
+ OpRegion->RegionOffset = (UINT32)(UINTN)MemoryAddress;
+ OpRegion->RegionLen = (UINT8)Size;
+ break;
+ }
+ }
+
+ return (VOID *)(UINTN)MemoryAddress;
+}
+
+/**
+ Find the fTPM Control Area operation region in TCG ACPI table by given Name and Size,
+ and initialize it if the region is found.
+
+ @param[in, out] Table The TPM item in ACPI table.
+ @param[in] Name The name string to find in TPM table.
+ @param[in] ControlAreaAddr The Control Area address to set.
+ @param[in] ControlAreaSize The Control Area size to size.
+
+ @return The allocated address for the found region.
+
+**/
+EFI_STATUS
+PatchTpmControlAreaOpRegion (
+ EFI_ACPI_DESCRIPTION_HEADER *Table,
+ UINT32 Name,
+ UINT32 ControlAreaAddr,
+ UINT8 ControlAreaSize
+ )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ AML_OP_REGION_32_8 *OpRegion = NULL;
+
+ //
+ // Patch some pointers for the ASL code before loading the SSDT.
+ //
+ for (OpRegion = (AML_OP_REGION_32_8 *)(Table + 1);
+ OpRegion <= (AML_OP_REGION_32_8 *)((UINT8 *)Table + Table->Length);
+ OpRegion = (AML_OP_REGION_32_8 *)((UINT8 *)OpRegion + 1))
+ {
+ if ((OpRegion->OpRegionOp == AML_EXT_REGION_OP) &&
+ (OpRegion->NameString == Name) &&
+ (OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&
+ (OpRegion->BytePrefix == AML_BYTE_PREFIX))
+ {
+ OpRegion->RegionOffset = ControlAreaAddr;
+ OpRegion->RegionLen = ControlAreaSize;
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Patch the Memory32Fixed definitions in TCG ACPI table, and initialize their value for pre-defined signatures.
+
+ @param[in, out] Table The TPM item in ACPI table.
+ @param[in] CommandAddr The Command Address to set for certain signature in Memory32Fixed.
+ @param[in] ResponseAddr The Response Address to set for certain signature in Memory32Fixed.
+
+ @return The allocated address for the found region.
+
+**/
+EFI_STATUS
+AssignMemory32Fixed (
+ EFI_ACPI_DESCRIPTION_HEADER *Table,
+ UINT32 CommandAddr,
+ UINT32 ResponseAddr
+ )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINT8 *TmpPtr = NULL;
+ BOOLEAN CommandAddrPatched = FALSE;
+ BOOLEAN ResponseAddrPatched = FALSE;
+
+ //
+ // Patch some pointers for the ASL code before loading the SSDT.
+ //
+ for (TmpPtr = (UINT8 *)Table; TmpPtr <= (UINT8 *)Table + Table->Length; ) {
+ if (*(UINT32 *)TmpPtr == 0xA5A5A5A5) {
+ *(UINT32 *)TmpPtr = CommandAddr;
+ CommandAddrPatched = TRUE;
+ TmpPtr = TmpPtr + 4;
+ } else if (*(UINT32 *)TmpPtr == 0xAAAAAAAA) {
+ *(UINT32 *)TmpPtr = ResponseAddr;
+ ResponseAddrPatched = TRUE;
+ TmpPtr = TmpPtr + 4;
+ } else if (CommandAddrPatched && ResponseAddrPatched) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ ++TmpPtr;
+ }
+
+ return Status;
+}
+
+/**
+ Patch version string of Physical Presence interface supported by platform. The initial string tag in TPM
+ACPI table is "$PV".
+
+ @param[in, out] Table The TPM item in ACPI table.
+ @param[in] PPVer Version string of Physical Presence interface supported by platform.
+
+ @return The allocated address for the found region.
+
+**/
+EFI_STATUS
+UpdatePPVersion (
+ EFI_ACPI_DESCRIPTION_HEADER *Table,
+ CHAR8 *PPVer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *DataPtr;
+
+ //
+ // Patch some pointers for the ASL code before loading the SSDT.
+ //
+ for (DataPtr = (UINT8 *)(Table + 1);
+ DataPtr <= (UINT8 *)((UINT8 *)Table + Table->Length - PHYSICAL_PRESENCE_VERSION_SIZE);
+ DataPtr += 1)
+ {
+ if (AsciiStrCmp ((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_TAG) == 0) {
+ Status = AsciiStrCpyS ((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_SIZE, PPVer);
+ DEBUG ((DEBUG_INFO, "TPM2 Physical Presence Interface Version update status 0x%x\n", Status));
+ return Status;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Patch interrupt resources returned by TPM _PRS. ResourceTemplate to patch is determined by input
+ interrupt buffer size. BufferSize, PkgLength and interrupt descirptor in ByteList need to be patched
+
+ @param[in, out] Table The TPM item in ACPI table.
+ @param[in] IrqBuffer Input new IRQ buffer.
+ @param[in] IrqBuffserSize Input new IRQ buffer size.
+ @param[out] IsShortFormPkgLength If _PRS returns Short length Package(ACPI spec 20.2.4).
+
+ @return patch status.
+
+**/
+EFI_STATUS
+UpdatePossibleResource (
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER *Table,
+ IN UINT32 *IrqBuffer,
+ IN UINT32 IrqBuffserSize,
+ OUT BOOLEAN *IsShortFormPkgLength
+ )
+{
+ UINT8 *DataPtr;
+ UINT8 *DataEndPtr;
+ UINT32 NewPkgLength;
+ UINT32 OrignalPkgLength;
+
+ NewPkgLength = 0;
+ OrignalPkgLength = 0;
+ DataEndPtr = NULL;
+
+ //
+ // Follow ACPI spec
+ // 6.4.3 Extend Interrupt Descriptor.
+ // 19.3.3 ASL Resource Template
+ // 20 AML specification
+ // to patch TPM ACPI object _PRS returned ResourceTemplate() containing 2 resource descriptors and an auto appended End Tag
+ //
+ // AML data is organized by following rule.
+ // Code need to patch BufferSize and PkgLength and interrupt descirptor in ByteList
+ //
+ // ============= Buffer ====================
+ // DefBuffer := BufferOp PkgLength BufferSize ByteList
+ // BufferOp := 0x11
+ //
+ // ==============PkgLength==================
+ // PkgLength := PkgLeadByte |
+ // <PkgLeadByte ByteData> |
+ // <PkgLeadByte ByteData ByteData> |
+ // <PkgLeadByte ByteData ByteData ByteData>
+ //
+ // PkgLeadByte := <bit 7-6: ByteData count that follows (0-3)>
+ // <bit 5-4: Only used if PkgLength <= 63 >
+ // <bit 3-0: Least significant package length nybble>
+ //
+ // ==============BufferSize==================
+ // BufferSize := Integar
+ // Integar := ByteConst|WordConst|DwordConst....
+ //
+ // ByteConst := BytePrefix ByteData
+ //
+ // ==============ByteList===================
+ // ByteList := ByteData ByteList
+ //
+ // =========================================
+
+ //
+ // 1. Check TPM_PRS_RESS with PkgLength <=63 can hold the input interrupt number buffer for patching
+ //
+ for (DataPtr = (UINT8 *)(Table + 1);
+ DataPtr < (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE));
+ DataPtr += 1)
+ {
+ if (CompareMem (DataPtr, TPM_PRS_RESS, TPM_PRS_RES_NAME_SIZE) == 0) {
+ //
+ // Jump over object name & BufferOp
+ //
+ DataPtr += TPM_PRS_RES_NAME_SIZE + 1;
+
+ if ((*DataPtr & (BIT7|BIT6)) == 0) {
+ OrignalPkgLength = (UINT32)*DataPtr;
+ DataEndPtr = DataPtr + OrignalPkgLength;
+
+ //
+ // Jump over PkgLength = PkgLeadByte only
+ //
+ NewPkgLength++;
+
+ //
+ // Jump over BufferSize
+ //
+ if (*(DataPtr + 1) == AML_BYTE_PREFIX) {
+ NewPkgLength += 2;
+ } else if (*(DataPtr + 1) == AML_WORD_PREFIX) {
+ NewPkgLength += 3;
+ } else if (*(DataPtr + 1) == AML_DWORD_PREFIX) {
+ NewPkgLength += 5;
+ } else {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Include Memory32Fixed Descritor (12 Bytes) + Interrupt Descriptor header(5 Bytes) + End Tag(2 Bytes)
+ //
+ NewPkgLength += 19 + IrqBuffserSize;
+ if (NewPkgLength > 63) {
+ break;
+ }
+
+ if (NewPkgLength > OrignalPkgLength) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // 1.1 Patch PkgLength
+ //
+ *DataPtr = (UINT8)NewPkgLength;
+
+ //
+ // 1.2 Patch BufferSize = sizeof(Memory32Fixed Descritor + Interrupt Descriptor + End Tag).
+ // It is Little endian. So only patch lowest byte of BufferSize due to current interrupt number limit.
+ //
+ *(DataPtr + 2) = (UINT8)(IrqBuffserSize + 19);
+
+ //
+ // Notify _PRS to report short formed ResourceTemplate
+ //
+ *IsShortFormPkgLength = TRUE;
+
+ break;
+ }
+ }
+
+ //
+ // 2. Use TPM_PRS_RESL with PkgLength > 63 to hold longer input interrupt number buffer for patching
+ //
+ if (NewPkgLength > 63) {
+ NewPkgLength = 0;
+ OrignalPkgLength = 0;
+ for (DataPtr = (UINT8 *)(Table + 1);
+ DataPtr < (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE));
+ DataPtr += 1)
+ {
+ if (CompareMem (DataPtr, TPM_PRS_RESL, TPM_PRS_RES_NAME_SIZE) == 0) {
+ //
+ // Jump over object name & BufferOp
+ //
+ DataPtr += TPM_PRS_RES_NAME_SIZE + 1;
+
+ if ((*DataPtr & (BIT7|BIT6)) != 0) {
+ OrignalPkgLength = (UINT32)(*(DataPtr + 1) << 4) + (*DataPtr & 0x0F);
+ DataEndPtr = DataPtr + OrignalPkgLength;
+ //
+ // Jump over PkgLength = PkgLeadByte + ByteData length
+ //
+ NewPkgLength += 1 + ((*DataPtr & (BIT7|BIT6)) >> 6);
+
+ //
+ // Jump over BufferSize
+ //
+ if (*(DataPtr + NewPkgLength) == AML_BYTE_PREFIX) {
+ NewPkgLength += 2;
+ } else if (*(DataPtr + NewPkgLength) == AML_WORD_PREFIX) {
+ NewPkgLength += 3;
+ } else if (*(DataPtr + NewPkgLength) == AML_DWORD_PREFIX) {
+ NewPkgLength += 5;
+ } else {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Include Memory32Fixed Descritor (12 Bytes) + Interrupt Descriptor header(5 Bytes) + End Tag(2 Bytes)
+ //
+ NewPkgLength += 19 + IrqBuffserSize;
+
+ if (NewPkgLength > OrignalPkgLength) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // 2.1 Patch PkgLength. Only patch PkgLeadByte and first ByteData
+ //
+ *DataPtr = (UINT8)((*DataPtr) & 0xF0) | (NewPkgLength & 0x0F);
+ *(DataPtr + 1) = (UINT8)((NewPkgLength & 0xFF0) >> 4);
+
+ //
+ // 2.2 Patch BufferSize = sizeof(Memory32Fixed Descritor + Interrupt Descriptor + End Tag).
+ // It is Little endian. Only patch lowest byte of BufferSize due to current interrupt number limit.
+ //
+ *(DataPtr + 2 + ((*DataPtr & (BIT7|BIT6)) >> 6)) = (UINT8)(IrqBuffserSize + 19);
+
+ //
+ // Notify _PRS to report long formed ResourceTemplate
+ //
+ *IsShortFormPkgLength = FALSE;
+ break;
+ }
+ }
+ }
+
+ if (DataPtr >= (UINT8 *)((UINT8 *)Table + Table->Length - (TPM_PRS_RES_NAME_SIZE + TPM_POS_RES_TEMPLATE_MIN_SIZE))) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // 3. Move DataPtr to Interrupt descriptor header and patch interrupt descriptor.
+ // 5 bytes for interrupt descriptor header, 2 bytes for End Tag
+ //
+ DataPtr += NewPkgLength - (5 + IrqBuffserSize + 2);
+ //
+ // 3.1 Patch Length bit[7:0] of Interrupt descirptor patch interrupt descriptor
+ //
+ *(DataPtr + 1) = (UINT8)(2 + IrqBuffserSize);
+ //
+ // 3.2 Patch Interrupt Table Length
+ //
+ *(DataPtr + 4) = (UINT8)(IrqBuffserSize / sizeof (UINT32));
+ //
+ // 3.3 Copy patched InterruptNumBuffer
+ //
+ CopyMem (DataPtr + 5, IrqBuffer, IrqBuffserSize);
+
+ //
+ // 4. Jump over Interrupt descirptor and Patch END Tag, set Checksum field to 0
+ //
+ DataPtr += 5 + IrqBuffserSize;
+ *DataPtr = ACPI_END_TAG_DESCRIPTOR;
+ *(DataPtr + 1) = 0;
+
+ //
+ // 5. Jump over new ResourceTemplate. Stuff rest bytes to NOOP
+ //
+ DataPtr += 2;
+ if (DataPtr < DataEndPtr) {
+ SetMem (DataPtr, (UINTN)DataEndPtr - (UINTN)DataPtr, AML_NOOP_OP);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize and publish TPM items in ACPI table.
+
+ @retval EFI_SUCCESS The TCG ACPI table is published successfully.
+ @retval Others The TCG ACPI table is not published.
+
+**/
+EFI_STATUS
+PublishAcpiTable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ UINTN TableKey;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+ UINTN TableSize;
+ UINT32 *PossibleIrqNumBuf;
+ UINT32 PossibleIrqNumBufSize;
+ BOOLEAN IsShortFormPkgLength;
+
+ IsShortFormPkgLength = FALSE;
+
+ Status = GetSectionFromFv (
+ &gEfiCallerIdGuid,
+ EFI_SECTION_RAW,
+ 0,
+ (VOID **)&Table,
+ &TableSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update Table version before measuring it to PCR
+ //
+ Status = UpdatePPVersion (Table, (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer));
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((
+ DEBUG_INFO,
+ "Current physical presence interface version - %a\n",
+ (CHAR8 *)PcdGetPtr (PcdTcgPhysicalPresenceInterfaceVer)
+ ));
+
+ //
+
+ if (PcdGet32 (PcdTpm2CurrentIrqNum) != 0) {
+ //
+ // Patch _PRS interrupt resource only when TPM interrupt is supported
+ //
+ PossibleIrqNumBuf = (UINT32 *)PcdGetPtr (PcdTpm2PossibleIrqNumBuf);
+ PossibleIrqNumBufSize = (UINT32)PcdGetSize (PcdTpm2PossibleIrqNumBuf);
+
+ if ((PossibleIrqNumBufSize <= MAX_PRS_INT_BUF_SIZE) && ((PossibleIrqNumBufSize % sizeof (UINT32)) == 0)) {
+ Status = UpdatePossibleResource (Table, PossibleIrqNumBuf, PossibleIrqNumBufSize, &IsShortFormPkgLength);
+ DEBUG ((
+ DEBUG_INFO,
+ "UpdatePossibleResource status - %x. TPM2 service may not ready in OS.\n",
+ Status
+ ));
+ } else {
+ DEBUG ((
+ DEBUG_INFO,
+ "PcdTpm2PossibleIrqNumBuf size %x is not correct. TPM2 service may not ready in OS.\n",
+ PossibleIrqNumBufSize
+ ));
+ }
+ }
+
+ //
+ // Measure to PCR[0] with event EV_POST_CODE ACPI DATA
+ //
+ TpmMeasureAndLogData (
+ 0,
+ EV_POST_CODE,
+ EV_POSTCODE_INFO_ACPI_DATA,
+ ACPI_DATA_LEN,
+ Table,
+ TableSize
+ );
+
+ ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l'));
+ CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId));
+
+ DEBUG ((DEBUG_INFO, "FtpmControlArea: 0x%lX\n", (UINTN)(VOID *)mFtpmControlArea));
+ DEBUG ((DEBUG_INFO, "CommandSize: 0x%lX, ResponseSize: 0x%lX \n", mFtpmControlArea->CommandSize, mFtpmControlArea->ResponseSize));
+
+ Status = AssignMemory32Fixed (Table, (UINT32)mFtpmControlArea->CommandAddress, (UINT32)mFtpmControlArea->ResponseAddress);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PatchTpmControlAreaOpRegion (Table, SIGNATURE_32 ('T', 'P', 'M', 'C'), (UINT32)(UINTN)(VOID *)mFtpmControlArea + 0x10, sizeof (EFI_TPM2_ACPI_CONTROL_AREA));
+ ASSERT_EFI_ERROR (Status);
+
+ mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16)sizeof (TCG_NVS));
+ ASSERT (mTcgNvs != NULL);
+ mTcgNvs->TpmIrqNum = PcdGet32 (PcdTpm2CurrentIrqNum);
+ mTcgNvs->IsShortFormPkgLength = IsShortFormPkgLength;
+
+ //
+ // Publish the TPM ACPI table. Table is re-checksumed.
+ //
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
+ ASSERT_EFI_ERROR (Status);
+
+ TableKey = 0;
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ Table,
+ TableSize,
+ &TableKey
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Publish TPM2 ACPI table
+
+ @retval EFI_SUCCESS The TPM2 ACPI table is published successfully.
+ @retval Others The TPM2 ACPI table is not published.
+
+**/
+EFI_STATUS
+PublishTpm2 (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ UINTN TableKey;
+ UINT64 OemTableId;
+
+ mTpm2AcpiTemplate.Header.Revision = PcdGet8 (PcdTpm2AcpiTableRev);
+ DEBUG ((DEBUG_INFO, "Tpm2 ACPI table revision is %d\n", mTpm2AcpiTemplate.Header.Revision));
+
+ //
+ // PlatformClass is only valid for version 4 and above
+ // BIT0~15: PlatformClass
+ // BIT16~31: Reserved
+ //
+ if (mTpm2AcpiTemplate.Header.Revision >= EFI_TPM2_ACPI_TABLE_REVISION_4) {
+ mTpm2AcpiTemplate.Flags = (mTpm2AcpiTemplate.Flags & 0xFFFF0000) | PcdGet8 (PcdTpmPlatformClass);
+ DEBUG ((DEBUG_INFO, "Tpm2 ACPI table PlatformClass is %d\n", (mTpm2AcpiTemplate.Flags & 0x0000FFFF)));
+ }
+
+ //
+ // Measure to PCR[0] with event EV_POST_CODE ACPI DATA
+ //
+ TpmMeasureAndLogData (
+ 0,
+ EV_POST_CODE,
+ EV_POSTCODE_INFO_ACPI_DATA,
+ ACPI_DATA_LEN,
+ &mTpm2AcpiTemplate,
+ sizeof (mTpm2AcpiTemplate)
+ );
+
+ mTpm2AcpiTemplate.StartMethod = EFI_TPM2_ACPI_TABLE_START_METHOD_ACPI;
+ mTpm2AcpiTemplate.AddressOfControlArea = ((UINT64)(UINTN)(VOID *)mFtpmControlArea + 0x10);
+
+ CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId));
+ OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
+ CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
+ mTpm2AcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
+ mTpm2AcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
+ mTpm2AcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
+
+ //
+ // Construct ACPI table
+ //
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ &mTpm2AcpiTemplate,
+ sizeof (mTpm2AcpiTemplate),
+ &TableKey
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ The driver's entry point.
+
+ It install callbacks for TPM physical presence and MemoryClear, and locate
+ SMM variable to be used in the callback function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval Others Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeTcgSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
+ EFI_SMM_SW_REGISTER_CONTEXT SwContext;
+ EFI_HANDLE SwHandle;
+
+ DEBUG ((DEBUG_INFO, "InitializeTcgSmm Entry \n"));
+ if (!CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid)) {
+ DEBUG ((DEBUG_ERROR, "No TPM2 DTPM instance required!\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ // if (!GetFtpmControlArea(&mFtpmControlArea)) {
+ // DEBUG ((DEBUG_ERROR, "Get fTPM Control Area failed!\n"));
+ // return EFI_UNSUPPORTED;
+ // }
+ mFtpmControlArea = (VOID *)(UINTN)PcdGet64 (PcdTpmBaseAddress);
+ DEBUG ((DEBUG_INFO, "Get PcdTpmBaseAddress:%x\n", mFtpmControlArea));
+ Status = PublishAcpiTable ();
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get the Sw dispatch protocol and register SMI callback functions.
+ //
+ Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID **)&SwDispatch);
+ ASSERT_EFI_ERROR (Status);
+ SwContext.SwSmiInputValue = (UINTN)-1;
+ Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8)SwContext.SwSmiInputValue;
+ DEBUG ((DEBUG_INFO, "PhysicalPresence SoftwareSmi: 0x%X\n", (UINT8)SwContext.SwSmiInputValue));
+
+ SwContext.SwSmiInputValue = (UINTN)-1;
+ Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ mTcgNvs->MemoryClear.SoftwareSmi = (UINT8)SwContext.SwSmiInputValue;
+ DEBUG ((DEBUG_INFO, "MemoryClear SoftwareSmi: 0x%X\n", (UINT8)SwContext.SwSmiInputValue));
+
+ //
+ // Locate SmmVariableProtocol.
+ //
+ Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Set TPM2 ACPI table
+ //
+ Status = PublishTpm2 ();
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h
new file mode 100644
index 0000000000..0e9b367c80
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.h
@@ -0,0 +1,123 @@
+/** @file
+ The header file for Tcg2 SMM driver.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef TCG2_SMM_H_
+#define TCG2_SMM_H_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Tpm2Acpi.h>
+
+#include <Guid/MemoryOverwriteControl.h>
+#include <Guid/TpmInstance.h>
+
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/SmmVariable.h>
+#include <Protocol/Tcg2Protocol.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/TpmMeasurementLib.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/Tcg2PhysicalPresenceLib.h>
+#include <Library/IoLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include <Library/AmdPspCommonLib.h>
+#include <Library/AmdPspFtpmLib.h>
+#include <IndustryStandard/TpmPtp.h>
+
+#pragma pack(1)
+typedef struct {
+ UINT8 SoftwareSmi;
+ UINT32 Parameter;
+ UINT32 Response;
+ UINT32 Request;
+ UINT32 RequestParameter;
+ UINT32 LastRequest;
+ UINT32 ReturnCode;
+} PHYSICAL_PRESENCE_NVS;
+
+typedef struct {
+ UINT8 SoftwareSmi;
+ UINT32 Parameter;
+ UINT32 Request;
+ UINT32 ReturnCode;
+} MEMORY_CLEAR_NVS;
+
+typedef struct {
+ PHYSICAL_PRESENCE_NVS PhysicalPresence;
+ MEMORY_CLEAR_NVS MemoryClear;
+ UINT32 PPRequestUserConfirm;
+ UINT32 TpmIrqNum;
+ BOOLEAN IsShortFormPkgLength;
+} TCG_NVS;
+
+typedef struct {
+ UINT8 OpRegionOp;
+ UINT32 NameString;
+ UINT8 RegionSpace;
+ UINT8 DWordPrefix;
+ UINT32 RegionOffset;
+ UINT8 BytePrefix;
+ UINT8 RegionLen;
+} AML_OP_REGION_32_8;
+#pragma pack()
+
+//
+// The definition for TCG MOR
+//
+#define ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE 1
+#define ACPI_FUNCTION_PTS_CLEAR_MOR_BIT 2
+
+//
+// The return code for Memory Clear Interface Functions
+//
+#define MOR_REQUEST_SUCCESS 0
+#define MOR_REQUEST_GENERAL_FAILURE 1
+
+//
+// Physical Presence Interface Version supported by Platform
+//
+#define PHYSICAL_PRESENCE_VERSION_TAG "$PV"
+#define PHYSICAL_PRESENCE_VERSION_SIZE 4
+
+//
+// PNP _HID for TPM2 device
+//
+#define TPM_HID_TAG "NNNN0000"
+#define TPM_HID_PNP_SIZE 8
+#define TPM_HID_ACPI_SIZE 9
+
+#define TPM_PRS_RESL "RESL"
+#define TPM_PRS_RESS "RESS"
+#define TPM_PRS_RES_NAME_SIZE 4
+//
+// Minimum PRS resource template size
+// 1 byte for BufferOp
+// 1 byte for PkgLength
+// 2 bytes for BufferSize
+// 12 bytes for Memory32Fixed descriptor
+// 5 bytes for Interrupt descriptor
+// 2 bytes for END Tag
+//
+#define TPM_POS_RES_TEMPLATE_MIN_SIZE (1 + 1 + 2 + 12 + 5 + 2)
+
+//
+// Max Interrupt buffer size for PRS interrupt resource
+// Now support 15 interrupts in maxmum
+//
+#define MAX_PRS_INT_BUF_SIZE (15*4)
+#endif // TCG_SMM_H_
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf
new file mode 100644
index 0000000000..52419f55ea
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.inf
@@ -0,0 +1,92 @@
+## @file
+# Provides ACPI methods for fTPM 2.0 support
+#
+# Spec Compliance Info:
+# "TCG ACPI Specification Level 00 Revision 00.37"
+# "Physical Presence Interface Specification Version 1.30 Revision 00.52"
+# "Platform Reset Attack Mitigation Specification Version 1.00"
+# TPM2.0 ACPI device object
+# "TCG PC Client Platform Firmware Profile Specification for TPM Family 2.0 Level 00 Revision 00.21"
+#
+# This driver implements TPM 2.0 definition block in ACPI table and
+# registers SMI callback functions for Tcg2 physical presence and
+# MemoryClear to handle the requests from ACPI method.
+#
+# Caution: This module requires additional review when modified.
+# This driver will have external input - variable and ACPINvs data in SMM mode.
+# This external input must be validated carefully to avoid security issue.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Tcg2Smm
+ MODULE_UNI_FILE = Tcg2Smm.uni
+ FILE_GUID = 44A20657-10B8-4049-A148-ACD8812AF257
+ MODULE_TYPE = DXE_SMM_DRIVER
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeTcgSmm
+
+[Sources]
+ Tcg2Smm.h
+ Tcg2Smm.c
+ Tpm.asl
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ ChachaniBoardPkg/Project.dec
+ AgesaPublic/AgesaPublic.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ UefiDriverEntryPoint
+ SmmServicesTableLib
+ UefiBootServicesTableLib
+ DebugLib
+ DxeServicesLib
+ TpmMeasurementLib
+ Tcg2PhysicalPresenceLib
+ PcdLib
+ # AmdPspCommonLib
+
+[Guids]
+ ## SOMETIMES_PRODUCES ## Variable:L"MemoryOverwriteRequestControl"
+ ## SOMETIMES_CONSUMES ## Variable:L"MemoryOverwriteRequestControl"
+ gEfiMemoryOverwriteControlDataGuid
+ gEfiTpmDeviceInstanceTpm20DtpmGuid ## CONSUMES ## GUID # TPM device identifier
+
+[Protocols]
+ gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES
+ gEfiSmmVariableProtocolGuid ## CONSUMES
+ gEfiAcpiTableProtocolGuid ## CONSUMES
+
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## SOMETIMES_CONSUMES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer ## CONSUMES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev ## CONSUMES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass ## SOMETIMES_CONSUMES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpm2CurrentIrqNum ## CONSUMES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpm2PossibleIrqNumBuf ## CONSUMES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress
+
+[Depex]
+ gEfiAcpiTableProtocolGuid AND
+ gEfiSmmSwDispatch2ProtocolGuid AND
+ gEfiSmmVariableProtocolGuid AND
+ gEfiTcg2ProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ Tcg2SmmExtra.uni
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni
new file mode 100644
index 0000000000..d2cf9159c6
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2Smm.uni
@@ -0,0 +1,19 @@
+// /** @file
+// Provides ACPI metholds for fTPM 2.0 support
+//
+// This driver implements TPM 2.0 definition block in ACPI table and
+// registers SMI callback functions for TCG2 physical presence and
+// MemoryClear to handle the requests from ACPI method.
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides ACPI metholds for TPM 2.0 support"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This driver implements TPM 2.0 definition block in ACPI table and registers SMI callback functions for TCG2 physical presence and MemoryClear to handle the requests from ACPI method.\n"
+ "Caution: This module requires additional review when modified. This driver will have external input - variable and ACPINvs data in SMM mode. This external input must be validated carefully to avoid security issues."
+
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni
new file mode 100644
index 0000000000..b85ec10eba
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tcg2SmmExtra.uni
@@ -0,0 +1,15 @@
+// /** @file
+// Tcg2Smm Localized Strings and Content
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"TCG2 (Trusted Computing Group) SMM"
+
+
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tpm.asl b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tpm.asl
new file mode 100644
index 0000000000..a11ce43f85
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/AmdFtpm/FtpmTcg2Smm/Tpm.asl
@@ -0,0 +1,397 @@
+/** @file
+ The TPM2 definition block in ACPI table for TCG2 physical presence
+ and MemoryClear.
+
+Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+(c)Copyright 2016 HP Development Company, L.P.<BR>
+Copyright (c) 2017, Microsoft Corporation. All rights reserved. <BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+DefinitionBlock (
+ "Tpm.aml",
+ "SSDT",
+ 2,
+ "AMD ",
+ "Tpm2Tabl",
+ 0x1000
+ )
+{
+ Scope (\_SB)
+ {
+ Device (TPM)
+ {
+ //
+ // TCG2
+ //
+
+ //
+ // TAG for patching TPM2.0 _HID
+ //
+ Name (_HID, "MSFT0101")
+
+ Name (_CID, "MSFT0101")
+
+ //
+ // Readable name of this device, don't know if this way is correct yet
+ //
+ Name (_STR, Unicode ("TPM 2.0 Device"))
+
+ //
+ // Return the resource consumed by TPM device
+ //
+ Name (_CRS, ResourceTemplate () {
+ Memory32Fixed (ReadWrite, 0xA5A5A5A5, 0x4000) // Command Address
+ Memory32Fixed (ReadWrite, 0xAAAAAAAA, 0x4000) // Response Address
+ })
+
+ //
+ // Operational region for Smi port access, FixedPcdGet16 (PcdAmdFchCfgSmiCmdPortAddr)
+ //
+ OperationRegion (SMIP, SystemIO, 0xB0, 1)
+ Field (SMIP, ByteAcc, NoLock, Preserve)
+ {
+ IOB0, 8
+ }
+
+ //
+ // Operational region for fTPM control area.
+ // Region Offset 0xFFFF0000 and Length 0xF0 will be fixed in C code.
+ //
+ OperationRegion (TPMC, SystemMemory, 0xFFFF0000, 0xF0)
+ Field (TPMC, DWordAcc, NoLock, Preserve)
+ {
+ REQS, 32,
+ STAS, 32,
+ CANC, 32,
+ STAR, 32,
+ AccessAs (QWordAcc, 0),
+ INTC, 64,
+ AccessAs (DWordAcc, 0),
+ CMDS, 32,
+ AccessAs (QWordAcc, 0),
+ CMDA, 64,
+ AccessAs (DWordAcc, 0),
+ RSPS, 32,
+ AccessAs (QWordAcc, 0),
+ RSPA, 64
+ }
+
+ //
+ // Operational region for TPM support, TPM Physical Presence and TPM Memory Clear
+ // Region Offset 0xFFFF0000 and Length 0xF0 will be fixed in C code.
+ //
+ OperationRegion (TNVS, SystemMemory, 0xFFFF0000, 0xF0)
+ Field (TNVS, AnyAcc, NoLock, Preserve)
+ {
+ PPIN, 8, // Software SMI for Physical Presence Interface
+ PPIP, 32, // Used for save physical presence paramter
+ PPRP, 32, // Physical Presence request operation response
+ PPRQ, 32, // Physical Presence request operation
+ PPRM, 32, // Physical Presence request operation parameter
+ LPPR, 32, // Last Physical Presence request operation
+ FRET, 32, // Physical Presence function return code
+ MCIN, 8, // Software SMI for Memory Clear Interface
+ MCIP, 32, // Used for save the Mor paramter
+ MORD, 32, // Memory Overwrite Request Data
+ MRET, 32, // Memory Overwrite function return code
+ UCRQ, 32 // Phyical Presence request operation to Get User Confirmation Status
+ }
+
+ Method (PTS, 1, Serialized)
+ {
+ //
+ // Detect Sx state for MOR, only S4, S5 need to handle
+ //
+ If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3)))
+ {
+ //
+ // Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect.
+ //
+ If (LNot (And (MORD, 0x10)))
+ {
+ //
+ // Trigger the SMI through ACPI _PTS method.
+ //
+ Store (0x02, MCIP)
+
+ //
+ // Trigger the SMI interrupt
+ //
+ Store (MCIN, IOB0)
+ }
+ }
+ Return (0)
+ }
+
+ Method (_STA, 0)
+ {
+ Return (0x0f)
+ }
+
+ //
+ // TCG Hardware Information
+ //
+ Method (HINF, 3, Serialized, 0, {BuffObj, PkgObj}, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj
+ {
+ //
+ // Switch by function index
+ //
+ Switch (ToInteger(Arg1))
+ {
+ Case (0)
+ {
+ //
+ // Standard query
+ //
+ Return (Buffer () {0x03})
+ }
+ Case (1)
+ {
+ //
+ // Return failure if no TPM present
+ //
+ Name(TPMV, Package () {0x01, Package () {0x2, 0x0}})
+ if (LEqual (_STA (), 0x00))
+ {
+ Return (Package () {0x00})
+ }
+
+ //
+ // Return TPM version
+ //
+ Return (TPMV)
+ }
+ Default {BreakPoint}
+ }
+ Return (Buffer () {0})
+ }
+
+ Name(TPM2, Package (0x02){
+ Zero,
+ Zero
+ })
+
+ Name(TPM3, Package (0x03){
+ Zero,
+ Zero,
+ Zero
+ })
+
+ //
+ // TCG Physical Presence Interface
+ //
+ Method (TPPI, 3, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj
+ {
+ //
+ // Switch by function index
+ //
+ Switch (ToInteger(Arg1))
+ {
+ Case (0)
+ {
+ //
+ // Standard query, supports function 1-8
+ //
+ Return (Buffer () {0xFF, 0x01})
+ }
+ Case (1)
+ {
+ //
+ // a) Get Physical Presence Interface Version
+ //
+ Return ("$PV")
+ }
+ Case (2)
+ {
+ //
+ // b) Submit TPM Operation Request to Pre-OS Environment
+ //
+ Store (DerefOf (Index (Arg2, 0x00)), PPRQ)
+ Store (0, PPRM)
+ Store (0x02, PPIP)
+ //
+ // Trigger the SMI interrupt
+ //
+ Store (PPIN, IOB0)
+ Return (FRET)
+
+
+ }
+ Case (3)
+ {
+ //
+ // c) Get Pending TPM Operation Requested By the OS
+ //
+ Store (PPRQ, Index (TPM2, 0x01))
+ Return (TPM2)
+ }
+ Case (4)
+ {
+ //
+ // d) Get Platform-Specific Action to Transition to Pre-OS Environment
+ //
+ Return (2)
+ }
+ Case (5)
+ {
+ //
+ // e) Return TPM Operation Response to OS Environment
+ //
+ Store (0x05, PPIP)
+ //
+ // Trigger the SMI interrupt
+ //
+ Store (PPIN, IOB0)
+ Store (LPPR, Index (TPM3, 0x01))
+ Store (PPRP, Index (TPM3, 0x02))
+
+ Return (TPM3)
+ }
+ Case (6)
+ {
+
+ //
+ // f) Submit preferred user language (Not implemented)
+ //
+
+ Return (3)
+
+ }
+ Case (7)
+ {
+ //
+ // g) Submit TPM Operation Request to Pre-OS Environment 2
+ //
+ Store (7, PPIP)
+ Store (DerefOf (Index (Arg2, 0x00)), PPRQ)
+ Store (0, PPRM)
+ If (LEqual (PPRQ, 23)) {
+ Store (DerefOf (Index (Arg2, 0x01)), PPRM)
+ }
+ //
+ // Trigger the SMI interrupt
+ //
+ Store (PPIN, IOB0)
+ Return (FRET)
+ }
+ Case (8)
+ {
+ //
+ // e) Get User Confirmation Status for Operation
+ //
+ Store (8, PPIP)
+ Store (DerefOf (Index (Arg2, 0x00)), UCRQ)
+ //
+ // Trigger the SMI interrupt
+ //
+ Store (PPIN, IOB0)
+ Return (FRET)
+ }
+
+ Default {BreakPoint}
+ }
+ Return (1)
+ }
+
+ Method (TMCI, 3, Serialized, 0, IntObj, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj
+ {
+ //
+ // Switch by function index
+ //
+ Switch (ToInteger (Arg1))
+ {
+ Case (0)
+ {
+ //
+ // Standard query, supports function 1-1
+ //
+ Return (Buffer () {0x03})
+ }
+ Case (1)
+ {
+ //
+ // Save the Operation Value of the Request to MORD (reserved memory)
+ //
+ Store (DerefOf (Index (Arg2, 0x00)), MORD)
+ //
+ // Trigger the SMI through ACPI _DSM method.
+ //
+ Store (0x01, MCIP)
+ //
+ // Trigger the SMI interrupt
+ //
+ Store (MCIN, IOB0)
+ Return (MRET)
+ }
+ Default {BreakPoint}
+ }
+ Return (1)
+ }
+
+ // ACPI Start Method to permit the OS to request the firmware to execute or cancel a TPM 2.0 command.
+ Method (TPMS, 3, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {UnknownObj, UnknownObj, UnknownObj})
+ {
+ //
+ // Switch by function index
+ //
+ Switch (ToInteger(Arg1)) {
+
+ Case (0) {
+ //
+ // Standard query, supports function 1
+ //
+ Return (Buffer () {0x03})
+ }
+
+ Case (1) {
+ //
+ // Start
+ //
+ Return (0)
+ }
+
+ Default {BreakPoint}
+ }
+ Return (1)
+ }
+
+ Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj})
+ {
+ //
+ // TCG Hardware Information
+ //
+ If(LEqual(Arg0, ToUUID ("cf8e16a5-c1e8-4e25-b712-4f54a96702c8")))
+ {
+ Return (HINF (Arg1, Arg2, Arg3))
+ }
+ //
+ // TCG Physical Presence Interface
+ //
+ If(LEqual(Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653")))
+ {
+ Return (TPPI (Arg1, Arg2, Arg3))
+ }
+ //
+ // TCG Memory Clear Interface
+ //
+ If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d")))
+ {
+ Return (TMCI (Arg1, Arg2, Arg3))
+ }
+ //
+ // ACPI Start Method
+ //
+ If(LEqual (Arg0, ToUUID ("6bbf6cab-5463-4714-b7cd-f0203c0368d4")))
+ {
+ Return (TPMS (Arg1, Arg2, Arg3))
+ }
+
+ Return (Buffer () {0})
+ }
+ }
+ }
+}
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h
new file mode 100644
index 0000000000..8833c40f74
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigNvData.h
@@ -0,0 +1,124 @@
+/** @file
+ Header file for NV data structure definition.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef TCG2_CONFIG_NV_DATA_H_
+#define TCG2_CONFIG_NV_DATA_H_
+
+#include <Guid/HiiPlatformSetupFormset.h>
+#include <Guid/Tcg2ConfigHii.h>
+#include <IndustryStandard/TcgPhysicalPresence.h>
+
+//
+// BUGBUG: In order to pass VfrCompiler, we have to redefine below MACRO, which already in <Protocol/Tcg2Protocol.h>.
+//
+#ifndef TCG2_H_
+#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x00000001
+#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x00000002
+#endif
+#define EFI_TCG2_EVENT_LOG_FORMAT_ALL (EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
+
+#define TCG2_CONFIGURATION_VARSTORE_ID 0x0001
+#define TCG2_CONFIGURATION_INFO_VARSTORE_ID 0x0002
+#define TCG2_VERSION_VARSTORE_ID 0x0003
+#define TCG2_CONFIGURATION_FORM_ID 0x0001
+
+#define KEY_TPM_DEVICE 0x2000
+#define KEY_TPM2_OPERATION 0x2001
+#define KEY_TPM2_OPERATION_PARAMETER 0x2002
+#define KEY_TPM2_PCR_BANKS_REQUEST_0 0x2003
+#define KEY_TPM2_PCR_BANKS_REQUEST_1 0x2004
+#define KEY_TPM2_PCR_BANKS_REQUEST_2 0x2005
+#define KEY_TPM2_PCR_BANKS_REQUEST_3 0x2006
+#define KEY_TPM2_PCR_BANKS_REQUEST_4 0x2007
+#define KEY_TPM_DEVICE_INTERFACE 0x2008
+#define KEY_TCG2_PPI_VERSION 0x2009
+#define KEY_TPM2_ACPI_REVISION 0x200A
+
+#define TPM_DEVICE_NULL 0
+#define TPM_DEVICE_1_2 1
+#define TPM_DEVICE_2_0_DTPM 2
+#define TPM_DEVICE_MIN TPM_DEVICE_1_2
+#define TPM_DEVICE_MAX TPM_DEVICE_2_0_DTPM
+#define TPM_DEVICE_DEFAULT TPM_DEVICE_2_0_DTPM
+
+#define TPM2_ACPI_REVISION_3 3
+#define TPM2_ACPI_REVISION_4 4
+
+#define TPM_DEVICE_INTERFACE_TIS 0
+#define TPM_DEVICE_INTERFACE_PTP_FIFO 1
+#define TPM_DEVICE_INTERFACE_PTP_CRB 2
+#define TPM_DEVICE_INTERFACE_MAX TPM_DEVICE_INTERFACE_PTP_FIFO
+#define TPM_DEVICE_INTERFACE_DEFAULT TPM_DEVICE_INTERFACE_PTP_CRB
+
+#define TCG2_PROTOCOL_VERSION_DEFAULT 0x0001
+#define EFI_TCG2_EVENT_LOG_FORMAT_DEFAULT EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2
+
+#define TCG2_PPI_VERSION_1_2 0x322E31 // "1.2"
+#define TCG2_PPI_VERSION_1_3 0x332E31 // "1.3"
+
+//
+// Nv Data structure referenced by IFR, TPM device user desired
+//
+typedef struct {
+ UINT8 TpmDevice;
+} TCG2_CONFIGURATION;
+
+typedef struct {
+ UINT64 PpiVersion;
+ UINT8 Tpm2AcpiTableRev;
+} TCG2_VERSION;
+
+typedef struct {
+ BOOLEAN Sha1Supported;
+ BOOLEAN Sha256Supported;
+ BOOLEAN Sha384Supported;
+ BOOLEAN Sha512Supported;
+ BOOLEAN Sm3Supported;
+ UINT8 TpmDeviceInterfaceAttempt;
+ BOOLEAN TpmDeviceInterfacePtpFifoSupported;
+ BOOLEAN TpmDeviceInterfacePtpCrbSupported;
+} TCG2_CONFIGURATION_INFO;
+
+//
+// Variable saved for S3, TPM detected, only valid in S3 path.
+// This variable is ReadOnly.
+//
+typedef struct {
+ UINT8 TpmDeviceDetected;
+} TCG2_DEVICE_DETECTION;
+
+#define TCG2_STORAGE_NAME L"TCG2_CONFIGURATION"
+#define TCG2_STORAGE_INFO_NAME L"TCG2_CONFIGURATION_INFO"
+#define TCG2_DEVICE_DETECTION_NAME L"TCG2_DEVICE_DETECTION"
+#define TCG2_VERSION_NAME L"TCG2_VERSION"
+
+#define TPM_INSTANCE_ID_LIST { \
+ {TPM_DEVICE_INTERFACE_NONE, TPM_DEVICE_NULL}, \
+ {TPM_DEVICE_INTERFACE_TPM12, TPM_DEVICE_1_2}, \
+ {TPM_DEVICE_INTERFACE_TPM20_DTPM, TPM_DEVICE_2_0_DTPM}, \
+}
+
+//
+// BUGBUG: In order to pass VfrCompiler, we have to redefine GUID here.
+//
+#ifndef __BASE_H__
+typedef struct {
+ UINT32 Data1;
+ UINT16 Data2;
+ UINT16 Data3;
+ UINT8 Data4[8];
+} GUID;
+#endif
+
+typedef struct {
+ GUID TpmInstanceGuid;
+ UINT8 TpmDevice;
+} TPM_INSTANCE_ID;
+
+#endif
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
new file mode 100644
index 0000000000..e1530fb874
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf
@@ -0,0 +1,77 @@
+## @file
+# Set TPM device type
+#
+# This module initializes TPM device type based on variable and detection.
+# NOTE: This module is only for reference only, each platform should have its own setup page.
+#
+# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Tcg2ConfigPei
+ MODULE_UNI_FILE = Tcg2ConfigPei.uni
+ FILE_GUID = EADD5061-93EF-4CCC-8450-F78A7F0820F0
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = Tcg2ConfigPeimEntryPoint
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+# [BootMode]
+# S3_RESUME ## SOMETIMES_CONSUMES
+#
+
+[Sources]
+ Tcg2ConfigPeim.c
+ Tcg2ConfigNvData.h
+ TpmDetection.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+ ChachaniBoardPkg/Project.dec
+ AgesaPublic/AgesaPublic.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ PeiServicesLib
+ PeimEntryPoint
+ DebugLib
+ PcdLib
+ Tpm2CommandLib
+ Tpm2DeviceLib
+ IoLib
+ PciExpressLib
+
+[Guids]
+ ## SOMETIMES_CONSUMES ## Variable:L"TCG2_CONFIGURATION"
+ ## SOMETIMES_CONSUMES ## Variable:L"TCG2_DEVICE_DETECTION"
+ gTcg2ConfigFormSetGuid
+ gEfiTpmDeviceSelectedGuid ## PRODUCES ## GUID # Used as a PPI GUID
+ gEfiTpmDeviceInstanceNoneGuid ## SOMETIMES_CONSUMES ## GUID # TPM device identifier
+
+[Ppis]
+ gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES
+ gPeiTpmInitializationDonePpiGuid ## SOMETIMES_PRODUCES
+
+[Pcd]
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid ## PRODUCES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy ## PRODUCES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmAutoDetection ## CONSUMES
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress ## SOMETIMES_CONSUMES
+ gPlatformPkgTokenSpaceGuid.PcdSpiDtpmEnabled
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid AND
+ gEfiPeiMasterBootModePpiGuid AND
+ gEfiPeiReadOnlyVariable2PpiGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ Tcg2ConfigPeiExtra.uni
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni
new file mode 100644
index 0000000000..4d1e7ae6ac
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Set TPM device type
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#string STR_MODULE_ABSTRACT #language en-US "Set TPM device type"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module initializes TPM device type based on variable and detection.\n"
+ "NOTE: This module is only for reference only, each platform should have its own setup page."
+
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni
new file mode 100644
index 0000000000..0e79ee614a
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeiExtra.uni
@@ -0,0 +1,15 @@
+// /** @file
+// Tcg2ConfigDxe Localized Strings and Content
+//
+// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+// Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"TCG2 (Trusted Computing Group) Configuration DXE"
+
+
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c
new file mode 100644
index 0000000000..9d90581388
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPeim.c
@@ -0,0 +1,148 @@
+/** @file
+ The module entry point for Tcg2 configuration module.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Guid/TpmInstance.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/TpmInitialized.h>
+#include <Protocol/Tcg2Protocol.h>
+#include "Tcg2ConfigNvData.h"
+
+TPM_INSTANCE_ID mTpmInstanceId[] = TPM_INSTANCE_ID_LIST;
+
+CONST EFI_PEI_PPI_DESCRIPTOR gTpmSelectedPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTpmDeviceSelectedGuid,
+ NULL
+};
+
+EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTpmInitializationDonePpiGuid,
+ NULL
+};
+
+/**
+ This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration.
+
+ @param SetupTpmDevice TpmDevice configuration in setup driver
+
+ @return TpmDevice configuration
+**/
+UINT8
+DetectTpmDevice (
+ IN UINT8 SetupTpmDevice
+ );
+
+/**
+ The entry point for Tcg2 configuration driver.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCES Convert variable to PCD successfully.
+ @retval Others Fail to convert variable to PCD.
+**/
+EFI_STATUS
+EFIAPI
+Tcg2ConfigPeimEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ UINTN Size;
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;
+ TCG2_CONFIGURATION Tcg2Configuration;
+ UINTN Index;
+ UINT8 TpmDevice;
+
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&VariablePpi);
+ ASSERT_EFI_ERROR (Status);
+
+ Size = sizeof (Tcg2Configuration);
+ Status = VariablePpi->GetVariable (
+ VariablePpi,
+ TCG2_STORAGE_NAME,
+ &gTcg2ConfigFormSetGuid,
+ NULL,
+ &Size,
+ &Tcg2Configuration
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Variable not ready, set default value
+ //
+ Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;
+ }
+
+ //
+ // Validation
+ //
+ if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) {
+ Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;
+ }
+
+ //
+ // Although we have SetupVariable info, we still need detect TPM device manually.
+ //
+ DEBUG ((DEBUG_INFO, "Tcg2Configuration.TpmDevice from Setup: %x\n", Tcg2Configuration.TpmDevice));
+
+ if (PcdGetBool (PcdTpmAutoDetection)) {
+ TpmDevice = DetectTpmDevice (Tcg2Configuration.TpmDevice);
+ DEBUG ((DEBUG_INFO, "TpmDevice final: %x\n", TpmDevice));
+ if (TpmDevice != TPM_DEVICE_NULL) {
+ Tcg2Configuration.TpmDevice = TpmDevice;
+ }
+ } else {
+ TpmDevice = Tcg2Configuration.TpmDevice;
+ }
+
+ //
+ // Convert variable to PCD.
+ // This is work-around because there is no gurantee DynamicHiiPcd can return correct value in DXE phase.
+ // Using DynamicPcd instead.
+ //
+ // NOTE: Tcg2Configuration variable contains the desired TpmDevice type,
+ // while PcdTpmInstanceGuid PCD contains the real detected TpmDevice type
+ //
+ for (Index = 0; Index < sizeof (mTpmInstanceId)/sizeof (mTpmInstanceId[0]); Index++) {
+ if (TpmDevice == mTpmInstanceId[Index].TpmDevice) {
+ Size = sizeof (mTpmInstanceId[Index].TpmInstanceGuid);
+ Status = PcdSetPtrS (PcdTpmInstanceGuid, &Size, &mTpmInstanceId[Index].TpmInstanceGuid);
+ ASSERT_EFI_ERROR (Status);
+ DEBUG ((DEBUG_INFO, "TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid));
+ break;
+ }
+ }
+
+ //
+ // Selection done
+ //
+ Status = PeiServicesInstallPpi (&gTpmSelectedPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Even if no TPM is selected or detected, we still need intall TpmInitializationDonePpi.
+ // Because TcgPei or Tcg2Pei will not run, but we still need a way to notify other driver.
+ // Other driver can know TPM initialization state by TpmInitializedPpi.
+ //
+ if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid)) {
+ Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);
+ ASSERT_EFI_ERROR (Status2);
+ }
+
+ return Status;
+}
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/TpmDetection.c b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/TpmDetection.c
new file mode 100644
index 0000000000..4a31738b13
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/SecurityPkg/Tcg/Tcg2Config/TpmDetection.c
@@ -0,0 +1,99 @@
+/** @file
+ fTPM2.0/dTPM2.0 auto detection.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/IoLib.h>
+#include <IndustryStandard/Tpm20.h>
+#include "Tcg2ConfigNvData.h"
+
+EFI_STATUS
+InitDtpmInterface (
+ IN VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration.
+
+ @param SetupTpmDevice TpmDevice configuration in setup driver
+
+ @return TpmDevice configuration
+**/
+UINT8
+DetectTpmDevice (
+ IN UINT8 SetupTpmDevice
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ TCG2_DEVICE_DETECTION Tcg2DeviceDetection;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;
+ UINTN Size;
+
+ Status = PeiServicesGetBootMode (&BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // In S3, we rely on normal boot Detection, because we save to ReadOnly Variable in normal boot.
+ //
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ DEBUG ((DEBUG_INFO, "DetectTpmDevice: S3 mode\n"));
+
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&VariablePpi);
+ ASSERT_EFI_ERROR (Status);
+
+ Size = sizeof (TCG2_DEVICE_DETECTION);
+ ZeroMem (&Tcg2DeviceDetection, sizeof (Tcg2DeviceDetection));
+ Status = VariablePpi->GetVariable (
+ VariablePpi,
+ TCG2_DEVICE_DETECTION_NAME,
+ &gTcg2ConfigFormSetGuid,
+ NULL,
+ &Size,
+ &Tcg2DeviceDetection
+ );
+ if (!EFI_ERROR (Status) &&
+ (Tcg2DeviceDetection.TpmDeviceDetected >= TPM_DEVICE_MIN) &&
+ (Tcg2DeviceDetection.TpmDeviceDetected <= TPM_DEVICE_MAX))
+ {
+ DEBUG ((DEBUG_INFO, "TpmDevice from DeviceDetection: %x\n", Tcg2DeviceDetection.TpmDeviceDetected));
+ Status = Tpm2Startup (TPM_SU_STATE);
+ return Tcg2DeviceDetection.TpmDeviceDetected;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "DetectTpmDevice:\n"));
+
+ Status = Tpm2RequestUseTpm ();
+ if (EFI_ERROR (Status)) {
+ //
+ // TPM 2.0 not available
+ //
+ return TPM_DEVICE_NULL;
+ }
+
+ Status = Tpm2Startup (TPM_SU_CLEAR);
+ DEBUG ((DEBUG_INFO, "Tpm2Startup: %r\n", Status));
+ if (EFI_ERROR (Status)) {
+ return TPM_DEVICE_NULL;
+ }
+
+ return TPM_DEVICE_2_0_DTPM;
+}
--
2.31.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114596): https://edk2.groups.io/g/devel/message/114596
Mute This Topic: https://groups.io/mt/103975473/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2024 Red Hat, Inc.