]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
UefiCpuPkg S3ResumePei: Signal S3SmmInitDone
[mirror_edk2.git] / UefiCpuPkg / Universal / Acpi / S3Resume2Pei / S3Resume.c
index e0c2d366cd0de86918bc0e52d935656a7c39d273..4ae168a2c3ce4cad274a679019b29328fa4b88ca 100644 (file)
@@ -4,7 +4,7 @@
   This module will execute the boot script saved during last boot and after that,\r
   control is passed to OS waking up handler.\r
 \r
-  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
   Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
@@ -22,7 +22,9 @@
 \r
 #include <Guid/AcpiS3Context.h>\r
 #include <Guid/BootScriptExecutorVariable.h>\r
-#include <Guid/Performance.h>\r
+#include <Guid/ExtendedFirmwarePerformance.h>\r
+#include <Guid/EndOfS3Resume.h>\r
+#include <Guid/S3SmmInitDone.h>\r
 #include <Ppi/ReadOnlyVariable2.h>\r
 #include <Ppi/S3Resume2.h>\r
 #include <Ppi/SmmAccess.h>\r
@@ -30,8 +32,6 @@
 #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
 #include <Library/TimerLib.h>\r
@@ -156,7 +156,7 @@ typedef union {
 \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
+// 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
@@ -260,6 +260,12 @@ EFI_PEI_PPI_DESCRIPTOR mPpiListEndOfPeiTable = {
   0\r
 };\r
 \r
+EFI_PEI_PPI_DESCRIPTOR mPpiListS3SmmInitDoneTable = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEdkiiS3SmmInitDoneGuid,\r
+  0\r
+};\r
+\r
 //\r
 // Global Descriptor Table (GDT)\r
 //\r
@@ -286,132 +292,6 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR mGdt = {
   (UINTN) mGdtEntries\r
   };\r
 \r
