diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c index d954503f86..0bd0bd04f6 100644 --- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c +++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c @@ -1,7 +1,7 @@ /** @file - Save the S3 data to S3 boot script. - - Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+ Save the S3 data to S3 boot script. + + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions @@ -124,6 +124,14 @@ EFI_GUID mBootScriptSmmPrivateDataGuid = { 0x627ee2da, 0x3bf9, 0x439b, { 0x92, 0x9f, 0x2e, 0xe, 0x6e, 0x9d, 0xba, 0x62 } }; +EFI_EVENT mEventDxeSmmReadyToLock = NULL; +VOID *mRegistrationSmmExitBootServices = NULL; +VOID *mRegistrationSmmLegacyBoot = NULL; +VOID *mRegistrationSmmReadyToLock = NULL; +BOOLEAN mS3BootScriptTableAllocated = FALSE; +BOOLEAN mS3BootScriptTableSmmAllocated = FALSE; +EFI_SMM_SYSTEM_TABLE2 *mSmst = NULL; + /** This is an internal function to add a terminate node the entry, recalculate the table length and fill into the table. @@ -417,8 +425,8 @@ S3BootScriptSmmAtRuntimeCallBack ( @param ImageHandle The firmware allocated handle for the EFI image. @param SystemTable A pointer to the EFI System Table. - @retval RETURN_SUCCESS Allocate the global memory space to store S3 boot script table private data - @retval RETURN_OUT_OF_RESOURCES No enough memory to allocated. + @retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS. + **/ RETURN_STATUS EFIAPI @@ -433,9 +441,7 @@ S3BootScriptLibInitialize ( VOID *Registration; EFI_SMM_BASE2_PROTOCOL *SmmBase2; BOOLEAN InSmm; - EFI_SMM_SYSTEM_TABLE2 *Smst; EFI_PHYSICAL_ADDRESS Buffer; - EFI_EVENT Event; if (!PcdGetBool (PcdAcpiS3Enable)) { return RETURN_SUCCESS; @@ -453,25 +459,24 @@ S3BootScriptLibInitialize ( EFI_SIZE_TO_PAGES(sizeof(SCRIPT_TABLE_PRIVATE_DATA)), &Buffer ); - if (EFI_ERROR (Status)) { - return RETURN_OUT_OF_RESOURCES; - } + ASSERT_EFI_ERROR (Status); + mS3BootScriptTableAllocated = TRUE; S3TablePtr = (VOID *) (UINTN) Buffer; Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, (UINT64) (UINTN)S3TablePtr); ASSERT_EFI_ERROR (Status); - ZeroMem (S3TablePtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA)); + ZeroMem (S3TablePtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA)); // // Create event to notify the library system enter the SmmLocked phase. // - Event = EfiCreateProtocolNotifyEvent ( - &gEfiDxeSmmReadyToLockProtocolGuid, - TPL_CALLBACK, - S3BootScriptEventCallBack, - NULL, - &Registration - ); - ASSERT (Event != NULL); + mEventDxeSmmReadyToLock = EfiCreateProtocolNotifyEvent ( + &gEfiDxeSmmReadyToLockProtocolGuid, + TPL_CALLBACK, + S3BootScriptEventCallBack, + NULL, + &Registration + ); + ASSERT (mEventDxeSmmReadyToLock != NULL); } mS3BootScriptTablePtr = S3TablePtr; @@ -492,7 +497,7 @@ S3BootScriptLibInitialize ( // // Good, we are in SMM // - Status = SmmBase2->GetSmstLocation (SmmBase2, &Smst); + Status = SmmBase2->GetSmstLocation (SmmBase2, &mSmst); if (EFI_ERROR (Status)) { return RETURN_SUCCESS; } @@ -502,14 +507,13 @@ S3BootScriptLibInitialize ( // The Boot script private data in SMM is not be initialized. create it // if (S3TableSmmPtr == 0) { - Status = Smst->SmmAllocatePool ( + Status = mSmst->SmmAllocatePool ( EfiRuntimeServicesData, sizeof(SCRIPT_TABLE_PRIVATE_DATA), (VOID **) &S3TableSmmPtr ); - if (EFI_ERROR (Status)) { - return RETURN_OUT_OF_RESOURCES; - } + ASSERT_EFI_ERROR (Status); + mS3BootScriptTableSmmAllocated = TRUE; Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, (UINT64) (UINTN)S3TableSmmPtr); ASSERT_EFI_ERROR (Status); @@ -518,19 +522,17 @@ S3BootScriptLibInitialize ( // // Register SmmExitBootServices and SmmLegacyBoot notification. // - Registration = NULL; - Status = Smst->SmmRegisterProtocolNotify ( + Status = mSmst->SmmRegisterProtocolNotify ( &gEdkiiSmmExitBootServicesProtocolGuid, S3BootScriptSmmAtRuntimeCallBack, - &Registration + &mRegistrationSmmExitBootServices ); ASSERT_EFI_ERROR (Status); - Registration = NULL; - Status = Smst->SmmRegisterProtocolNotify ( + Status = mSmst->SmmRegisterProtocolNotify ( &gEdkiiSmmLegacyBootProtocolGuid, S3BootScriptSmmAtRuntimeCallBack, - &Registration + &mRegistrationSmmLegacyBoot ); ASSERT_EFI_ERROR (Status); } @@ -539,16 +541,103 @@ S3BootScriptLibInitialize ( // // Register SmmReadyToLock notification. // - Registration = NULL; - Status = Smst->SmmRegisterProtocolNotify ( + Status = mSmst->SmmRegisterProtocolNotify ( &gEfiSmmReadyToLockProtocolGuid, S3BootScriptSmmEventCallBack, - &Registration + &mRegistrationSmmReadyToLock ); ASSERT_EFI_ERROR (Status); return RETURN_SUCCESS; } + +/** + Library Destructor to free the resources allocated by + S3BootScriptLibInitialize() and unregister callbacks. + + NOTICE: The destructor doesn't support unloading as a separate action, and it + only supports unloading if the containing driver's entry point function fails. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval RETURN_SUCCESS The destructor always returns RETURN_SUCCESS. + +**/ +RETURN_STATUS +EFIAPI +S3BootScriptLibDeinitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "%a() in %a module\n", __FUNCTION__, gEfiCallerBaseName)); + + if (mEventDxeSmmReadyToLock != NULL) { + // + // Close the DxeSmmReadyToLock event. + // + Status = gBS->CloseEvent (mEventDxeSmmReadyToLock); + ASSERT_EFI_ERROR (Status); + } + + if (mSmst != NULL) { + if (mRegistrationSmmExitBootServices != NULL) { + // + // Unregister SmmExitBootServices notification. + // + Status = mSmst->SmmRegisterProtocolNotify ( + &gEdkiiSmmExitBootServicesProtocolGuid, + NULL, + &mRegistrationSmmExitBootServices + ); + ASSERT_EFI_ERROR (Status); + } + if (mRegistrationSmmLegacyBoot != NULL) { + // + // Unregister SmmLegacyBoot notification. + // + Status = mSmst->SmmRegisterProtocolNotify ( + &gEdkiiSmmLegacyBootProtocolGuid, + NULL, + &mRegistrationSmmLegacyBoot + ); + ASSERT_EFI_ERROR (Status); + } + if (mRegistrationSmmReadyToLock != NULL) { + // + // Unregister SmmReadyToLock notification. + // + Status = mSmst->SmmRegisterProtocolNotify ( + &gEfiSmmReadyToLockProtocolGuid, + NULL, + &mRegistrationSmmReadyToLock + ); + ASSERT_EFI_ERROR (Status); + } + } + + // + // Free the resources allocated and set PCDs to 0. + // + if (mS3BootScriptTableAllocated) { + Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) mS3BootScriptTablePtr, EFI_SIZE_TO_PAGES(sizeof(SCRIPT_TABLE_PRIVATE_DATA))); + ASSERT_EFI_ERROR (Status); + Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, 0); + ASSERT_EFI_ERROR (Status); + } + if (mS3BootScriptTableSmmAllocated) { + Status = mSmst->SmmFreePool (mS3BootScriptTableSmmPtr); + ASSERT_EFI_ERROR (Status); + Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, 0); + ASSERT_EFI_ERROR (Status); + } + + return RETURN_SUCCESS; +} + /** To get the start address from which a new boot time s3 boot script entry will write into. If the table is not exist, the functio will first allocate a buffer for the table diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf b/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf index 4e0919ea2c..0f4151180f 100644 --- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf +++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf @@ -1,7 +1,7 @@ ## @file # DXE S3 boot script Library. # -# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
# # This program and the accompanying materials are # licensed and made available under the terms and conditions of the BSD License @@ -24,6 +24,7 @@ CONSTRUCTOR = S3BootScriptLibInitialize + DESTRUCTOR = S3BootScriptLibDeinitialize # # The following information is for reference only and not required by the build tools.