/** @file\r
- Save the S3 data to S3 boot script. \r
- \r
- Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+ Save the S3 data to S3 boot script.\r
+\r
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions\r
0x627ee2da, 0x3bf9, 0x439b, { 0x92, 0x9f, 0x2e, 0xe, 0x6e, 0x9d, 0xba, 0x62 }\r
};\r
\r
+EFI_EVENT mEventDxeSmmReadyToLock = NULL;\r
+VOID *mRegistrationSmmExitBootServices = NULL;\r
+VOID *mRegistrationSmmLegacyBoot = NULL;\r
+VOID *mRegistrationSmmReadyToLock = NULL;\r
+BOOLEAN mS3BootScriptTableAllocated = FALSE;\r
+BOOLEAN mS3BootScriptTableSmmAllocated = FALSE;\r
+EFI_SMM_SYSTEM_TABLE2 *mSmst = NULL;\r
+\r
/**\r
This is an internal function to add a terminate node the entry, recalculate the table \r
length and fill into the table. \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 Allocate the global memory space to store S3 boot script table private data\r
- @retval RETURN_OUT_OF_RESOURCES No enough memory to allocated.\r
+ @retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS.\r
+\r
**/\r
RETURN_STATUS\r
EFIAPI\r
VOID *Registration;\r
EFI_SMM_BASE2_PROTOCOL *SmmBase2;\r
BOOLEAN InSmm;\r
- EFI_SMM_SYSTEM_TABLE2 *Smst;\r
EFI_PHYSICAL_ADDRESS Buffer;\r
- EFI_EVENT Event;\r
\r
if (!PcdGetBool (PcdAcpiS3Enable)) {\r
return RETURN_SUCCESS;\r
EFI_SIZE_TO_PAGES(sizeof(SCRIPT_TABLE_PRIVATE_DATA)),\r
&Buffer\r
);\r
- if (EFI_ERROR (Status)) {\r
- return RETURN_OUT_OF_RESOURCES;\r
- }\r
+ ASSERT_EFI_ERROR (Status);\r
+ mS3BootScriptTableAllocated = TRUE;\r
S3TablePtr = (VOID *) (UINTN) Buffer;\r
\r
Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, (UINT64) (UINTN)S3TablePtr);\r
ASSERT_EFI_ERROR (Status);\r
- ZeroMem (S3TablePtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA)); \r
+ ZeroMem (S3TablePtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA));\r
//\r
// Create event to notify the library system enter the SmmLocked phase.\r
//\r
- Event = EfiCreateProtocolNotifyEvent (\r
- &gEfiDxeSmmReadyToLockProtocolGuid,\r
- TPL_CALLBACK,\r
- S3BootScriptEventCallBack,\r
- NULL,\r
- &Registration\r
- );\r
- ASSERT (Event != NULL);\r
+ mEventDxeSmmReadyToLock = EfiCreateProtocolNotifyEvent (\r
+ &gEfiDxeSmmReadyToLockProtocolGuid,\r
+ TPL_CALLBACK,\r
+ S3BootScriptEventCallBack,\r
+ NULL,\r
+ &Registration\r
+ );\r
+ ASSERT (mEventDxeSmmReadyToLock != NULL);\r
}\r
mS3BootScriptTablePtr = S3TablePtr;\r
\r
//\r
// Good, we are in SMM\r
//\r
- Status = SmmBase2->GetSmstLocation (SmmBase2, &Smst);\r
+ Status = SmmBase2->GetSmstLocation (SmmBase2, &mSmst);\r
if (EFI_ERROR (Status)) {\r
return RETURN_SUCCESS;\r
}\r
// The Boot script private data in SMM is not be initialized. create it\r
//\r
if (S3TableSmmPtr == 0) {\r
- Status = Smst->SmmAllocatePool (\r
+ Status = mSmst->SmmAllocatePool (\r
EfiRuntimeServicesData,\r
sizeof(SCRIPT_TABLE_PRIVATE_DATA),\r
(VOID **) &S3TableSmmPtr\r
);\r
- if (EFI_ERROR (Status)) {\r
- return RETURN_OUT_OF_RESOURCES;\r
- }\r
+ ASSERT_EFI_ERROR (Status);\r
+ mS3BootScriptTableSmmAllocated = TRUE;\r
\r
Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, (UINT64) (UINTN)S3TableSmmPtr);\r
ASSERT_EFI_ERROR (Status);\r
//\r
// Register SmmExitBootServices and SmmLegacyBoot notification.\r
//\r
- Registration = NULL;\r
- Status = Smst->SmmRegisterProtocolNotify (\r
+ Status = mSmst->SmmRegisterProtocolNotify (\r
&gEdkiiSmmExitBootServicesProtocolGuid,\r
S3BootScriptSmmAtRuntimeCallBack,\r
- &Registration\r
+ &mRegistrationSmmExitBootServices\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- Registration = NULL;\r
- Status = Smst->SmmRegisterProtocolNotify (\r
+ Status = mSmst->SmmRegisterProtocolNotify (\r
&gEdkiiSmmLegacyBootProtocolGuid,\r
S3BootScriptSmmAtRuntimeCallBack,\r
- &Registration\r
+ &mRegistrationSmmLegacyBoot\r
);\r
ASSERT_EFI_ERROR (Status);\r
}\r
//\r
// Register SmmReadyToLock notification.\r
//\r
- Registration = NULL;\r
- Status = Smst->SmmRegisterProtocolNotify (\r
+ Status = mSmst->SmmRegisterProtocolNotify (\r
&gEfiSmmReadyToLockProtocolGuid,\r
S3BootScriptSmmEventCallBack,\r
- &Registration\r
+ &mRegistrationSmmReadyToLock\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
return RETURN_SUCCESS;\r
}\r
+\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 (mSmst != NULL) {\r
+ if (mRegistrationSmmExitBootServices != NULL) {\r
+ //\r
+ // Unregister SmmExitBootServices notification.\r
+ //\r
+ Status = mSmst->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 = mSmst->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 = mSmst->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 (mS3BootScriptTableSmmAllocated) {\r
+ Status = mSmst->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
/**\r
To get the start address from which a new boot time s3 boot script entry will write into.\r
If the table is not exist, the functio will first allocate a buffer for the table\r