]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Sec/SecMain.c
OvmfPkg/SecMain: Fix stack switching to permanent memory
[mirror_edk2.git] / OvmfPkg / Sec / SecMain.c
index 8bdf6e5238c5b762343578a1faaf4fbae10781cf..f7fec3d8c03b93d73042e480e4400be41f22ce32 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   Main SEC phase code.  Transitions to PEI.\r
 \r
 /** @file\r
   Main SEC phase code.  Transitions to PEI.\r
 \r
-  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -28,6 +29,7 @@
 #include <Library/PeCoffGetEntryPointLib.h>\r
 #include <Library/PeCoffExtraActionLib.h>\r
 #include <Library/ExtractGuidedSectionLib.h>\r
 #include <Library/PeCoffGetEntryPointLib.h>\r
 #include <Library/PeCoffExtraActionLib.h>\r
 #include <Library/ExtractGuidedSectionLib.h>\r
+#include <Library/LocalApicLib.h>\r
 \r
 #include <Ppi/TemporaryRamSupport.h>\r
 \r
 \r
 #include <Ppi/TemporaryRamSupport.h>\r
 \r
@@ -128,9 +130,13 @@ FindMainFv (
   Locates a section within a series of sections\r
   with the specified section type.\r
 \r
   Locates a section within a series of sections\r
   with the specified section type.\r
 \r
+  The Instance parameter indicates which instance of the section\r
+  type to return. (0 is first instance, 1 is second...)\r
+\r
   @param[in]   Sections        The sections to search\r
   @param[in]   SizeOfSections  Total size of all sections\r
   @param[in]   SectionType     The section type to locate\r
   @param[in]   Sections        The sections to search\r
   @param[in]   SizeOfSections  Total size of all sections\r
   @param[in]   SectionType     The section type to locate\r
+  @param[in]   Instance        The section instance number\r
   @param[out]  FoundSection    The FFS section if found\r
 \r
   @retval EFI_SUCCESS           The file and section was found\r
   @param[out]  FoundSection    The FFS section if found\r
 \r
   @retval EFI_SUCCESS           The file and section was found\r
@@ -139,10 +145,11 @@ FindMainFv (
 \r
 **/\r
 EFI_STATUS\r
 \r
 **/\r
 EFI_STATUS\r
-FindFfsSectionInSections (\r
+FindFfsSectionInstance (\r
   IN  VOID                             *Sections,\r
   IN  UINTN                            SizeOfSections,\r
   IN  EFI_SECTION_TYPE                 SectionType,\r
   IN  VOID                             *Sections,\r
   IN  UINTN                            SizeOfSections,\r
   IN  EFI_SECTION_TYPE                 SectionType,\r
+  IN  UINTN                            Instance,\r
   OUT EFI_COMMON_SECTION_HEADER        **FoundSection\r
   )\r
 {\r
   OUT EFI_COMMON_SECTION_HEADER        **FoundSection\r
   )\r
 {\r
@@ -167,7 +174,6 @@ FindFfsSectionInSections (
     }\r
 \r
     Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;\r
     }\r
 \r
     Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;\r
-    DEBUG ((EFI_D_INFO, "Section->Type: 0x%x\n", Section->Type));\r
 \r
     Size = SECTION_SIZE (Section);\r
     if (Size < sizeof (*Section)) {\r
 \r
     Size = SECTION_SIZE (Section);\r
     if (Size < sizeof (*Section)) {\r
@@ -183,15 +189,49 @@ FindFfsSectionInSections (
     // Look for the requested section type\r
     //\r
     if (Section->Type == SectionType) {\r
     // Look for the requested section type\r
     //\r
     if (Section->Type == SectionType) {\r
-      *FoundSection = Section;\r
-      return EFI_SUCCESS;\r
+      if (Instance == 0) {\r
+        *FoundSection = Section;\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        Instance--;\r
+      }\r
     }\r
     }\r
-    DEBUG ((EFI_D_INFO, "Section->Type (0x%x) != SectionType (0x%x)\n", Section->Type, SectionType));\r
   }\r
 \r
   return EFI_NOT_FOUND;\r
 }\r
 \r
   }\r
 \r
   return EFI_NOT_FOUND;\r
 }\r
 \r
