mirror of https://github.com/acidanthera/audk.git
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:
parent
edae8d2dbd
commit
3aa764ed74
|
@ -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) {
|
||||
//
|
||||
|
|
|
@ -61,4 +61,5 @@
|
|||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr ## CONSUMES
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptRuntimeTableReservePageNumber ## CONSUMES
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue