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;
|
SCRIPT_TABLE_PRIVATE_DATA *mS3BootScriptTablePtr;
|
||||||
EFI_EVENT mEnterRuntimeEvent;
|
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;
|
UINTN mLockBoxLength;
|
||||||
|
|
||||||
EFI_GUID mBootScriptDataGuid = {
|
EFI_GUID mBootScriptDataGuid = {
|
||||||
|
@ -212,7 +212,7 @@ S3BootScriptSmmEventCallBack (
|
||||||
//
|
//
|
||||||
// Check if it is already done
|
// Check if it is already done
|
||||||
//
|
//
|
||||||
if (mS3BootScriptTablePtr == &mS3BootScriptTable) {
|
if (mS3BootScriptTablePtr == mS3BootScriptTableSmmPtr) {
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,13 +222,15 @@ S3BootScriptSmmEventCallBack (
|
||||||
S3BootScriptEventCallBack (NULL, NULL);
|
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.
|
// 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.
|
// Set InSmm, we allow boot script update when InSmm, but not allow boot script outside SMM.
|
||||||
|
@ -239,7 +241,7 @@ S3BootScriptSmmEventCallBack (
|
||||||
//
|
//
|
||||||
// Record LockBoxLength
|
// Record LockBoxLength
|
||||||
//
|
//
|
||||||
mLockBoxLength = mS3BootScriptTable.TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE);
|
mLockBoxLength = mS3BootScriptTableSmmPtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -264,6 +266,7 @@ S3BootScriptLibInitialize (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
SCRIPT_TABLE_PRIVATE_DATA *S3TablePtr;
|
SCRIPT_TABLE_PRIVATE_DATA *S3TablePtr;
|
||||||
|
SCRIPT_TABLE_PRIVATE_DATA *S3TableSmmPtr;
|
||||||
VOID *Registration;
|
VOID *Registration;
|
||||||
EFI_SMM_BASE2_PROTOCOL *SmmBase2;
|
EFI_SMM_BASE2_PROTOCOL *SmmBase2;
|
||||||
BOOLEAN InSmm;
|
BOOLEAN InSmm;
|
||||||
|
@ -325,6 +328,25 @@ S3BootScriptLibInitialize (
|
||||||
return RETURN_SUCCESS;
|
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
|
// 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).
|
// 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
|
// So here we need sync them. We choose ACPINvs table length, because we want to override the boot script saved
|
||||||
// in SMM every time.
|
// in SMM every time.
|
||||||
//
|
//
|
||||||
ASSERT (mS3BootScriptTablePtr == &mS3BootScriptTable);
|
ASSERT (mS3BootScriptTablePtr == mS3BootScriptTableSmmPtr);
|
||||||
CopyMem ((VOID*)&TableHeader, (VOID*)mS3BootScriptTablePtr->TableBase, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));
|
CopyMem ((VOID*)&TableHeader, (VOID*)mS3BootScriptTablePtr->TableBase, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));
|
||||||
if (mS3BootScriptTablePtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE) != TableHeader.TableLength) {
|
if (mS3BootScriptTablePtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE) != TableHeader.TableLength) {
|
||||||
//
|
//
|
||||||
|
|
|
@ -61,4 +61,5 @@
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr ## CONSUMES
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr ## CONSUMES
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptRuntimeTableReservePageNumber ## 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.
|
# default value is set to Zero. And the PCD is assumed ONLY to be accessed in DxeS3BootScriptLib Library.
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0|UINT64|0x00030000
|
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