+/**\r
+  Locates a section within a series of sections\r
+  with the specified section type.\r
+\r
+  @param[in]   Sections        The sections to search\r
+  @param[in]   SizeOfSections  Total size of all sections\r
+  @param[in]   SectionType     The section type to locate\r
+  @param[out]  FoundSection    The FFS section if found\r
+\r
+  @retval EFI_SUCCESS           The file and section was found\r
+  @retval EFI_NOT_FOUND         The file and section was not found\r
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted\r
+\r
+**/\r
+EFI_STATUS\r
+FindFfsSectionInSections (\r
+  IN  VOID                             *Sections,\r
+  IN  UINTN                            SizeOfSections,\r
+  IN  EFI_SECTION_TYPE                 SectionType,\r
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection\r
+  )\r
+{\r
+  return FindFfsSectionInstance (\r
+           Sections,\r
+           SizeOfSections,\r
+           SectionType,\r
+           0,\r
+           FoundSection\r
+           );\r
+}\r
+\r
 /**\r
   Locates a FFS file with the specified file type and a section\r
   within that file with the specified section type.\r
 /**\r
   Locates a FFS file with the specified file type and a section\r
   within that file with the specified section type.\r
@@ -207,7 +247,6 @@ FindFfsSectionInSections (
 \r
 **/\r
 EFI_STATUS\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 FindFfsFileAndSection (\r
   IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,\r
   IN  EFI_FV_FILETYPE                  FileType,\r
 FindFfsFileAndSection (\r
   IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,\r
   IN  EFI_FV_FILETYPE                  FileType,\r
@@ -223,7 +262,7 @@ FindFfsFileAndSection (
   EFI_PHYSICAL_ADDRESS        EndOfFile;\r
 \r
   if (Fv->Signature != EFI_FVH_SIGNATURE) {\r
   EFI_PHYSICAL_ADDRESS        EndOfFile;\r
 \r
   if (Fv->Signature != EFI_FVH_SIGNATURE) {\r
-    DEBUG ((EFI_D_INFO, "FV at %p does not have FV header signature\n", Fv));\r
+    DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n", Fv));\r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
 \r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
 \r
@@ -245,7 +284,6 @@ FindFfsFileAndSection (
     if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {\r
       return EFI_VOLUME_CORRUPTED;\r
     }\r
     if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {\r
       return EFI_VOLUME_CORRUPTED;\r
     }\r
-    DEBUG ((EFI_D_INFO, "File->Type: 0x%x\n", File->Type));\r
 \r
     EndOfFile = CurrentAddress + Size;\r
     if (EndOfFile > EndOfFirmwareVolume) {\r
 \r
     EndOfFile = CurrentAddress + Size;\r
     if (EndOfFile > EndOfFirmwareVolume) {\r
@@ -256,7 +294,6 @@ FindFfsFileAndSection (
     // Look for the request file type\r
     //\r
     if (File->Type != FileType) {\r
     // Look for the request file type\r
     //\r
     if (File->Type != FileType) {\r
-      DEBUG ((EFI_D_INFO, "File->Type (0x%x) != FileType (0x%x)\n", File->Type, FileType));\r
       continue;\r
     }\r
 \r
       continue;\r
     }\r
 \r
@@ -276,7 +313,7 @@ FindFfsFileAndSection (
   Locates the compressed main firmware volume and decompresses it.\r
 \r
   @param[in,out]  Fv            On input, the firmware volume to search\r
   Locates the compressed main firmware volume and decompresses it.\r
 \r
   @param[in,out]  Fv            On input, the firmware volume to search\r
-                                On output, the decompressed main FV\r
+                                On output, the decompressed BOOT/PEI FV\r
 \r
   @retval EFI_SUCCESS           The file and section was found\r
   @retval EFI_NOT_FOUND         The file and section was not found\r
 \r
   @retval EFI_SUCCESS           The file and section was found\r
   @retval EFI_NOT_FOUND         The file and section was not found\r
@@ -284,8 +321,7 @@ FindFfsFileAndSection (
 \r
 **/\r
 EFI_STATUS\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
-DecompressGuidedFv (\r
+DecompressMemFvs (\r
   IN OUT EFI_FIRMWARE_VOLUME_HEADER       **Fv\r
   )\r
 {\r
   IN OUT EFI_FIRMWARE_VOLUME_HEADER       **Fv\r
   )\r
 {\r
@@ -297,10 +333,13 @@ DecompressGuidedFv (
   UINT32                            AuthenticationStatus;\r
   VOID                              *OutputBuffer;\r
   VOID                              *ScratchBuffer;\r
   UINT32                            AuthenticationStatus;\r
   VOID                              *OutputBuffer;\r
   VOID                              *ScratchBuffer;\r
-  EFI_FIRMWARE_VOLUME_IMAGE_SECTION *NewFvSection;\r
-  EFI_FIRMWARE_VOLUME_HEADER        *NewFv;\r
+  EFI_COMMON_SECTION_HEADER         *FvSection;\r
+  EFI_FIRMWARE_VOLUME_HEADER        *PeiMemFv;\r
+  EFI_FIRMWARE_VOLUME_HEADER        *DxeMemFv;\r
+  UINT32                            FvHeaderSize;\r
+  UINT32                            FvSectionSize;\r
 \r
 \r
-  NewFvSection = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*) NULL;\r
+  FvSection = (EFI_COMMON_SECTION_HEADER*) NULL;\r
 \r
   Status = FindFfsFileAndSection (\r
              *Fv,\r
 \r
   Status = FindFfsFileAndSection (\r
              *Fv,\r
@@ -324,9 +363,16 @@ DecompressGuidedFv (
     return Status;\r
   }\r
 \r
     return Status;\r
   }\r
 \r
-  //PcdGet32 (PcdOvmfMemFvBase), PcdGet32 (PcdOvmfMemFvSize)\r
-  OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdOvmfMemFvBase) + SIZE_1MB);\r
+  OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase) + SIZE_1MB);\r
   ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB);\r
   ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB);\r
+\r
+  DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "\r
+    "PcdOvmfDecompressionScratchEnd=0x%x\n", __FUNCTION__, OutputBuffer,\r
+    OutputBufferSize, ScratchBuffer, ScratchBufferSize,\r
+    PcdGet32 (PcdOvmfDecompressionScratchEnd)));\r
+  ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==\r
+    PcdGet32 (PcdOvmfDecompressionScratchEnd));\r
+\r
   Status = ExtractGuidedSectionDecode (\r
              Section,\r
              &OutputBuffer,\r
   Status = ExtractGuidedSectionDecode (\r
              Section,\r
              &OutputBuffer,\r
@@ -338,27 +384,65 @@ DecompressGuidedFv (
     return Status;\r
   }\r
 \r
     return Status;\r
   }\r
 \r
-  Status = FindFfsSectionInSections (\r
+  Status = FindFfsSectionInstance (\r
+             OutputBuffer,\r
+             OutputBufferSize,\r
+             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
+             0,\r
+             &FvSection\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));\r
+    return Status;\r
+  }\r
+\r
+  ASSERT (SECTION_SIZE (FvSection) ==\r
+          (PcdGet32 (PcdOvmfPeiMemFvSize) + sizeof (*FvSection)));\r
+  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);\r
+\r
+  PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfPeiMemFvBase);\r
+  CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdOvmfPeiMemFvSize));\r
+\r
+  if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {\r
+    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", PeiMemFv));\r
+    CpuDeadLoop ();\r
+    return EFI_VOLUME_CORRUPTED;\r
+  }\r
+\r
+  Status = FindFfsSectionInstance (\r
              OutputBuffer,\r
              OutputBufferSize,\r
              EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
              OutputBuffer,\r
              OutputBufferSize,\r
              EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
-             (EFI_COMMON_SECTION_HEADER**) &NewFvSection\r
+             1,\r
+             &FvSection\r
              );\r
   if (EFI_ERROR (Status)) {\r
              );\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Unable to find FV image in extracted data\n"));\r
+    DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));\r
     return Status;\r
   }\r
 \r
     return Status;\r
   }\r
 \r
