From 3aa764ed7477d45ee78c7080c9f7624e62d10346 Mon Sep 17 00:00:00 2001 From: lzeng14 Date: Thu, 6 Dec 2012 01:15:40 +0000 Subject: [PATCH] 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 Reviewed-by: Jiewen Yao git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13984 6f19259b-4bc3-4df7-8a09-765794883524 --- .../PiDxeS3BootScriptLib/BootScriptSave.c | 40 ++++++++++++++----- .../DxeS3BootScriptLib.inf | 1 + MdeModulePkg/MdeModulePkg.dec | 6 +++ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c index 09dc2c4ec3..afb5ed1bb3 100644 --- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c +++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c @@ -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) { // diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf b/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf index 26eecaf412..e84aabac95 100644 --- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf +++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf @@ -61,4 +61,5 @@ [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptRuntimeTableReservePageNumber ## CONSUMES diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index d3d1a299b4..710e3e6a04 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -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 +