]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/AcpiS3SaveDxe/AcpiS3Save.c
OvmfPkg: S3 Suspend: save boot script after ACPI context
[mirror_edk2.git] / OvmfPkg / AcpiS3SaveDxe / AcpiS3Save.c
index 80f12eb77abbae78b50a06538f446f2e16810cc7..684ddb70114a3890ffcb49022fb0add79c923e0d 100644 (file)
@@ -28,6 +28,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Guid/AcpiS3Context.h>\r
 #include <Guid/Acpi.h>\r
 #include <Protocol/AcpiS3Save.h>\r
+#include <Protocol/S3SaveState.h>\r
+#include <Protocol/DxeSmmReadyToLock.h>\r
 #include <IndustryStandard/Acpi.h>\r
 \r
 #include "AcpiS3Save.h"\r
@@ -406,6 +408,48 @@ LegacyGetS3MemorySize (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Save the S3 boot script.\r
+\r
+  Note that we trigger DxeSmmReadyToLock here -- otherwise the script wouldn't\r
+  be saved actually. Triggering this protocol installation event in turn locks\r
+  down SMM, so no further changes to LockBoxes or SMRAM are possible\r
+  afterwards.\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+SaveS3BootScript (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                 Status;\r
+  EFI_S3_SAVE_STATE_PROTOCOL *BootScript;\r
+  EFI_HANDLE                 Handle;\r
+  STATIC CONST UINT8         Info[] = { 0xDE, 0xAD, 0xBE, 0xEF };\r
+\r
+  Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL,\r
+                  (VOID **) &BootScript);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Despite the opcode documentation in the PI spec, the protocol\r
+  // implementation embeds a deep copy of the info in the boot script, rather\r
+  // than storing just a pointer to runtime or NVS storage.\r
+  //\r
+  Status = BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPCODE,\r
+                         (UINT32) sizeof Info,\r
+                         (EFI_PHYSICAL_ADDRESS)(UINTN) &Info);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Handle = NULL;\r
+  Status = gBS->InstallProtocolInterface (&Handle,\r
+                  &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,\r
+                  NULL);\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+\r
 /**\r
   Prepares all information that is needed in the S3 resume boot path.\r
   \r
@@ -511,6 +555,11 @@ S3Ready (
   Status = SetLockBoxAttributes (&gEfiAcpiS3ContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  //\r
+  // Save the boot script too. Note that this requires/includes emitting the\r
+  // DxeSmmReadyToLock event, which in turn locks down SMM.\r
+  //\r
+  SaveS3BootScript ();\r
   return EFI_SUCCESS;\r
 }\r
 \r