-/**\r
-  Performance measure function to get S3 detailed performance data.\r
-\r
-  This function will getS3 detailed performance data and saved in pre-reserved ACPI memory.\r
-**/\r
-VOID\r
-WriteToOsS3PerformanceData (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS                                    Status;\r
-  EFI_PHYSICAL_ADDRESS                          mAcpiLowMemoryBase;\r
-  PERF_HEADER                                   *PerfHeader;\r
-  PERF_DATA                                     *PerfData;\r
-  UINT64                                        Ticker;\r
-  UINTN                                         Index;\r
-  EFI_PEI_READ_ONLY_VARIABLE2_PPI               *VariableServices;\r
-  UINTN                                         VarSize;\r
-  UINTN                                         LogEntryKey;\r
-  CONST VOID                                    *Handle;\r
-  CONST CHAR8                                   *Token;\r
-  CONST CHAR8                                   *Module;\r
-  UINT64                                        StartTicker;\r
-  UINT64                                        EndTicker;\r
-  UINT64                                        StartValue;\r
-  UINT64                                        EndValue;\r
-  BOOLEAN                                       CountUp;\r
-  UINT64                                        Freq;\r
-\r
-  //\r
-  // Retrieve time stamp count as early as possible\r
-  //\r
-  Ticker = GetPerformanceCounter ();\r
-\r
-  Freq   = GetPerformanceCounterProperties (&StartValue, &EndValue);\r
-\r
-  Freq   = DivU64x32 (Freq, 1000);\r
-\r
-  Status = PeiServicesLocatePpi (\r
-             &gEfiPeiReadOnlyVariable2PpiGuid,\r
-             0,\r
-             NULL,\r
-             (VOID **) &VariableServices\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    return;\r
-  }\r
-\r
-  VarSize   = sizeof (EFI_PHYSICAL_ADDRESS);\r
-  Status = VariableServices->GetVariable (\r
-                               VariableServices,\r
-                               L"PerfDataMemAddr",\r
-                               &gPerformanceProtocolGuid,\r
-                               NULL,\r
-                               &VarSize,\r
-                               &mAcpiLowMemoryBase\r
-                               );\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Fail to retrieve variable to log S3 performance data \n"));\r
-    return;\r
-  }\r
-\r
-  PerfHeader = (PERF_HEADER *) (UINTN) mAcpiLowMemoryBase;\r
-\r
-  if (PerfHeader->Signiture != PERFORMANCE_SIGNATURE) {\r
-    DEBUG ((EFI_D_ERROR, "Performance data in ACPI memory get corrupted! \n"));\r
-    return;\r
-  }\r
-\r
-  //\r
-  // Record total S3 resume time.\r
-  //\r
-  if (EndValue >= StartValue) {\r
-    PerfHeader->S3Resume = Ticker - StartValue;\r
-    CountUp              = TRUE;\r
-  } else {\r
-    PerfHeader->S3Resume = StartValue - Ticker;\r
-    CountUp              = FALSE;\r
-  }\r
-\r
-  //\r
-  // Get S3 detailed performance data\r
-  //\r
-  Index = 0;\r
-  LogEntryKey = 0;\r
-  while ((LogEntryKey = GetPerformanceMeasurement (\r
-                          LogEntryKey,\r
-                          &Handle,\r
-                          &Token,\r
-                          &Module,\r
-                          &StartTicker,\r
-                          &EndTicker)) != 0) {\r
-    if (EndTicker != 0) {\r
-      PerfData = &PerfHeader->S3Entry[Index];\r
-\r
-      //\r
-      // Use File Handle to specify the different performance log for PEIM.\r
-      // File Handle is the base address of PEIM FFS file.\r
-      //\r
-      if ((AsciiStrnCmp (Token, "PEIM", PEI_PERFORMANCE_STRING_SIZE) == 0) && (Handle != NULL)) {\r
-        AsciiSPrint (PerfData->Token, PERF_TOKEN_LENGTH, "0x%11p", Handle);\r
-      } else {\r
-        AsciiStrnCpyS (PerfData->Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH);\r
-      }\r
-      if (StartTicker == 1) {\r
-        StartTicker = StartValue;\r
-      }\r
-      if (EndTicker == 1) {\r
-        EndTicker = StartValue;\r
-      }\r
-      Ticker = CountUp? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
-      PerfData->Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);\r
-\r
-      //\r
-      // Only Record > 1ms performance data so that more big performance can be recorded.\r
-      //\r
-      if ((Ticker > Freq) && (++Index >= PERF_PEI_ENTRY_MAX_NUM)) {\r
-        //\r
-        // Reach the maximum number of PEI performance log entries.\r
-        //\r
-        break;\r
-      }\r
-    }\r
-  }\r
-  PerfHeader->S3EntryNum = (UINT32) Index;\r
-}\r
 \r
 /**\r
   The function will check if current waking vector is long mode.\r
@@ -449,13 +329,14 @@ IsLongModeWakingVector (
 }\r
 \r
 /**\r
-  Send EndOfS3Resume event to SmmCore through communication buffer way.\r
+  Signal to SMM through communication buffer way.\r
+\r
+  @param[in]  HandlerType       SMI handler type to be signaled.\r
 \r
-  @retval  EFI_SUCCESS                 Return send the event success.\r
 **/\r
