]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
UefiCpuPkg/S3Resume2Pei: Send S3 resume finished event to SmmCore.
[mirror_edk2.git] / UefiCpuPkg / Universal / Acpi / S3Resume2Pei / S3Resume.c
index e53ed21bdc6a6d9e2b32bf409a8990fb5b65d2b7..c2171cbd4641d4d4b6fffe2ac662127f9241de1e 100644 (file)
@@ -28,6 +28,9 @@
 #include <Ppi/SmmAccess.h>\r
 #include <Ppi/PostBootScriptTable.h>\r
 #include <Ppi/EndOfPeiPhase.h>\r
+#include <Ppi/SmmCommunication.h>\r
+\r
+#include <Protocol/SmmEndOfS3Resume.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseLib.h>\r
@@ -151,6 +154,22 @@ typedef union {
   UINT64    Uint64;\r
 } PAGE_TABLE_1G_ENTRY;\r
 \r
+//\r
+// Define two type of smm communicate headers.\r
+// One for 32 bits  PEI + 64 bits DXE, the other for 32 bits PEI + 32 bits DXE case.\r
+//\r
+typedef struct {\r
+  EFI_GUID  HeaderGuid;\r
+  UINT32    MessageLength;\r
+  UINT8     Data[1];\r
+} SMM_COMMUNICATE_HEADER_32;\r
+\r
+typedef struct {\r
+  EFI_GUID  HeaderGuid;\r
+  UINT64    MessageLength;\r
+  UINT8     Data[1];\r
+} SMM_COMMUNICATE_HEADER_64;\r
+\r
 #pragma pack()\r
 \r
 //\r
@@ -429,6 +448,68 @@ IsLongModeWakingVector (
   return FALSE;\r
 }\r
 \r
+/**\r
+  Send EndOfS3Resume event to SmmCore through communication buffer way.\r
+\r
+  @retval  EFI_SUCCESS                 Return send the event success.\r
+**/\r
+EFI_STATUS\r
+SignalEndOfS3Resume (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                         Status;\r
+  EFI_PEI_SMM_COMMUNICATION_PPI      *SmmCommunicationPpi;\r
+  UINTN                              CommSize;\r
+  SMM_COMMUNICATE_HEADER_32          Header32;\r
+  SMM_COMMUNICATE_HEADER_64          Header64;\r
+  VOID                               *CommBuffer;\r
+\r
+  DEBUG ((EFI_D_INFO, "SignalEndOfS3Resume - Enter\n"));\r
+\r
+  //\r
+  // This buffer consumed in DXE phase, so base on DXE mode to prepare communicate buffer.\r
+  // Detect whether DXE is 64 bits mode.\r
+  // if (sizeof(UINTN) == sizeof(UINT64), PEI already 64 bits, assume DXE also 64 bits.\r
+  // or (FeaturePcdGet (PcdDxeIplSwitchToLongMode)), Dxe will switch to 64 bits.\r
+  //\r
+  if ((sizeof(UINTN) == sizeof(UINT64)) || (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {\r
+    CommBuffer = &Header64;\r
+    Header64.MessageLength = 0;\r
+    CommSize = OFFSET_OF (SMM_COMMUNICATE_HEADER_64, Data);\r
+  } else {\r
+    CommBuffer = &Header32;\r
+    Header32.MessageLength = 0;\r
+    CommSize = OFFSET_OF (SMM_COMMUNICATE_HEADER_32, Data);\r
+  }\r
+  CopyGuid (CommBuffer, &gEdkiiSmmEndOfS3ResumeProtocolGuid);\r
+\r
+  //\r
+  // Get needed resource\r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+             &gEfiPeiSmmCommunicationPpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&SmmCommunicationPpi\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Send command\r
+  //\r
+  Status = SmmCommunicationPpi->Communicate (\r
+                                  SmmCommunicationPpi,\r
+                                  (VOID *)CommBuffer,\r
+                                  &CommSize\r
+                                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  DEBUG ((EFI_D_INFO, "SignalEndOfS3Resume - Exit (%r)\n", Status));\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   Jump to OS waking vector.\r
   The function will install boot script done PPI, report S3 resume status code, and then jump to OS waking vector.\r
@@ -503,6 +584,12 @@ S3ResumeBootOs (
   Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  //\r
+  // Signal EndOfS3Resume event.\r
+  //\r
+  Status = SignalEndOfS3Resume ();\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   //\r
   // report status code on S3 resume\r
   //\r