#include <Protocol/VariableWrite.h>\r
#include <Protocol/Tcg2Protocol.h>\r
#include <Protocol/TrEEProtocol.h>\r
+#include <Protocol/ResetNotification.h>\r
\r
#include <Library/DebugLib.h>\r
#include <Library/BaseMemoryLib.h>\r
\r
}\r
\r
+/**\r
+ This routine is called to properly shutdown the TPM before system reset.\r
+ It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
+ Part 1: Architecture, Revision 01.16.\r
+\r
+ @param[in] ResetType The type of reset to perform.\r
+ @param[in] ResetStatus The status code for the reset.\r
+ @param[in] DataSize The size, in bytes, of ResetData.\r
+ @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or\r
+ EfiResetShutdown the data buffer starts with a Null-terminated\r
+ string, optionally followed by additional binary data.\r
+ The string is a description that the caller may use to further\r
+ indicate the reason for the system reset. ResetData is only\r
+ valid if ResetStatus is something other than EFI_SUCCESS\r
+ unless the ResetType is EfiResetPlatformSpecific\r
+ where a minimum amount of ResetData is always required.\r
+ For a ResetType of EfiResetPlatformSpecific the data buffer\r
+ also starts with a Null-terminated string that is followed\r
+ by an EFI_GUID that describes the specific type of reset to perform.\r
+**/\r
+VOID\r
+EFIAPI\r
+ShutdownTpmOnReset (\r
+ IN EFI_RESET_TYPE ResetType,\r
+ IN EFI_STATUS ResetStatus,\r
+ IN UINTN DataSize,\r
+ IN VOID *ResetData OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ Status = Tpm2Shutdown (TPM_SU_CLEAR);\r
+ DEBUG ((DEBUG_VERBOSE, "Tpm2Shutdown (SU_CLEAR) - %r\n", Status));\r
+}\r
+\r
+/**\r
+ Hook the system reset to properly shutdown TPM.\r
+ It follow chapter "12.2.3 Startup State" in Trusted Platform Module Library\r
+ Part 1: Architecture, Revision 01.16.\r
+\r
+ @param[in] Event Event whose notification function is being invoked\r
+ @param[in] Context Pointer to the notification function's context\r
+**/\r
+VOID\r
+EFIAPI\r
+OnResetNotificationInstall (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_RESET_NOTIFICATION_PROTOCOL *ResetNotify;\r
+\r
+ Status = gBS->LocateProtocol (&gEfiResetNotificationProtocolGuid, NULL, (VOID **) &ResetNotify);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = ResetNotify->RegisterResetNotify (ResetNotify, ShutdownTpmOnReset);\r
+ ASSERT_EFI_ERROR (Status);\r
+ DEBUG ((DEBUG_VERBOSE, "TCG2: Hook system reset to properly shutdown TPM.\n"));\r
+\r
+ gBS->CloseEvent (Event);\r
+ }\r
+}\r
+\r
/**\r
The function install Tcg2 protocol.\r
\r
// may update SecureBoot value based on last setting.\r
//\r
EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
+\r
+ //\r
+ // Hook the system reset to properly shutdown TPM.\r
+ //\r
+ EfiCreateProtocolNotifyEvent (&gEfiResetNotificationProtocolGuid, TPL_CALLBACK, OnResetNotificationInstall, NULL, &Registration);\r
}\r
\r
//\r