-EFI_STATUS\r
-SignalEndOfS3Resume (\r
-  VOID\r
+VOID\r
+SignalToSmmByCommunication (\r
+  IN EFI_GUID   *HandlerType\r
   )\r
 {\r
   EFI_STATUS                         Status;\r
@@ -465,13 +346,13 @@ SignalEndOfS3Resume (
   SMM_COMMUNICATE_HEADER_64          Header64;\r
   VOID                               *CommBuffer;\r
 \r
-  DEBUG ((DEBUG_INFO, "SignalEndOfS3Resume - Enter\n"));\r
+  DEBUG ((DEBUG_INFO, "Signal %g to SMM - Enter\n", HandlerType));\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
+  // or (FeaturePcdGet (PcdDxeIplSwitchToLongMode)), DXE will switch to 64 bits.\r
   //\r
   if ((sizeof(UINTN) == sizeof(UINT64)) || (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {\r
     CommBuffer = &Header64;\r
@@ -482,7 +363,7 @@ SignalEndOfS3Resume (
     Header32.MessageLength = 0;\r
     CommSize = OFFSET_OF (SMM_COMMUNICATE_HEADER_32, Data);\r
   }\r
-  CopyGuid (CommBuffer, &gEdkiiSmmEndOfS3ResumeProtocolGuid);\r
+  CopyGuid (CommBuffer, HandlerType);\r
 \r
   Status = PeiServicesLocatePpi (\r
              &gEfiPeiSmmCommunicationPpiGuid,\r
@@ -492,7 +373,7 @@ SignalEndOfS3Resume (
              );\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((DEBUG_ERROR, "Locate Smm Communicate Ppi failed (%r)!\n", Status));\r
-    return Status;\r
+    return;\r
   }\r
 \r
   Status = SmmCommunicationPpi->Communicate (\r
@@ -504,8 +385,8 @@ SignalEndOfS3Resume (
     DEBUG ((DEBUG_ERROR, "SmmCommunicationPpi->Communicate return failure (%r)!\n", Status));\r
   }\r
 \r
-  DEBUG ((DEBUG_INFO, "SignalEndOfS3Resume - Exit (%r)\n", Status));\r
-  return Status;\r
+  DEBUG ((DEBUG_INFO, "Signal %g to SMM - Exit (%r)\n", HandlerType, Status));\r
+  return;\r
 }\r
 \r
 /**\r
@@ -554,9 +435,13 @@ S3ResumeBootOs (
   //\r
   // Install BootScriptDonePpi\r
   //\r
+  PERF_START_EX (NULL, "BootScriptDonePpi", NULL, 0, PERF_INMODULE_START_ID);\r
+\r
   Status = PeiServicesInstallPpi (&mPpiListPostScriptTable);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  PERF_END_EX (NULL, "BootScriptDonePpi", NULL, 0, PERF_INMODULE_END_ID);\r
+\r
   //\r
   // Get ACPI Table Address\r
   //\r
@@ -579,23 +464,28 @@ S3ResumeBootOs (
   //\r
   // Install EndOfPeiPpi\r
   //\r
+  PERF_START_EX (NULL, "EndOfPeiPpi", NULL, 0, PERF_INMODULE_START_ID);\r
+\r
   Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  PERF_END_EX (NULL, "EndOfPeiPpi", NULL, 0, PERF_INMODULE_END_ID);\r
+\r
+  PERF_START_EX (NULL, "EndOfS3Resume", NULL, 0, PERF_INMODULE_START_ID);\r
+\r
+  DEBUG ((DEBUG_INFO, "Signal EndOfS3Resume\n"));\r
   //\r
-  // Signal EndOfS3Resume event.\r
+  // Signal EndOfS3Resume to SMM.\r
   //\r
-  SignalEndOfS3Resume ();\r
+  SignalToSmmByCommunication (&gEdkiiEndOfS3ResumeGuid);\r
+\r
+  PERF_END_EX (NULL, "EndOfS3Resume", NULL, 0, PERF_INMODULE_END_ID);\r
 \r
   //\r
   // report status code on S3 resume\r
   //\r
   REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE);\r
 \r
-  PERF_CODE (\r
-    WriteToOsS3PerformanceData ();\r
-    );\r
-\r
   AsmTransferControl = (ASM_TRANSFER_CONTROL)(UINTN)PeiS3ResumeState->AsmTransferControl;\r
   if (Facs->XFirmwareWakingVector != 0) {\r
     //\r
@@ -906,6 +796,17 @@ S3ResumeExecuteBootScript (
         Status = SmmAccess->Lock ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
       }\r
     }\r
+\r
+    DEBUG ((DEBUG_INFO, "Signal S3SmmInitDone\n"));\r
+    //\r
+    // Install S3SmmInitDone PPI.\r
+    //\r
+    Status = PeiServicesInstallPpi (&mPpiListS3SmmInitDoneTable);\r
+    ASSERT_EFI_ERROR (Status);\r
+    //\r
+    // Signal S3SmmInitDone to SMM.\r
+    //\r
+    SignalToSmmByCommunication (&gEdkiiS3SmmInitDoneGuid);\r
   }\r
 \r
   if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r