+\r
+/**\r
+ Library Destructor to free the resources allocated by\r
+ S3BootScriptLibInitialize() and unregister callbacks.\r
+\r
+ NOTICE: The destructor doesn't support unloading as a separate action, and it\r
+ only supports unloading if the containing driver's entry point function fails.\r
+\r
+ @param ImageHandle The firmware allocated handle for the EFI image.\r
+ @param SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval RETURN_SUCCESS The destructor always returns RETURN_SUCCESS.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+S3BootScriptLibDeinitialize (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ DEBUG ((EFI_D_INFO, "%a() in %a module\n", __FUNCTION__, gEfiCallerBaseName));\r
+\r
+ if (mEventDxeSmmReadyToLock != NULL) {\r
+ //\r
+ // Close the DxeSmmReadyToLock event.\r
+ //\r
+ Status = gBS->CloseEvent (mEventDxeSmmReadyToLock);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ if (mBootScriptSmst != NULL) {\r
+ if (mRegistrationSmmExitBootServices != NULL) {\r
+ //\r
+ // Unregister SmmExitBootServices notification.\r
+ //\r
+ Status = mBootScriptSmst->SmmRegisterProtocolNotify (\r
+ &gEdkiiSmmExitBootServicesProtocolGuid,\r
+ NULL,\r
+ &mRegistrationSmmExitBootServices\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ if (mRegistrationSmmLegacyBoot != NULL) {\r
+ //\r
+ // Unregister SmmLegacyBoot notification.\r
+ //\r
+ Status = mBootScriptSmst->SmmRegisterProtocolNotify (\r
+ &gEdkiiSmmLegacyBootProtocolGuid,\r
+ NULL,\r
+ &mRegistrationSmmLegacyBoot\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ if (mRegistrationSmmReadyToLock != NULL) {\r
+ //\r
+ // Unregister SmmReadyToLock notification.\r
+ //\r
+ Status = mBootScriptSmst->SmmRegisterProtocolNotify (\r
+ &gEfiSmmReadyToLockProtocolGuid,\r
+ NULL,\r
+ &mRegistrationSmmReadyToLock\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Free the resources allocated and set PCDs to 0.\r
+ //\r
+ if (mS3BootScriptTableAllocated) {\r
+ Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) mS3BootScriptTablePtr, EFI_SIZE_TO_PAGES(sizeof(SCRIPT_TABLE_PRIVATE_DATA)));\r
+ ASSERT_EFI_ERROR (Status);\r
+ Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, 0);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ if ((mBootScriptSmst != NULL) && mS3BootScriptTableSmmAllocated) {\r
+ Status = mBootScriptSmst->SmmFreePool (mS3BootScriptTableSmmPtr);\r
+ ASSERT_EFI_ERROR (Status);\r
+ Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, 0);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r