-  NewFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfMemFvBase);\r
-  CopyMem (NewFv, (VOID*) (NewFvSection + 1), PcdGet32 (PcdOvmfMemFvSize));\r
+  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);\r
 \r
 \r
-  if (NewFv->Signature != EFI_FVH_SIGNATURE) {\r
-    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", NewFv));\r
+  if (IS_SECTION2 (FvSection)) {\r
+    FvSectionSize = SECTION2_SIZE (FvSection);\r
+    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);\r
+  } else {\r
+    FvSectionSize = SECTION_SIZE (FvSection);\r
+    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);\r
+  }\r
+\r
+  ASSERT (FvSectionSize == (PcdGet32 (PcdOvmfDxeMemFvSize) + FvHeaderSize));\r
+\r
+  DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase);\r
+  CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize), PcdGet32 (PcdOvmfDxeMemFvSize));\r
+\r
+  if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {\r
+    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv));\r
     CpuDeadLoop ();\r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
 \r
     CpuDeadLoop ();\r
     return EFI_VOLUME_CORRUPTED;\r
   }\r
 \r
-  *Fv = NewFv;\r
+  *Fv = PeiMemFv;\r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -374,7 +458,6 @@ DecompressGuidedFv (
 \r
 **/\r
 EFI_STATUS\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 FindPeiCoreImageBaseInFv (\r
   IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,\r
   OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase\r
 FindPeiCoreImageBaseInFv (\r
   IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,\r
   OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase\r
@@ -406,6 +489,50 @@ FindPeiCoreImageBaseInFv (
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+\r
+/**\r
+  Reads 8-bits of CMOS data.\r
+\r
+  Reads the 8-bits of CMOS data at the location specified by Index.\r
+  The 8-bit read value is returned.\r
+\r
+  @param  Index  The CMOS location to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+STATIC\r
+UINT8\r
+CmosRead8 (\r
+  IN      UINTN                     Index\r
+  )\r
+{\r
+  IoWrite8 (0x70, (UINT8) Index);\r
+  return IoRead8 (0x71);\r
+}\r
+\r
+\r
+STATIC\r
+BOOLEAN\r
+IsS3Resume (\r
+  VOID\r
+  )\r
+{\r
+  return (CmosRead8 (0xF) == 0xFE);\r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetS3ResumePeiFv (\r
+  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **PeiFv\r
+  )\r
+{\r
+  *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfPeiMemFvBase);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
 /**\r
   Locates the PEI Core entry point address\r
 \r
 /**\r
   Locates the PEI Core entry point address\r
 \r
@@ -418,17 +545,34 @@ FindPeiCoreImageBaseInFv (
 \r
 **/\r
 VOID\r
 \r
 **/\r
 VOID\r
-EFIAPI\r
 FindPeiCoreImageBase (\r
   IN OUT  EFI_FIRMWARE_VOLUME_HEADER       **BootFv,\r
      OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase\r
   )\r
 {\r
 FindPeiCoreImageBase (\r
   IN OUT  EFI_FIRMWARE_VOLUME_HEADER       **BootFv,\r
      OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase\r
   )\r
 {\r
+  BOOLEAN S3Resume;\r
+\r
   *PeiCoreImageBase = 0;\r
 \r
   *PeiCoreImageBase = 0;\r
 \r
-  FindMainFv (BootFv);\r
+  S3Resume = IsS3Resume ();\r
+  if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {\r
+    //\r
+    // A malicious runtime OS may have injected something into our previously\r
+    // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required.\r
+    //\r
+    DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n"));\r
+    GetS3ResumePeiFv (BootFv);\r
+  } else {\r
+    //\r
+    // We're either not resuming, or resuming "securely" -- we'll decompress\r
+    // both PEI FV and DXE FV from pristine flash.\r
+    //\r
+    DEBUG ((EFI_D_VERBOSE, "SEC: %a\n",\r
+      S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"));\r
+    FindMainFv (BootFv);\r
 \r
 \r
-  DecompressGuidedFv (BootFv);\r
+    DecompressMemFvs (BootFv);\r
+  }\r
 \r
   FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);\r
 }\r
 \r
   FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);\r
 }\r
@@ -438,7 +582,6 @@ FindPeiCoreImageBase (
 \r
 **/\r
 EFI_STATUS\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
 FindImageBase (\r
   IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,\r
   OUT EFI_PHYSICAL_ADDRESS             *SecCoreImageBase\r
 FindImageBase (\r
   IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,\r
   OUT EFI_PHYSICAL_ADDRESS             *SecCoreImageBase\r
@@ -526,12 +669,11 @@ FindImageBase (
 /*\r
   Find and return Pei Core entry point.\r
 \r
 /*\r
   Find and return Pei Core entry point.\r
 \r
-  It also find SEC and PEI Core file debug inforamtion. It will report them if\r
+  It also find SEC and PEI Core file debug information. It will report them if\r
   remote debug is enabled.\r
 \r
 **/\r
 VOID\r
   remote debug is enabled.\r
 \r
 **/\r
 VOID\r
-EFIAPI\r
 FindAndReportEntryPoints (\r
   IN  EFI_FIRMWARE_VOLUME_HEADER       **BootFirmwareVolumePtr,\r
   OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint\r
 FindAndReportEntryPoints (\r
   IN  EFI_FIRMWARE_VOLUME_HEADER       **BootFirmwareVolumePtr,\r
   OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint\r
@@ -587,10 +729,23 @@ SecCoreStartupWithStack (
   SEC_IDT_TABLE               IdtTableInStack;\r
   IA32_DESCRIPTOR             IdtDescriptor;\r
   UINT32                      Index;\r
   SEC_IDT_TABLE               IdtTableInStack;\r
   IA32_DESCRIPTOR             IdtDescriptor;\r
   UINT32                      Index;\r
+  volatile UINT8              *Table;\r
+\r
+  //\r
+  // To ensure SMM can't be compromised on S3 resume, we must force re-init of\r
+  // the BaseExtractGuidedSectionLib. Since this is before library contructors\r
+  // are called, we must use a loop rather than SetMem.\r
+  //\r
+  Table = (UINT8*)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);\r
+  for (Index = 0;\r
+       Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);\r
+       ++Index) {\r
+    Table[Index] = 0;\r
+  }\r
 \r
   ProcessLibraryConstructorList (NULL, NULL);\r
 \r
 \r
   ProcessLibraryConstructorList (NULL, NULL);\r
 \r
-  DEBUG ((EFI_D_ERROR,\r
+  DEBUG ((EFI_D_INFO,\r
     "SecCoreStartupWithStack(0x%x, 0x%x)\n",\r
     (UINT32)(UINTN)BootFv,\r
     (UINT32)(UINTN)TopOfCurrentStack\r
     "SecCoreStartupWithStack(0x%x, 0x%x)\n",\r
     (UINT32)(UINTN)BootFv,\r
     (UINT32)(UINTN)TopOfCurrentStack\r
@@ -657,6 +812,14 @@ SecCoreStartupWithStack (
   //\r
   IoWrite8 (0x21, 0xff);\r
   IoWrite8 (0xA1, 0xff);\r
   //\r
   IoWrite8 (0x21, 0xff);\r
   IoWrite8 (0xA1, 0xff);\r
+\r
+  //\r
+  // Initialize Local APIC Timer hardware and disable Local APIC Timer\r
+  // interrupts before initializing the Debug Agent and the debug timer is\r
+  // enabled.\r
+  //\r
+  InitializeApicTimer (0, MAX_UINT32, TRUE, 5);\r
+  DisableApicTimerInterrupt ();\r
   \r
   //\r
   // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.\r
   \r
   //\r
   // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.\r
@@ -725,7 +888,12 @@ TemporaryRamMigration (
   BOOLEAN                          OldStatus;\r
   BASE_LIBRARY_JUMP_BUFFER         JumpBuffer;\r
   \r
   BOOLEAN                          OldStatus;\r
   BASE_LIBRARY_JUMP_BUFFER         JumpBuffer;\r
   \r
-  DEBUG ((EFI_D_ERROR, "TemporaryRamMigration(0x%x, 0x%x, 0x%x)\n", (UINTN)TemporaryMemoryBase, (UINTN)PermanentMemoryBase, CopySize));\r
+  DEBUG ((EFI_D_INFO,\r
+    "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",\r
+    TemporaryMemoryBase,\r
+    PermanentMemoryBase,\r
+    (UINT64)CopySize\r
+    ));\r
   \r
   OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;\r
   NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));\r
   \r
   OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;\r
   NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));\r
@@ -763,9 +931,11 @@ TemporaryRamMigration (
   if (SetJump (&JumpBuffer) == 0) {\r
 #if defined (MDE_CPU_IA32)\r
     JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;\r
   if (SetJump (&JumpBuffer) == 0) {\r
 #if defined (MDE_CPU_IA32)\r
     JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;\r
+    JumpBuffer.Ebp = JumpBuffer.Ebp + DebugAgentContext.StackMigrateOffset;\r
 #endif    \r
 #if defined (MDE_CPU_X64)\r
     JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;\r
 #endif    \r
 #if defined (MDE_CPU_X64)\r
     JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;\r
+    JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset;\r
 #endif    \r
     LongJump (&JumpBuffer, (UINTN)-1);\r
   }\r
 #endif    \r
     LongJump (&JumpBuffer, (UINTN)-1);\r
   }\r