]> 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 aa1c8032915879eae905b4bfc0dbecb1b938f6d8..4ae168a2c3ce4cad274a679019b29328fa4b88ca 100644 (file)
@@ -1,10 +1,11 @@
 /** @file\r
   This module produces the EFI_PEI_S3_RESUME2_PPI.\r
   This module works with StandAloneBootScriptExecutor to S3 resume to OS.\r
 /** @file\r
   This module produces the EFI_PEI_S3_RESUME2_PPI.\r
   This module works with StandAloneBootScriptExecutor to S3 resume to OS.\r
-  This module will excute the boot script saved during last boot and after that,\r
+  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
   control is passed to OS waking up handler.\r
 \r
-  Copyright (c) 2006 - 2014, 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
   are licensed and made available under the terms and conditions\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions\r
 \r
 #include <Guid/AcpiS3Context.h>\r
 #include <Guid/BootScriptExecutorVariable.h>\r
 \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
 #include <Ppi/PostBootScriptTable.h>\r
 #include <Ppi/EndOfPeiPhase.h>\r
 #include <Ppi/ReadOnlyVariable2.h>\r
 #include <Ppi/S3Resume2.h>\r
 #include <Ppi/SmmAccess.h>\r
 #include <Ppi/PostBootScriptTable.h>\r
 #include <Ppi/EndOfPeiPhase.h>\r
+#include <Ppi/SmmCommunication.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseLib.h>\r
 \r
 #include <Library/DebugLib.h>\r
 #include <Library/BaseLib.h>\r
@@ -58,6 +62,8 @@
 #define STACK_ALIGN_DOWN(Ptr) \\r
           ((UINTN)(Ptr) & ~(UINTN)(CPU_STACK_ALIGNMENT - 1))\r
 \r
 #define STACK_ALIGN_DOWN(Ptr) \\r
           ((UINTN)(Ptr) & ~(UINTN)(CPU_STACK_ALIGNMENT - 1))\r
 \r
+#define PAGING_1G_ADDRESS_MASK_64  0x000FFFFFC0000000ull\r
+\r
 #pragma pack(1)\r
 typedef union {\r
   struct {\r
 #pragma pack(1)\r
 typedef union {\r
   struct {\r
@@ -148,6 +154,22 @@ typedef union {
   UINT64    Uint64;\r
 } PAGE_TABLE_1G_ENTRY;\r
 \r
   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
 #pragma pack()\r
 \r
 //\r
@@ -238,6 +260,12 @@ EFI_PEI_PPI_DESCRIPTOR mPpiListEndOfPeiTable = {
   0\r
 };\r
 \r
   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
 //\r
 // Global Descriptor Table (GDT)\r
 //\r
@@ -264,133 +292,6 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR mGdt = {
   (UINTN) mGdtEntries\r
   };\r
 \r
   (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
-  // Retrive time stamp count as early as possilbe\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
-        AsciiStrnCpy (PerfData->Token, Token, PERF_TOKEN_LENGTH);\r
-        PerfData->Token[PERF_TOKEN_LENGTH] = '\0';\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
 \r
 /**\r
   The function will check if current waking vector is long mode.\r
@@ -427,6 +328,67 @@ IsLongModeWakingVector (
   return FALSE;\r
 }\r
 \r
   return FALSE;\r
 }\r
 \r
+/**\r
+  Signal to SMM through communication buffer way.\r
+\r
+  @param[in]  HandlerType       SMI handler type to be signaled.\r
+\r
+**/\r
+VOID\r
+SignalToSmmByCommunication (\r
+  IN EFI_GUID   *HandlerType\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 ((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
+  //\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, HandlerType);\r
+\r
+  Status = PeiServicesLocatePpi (\r
+             &gEfiPeiSmmCommunicationPpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&SmmCommunicationPpi\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Locate Smm Communicate Ppi failed (%r)!\n", Status));\r
+    return;\r
+  }\r
+\r
+  Status = SmmCommunicationPpi->Communicate (\r
+                                  SmmCommunicationPpi,\r
+                                  (VOID *)CommBuffer,\r
+                                  &CommSize\r
+                                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "SmmCommunicationPpi->Communicate return failure (%r)!\n", Status));\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "Signal %g to SMM - Exit (%r)\n", HandlerType, Status));\r
+  return;\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
 /**\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
@@ -473,9 +435,13 @@ S3ResumeBootOs (
   //\r
   // Install BootScriptDonePpi\r
   //\r
   //\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
   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
   //\r
   // Get ACPI Table Address\r
   //\r
@@ -498,31 +464,48 @@ S3ResumeBootOs (
   //\r
   // Install EndOfPeiPpi\r
   //\r
   //\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
   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 to SMM.\r
+  //\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
   //\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
     // Switch to native waking vector\r
     //\r
     TempStackTop = (UINTN)&TempStack + sizeof(TempStack);\r
   AsmTransferControl = (ASM_TRANSFER_CONTROL)(UINTN)PeiS3ResumeState->AsmTransferControl;\r
   if (Facs->XFirmwareWakingVector != 0) {\r
     //\r
     // Switch to native waking vector\r
     //\r
     TempStackTop = (UINTN)&TempStack + sizeof(TempStack);\r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "%a() Stack Base: 0x%x, Stack Size: 0x%x\n",\r
+      __FUNCTION__,\r
+      TempStackTop,\r
+      sizeof (TempStack)\r
+      ));\r
     if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&\r
         ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&\r
         ((Facs->Flags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) {\r
       //\r
       // X64 long mode waking vector\r
       //\r
     if ((Facs->Version == EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&\r
         ((Facs->Flags & EFI_ACPI_4_0_64BIT_WAKE_SUPPORTED_F) != 0) &&\r
         ((Facs->Flags & EFI_ACPI_4_0_OSPM_64BIT_WAKE__F) != 0)) {\r
       //\r
       // X64 long mode waking vector\r
       //\r
-      DEBUG (( EFI_D_ERROR, "Transfer to 64bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));\r
+      DEBUG ((DEBUG_INFO, "Transfer to 64bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));\r
       if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
         AsmEnablePaging64 (\r
           0x38,\r
       if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
         AsmEnablePaging64 (\r
           0x38,\r
@@ -548,7 +531,7 @@ S3ResumeBootOs (
       //\r
       // IA32 protected mode waking vector (Page disabled)\r
       //\r
       //\r
       // IA32 protected mode waking vector (Page disabled)\r
       //\r
-      DEBUG (( EFI_D_ERROR, "Transfer to 32bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));\r
+      DEBUG ((DEBUG_INFO, "Transfer to 32bit OS waking vector - %x\r\n", (UINTN)Facs->XFirmwareWakingVector));\r
       SwitchStack (\r
         (SWITCH_STACK_ENTRY_POINT) (UINTN) Facs->XFirmwareWakingVector,\r
         NULL,\r
       SwitchStack (\r
         (SWITCH_STACK_ENTRY_POINT) (UINTN) Facs->XFirmwareWakingVector,\r
         NULL,\r
@@ -560,7 +543,7 @@ S3ResumeBootOs (
     //\r
     // 16bit Realmode waking vector\r
     //\r
     //\r
     // 16bit Realmode waking vector\r
     //\r
-    DEBUG (( EFI_D_ERROR, "Transfer to 16bit OS waking vector - %x\r\n", (UINTN)Facs->FirmwareWakingVector));\r
+    DEBUG ((DEBUG_INFO, "Transfer to 16bit OS waking vector - %x\r\n", (UINTN)Facs->FirmwareWakingVector));\r
     AsmTransferControl (Facs->FirmwareWakingVector, 0x0);\r
   }\r
 \r
     AsmTransferControl (Facs->FirmwareWakingVector, 0x0);\r
   }\r
 \r
@@ -608,17 +591,23 @@ RestoreS3PageTables (
     VOID                                          *Hob;\r
     BOOLEAN                                       Page1GSupport;\r
     PAGE_TABLE_1G_ENTRY                           *PageDirectory1GEntry;\r
     VOID                                          *Hob;\r
     BOOLEAN                                       Page1GSupport;\r
     PAGE_TABLE_1G_ENTRY                           *PageDirectory1GEntry;\r
+    UINT64                                        AddressEncMask;\r
+\r
+    //\r
+    // Make sure AddressEncMask is contained to smallest supported address field\r
+    //\r
+    AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;\r
 \r
     //\r
     // NOTE: We have to ASSUME the page table generation format, because we do not know whole page table information.\r
     // The whole page table is too large to be saved in SMRAM.\r
     //\r
 \r
     //\r
     // NOTE: We have to ASSUME the page table generation format, because we do not know whole page table information.\r
     // The whole page table is too large to be saved in SMRAM.\r
     //\r
-    // The assumption is : whole page table is allocated in CONTINOUS memory and CR3 points to TOP page.\r
+    // The assumption is : whole page table is allocated in CONTINUOUS memory and CR3 points to TOP page.\r
     //\r
     //\r
-    DEBUG ((EFI_D_ERROR, "S3NvsPageTableAddress - %x (%x)\n", (UINTN)S3NvsPageTableAddress, (UINTN)Build4GPageTableOnly));\r
+    DEBUG ((DEBUG_INFO, "S3NvsPageTableAddress - %x (%x)\n", (UINTN)S3NvsPageTableAddress, (UINTN)Build4GPageTableOnly));\r
 \r
     //\r
 \r
     //\r
-    // By architecture only one PageMapLevel4 exists - so lets allocate storgage for it.\r
+    // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.\r
     //\r
     PageMap = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress;\r
     S3NvsPageTableAddress += SIZE_4KB;\r
     //\r
     PageMap = (PAGE_MAP_AND_DIRECTORY_POINTER *)S3NvsPageTableAddress;\r
     S3NvsPageTableAddress += SIZE_4KB;\r
@@ -690,7 +679,7 @@ RestoreS3PageTables (
       //\r
       // Make a PML4 Entry\r
       //\r
       //\r
       // Make a PML4 Entry\r
       //\r
-      PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry;\r
+      PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask;\r
       PageMapLevel4Entry->Bits.ReadWrite = 1;\r
       PageMapLevel4Entry->Bits.Present = 1;\r
 \r
       PageMapLevel4Entry->Bits.ReadWrite = 1;\r
       PageMapLevel4Entry->Bits.Present = 1;\r
 \r
@@ -701,7 +690,7 @@ RestoreS3PageTables (
           //\r
           // Fill in the Page Directory entries\r
           //\r
           //\r
           // Fill in the Page Directory entries\r
           //\r
-          PageDirectory1GEntry->Uint64 = (UINT64)PageAddress;\r
+          PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask;\r
           PageDirectory1GEntry->Bits.ReadWrite = 1;\r
           PageDirectory1GEntry->Bits.Present = 1;\r
           PageDirectory1GEntry->Bits.MustBe1 = 1;\r
           PageDirectory1GEntry->Bits.ReadWrite = 1;\r
           PageDirectory1GEntry->Bits.Present = 1;\r
           PageDirectory1GEntry->Bits.MustBe1 = 1;\r
@@ -718,7 +707,7 @@ RestoreS3PageTables (
           //\r
           // Fill in a Page Directory Pointer Entries\r
           //\r
           //\r
           // Fill in a Page Directory Pointer Entries\r
           //\r
-          PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry;\r
+          PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask;\r
           PageDirectoryPointerEntry->Bits.ReadWrite = 1;\r
           PageDirectoryPointerEntry->Bits.Present = 1;\r
     \r
           PageDirectoryPointerEntry->Bits.ReadWrite = 1;\r
           PageDirectoryPointerEntry->Bits.Present = 1;\r
     \r
@@ -726,7 +715,7 @@ RestoreS3PageTables (
             //\r
             // Fill in the Page Directory entries\r
             //\r
             //\r
             // Fill in the Page Directory entries\r
             //\r
-            PageDirectoryEntry->Uint64 = (UINT64)PageAddress;\r
+            PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask;\r
             PageDirectoryEntry->Bits.ReadWrite = 1;\r
             PageDirectoryEntry->Bits.Present = 1;\r
             PageDirectoryEntry->Bits.MustBe1 = 1;\r
             PageDirectoryEntry->Bits.ReadWrite = 1;\r
             PageDirectoryEntry->Bits.Present = 1;\r
             PageDirectoryEntry->Bits.MustBe1 = 1;\r
@@ -768,7 +757,7 @@ S3ResumeExecuteBootScript (
   PEI_S3_RESUME_STATE        *PeiS3ResumeState;\r
   BOOLEAN                    InterruptStatus;\r
 \r
   PEI_S3_RESUME_STATE        *PeiS3ResumeState;\r
   BOOLEAN                    InterruptStatus;\r
 \r
-  DEBUG ((EFI_D_ERROR, "S3ResumeExecuteBootScript()\n"));\r
+  DEBUG ((DEBUG_INFO, "S3ResumeExecuteBootScript()\n"));\r
 \r
   //\r
   // Attempt to use content from SMRAM first\r
 \r
   //\r
   // Attempt to use content from SMRAM first\r
@@ -795,18 +784,29 @@ S3ResumeExecuteBootScript (
                               (VOID **) &SmmAccess\r
                               );\r
     if (!EFI_ERROR (Status)) {\r
                               (VOID **) &SmmAccess\r
                               );\r
     if (!EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "Close all SMRAM regions before executing boot script\n"));\r
+      DEBUG ((DEBUG_INFO, "Close all SMRAM regions before executing boot script\n"));\r
   \r
       for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {\r
         Status = SmmAccess->Close ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
       }\r
 \r
   \r
       for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {\r
         Status = SmmAccess->Close ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
       }\r
 \r
-      DEBUG ((EFI_D_ERROR, "Lock all SMRAM regions before executing boot script\n"));\r
+      DEBUG ((DEBUG_INFO, "Lock all SMRAM regions before executing boot script\n"));\r
   \r
       for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {\r
         Status = SmmAccess->Lock ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
       }\r
     }\r
   \r
       for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {\r
         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
   }\r
 \r
   if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
@@ -820,10 +820,16 @@ S3ResumeExecuteBootScript (
     //\r
     IdtDescriptor = (IA32_DESCRIPTOR *) (UINTN) (AcpiS3Context->IdtrProfile);\r
     //\r
     //\r
     IdtDescriptor = (IA32_DESCRIPTOR *) (UINTN) (AcpiS3Context->IdtrProfile);\r
     //\r
-    // Make sure the newly allcated IDT align with 16-bytes\r
+    // Make sure the newly allocated IDT align with 16-bytes\r
     // \r
     IdtBuffer = AllocatePages (EFI_SIZE_TO_PAGES((IdtDescriptor->Limit + 1) + 16));\r
     // \r
     IdtBuffer = AllocatePages (EFI_SIZE_TO_PAGES((IdtDescriptor->Limit + 1) + 16));\r
-    ASSERT (IdtBuffer != NULL);\r
+    if (IdtBuffer == NULL) {\r
+      REPORT_STATUS_CODE (\r
+        EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
+        (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_FAILED)\r
+        );\r
+      ASSERT (FALSE);\r
+    }\r
     //\r
     // Additional 16 bytes allocated to save IA32 IDT descriptor and Pei Service Table Pointer\r
     // IA32 IDT descriptor will be used to setup IA32 IDT table for 32-bit Framework Boot Script code\r
     //\r
     // Additional 16 bytes allocated to save IA32 IDT descriptor and Pei Service Table Pointer\r
     // IA32 IDT descriptor will be used to setup IA32 IDT table for 32-bit Framework Boot Script code\r
@@ -853,8 +859,14 @@ S3ResumeExecuteBootScript (
   // Prepare data for return back\r
   //\r
   PeiS3ResumeState = AllocatePool (sizeof(*PeiS3ResumeState));\r
   // Prepare data for return back\r
   //\r
   PeiS3ResumeState = AllocatePool (sizeof(*PeiS3ResumeState));\r
-  ASSERT (PeiS3ResumeState != NULL);\r
-  DEBUG (( EFI_D_ERROR, "PeiS3ResumeState - %x\r\n", PeiS3ResumeState));\r
+  if (PeiS3ResumeState == NULL) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
+      (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_FAILED)\r
+      );\r
+    ASSERT (FALSE);\r
+  }\r
+  DEBUG ((DEBUG_INFO, "PeiS3ResumeState - %x\r\n", PeiS3ResumeState));\r
   PeiS3ResumeState->ReturnCs           = 0x10;\r
   PeiS3ResumeState->ReturnEntryPoint   = (EFI_PHYSICAL_ADDRESS)(UINTN)S3ResumeBootOs;\r
   PeiS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status);\r
   PeiS3ResumeState->ReturnCs           = 0x10;\r
   PeiS3ResumeState->ReturnEntryPoint   = (EFI_PHYSICAL_ADDRESS)(UINTN)S3ResumeBootOs;\r
   PeiS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status);\r
@@ -874,7 +886,7 @@ S3ResumeExecuteBootScript (
     //\r
     // X64 S3 Resume\r
     //\r
     //\r
     // X64 S3 Resume\r
     //\r
-    DEBUG (( EFI_D_ERROR, "Enable X64 and transfer control to Standalone Boot Script Executor\r\n"));\r
+    DEBUG ((DEBUG_INFO, "Enable X64 and transfer control to Standalone Boot Script Executor\r\n"));\r
 \r
     //\r
     // Switch to long mode to complete resume.\r
 \r
     //\r
     // Switch to long mode to complete resume.\r
@@ -890,7 +902,7 @@ S3ResumeExecuteBootScript (
     //\r
     // IA32 S3 Resume\r
     //\r
     //\r
     // IA32 S3 Resume\r
     //\r
-    DEBUG (( EFI_D_ERROR, "transfer control to Standalone Boot Script Executor\r\n"));\r
+    DEBUG ((DEBUG_INFO, "transfer control to Standalone Boot Script Executor\r\n"));\r
     SwitchStack (\r
       (SWITCH_STACK_ENTRY_POINT) (UINTN) EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint,\r
       (VOID *)AcpiS3Context,\r
     SwitchStack (\r
       (SWITCH_STACK_ENTRY_POINT) (UINTN) EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint,\r
       (VOID *)AcpiS3Context,\r
@@ -958,7 +970,7 @@ S3RestoreConfig2 (
   TempAcpiS3Context = 0;\r
   TempEfiBootScriptExecutorVariable = 0;\r
 \r
   TempAcpiS3Context = 0;\r
   TempEfiBootScriptExecutorVariable = 0;\r
 \r
-  DEBUG ((EFI_D_ERROR, "Enter S3 PEIM\r\n"));\r
+  DEBUG ((DEBUG_INFO, "Enter S3 PEIM\r\n"));\r
 \r
   VarSize = sizeof (EFI_PHYSICAL_ADDRESS);\r
   Status = RestoreLockBox (\r
 \r
   VarSize = sizeof (EFI_PHYSICAL_ADDRESS);\r
   Status = RestoreLockBox (\r
@@ -996,15 +1008,15 @@ S3RestoreConfig2 (
   EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *) (UINTN) TempEfiBootScriptExecutorVariable;\r
   ASSERT (EfiBootScriptExecutorVariable != NULL);\r
 \r
   EfiBootScriptExecutorVariable = (BOOT_SCRIPT_EXECUTOR_VARIABLE *) (UINTN) TempEfiBootScriptExecutorVariable;\r
   ASSERT (EfiBootScriptExecutorVariable != NULL);\r
 \r
-  DEBUG (( EFI_D_ERROR, "AcpiS3Context = %x\n", AcpiS3Context));\r
-  DEBUG (( EFI_D_ERROR, "Waking Vector = %x\n", ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable)))->FirmwareWakingVector));\r
-  DEBUG (( EFI_D_ERROR, "AcpiS3Context->AcpiFacsTable = %x\n", AcpiS3Context->AcpiFacsTable));\r
-  DEBUG (( EFI_D_ERROR, "AcpiS3Context->IdtrProfile = %x\n", AcpiS3Context->IdtrProfile));  \r
-  DEBUG (( EFI_D_ERROR, "AcpiS3Context->S3NvsPageTableAddress = %x\n", AcpiS3Context->S3NvsPageTableAddress));\r
-  DEBUG (( EFI_D_ERROR, "AcpiS3Context->S3DebugBufferAddress = %x\n", AcpiS3Context->S3DebugBufferAddress));\r
-  DEBUG (( EFI_D_ERROR, "AcpiS3Context->BootScriptStackBase = %x\n", AcpiS3Context->BootScriptStackBase));\r
-  DEBUG (( EFI_D_ERROR, "AcpiS3Context->BootScriptStackSize = %x\n", AcpiS3Context->BootScriptStackSize));\r
-  DEBUG (( EFI_D_ERROR, "EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = %x\n", EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint));\r
+  DEBUG (( DEBUG_INFO, "AcpiS3Context = %x\n", AcpiS3Context));\r
+  DEBUG (( DEBUG_INFO, "Waking Vector = %x\n", ((EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable)))->FirmwareWakingVector));\r
+  DEBUG (( DEBUG_INFO, "AcpiS3Context->AcpiFacsTable = %x\n", AcpiS3Context->AcpiFacsTable));\r
+  DEBUG (( DEBUG_INFO, "AcpiS3Context->IdtrProfile = %x\n", AcpiS3Context->IdtrProfile));  \r
+  DEBUG (( DEBUG_INFO, "AcpiS3Context->S3NvsPageTableAddress = %x\n", AcpiS3Context->S3NvsPageTableAddress));\r
+  DEBUG (( DEBUG_INFO, "AcpiS3Context->S3DebugBufferAddress = %x\n", AcpiS3Context->S3DebugBufferAddress));\r
+  DEBUG (( DEBUG_INFO, "AcpiS3Context->BootScriptStackBase = %x\n", AcpiS3Context->BootScriptStackBase));\r
+  DEBUG (( DEBUG_INFO, "AcpiS3Context->BootScriptStackSize = %x\n", AcpiS3Context->BootScriptStackSize));\r
+  DEBUG (( DEBUG_INFO, "EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint = %x\n", EfiBootScriptExecutorVariable->BootScriptExecutorEntrypoint));\r
 \r
   //\r
   // Additional step for BootScript integrity - we only handle BootScript and BootScriptExecutor.\r
 \r
   //\r
   // Additional step for BootScript integrity - we only handle BootScript and BootScriptExecutor.\r
@@ -1054,19 +1066,19 @@ S3RestoreConfig2 (
     SmmS3ResumeState->ReturnContext2     = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiBootScriptExecutorVariable;\r
     SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status);\r
 \r
     SmmS3ResumeState->ReturnContext2     = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiBootScriptExecutorVariable;\r
     SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status);\r
 \r
-    DEBUG (( EFI_D_ERROR, "SMM S3 Signature                = %x\n", SmmS3ResumeState->Signature));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 Stack Base               = %x\n", SmmS3ResumeState->SmmS3StackBase));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 Stack Size               = %x\n", SmmS3ResumeState->SmmS3StackSize));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 Resume Entry Point       = %x\n", SmmS3ResumeState->SmmS3ResumeEntryPoint));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 CR0                      = %x\n", SmmS3ResumeState->SmmS3Cr0));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 CR3                      = %x\n", SmmS3ResumeState->SmmS3Cr3));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 CR4                      = %x\n", SmmS3ResumeState->SmmS3Cr4));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 Return CS                = %x\n", SmmS3ResumeState->ReturnCs));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 Return Entry Point       = %x\n", SmmS3ResumeState->ReturnEntryPoint));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 Return Context1          = %x\n", SmmS3ResumeState->ReturnContext1));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 Return Context2          = %x\n", SmmS3ResumeState->ReturnContext2));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 Return Stack Pointer     = %x\n", SmmS3ResumeState->ReturnStackPointer));\r
-    DEBUG (( EFI_D_ERROR, "SMM S3 Smst                     = %x\n", SmmS3ResumeState->Smst));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 Signature                = %x\n", SmmS3ResumeState->Signature));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 Stack Base               = %x\n", SmmS3ResumeState->SmmS3StackBase));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 Stack Size               = %x\n", SmmS3ResumeState->SmmS3StackSize));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 Resume Entry Point       = %x\n", SmmS3ResumeState->SmmS3ResumeEntryPoint));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 CR0                      = %x\n", SmmS3ResumeState->SmmS3Cr0));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 CR3                      = %x\n", SmmS3ResumeState->SmmS3Cr3));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 CR4                      = %x\n", SmmS3ResumeState->SmmS3Cr4));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 Return CS                = %x\n", SmmS3ResumeState->ReturnCs));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 Return Entry Point       = %x\n", SmmS3ResumeState->ReturnEntryPoint));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 Return Context1          = %x\n", SmmS3ResumeState->ReturnContext1));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 Return Context2          = %x\n", SmmS3ResumeState->ReturnContext2));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 Return Stack Pointer     = %x\n", SmmS3ResumeState->ReturnStackPointer));\r
+    DEBUG (( DEBUG_INFO, "SMM S3 Smst                     = %x\n", SmmS3ResumeState->Smst));\r
 \r
     if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) {\r
       SwitchStack (\r
 \r
     if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) {\r
       SwitchStack (\r