0xaea6b965, 0xdcf5, 0x4311, { 0xb4, 0xb8, 0xf, 0x12, 0x46, 0x44, 0x94, 0xd2 }\r
};\r
\r
+EFI_GUID mBootScriptDataOrgGuid = {\r
+ 0xb5af1d7a, 0xb8cf, 0x4eb3, { 0x89, 0x25, 0xa8, 0x20, 0xe1, 0x6b, 0x68, 0x7d }\r
+};\r
+\r
EFI_GUID mBootScriptHeaderDataGuid = {\r
0x1810ab4a, 0x2314, 0x4df6, { 0x81, 0xeb, 0x67, 0xc6, 0xec, 0x5, 0x85, 0x91 }\r
};\r
Status = SetLockBoxAttributes (&mBootScriptDataGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ //\r
+ // We need duplicate the original copy, because it may have INSERT boot script at runtime in SMM.\r
+ // If so, we should use original copy to restore data after OS rewrites the ACPINvs region.\r
+ // Or the data inserted may cause some original boot script data lost.\r
+ //\r
+ Status = SaveLockBox (\r
+ &mBootScriptDataOrgGuid,\r
+ (VOID *)mS3BootScriptTablePtr->TableBase,\r
+ mS3BootScriptTablePtr->TableLength + sizeof(EFI_BOOT_SCRIPT_TERMINATE)\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
//\r
// Just need save TableBase.\r
// Do not update other field because they will NOT be used in S3.\r
UINT8* NewEntryPtr;\r
EFI_BOOT_SCRIPT_TABLE_HEADER TableHeader;\r
EFI_STATUS Status;\r
+ UINTN OrgLockBoxLength;\r
\r
if (mS3BootScriptTablePtr->AtRuntime) {\r
//\r
//\r
// Restore it to use original value\r
//\r
- RestoreLockBox (&mBootScriptDataGuid, NULL, NULL);\r
+ OrgLockBoxLength = mLockBoxLength;\r
+ Status = RestoreLockBox (\r
+ &mBootScriptDataOrgGuid,\r
+ (VOID *)mS3BootScriptTablePtr->TableBase,\r
+ &OrgLockBoxLength\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ ASSERT (OrgLockBoxLength == mLockBoxLength);\r
+\r
+ //\r
+ // Update the current BootScriptData into LockBox as well\r
+ //\r
+ Status = UpdateLockBox (\r
+ &mBootScriptDataGuid,\r
+ 0,\r
+ (VOID *)mS3BootScriptTablePtr->TableBase,\r
+ OrgLockBoxLength\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
//\r
- // Copy it again to get original value\r
// NOTE: We should NOT use TableHeader.TableLength, because it is already updated to be whole length.\r
//\r
mS3BootScriptTablePtr->TableLength = (UINT32)(mLockBoxLength - sizeof(EFI_BOOT_SCRIPT_TERMINATE));\r
}\r
\r
NewEntryPtr = S3BootScriptGetRuntimeEntryAddAddress (EntryLength);\r
- //\r
- // Now the length field is updated, need sync to lockbox.\r
- // So in S3 resume, the data can be restored correctly.\r
- //\r
- CopyMem ((VOID*)&TableHeader, (VOID*)mS3BootScriptTablePtr->TableBase, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));\r
- Status = UpdateLockBox (\r
- &mBootScriptDataGuid,\r
- OFFSET_OF(EFI_BOOT_SCRIPT_TABLE_HEADER, TableLength),\r
- &TableHeader.TableLength,\r
- sizeof(TableHeader.TableLength)\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
+\r
+ if (EntryLength != 0) {\r
+ //\r
+ // Now the length field is updated, need sync to lockbox.\r
+ // So in S3 resume, the data can be restored correctly.\r
+ //\r
+ CopyMem ((VOID*)&TableHeader, (VOID*)mS3BootScriptTablePtr->TableBase, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));\r
+ Status = UpdateLockBox (\r
+ &mBootScriptDataGuid,\r
+ OFFSET_OF(EFI_BOOT_SCRIPT_TABLE_HEADER, TableLength),\r
+ &TableHeader.TableLength,\r
+ sizeof(TableHeader.TableLength)\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
} else { \r
NewEntryPtr = S3BootScriptGetBootTimeEntryAddAddress (EntryLength);\r
} \r
\r
/**\r
Sync BootScript LockBox data.\r
+\r
+ @param Script The address from where the boot script has been added or updated.\r
+\r
**/\r
VOID\r
SyncBootScript (\r
- VOID\r
+ IN UINT8 *Script\r
)\r
{\r
EFI_STATUS Status;\r
+ UINTN ScriptOffset;\r
+\r
+ ScriptOffset = (UINTN) (Script - mS3BootScriptTablePtr->TableBase);\r
\r
- if (!mS3BootScriptTablePtr->AtRuntime || !mS3BootScriptTablePtr->InSmm) {\r
+ if (!mS3BootScriptTablePtr->AtRuntime || !mS3BootScriptTablePtr->InSmm || ScriptOffset >= mLockBoxLength) {\r
+ //\r
+ // If it is not at runtime in SMM or in the range that needs to be synced in LockBox, just return.\r
+ //\r
return ;\r
}\r
+\r
//\r
- // Update Terminate\r
+ // Update BootScriptData\r
// So in S3 resume, the data can be restored correctly.\r
//\r
Status = UpdateLockBox (\r
&mBootScriptDataGuid,\r
- mLockBoxLength - sizeof(EFI_BOOT_SCRIPT_TERMINATE),\r
- (VOID *)((UINTN)mS3BootScriptTablePtr->TableBase + mLockBoxLength - sizeof(EFI_BOOT_SCRIPT_TERMINATE)),\r
- sizeof(EFI_BOOT_SCRIPT_TERMINATE)\r
+ ScriptOffset,\r
+ (VOID *)((UINTN)mS3BootScriptTablePtr->TableBase + ScriptOffset),\r
+ mLockBoxLength - ScriptOffset\r
);\r
ASSERT_EFI_ERROR (Status);\r
}\r
CopyMem ((VOID*)Script, (VOID*)&ScriptIoWrite, sizeof(EFI_BOOT_SCRIPT_IO_WRITE));\r
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_IO_WRITE)), Buffer, WidthInByte * Count);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE)), Data, WidthInByte);\r
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE) + WidthInByte), DataMask, WidthInByte);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
CopyMem ((VOID*)Script, (VOID*)&ScriptMemWrite, sizeof(EFI_BOOT_SCRIPT_MEM_WRITE));\r
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_WRITE)), Buffer, WidthInByte * Count);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE)), Data, WidthInByte);\r
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE) + WidthInByte), DataMask, WidthInByte);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
CopyMem ((VOID*)Script, (VOID*)&ScriptPciWrite, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE));\r
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE)), Buffer, WidthInByte * Count);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
WidthInByte\r
);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
/**\r
- Adds a record for a PCI configuration space modify operation into a specified boot script table.\r
+ Adds a record for a PCI configuration 2 space write operation into a specified boot script table.\r
\r
@param Width The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.\r
@param Segment The PCI segment number for Address.\r
CopyMem ((VOID*)Script, (VOID*)&ScriptPciWrite2, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE));\r
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE)), Buffer, WidthInByte * Count);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
/**\r
- Adds a record for a PCI configuration space modify operation into a specified boot script table.\r
+ Adds a record for a PCI configuration 2 space modify operation into a specified boot script table.\r
\r
@param Width The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.\r
@param Segment The PCI segment number for Address.\r
WidthInByte\r
);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
(*Length)\r
);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
\r
CopyMem ((VOID*)Script, (VOID*)&ScriptStall, sizeof (EFI_BOOT_SCRIPT_STALL));\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
/**\r
- Adds a record for an execution stall on the processor into a specified boot script table.\r
+ Adds a record for dispatching specified arbitrary code into a specified boot script table.\r
\r
@param EntryPoint Entry point of the code to be dispatched.\r
@param Context Argument to be passed into the EntryPoint of the code to be dispatched.\r
\r
CopyMem ((VOID*)Script, (VOID*)&ScriptDispatch2, sizeof (EFI_BOOT_SCRIPT_DISPATCH_2));\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
\r
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_MEM_POLL) + WidthInByte), BitMask, WidthInByte);\r
CopyMem ((VOID*)Script, (VOID*)&ScriptMemPoll, sizeof (EFI_BOOT_SCRIPT_MEM_POLL)); \r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
CopyMem ((VOID*)Script, (VOID*)&ScriptInformation, sizeof (EFI_BOOT_SCRIPT_INFORMATION));\r
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION)), (VOID *) Information, (UINTN) InformationLength);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
\r
\r
CopyMem ((VOID*)Script, (VOID*)&ScriptDispatch, sizeof (EFI_BOOT_SCRIPT_DISPATCH)); \r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
\r
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_IO_POLL)), Data, WidthInByte);\r
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_IO_POLL) + WidthInByte), DataMask, WidthInByte);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL)), Data, WidthInByte);\r
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL) + WidthInByte), DataMask, WidthInByte);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL)), Data, WidthInByte);\r
CopyMem ((UINT8 *) (Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL) + WidthInByte), DataMask, WidthInByte);\r
\r
- SyncBootScript ();\r
+ SyncBootScript (Script);\r
\r
return RETURN_SUCCESS;\r
}\r
\r
ValidatePosition = FALSE;\r
TempPosition = (Position == NULL) ? NULL:(*Position);\r
- Script = mS3BootScriptTablePtr->TableBase;\r
- if (Script == 0) { \r
- return EFI_OUT_OF_RESOURCES;\r
+\r
+ //\r
+ // Check that the script is initialized and synced without adding an entry to the script.\r
+ //\r
+ Script = S3BootScriptGetEntryAddAddress (0);\r
+ if (Script == NULL) {\r
+ return RETURN_OUT_OF_RESOURCES;\r
}\r
+ Script = mS3BootScriptTablePtr->TableBase;\r
+\r
StartAddress = (UINTN) Script;\r
TableLength = mS3BootScriptTablePtr->TableLength;\r
Script = Script + sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);\r
//\r
// Copy the node to Boot script table\r
//\r
- CopyMem((VOID*)Script, (VOID*)TempBootScriptEntry, ScriptHeader.Length); \r
+ CopyMem((VOID*)Script, (VOID*)TempBootScriptEntry, ScriptHeader.Length);\r
+\r
+ SyncBootScript (Script);\r
+\r
//\r
// return out the Position\r
//\r
CopyMem ((VOID*)Script, (VOID*)&ScriptInformation, sizeof (EFI_BOOT_SCRIPT_INFORMATION));\r
CopyMem ((VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION)), (VOID *) Information, (UINTN) InformationLength);\r
\r
+ SyncBootScript (Script);\r
+\r
return S3BootScriptMoveLastOpcode (BeforeOrAfter, Position);\r
\r
}\r
}\r
\r
//\r
- // Check that the script is initialized without adding an entry to the script.\r
- // The code must search for the label first befor it knows if a new entry needs\r
+ // Check that the script is initialized and synced without adding an entry to the script.\r
+ // The code must search for the label first before it knows if a new entry needs\r
// to be added.\r
//\r
Script = S3BootScriptGetEntryAddAddress (0);\r
UINT8* Script;\r
UINT32 TableLength; \r
\r
- Script = mS3BootScriptTablePtr->TableBase;\r
- if (Script == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
if (RelativePosition == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
+\r
+ //\r
+ // Check that the script is initialized and synced without adding an entry to the script.\r
+ //\r
+ Script = S3BootScriptGetEntryAddAddress (0);\r
+ if (Script == NULL) {\r
+ return RETURN_OUT_OF_RESOURCES;\r
+ }\r
+ Script = mS3BootScriptTablePtr->TableBase;\r
+\r
//\r
// mS3BootScriptTablePtr->TableLength does not include the termination node, so add it up\r
//\r