Multi-SMM drivers couldn't save their boot script successfully all at runtime in SMM, one module's boot script will overwrite another module's.

Allocate a SMM copy for private data structure, and use a new PCD PcdS3BootScriptTablePrivateSmmDataPtr to transfer and share data between multi-SMM drivers.

Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13984 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lzeng14 2012-12-06 01:15:40 +00:00
parent edae8d2dbd
commit 3aa764ed74
3 changed files with 38 additions and 9 deletions

View File

@ -41,9 +41,9 @@
SCRIPT_TABLE_PRIVATE_DATA *mS3BootScriptTablePtr;
EFI_EVENT mEnterRuntimeEvent;
//
// Allocate local copy in SMM because we can not use mS3BootScriptTablePtr when we AtRuntime in InSmm.
// Allocate SMM copy because we can not use mS3BootScriptTablePtr when we AtRuntime in InSmm.
//
SCRIPT_TABLE_PRIVATE_DATA mS3BootScriptTable;
SCRIPT_TABLE_PRIVATE_DATA *mS3BootScriptTableSmmPtr;
UINTN mLockBoxLength;
EFI_GUID mBootScriptDataGuid = {
@ -212,7 +212,7 @@ S3BootScriptSmmEventCallBack (
//
// Check if it is already done
//
if (mS3BootScriptTablePtr == &mS3BootScriptTable) {
if (mS3BootScriptTablePtr == mS3BootScriptTableSmmPtr) {
return EFI_SUCCESS;
}
@ -222,13 +222,15 @@ S3BootScriptSmmEventCallBack (
S3BootScriptEventCallBack (NULL, NULL);
//
// Save a local copy
// Save a SMM copy. If TableBase is NOT null, it means SMM copy has been ready, skip copy mem.
//
CopyMem (&mS3BootScriptTable, mS3BootScriptTablePtr, sizeof(*mS3BootScriptTablePtr));
if (mS3BootScriptTableSmmPtr->TableBase == NULL) {
CopyMem (mS3BootScriptTableSmmPtr, mS3BootScriptTablePtr, sizeof(*mS3BootScriptTablePtr));
}
//
// We should not use ACPINvs copy, because it is not safe.
//
mS3BootScriptTablePtr = &mS3BootScriptTable;
mS3BootScriptTablePtr = mS3BootScriptTableSmmPtr;
//
// Set InSmm, we allow boot script update when InSmm, but not allow boot script outside SMM.
@ -239,7 +241,7 @@ S3BootScriptSmmEventCallBack (
//
// Record LockBoxLength
//
mLockBoxLength = mS3BootScriptTable.TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE);
mLockBoxLength = mS3BootScriptTableSmmPtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE);
return EFI_SUCCESS;
}
@ -264,6 +266,7 @@ S3BootScriptLibInitialize (
{
EFI_STATUS Status;
SCRIPT_TABLE_PRIVATE_DATA *S3TablePtr;
SCRIPT_TABLE_PRIVATE_DATA *S3TableSmmPtr;
VOID *Registration;
EFI_SMM_BASE2_PROTOCOL *SmmBase2;
BOOLEAN InSmm;
@ -325,6 +328,25 @@ S3BootScriptLibInitialize (
return RETURN_SUCCESS;
}
S3TableSmmPtr = (SCRIPT_TABLE_PRIVATE_DATA*)(UINTN)PcdGet64(PcdS3BootScriptTablePrivateSmmDataPtr);
//
// The Boot script private data in SMM is not be initialized. create it
//
if (S3TableSmmPtr == 0) {
Status = Smst->SmmAllocatePool (
EfiRuntimeServicesData,
sizeof(SCRIPT_TABLE_PRIVATE_DATA),
(VOID **) &S3TableSmmPtr
);
if (EFI_ERROR (Status)) {
return RETURN_OUT_OF_RESOURCES;
}
PcdSet64 (PcdS3BootScriptTablePrivateSmmDataPtr, (UINT64) (UINTN)S3TableSmmPtr);
ZeroMem (S3TableSmmPtr, sizeof(SCRIPT_TABLE_PRIVATE_DATA));
}
mS3BootScriptTableSmmPtr = S3TableSmmPtr;
//
// Then register event after lock
//
@ -495,12 +517,12 @@ S3BootScriptGetEntryAddAddress (
}
//
// NOTE: OS will restore ACPINvs data. After S3, the table length in mS3BootScriptTable (SMM) is different with
// NOTE: OS will restore ACPINvs data. After S3, the table length in mS3BootScriptTableSmmPtr (SMM) is different with
// table length in BootScriptTable header (ACPINvs).
// So here we need sync them. We choose ACPINvs table length, because we want to override the boot script saved
// in SMM every time.
//
ASSERT (mS3BootScriptTablePtr == &mS3BootScriptTable);
ASSERT (mS3BootScriptTablePtr == mS3BootScriptTableSmmPtr);
CopyMem ((VOID*)&TableHeader, (VOID*)mS3BootScriptTablePtr->TableBase, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));
if (mS3BootScriptTablePtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE) != TableHeader.TableLength) {
//

View File

@ -61,4 +61,5 @@
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptRuntimeTableReservePageNumber ## CONSUMES

View File

@ -852,3 +852,9 @@
# default value is set to Zero. And the PCD is assumed ONLY to be accessed in DxeS3BootScriptLib Library.
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0|UINT64|0x00030000
## This dynamic PCD hold an address to point to private data structure SMM copy used in DxeS3BootScriptLib library
# instance which records the S3 boot script table start address, length, etc. To introduce this PCD is
# only for DxeS3BootScriptLib instance implementation purpose. The platform developer should make sure the
# default value is set to Zero. And the PCD is assumed ONLY to be accessed in DxeS3BootScriptLib Library.
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr|0x0|UINT64|0x00030001