[edk2-devel] [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58

David Wei posted 7 patches 6 years, 4 months ago
There is a newer version of this series
[edk2-devel] [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
Posted by David Wei 6 years, 4 months ago
Add CPU Pkg for SimicsX58. It is added for simics QSP project support

Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: David Wei <david.y.wei@intel.com>
---
 .../Override/UefiCpuPkg/SecCore/SecMain.c          | 956 +++++++++++++++++++++
 .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c     | 148 ++++
 .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c      | 353 ++++++++
 .../SimicsX58SktPkg/Smm/Access/SmramInternal.c     | 199 +++++
 .../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm |  45 +
 .../Override/UefiCpuPkg/SecCore/SecMain.inf        |  71 ++
 .../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm  |  45 +
 Silicon/Intel/SimicsX58SktPkg/SktPei.dsc           |  18 +
 .../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf |   9 +
 .../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf  |  10 +
 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf    |  17 +
 .../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf   |  16 +
 .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf   |  52 ++
 .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf    |  64 ++
 .../SimicsX58SktPkg/Smm/Access/SmramInternal.h     |  81 ++
 15 files changed, 2084 insertions(+)
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h

diff --git a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
new file mode 100644
index 0000000000..c52d459ef2
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
@@ -0,0 +1,956 @@
+/** @file
+  Main SEC phase code.  Transitions to PEI.
+
+  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiCpuLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/PciCf8Lib.h>
+
+#include <Ppi/TemporaryRamSupport.h>
+#include <IndustryStandard/X58Ich10.h>
+
+#define SEC_IDT_ENTRY_COUNT  34
+
+typedef struct _SEC_IDT_TABLE {
+  EFI_PEI_SERVICES          *PeiService;
+  IA32_IDT_GATE_DESCRIPTOR  IdtTable[SEC_IDT_ENTRY_COUNT];
+} SEC_IDT_TABLE;
+
+VOID
+EFIAPI
+SecStartupPhase2 (
+  IN VOID                     *Context
+  );
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
+  IN UINTN                    CopySize
+  );
+
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+  TemporaryRamMigration
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiTemporaryRamSupportPpiGuid,
+    &mTemporaryRamSupportPpi
+  },
+};
+
+//
+// Template of an IDT entry pointing to 10:FFFFFFE4h.
+//
+IA32_IDT_GATE_DESCRIPTOR  mIdtEntryTemplate = {
+  {                                      // Bits
+    0xffe4,                              // OffsetLow
+    0x10,                                // Selector
+    0x0,                                 // Reserved_0
+    IA32_IDT_GATE_TYPE_INTERRUPT_32,     // GateType
+    0xffff                               // OffsetHigh
+  }
+};
+
+/**
+  Locates the main boot firmware volume.
+
+  @param[in,out]  BootFv  On input, the base of the BootFv
+                          On output, the decompressed main firmware volume
+
+  @retval EFI_SUCCESS    The main firmware volume was located and decompressed
+  @retval EFI_NOT_FOUND  The main firmware volume was not found
+
+**/
+EFI_STATUS
+FindMainFv (
+  IN OUT  EFI_FIRMWARE_VOLUME_HEADER   **BootFv
+  )
+{
+  EFI_FIRMWARE_VOLUME_HEADER  *Fv;
+  UINTN                       Distance;
+
+  ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
+
+  Fv = *BootFv;
+  Distance = (UINTN) (*BootFv)->FvLength;
+  do {
+    Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE);
+    Distance += EFI_PAGE_SIZE;
+    if (Distance > SIZE_32MB) {
+      return EFI_NOT_FOUND;
+    }
+
+    if (Fv->Signature != EFI_FVH_SIGNATURE) {
+      continue;
+    }
+
+    if ((UINTN) Fv->FvLength > Distance) {
+      continue;
+    }
+
+    *BootFv = Fv;
+    return EFI_SUCCESS;
+
+  } while (TRUE);
+}
+
+/**
+  Locates a section within a series of sections
+  with the specified section type.
+
+  The Instance parameter indicates which instance of the section
+  type to return. (0 is first instance, 1 is second...)
+
+  @param[in]   Sections        The sections to search
+  @param[in]   SizeOfSections  Total size of all sections
+  @param[in]   SectionType     The section type to locate
+  @param[in]   Instance        The section instance number
+  @param[out]  FoundSection    The FFS section if found
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInstance (
+  IN  VOID                             *Sections,
+  IN  UINTN                            SizeOfSections,
+  IN  EFI_SECTION_TYPE                 SectionType,
+  IN  UINTN                            Instance,
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
+  )
+{
+  EFI_PHYSICAL_ADDRESS        CurrentAddress;
+  UINT32                      Size;
+  EFI_PHYSICAL_ADDRESS        EndOfSections;
+  EFI_COMMON_SECTION_HEADER   *Section;
+  EFI_PHYSICAL_ADDRESS        EndOfSection;
+
+  //
+  // Loop through the FFS file sections within the PEI Core FFS file
+  //
+  EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
+  EndOfSections = EndOfSection + SizeOfSections;
+  for (;;) {
+    if (EndOfSection == EndOfSections) {
+      break;
+    }
+    CurrentAddress = (EndOfSection + 3) & ~(3ULL);
+    if (CurrentAddress >= EndOfSections) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+    DEBUG ((EFI_D_INFO, "Section->Type: 0x%x\n", Section->Type));
+
+    Size = SECTION_SIZE (Section);
+    if (Size < sizeof (*Section)) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    EndOfSection = CurrentAddress + Size;
+    if (EndOfSection > EndOfSections) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    //
+    // Look for the requested section type
+    //
+    if (Section->Type == SectionType) {
+      if (Instance == 0) {
+        *FoundSection = Section;
+        return EFI_SUCCESS;
+      } else {
+        Instance--;
+      }
+    }
+    DEBUG ((EFI_D_INFO, "Section->Type (0x%x) != SectionType (0x%x)\n", Section->Type, SectionType));
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Locates a section within a series of sections
+  with the specified section type.
+
+  @param[in]   Sections        The sections to search
+  @param[in]   SizeOfSections  Total size of all sections
+  @param[in]   SectionType     The section type to locate
+  @param[out]  FoundSection    The FFS section if found
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInSections (
+  IN  VOID                             *Sections,
+  IN  UINTN                            SizeOfSections,
+  IN  EFI_SECTION_TYPE                 SectionType,
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
+  )
+{
+  return FindFfsSectionInstance (
+           Sections,
+           SizeOfSections,
+           SectionType,
+           0,
+           FoundSection
+           );
+}
+
+/**
+  Locates a FFS file with the specified file type and a section
+  within that file with the specified section type.
+
+  @param[in]   Fv            The firmware volume to search
+  @param[in]   FileType      The file type to locate
+  @param[in]   SectionType   The section type to locate
+  @param[out]  FoundSection  The FFS section if found
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsFileAndSection (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
+  IN  EFI_FV_FILETYPE                  FileType,
+  IN  EFI_SECTION_TYPE                 SectionType,
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PHYSICAL_ADDRESS        CurrentAddress;
+  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
+  EFI_FFS_FILE_HEADER         *File;
+  UINT32                      Size;
+  EFI_PHYSICAL_ADDRESS        EndOfFile;
+
+  if (Fv->Signature != EFI_FVH_SIGNATURE) {
+    DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n", Fv));
+    return EFI_VOLUME_CORRUPTED;
+  }
+
+  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
+  EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
+
+  //
+  // Loop through the FFS files in the Boot Firmware Volume
+  //
+  for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
+
+    CurrentAddress = (EndOfFile + 7) & ~(7ULL);
+    if (CurrentAddress > EndOfFirmwareVolume) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+    Size = *(UINT32*) File->Size & 0xffffff;
+    if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+    DEBUG ((EFI_D_INFO, "File->Type: 0x%x\n", File->Type));
+
+    EndOfFile = CurrentAddress + Size;
+    if (EndOfFile > EndOfFirmwareVolume) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    //
+    // Look for the request file type
+    //
+    if (File->Type != FileType) {
+      DEBUG ((EFI_D_INFO, "File->Type (0x%x) != FileType (0x%x)\n", File->Type, FileType));
+      continue;
+    }
+
+    Status = FindFfsSectionInSections (
+               (VOID*) (File + 1),
+               (UINTN) EndOfFile - (UINTN) (File + 1),
+               SectionType,
+               FoundSection
+               );
+    if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
+      return Status;
+    }
+  }
+}
+
+/**
+  Locates the compressed main firmware volume and decompresses it.
+
+  @param[in,out]  Fv            On input, the firmware volume to search
+                                On output, the decompressed BOOT/PEI FV
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+DecompressMemFvs (
+  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **Fv
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_GUID_DEFINED_SECTION          *Section;
+  UINT32                            OutputBufferSize;
+  UINT32                            ScratchBufferSize;
+  UINT16                            SectionAttribute;
+  UINT32                            AuthenticationStatus;
+  VOID                              *OutputBuffer;
+  VOID                              *ScratchBuffer;
+  EFI_COMMON_SECTION_HEADER         *FvSection;
+  EFI_FIRMWARE_VOLUME_HEADER        *PeiMemFv;
+  EFI_FIRMWARE_VOLUME_HEADER        *DxeMemFv;
+  UINT32                            FvHeaderSize;
+  UINT32                            FvSectionSize;
+
+  FvSection = (EFI_COMMON_SECTION_HEADER*) NULL;
+
+  DEBUG ((EFI_D_INFO, "Find and decompress FV image.\n"));
+  Status = FindFfsFileAndSection (
+             *Fv,
+             EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
+             EFI_SECTION_GUID_DEFINED,
+             (EFI_COMMON_SECTION_HEADER**) &Section
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
+    return Status;
+  }
+
+  Status = ExtractGuidedSectionGetInfo (
+             Section,
+             &OutputBufferSize,
+             &ScratchBufferSize,
+             &SectionAttribute
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
+    return Status;
+  }
+
+  OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase) + SIZE_1MB);
+  ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB);
+  
+  DEBUG ((EFI_D_INFO, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32 (PcdSimicsDxeMemFvBase)));
+  DEBUG ((EFI_D_INFO, "OutputBuffer: 0x%x\n", OutputBuffer));
+  DEBUG ((EFI_D_INFO, "OutputBufferSize: 0x%x\n", OutputBufferSize));
+  DEBUG ((EFI_D_INFO, "ScratchBuffer: 0x%x\n", ScratchBuffer));
+  DEBUG ((EFI_D_INFO, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
+  DEBUG ((EFI_D_INFO, "PcdSimicsDecompressionScratchEnd: 0x%x\n", PcdGet32 (PcdSimicsDecompressionScratchEnd)));
+
+  DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "
+    "PcdSimicsDecompressionScratchEnd=0x%x\n", __FUNCTION__, OutputBuffer,
+    OutputBufferSize, ScratchBuffer, ScratchBufferSize,
+    PcdGet32 (PcdSimicsDecompressionScratchEnd)));
+  ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==
+    PcdGet32 (PcdSimicsDecompressionScratchEnd));
+
+  Status = ExtractGuidedSectionDecode (
+             Section,
+             &OutputBuffer,
+             ScratchBuffer,
+             &AuthenticationStatus
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
+    return Status;
+  }
+
+  Status = FindFfsSectionInstance (
+             OutputBuffer,
+             OutputBufferSize,
+             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
+             0,
+             &FvSection
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));
+    return Status;
+  }
+
+  ASSERT (SECTION_SIZE (FvSection) ==
+          (PcdGet32 (PcdSimicsPeiMemFvSize) + sizeof (*FvSection)));
+  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
+
+  PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsPeiMemFvBase);
+  CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdSimicsPeiMemFvSize));
+
+  if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {
+    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", PeiMemFv));
+    CpuDeadLoop ();
+    return EFI_VOLUME_CORRUPTED;
+  }
+
+  Status = FindFfsSectionInstance (
+             OutputBuffer,
+             OutputBufferSize,
+             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
+             1,
+             &FvSection
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));
+    return Status;
+  }
+
+  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
+
+  if (IS_SECTION2 (FvSection)) {
+    FvSectionSize = SECTION2_SIZE (FvSection);
+    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
+  } else {
+    FvSectionSize = SECTION_SIZE (FvSection);
+    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
+  }
+
+  ASSERT (FvSectionSize == (PcdGet32 (PcdSimicsDxeMemFvSize) + FvHeaderSize));
+
+  DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase);
+  CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize), PcdGet32 (PcdSimicsDxeMemFvSize));
+
+  if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
+    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv));
+    CpuDeadLoop ();
+    return EFI_VOLUME_CORRUPTED;
+  }
+
+  *Fv = PeiMemFv;
+  return EFI_SUCCESS;
+}
+
+/**
+  Locates the PEI Core entry point address
+
+  @param[in]  Fv                 The firmware volume to search
+  @param[out] PeiCoreEntryPoint  The entry point of the PEI Core image
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindPeiCoreImageBaseInFv (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
+  OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_COMMON_SECTION_HEADER   *Section;
+
+  DEBUG ((EFI_D_ERROR, "Find PEI Core image.\n"));
+  Status = FindFfsFileAndSection (
+             Fv,
+             EFI_FV_FILETYPE_PEI_CORE,
+             EFI_SECTION_PE32,
+             &Section
+             );
+  if (EFI_ERROR (Status)) {
+    Status = FindFfsFileAndSection (
+               Fv,
+               EFI_FV_FILETYPE_PEI_CORE,
+               EFI_SECTION_TE,
+               &Section
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
+      return Status;
+    }
+  }
+
+  *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
+  DEBUG ((EFI_D_INFO, "PEI core image base 0x%016LX.\n", *PeiCoreImageBase));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Reads 8-bits of CMOS data.
+
+  Reads the 8-bits of CMOS data at the location specified by Index.
+  The 8-bit read value is returned.
+
+  @param  Index  The CMOS location to read.
+
+  @return The value read.
+
+**/
+STATIC
+UINT8
+CmosRead8 (
+  IN UINTN        Index
+  )
+{
+  IoWrite8 (0x70, (UINT8) Index);
+  return IoRead8 (0x71);
+}
+
+
+STATIC
+BOOLEAN
+IsS3Resume (
+  VOID
+  )
+{
+  DEBUG((EFI_D_INFO, "modeValue = %x\n", IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
+  return (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5);
+}
+
+
+STATIC
+EFI_STATUS
+GetS3ResumePeiFv (
+  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **PeiFv
+  )
+{
+  *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsPeiMemFvBase);
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Locates the PEI Core entry point address
+
+  @param[in,out]  Fv                 The firmware volume to search
+  @param[out]     PeiCoreEntryPoint  The entry point of the PEI Core image
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+VOID
+FindPeiCoreImageBase (
+  IN OUT  EFI_FIRMWARE_VOLUME_HEADER       **BootFv,
+     OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
+  )
+{
+  BOOLEAN S3Resume;
+
+  *PeiCoreImageBase = 0;
+
+  S3Resume = IsS3Resume ();
+  if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
+    //
+    // A malicious runtime OS may have injected something into our previously
+    // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required.
+    //
+    DEBUG ((EFI_D_INFO, "SEC: S3 resume\n"));
+    GetS3ResumePeiFv (BootFv);
+  } else {
+    //
+    // We're either not resuming, or resuming "securely" -- we'll decompress
+    // both PEI FV and DXE FV from pristine flash.
+    //
+    DEBUG ((EFI_D_INFO, "SEC: %a\n",
+      S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"));
+    FindMainFv (BootFv);
+
+    DecompressMemFvs (BootFv);
+  }
+
+  FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
+}
+
+/**
+  Find core image base.
+
+**/
+EFI_STATUS
+FindImageBase (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
+  OUT EFI_PHYSICAL_ADDRESS             *SecCoreImageBase
+  )
+{
+  EFI_PHYSICAL_ADDRESS        CurrentAddress;
+  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
+  EFI_FFS_FILE_HEADER         *File;
+  UINT32                      Size;
+  EFI_PHYSICAL_ADDRESS        EndOfFile;
+  EFI_COMMON_SECTION_HEADER   *Section;
+  EFI_PHYSICAL_ADDRESS        EndOfSection;
+
+  *SecCoreImageBase = 0;
+
+  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
+  EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
+
+  //
+  // Loop through the FFS files in the Boot Firmware Volume
+  //
+  for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
+
+    CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
+    if (CurrentAddress > EndOfFirmwareVolume) {
+      return EFI_NOT_FOUND;
+    }
+
+    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+    Size = *(UINT32*) File->Size & 0xffffff;
+    if (Size < sizeof (*File)) {
+      return EFI_NOT_FOUND;
+    }
+
+    EndOfFile = CurrentAddress + Size;
+    if (EndOfFile > EndOfFirmwareVolume) {
+      return EFI_NOT_FOUND;
+    }
+
+    //
+    // Look for SEC Core
+    //
+    if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {
+      continue;
+    }
+
+    //
+    // Loop through the FFS file sections within the FFS file
+    //
+    EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1);
+    for (;;) {
+      CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
+      Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+
+      Size = *(UINT32*) Section->Size & 0xffffff;
+      if (Size < sizeof (*Section)) {
+        return EFI_NOT_FOUND;
+      }
+
+      EndOfSection = CurrentAddress + Size;
+      if (EndOfSection > EndOfFile) {
+        return EFI_NOT_FOUND;
+      }
+
+      //
+      // Look for executable sections
+      //
+      if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) {
+        if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
+          *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) (Section + 1);
+        }
+        break;
+      }
+    }
+
+    //
+    // SEC Core image found
+    //
+    if (*SecCoreImageBase != 0) {
+      return EFI_SUCCESS;
+    }
+  }
+}
+
+/*
+  Find and return Pei Core entry point.
+
+  It also find SEC and PEI Core file debug information. It will report them if
+  remote debug is enabled.
+
+**/
+VOID
+FindAndReportEntryPoints (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       **BootFirmwareVolumePtr,
+  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_PHYSICAL_ADDRESS             SecCoreImageBase;
+  EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
+  PE_COFF_LOADER_IMAGE_CONTEXT     ImageContext;
+
+  //
+  // Find SEC Core and PEI Core image base
+   //
+  Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);
+  ASSERT_EFI_ERROR (Status);
+
+  FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
+  
+  ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
+  //
+  // Report SEC Core debug information when remote debug is enabled
+  //
+  ImageContext.ImageAddress = SecCoreImageBase;
+  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+  //
+  // Report PEI Core debug information when remote debug is enabled
+  //
+  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
+  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+  //
+  // Find PEI Core entry point
+  //
+  Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
+  if (EFI_ERROR (Status)) {
+    *PeiCoreEntryPoint = 0;
+  }
+
+  return;
+}
+
+VOID
+EFIAPI
+SecCoreStartupWithStack (
+  IN EFI_FIRMWARE_VOLUME_HEADER       *BootFv,
+  IN VOID                             *TopOfCurrentStack
+  )
+{
+  EFI_SEC_PEI_HAND_OFF        SecCoreData;
+  SEC_IDT_TABLE               IdtTableInStack;
+  IA32_DESCRIPTOR             IdtDescriptor;
+  UINT32                      Index;
+  volatile UINT8              *Table;
+  
+  //
+  // Initialize floating point operating environment
+  // to be compliant with UEFI spec.
+  //
+  InitializeFloatingPointUnits ();
+
+  //
+  // Initialize the PCIe Configuration base register.
+  //
+  PciCf8Write32 (PCI_CF8_LIB_ADDRESS (0xFF, 0, 1, 0x50), 0xE0000001);
+
+  //
+  // To ensure SMM can't be compromised on S3 resume, we must force re-init of
+  // the BaseExtractGuidedSectionLib. Since this is before library contructors
+  // are called, we must use a loop rather than SetMem.
+  //
+  Table = (UINT8*)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);
+  for (Index = 0;
+       Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
+       ++Index) {
+    Table[Index] = 0;
+  }
+
+  ProcessLibraryConstructorList (NULL, NULL);
+
+  DEBUG ((EFI_D_INFO,
+    "SecCoreStartupWithStack(0x%x, 0x%x)\n",
+    (UINT32)(UINTN)BootFv,
+    (UINT32)(UINTN)TopOfCurrentStack
+    ));
+  
+  //
+  // Initialize IDT
+  //
+  IdtTableInStack.PeiService = NULL;
+  for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
+    CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof (mIdtEntryTemplate));
+  }
+
+  IdtDescriptor.Base  = (UINTN)&IdtTableInStack.IdtTable;
+  IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
+
+  AsmWriteIdtr (&IdtDescriptor);
+
+#if defined (MDE_CPU_X64)
+  //
+  // ASSERT that the Page Tables were set by the reset vector code to
+  // the address we expect.
+  //
+  ASSERT (AsmReadCr3 () == (UINTN) PcdGet32 (PcdSimicsSecPageTablesBase));
+#endif
+
+  //
+  // |-------------|       <-- TopOfCurrentStack
+  // |   Stack     | 32k
+  // |-------------|
+  // |    Heap     | 32k
+  // |-------------|       <-- SecCoreData.TemporaryRamBase
+  //
+
+  ASSERT ((UINTN) (PcdGet32 (PcdSimicsSecPeiTempRamBase) +
+                   PcdGet32 (PcdSimicsSecPeiTempRamSize)) ==
+          (UINTN) TopOfCurrentStack);
+
+  //
+  // Initialize SEC hand-off state
+  //
+  SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
+
+  SecCoreData.TemporaryRamSize       = (UINTN) PcdGet32 (PcdSimicsSecPeiTempRamSize);
+  SecCoreData.TemporaryRamBase       = (VOID*)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);
+
+  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
+  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize >> 1;
+
+  SecCoreData.StackBase              = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;
+  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize >> 1;
+
+  SecCoreData.BootFirmwareVolumeBase = BootFv;
+  SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+
+  //
+  // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
+  //
+  IoWrite8 (0x21, 0xff);
+  IoWrite8 (0xA1, 0xff);
+
+  //
+  // Initialize Local APIC Timer hardware and disable Local APIC Timer
+  // interrupts before initializing the Debug Agent and the debug timer is
+  // enabled.
+  //
+  InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
+  DisableApicTimerInterrupt ();
+
+  //
+  // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
+  //
+  InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);
+}
+
+/**
+  Caller provided function to be invoked at the end of InitializeDebugAgent().
+
+  Entry point to the C language phase of SEC. After the SEC assembly
+  code has initialized some temporary memory and set up the stack,
+  the control is transferred to this function.
+
+  @param[in] Context    The first input parameter of InitializeDebugAgent().
+
+**/
+VOID
+EFIAPI
+SecStartupPhase2(
+  IN VOID                     *Context
+  )
+{
+  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
+  EFI_FIRMWARE_VOLUME_HEADER  *BootFv;
+  EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
+  
+  SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
+
+  //
+  // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
+  // is enabled.
+  //
+  BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
+  FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
+  SecCoreData->BootFirmwareVolumeBase = BootFv;
+  SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+
+  //
+  // Transfer the control to the PEI core
+  //
+  (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
+  
+  //
+  // If we get here then the PEI Core returned, which is not recoverable.
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+}
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
+  IN UINTN                    CopySize
+  )
+{
+  IA32_DESCRIPTOR                  IdtDescriptor;
+  VOID                             *OldHeap;
+  VOID                             *NewHeap;
+  VOID                             *OldStack;
+  VOID                             *NewStack;
+  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  DebugAgentContext;
+  BOOLEAN                          OldStatus;
+  BASE_LIBRARY_JUMP_BUFFER         JumpBuffer;
+
+  DEBUG ((EFI_D_INFO,
+    "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
+    TemporaryMemoryBase,
+    PermanentMemoryBase,
+    (UINT64)CopySize
+    ));
+
+  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
+
+  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
+  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
+
+  DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
+  DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
+
+  OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
+  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
+
+  //
+  // Migrate Heap
+  //
+  CopyMem (NewHeap, OldHeap, CopySize >> 1);
+
+  //
+  // Migrate Stack
+  //
+  CopyMem (NewStack, OldStack, CopySize >> 1);
+  
+  //
+  // Rebase IDT table in permanent memory
+  //
+  AsmReadIdtr (&IdtDescriptor);
+  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
+
+  AsmWriteIdtr (&IdtDescriptor);
+
+  //
+  // Use SetJump()/LongJump() to switch to a new stack.
+  // 
+  if (SetJump (&JumpBuffer) == 0) {
+#if defined (MDE_CPU_IA32)
+    JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;
+#endif
+#if defined (MDE_CPU_X64)
+    JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;
+#endif
+    LongJump (&JumpBuffer, (UINTN)-1);
+  }
+
+  SaveAndSetDebugTimerInterrupt (OldStatus);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
new file mode 100644
index 0000000000..771fddb487
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
@@ -0,0 +1,148 @@
+/** @file
+  A DXE_DRIVER providing SMRAM access by producing EFI_SMM_ACCESS2_PROTOCOL.
+
+  X58 TSEG is expected to have been verified and set up by the SmmAccessPei
+  driver.
+
+  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
+  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/SmmAccess2.h>
+
+#include "SmramInternal.h"
+
+/**
+  Opens the SMRAM area to be accessible by a boot-service driver.
+
+  This function "opens" SMRAM so that it is visible while not inside of SMM.
+  The function should return EFI_UNSUPPORTED if the hardware does not support
+  hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the SMRAM
+  configuration is locked.
+
+  @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The operation was successful.
+  @retval EFI_UNSUPPORTED   The system does not support opening and closing of
+                            SMRAM.
+  @retval EFI_DEVICE_ERROR  SMRAM cannot be opened, perhaps because it is
+                            locked.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeOpen (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  return SmramAccessOpen (&This->LockState, &This->OpenState);
+}
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function "closes" SMRAM so that it is not visible while outside of SMM.
+  The function should return EFI_UNSUPPORTED if the hardware does not support
+  hiding of SMRAM.
+
+  @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The operation was successful.
+  @retval EFI_UNSUPPORTED   The system does not support opening and closing of
+                            SMRAM.
+  @retval EFI_DEVICE_ERROR  SMRAM cannot be closed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeClose (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  return SmramAccessClose (&This->LockState, &This->OpenState);
+}
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function prohibits access to the SMRAM region.  This function is usually
+  implemented such that it is a write-once operation.
+
+  @param[in] This          The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+  @retval EFI_SUCCESS      The device was successfully locked.
+  @retval EFI_UNSUPPORTED  The system does not support locking of SMRAM.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeLock (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  return SmramAccessLock (&This->LockState, &This->OpenState);
+}
+
+/**
+  Queries the memory controller for the possible regions that will support
+  SMRAM.
+
+  @param[in]     This           The EFI_SMM_ACCESS2_PROTOCOL instance.
+  @param[in,out] SmramMapSize   A pointer to the size, in bytes, of the
+                                SmramMemoryMap buffer.
+  @param[in,out] SmramMap       A pointer to the buffer in which firmware
+                                places the current memory map.
+
+  @retval EFI_SUCCESS           The chipset supported the given resource.
+  @retval EFI_BUFFER_TOO_SMALL  The SmramMap parameter was too small.  The
+                                current buffer size needed to hold the memory
+                                map is returned in SmramMapSize.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeGetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+{
+  return SmramAccessGetCapabilities (This->LockState, This->OpenState,
+           SmramMapSize, SmramMap);
+}
+
+//
+// LockState and OpenState will be filled in by the entry point.
+//
+STATIC EFI_SMM_ACCESS2_PROTOCOL mAccess2 = {
+  &SmmAccess2DxeOpen,
+  &SmmAccess2DxeClose,
+  &SmmAccess2DxeLock,
+  &SmmAccess2DxeGetCapabilities
+};
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  //
+  // This module should only be included if SMRAM support is required.
+  //
+  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+  GetStates (&mAccess2.LockState, &mAccess2.OpenState);
+  return gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+                &gEfiSmmAccess2ProtocolGuid, &mAccess2,
+                NULL);
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
new file mode 100644
index 0000000000..d07d88142a
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
@@ -0,0 +1,353 @@
+/** @file
+  A PEIM with the following responsibilities:
+
+  - verify & configure the X58 TSEG in the entry point,
+  - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
+  - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and expose
+    it via the gEfiAcpiVariableGuid GUID HOB.
+
+  This PEIM runs from RAM, so we can write to variables with static storage
+  duration.
+
+  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Guid/AcpiS3Context.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/SmmAccess.h>
+
+#include <SimicsPlatforms.h>
+
+#include "SmramInternal.h"
+
+//
+// PEI_SMM_ACCESS_PPI implementation.
+//
+
+/**
+  Opens the SMRAM area to be accessible by a PEIM driver.
+
+  This function "opens" SMRAM so that it is visible while not inside of SMM.
+  The function should return EFI_UNSUPPORTED if the hardware does not support
+  hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the SMRAM
+  configuration is locked.
+
+  @param  PeiServices            General purpose services available to every
+                                 PEIM.
+  @param  This                   The pointer to the SMM Access Interface.
+  @param  DescriptorIndex        The region of SMRAM to Open.
+
+  @retval EFI_SUCCESS            The region was successfully opened.
+  @retval EFI_DEVICE_ERROR       The region could not be opened because locked
+                                 by chipset.
+  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiOpen (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  )
+{
+  if (DescriptorIndex >= DescIdxCount) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // According to current practice, DescriptorIndex is not considered at all,
+  // beyond validating it.
+  //
+  return SmramAccessOpen (&This->LockState, &This->OpenState);
+}
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function "closes" SMRAM so that it is not visible while outside of SMM.
+  The function should return EFI_UNSUPPORTED if the hardware does not support
+  hiding of SMRAM.
+
+  @param  PeiServices              General purpose services available to every
+                                   PEIM.
+  @param  This                     The pointer to the SMM Access Interface.
+  @param  DescriptorIndex          The region of SMRAM to Close.
+
+  @retval EFI_SUCCESS              The region was successfully closed.
+  @retval EFI_DEVICE_ERROR         The region could not be closed because
+                                   locked by chipset.
+  @retval EFI_INVALID_PARAMETER    The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiClose (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  )
+{
+  if (DescriptorIndex >= DescIdxCount) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // According to current practice, DescriptorIndex is not considered at all,
+  // beyond validating it.
+  //
+  return SmramAccessClose (&This->LockState, &This->OpenState);
+}
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function prohibits access to the SMRAM region.  This function is usually
+  implemented such that it is a write-once operation.
+
+  @param  PeiServices              General purpose services available to every
+                                   PEIM.
+  @param  This                     The pointer to the SMM Access Interface.
+  @param  DescriptorIndex          The region of SMRAM to Close.
+
+  @retval EFI_SUCCESS            The region was successfully locked.
+  @retval EFI_DEVICE_ERROR       The region could not be locked because at
+                                 least one range is still open.
+  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiLock (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  )
+{
+  if (DescriptorIndex >= DescIdxCount) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // According to current practice, DescriptorIndex is not considered at all,
+  // beyond validating it.
+  //
+  return SmramAccessLock (&This->LockState, &This->OpenState);
+}
+
+/**
+  Queries the memory controller for the possible regions that will support
+  SMRAM.
+
+  @param  PeiServices           General purpose services available to every
+                                PEIM.
+  @param This                   The pointer to the SmmAccessPpi Interface.
+  @param SmramMapSize           The pointer to the variable containing size of
+                                the buffer to contain the description
+                                information.
+  @param SmramMap               The buffer containing the data describing the
+                                Smram region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           The user provided a sufficiently-sized buffer.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiGetCapabilities (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+{
+  return SmramAccessGetCapabilities (This->LockState, This->OpenState,
+           SmramMapSize, SmramMap);
+}
+
+//
+// LockState and OpenState will be filled in by the entry point.
+//
+STATIC PEI_SMM_ACCESS_PPI mAccess = {
+  &SmmAccessPeiOpen,
+  &SmmAccessPeiClose,
+  &SmmAccessPeiLock,
+  &SmmAccessPeiGetCapabilities
+};
+
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gPeiSmmAccessPpiGuid, &mAccess
+  }
+};
+
+
+//
+// Utility functions.
+//
+STATIC
+UINT8
+CmosRead8 (
+  IN UINT8  Index
+  )
+{
+  IoWrite8 (0x70, Index);
+  return IoRead8 (0x71);
+}
+
+STATIC
+UINT32
+GetSystemMemorySizeBelow4gb (
+  VOID
+  )
+{
+  UINT32 Cmos0x34;
+  UINT32 Cmos0x35;
+
+  Cmos0x34 = CmosRead8 (0x34);
+  Cmos0x35 = CmosRead8 (0x35);
+
+  return ((Cmos0x35 << 8 | Cmos0x34) << 16) + SIZE_16MB;
+}
+
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+SmmAccessPeiEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  UINT16               HostBridgeDevId;
+  UINT32                EsmramcVal;
+  UINT32               TopOfLowRam, TopOfLowRamMb;
+  EFI_STATUS           Status;
+  UINTN                SmramMapSize;
+  EFI_SMRAM_DESCRIPTOR SmramMap[DescIdxCount];
+  VOID                 *GuidHob;
+
+  //
+  // This module should only be included if SMRAM support is required.
+  //
+  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+  //
+  // Verify if we're running on a X58 machine type.
+  //
+  HostBridgeDevId = PciRead16 (SIMICS_HOSTBRIDGE_DID);
+  if (HostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
+    DEBUG ((EFI_D_ERROR, "%a: no SMRAM with host bridge DID=0x%04x; only "
+      "DID=0x%04x (X58) is supported\n", __FUNCTION__, HostBridgeDevId,
+      INTEL_ICH10_DEVICE_ID));
+    goto WrongConfig;
+  }
+
+  //
+  // Confirm if QEMU supports SMRAM.
+  //
+  // With no support for it, the ESMRAMC (Extended System Management RAM
+  // Control) register reads as zero. If there is support, the cache-enable
+  // bits are hard-coded as 1 by QEMU.
+  //
+
+  TopOfLowRam = GetSystemMemorySizeBelow4gb ();
+  ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
+  TopOfLowRamMb = TopOfLowRam >> 20;
+  DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x \n", TopOfLowRam, TopOfLowRamMb));
+
+
+  //
+  // Set Top of Low Usable DRAM.
+  //
+  PciWrite32 (DRAMC_REGISTER_X58(MCH_TOLUD),
+               TopOfLowRam);
+  DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));
+
+  //
+  // Set TSEG Memory Base.
+  //
+  EsmramcVal = (TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) << MCH_TSEGMB_MB_SHIFT;
+  //
+  // Set TSEG size, and disable TSEG visibility outside of SMM. Note that the
+  // T_EN bit has inverse meaning; when T_EN is set, then TSEG visibility is
+  // *restricted* to SMM.
+  //
+  EsmramcVal &= ~(UINT32)MCH_ESMRAMC_TSEG_MASK;
+  EsmramcVal |= FixedPcdGet8 (PcdX58TsegMbytes) == 8 ? MCH_ESMRAMC_TSEG_8MB :
+                FixedPcdGet8 (PcdX58TsegMbytes) == 2 ? MCH_ESMRAMC_TSEG_2MB :
+                MCH_ESMRAMC_TSEG_1MB;
+  EsmramcVal |= MCH_ESMRAMC_T_EN;
+  PciWrite32(DRAMC_REGISTER_X58(MCH_TSEGMB), EsmramcVal);
+  DEBUG((EFI_D_ERROR, "MCH_TSEGMB =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
+  DEBUG((EFI_D_ERROR, "MCH_TSEGMB_1 =0x%x; MCH_TSEGMB_2 =0x%x;\n", ((TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) << MCH_TSEGMB_MB_SHIFT), EsmramcVal));
+
+  //
+  // Create the GUID HOB and point it to the first SMRAM range.
+  //
+  GetStates (&mAccess.LockState, &mAccess.OpenState);
+  SmramMapSize = sizeof SmramMap;
+  Status = SmramAccessGetCapabilities (mAccess.LockState, mAccess.OpenState,
+             &SmramMapSize, SmramMap);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG_CODE_BEGIN ();
+  {
+    UINTN Count;
+    UINTN Idx;
+
+    Count = SmramMapSize / sizeof SmramMap[0];
+    DEBUG ((EFI_D_VERBOSE, "%a: SMRAM map follows, %d entries\n", __FUNCTION__,
+      (INT32)Count));
+    DEBUG ((EFI_D_VERBOSE, "% 20a % 20a % 20a % 20a\n", "PhysicalStart(0x)",
+      "PhysicalSize(0x)", "CpuStart(0x)", "RegionState(0x)"));
+    for (Idx = 0; Idx < Count; ++Idx) {
+      DEBUG ((EFI_D_VERBOSE, "% 20Lx % 20Lx % 20Lx % 20Lx\n",
+        SmramMap[Idx].PhysicalStart, SmramMap[Idx].PhysicalSize,
+        SmramMap[Idx].CpuStart, SmramMap[Idx].RegionState));
+    }
+  }
+  DEBUG_CODE_END ();
+
+  GuidHob = BuildGuidHob (&gEfiAcpiVariableGuid,
+    sizeof SmramMap[DescIdxSmmS3ResumeState]);
+  if (GuidHob == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CopyMem (GuidHob, &SmramMap[DescIdxSmmS3ResumeState],
+    sizeof SmramMap[DescIdxSmmS3ResumeState]);
+
+  //
+  // We're done. The next step should succeed, but even if it fails, we can't
+  // roll back the above BuildGuidHob() allocation, because PEI doesn't support
+  // releasing memory.
+  //
+  return PeiServicesInstallPpi (mPpiList);
+
+WrongConfig:
+  //
+  // We really don't want to continue in this case.
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+  return EFI_UNSUPPORTED;
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
new file mode 100644
index 0000000000..898fc25084
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
@@ -0,0 +1,199 @@
+/** @file
+  Functions and types shared by the SMM accessor PEI and DXE modules.
+
+  Copyright (C) 2015, Red Hat, Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Guid/AcpiS3Context.h>
+#include <IndustryStandard/X58Ich10.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+
+#include "SmramInternal.h"
+
+BOOLEAN gLockState;
+BOOLEAN gOpenState;
+
+/**
+  Read the MCH_SMRAM and ESMRAMC registers, and update the LockState and
+  OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL object,
+  from the D_LCK and T_EN bits.
+
+  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can rely on
+  the LockState and OpenState fields being up-to-date on entry, and they need
+  to restore the same invariant on exit, if they touch the bits in question.
+
+  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff SMRAM is
+                         locked.
+  @param[out] OpenState  Reflects the inverse of the T_EN bit on output; TRUE
+                         iff SMRAM is open.
+**/
+VOID
+GetStates (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+)
+{
+  UINT8 EsmramcVal;
+
+  EsmramcVal = PciRead8(DRAMC_REGISTER_X58(MCH_TSEGMB));
+
+  *OpenState = !(EsmramcVal & MCH_ESMRAMC_T_EN);
+  *LockState = !*OpenState;
+
+  *OpenState = gOpenState;
+  *LockState = gLockState;
+}
+
+//
+// The functions below follow the PEI_SMM_ACCESS_PPI and
+// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This
+// pointers are removed (TSEG doesn't depend on them), and so is the
+// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
+//
+// The LockState and OpenState members that are common to both
+// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated in
+// isolation from the rest of the (non-shared) members.
+//
+
+EFI_STATUS
+SmramAccessOpen (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+  )
+{
+
+  //
+  // Open TSEG by clearing T_EN.
+  //
+  PciAnd8(DRAMC_REGISTER_X58(MCH_TSEGMB),
+    (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff));
+
+  gOpenState = TRUE;
+  gLockState = !gOpenState;
+
+  GetStates (LockState, OpenState);
+  if (!*OpenState) {
+    return EFI_DEVICE_ERROR;
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessClose (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+  )
+{
+  //
+  // Close TSEG by setting T_EN.
+  //
+  PciOr8(DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
+
+  gOpenState = FALSE;
+  gLockState = !gOpenState;
+
+  GetStates (LockState, OpenState);
+  if (*OpenState) {
+    return EFI_DEVICE_ERROR;
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessLock (
+  OUT    BOOLEAN *LockState,
+  IN OUT BOOLEAN *OpenState
+  )
+{
+  if (*OpenState) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Close & lock TSEG by setting T_EN and D_LCK.
+  //
+  PciOr8 (DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
+
+  gOpenState = FALSE;
+  gLockState = !gOpenState;
+
+  GetStates (LockState, OpenState);
+  if (*OpenState || !*LockState) {
+    return EFI_DEVICE_ERROR;
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessGetCapabilities (
+  IN BOOLEAN                  LockState,
+  IN BOOLEAN                  OpenState,
+  IN OUT UINTN                *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+  )
+{
+  UINTN  OriginalSize;
+  UINT32 TsegMemoryBaseMb, TsegMemoryBase;
+  UINT64 CommonRegionState;
+  UINT8  TsegSizeBits;
+
+  OriginalSize  = *SmramMapSize;
+  *SmramMapSize = DescIdxCount * sizeof *SmramMap;
+  if (OriginalSize < *SmramMapSize) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  //
+  // Read the TSEG Memory Base register.
+  //
+  TsegMemoryBaseMb = PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB));
+
+  TsegMemoryBaseMb = 0xDF800000;
+
+  TsegMemoryBase = (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) << 20;
+
+  //
+  // Precompute the region state bits that will be set for all regions.
+  //
+  CommonRegionState = (OpenState ? EFI_SMRAM_OPEN : EFI_SMRAM_CLOSED) |
+                      (LockState ? EFI_SMRAM_LOCKED : 0) |
+                      EFI_CACHEABLE;
+
+  //
+  // The first region hosts an SMM_S3_RESUME_STATE object. It is located at the
+  // start of TSEG. We round up the size to whole pages, and we report it as
+  // EFI_ALLOCATED, so that the SMM_CORE stays away from it.
+  //
+  SmramMap[DescIdxSmmS3ResumeState].PhysicalStart = TsegMemoryBase;
+  SmramMap[DescIdxSmmS3ResumeState].CpuStart      = TsegMemoryBase;
+  SmramMap[DescIdxSmmS3ResumeState].PhysicalSize  =
+    EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (SMM_S3_RESUME_STATE)));
+  SmramMap[DescIdxSmmS3ResumeState].RegionState   =
+    CommonRegionState | EFI_ALLOCATED;
+
+  //
+  // Get the TSEG size bits from the ESMRAMC register.
+  //
+  TsegSizeBits = PciRead8 (DRAMC_REGISTER_X58(MCH_TSEGMB)) &
+                            MCH_ESMRAMC_TSEG_MASK;
+
+  TsegSizeBits = MCH_ESMRAMC_TSEG_8MB;
+
+  //
+  // The second region is the main one, following the first.
+  //
+  SmramMap[DescIdxMain].PhysicalStart =
+    SmramMap[DescIdxSmmS3ResumeState].PhysicalStart +
+    SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
+  SmramMap[DescIdxMain].CpuStart = SmramMap[DescIdxMain].PhysicalStart;
+  SmramMap[DescIdxMain].PhysicalSize =
+    (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB :
+     TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB :
+     SIZE_1MB) - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
+  SmramMap[DescIdxMain].RegionState = CommonRegionState;
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
new file mode 100644
index 0000000000..19ffb6f86d
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+#include <Base.h>
+
+    SECTION .text
+
+extern ASM_PFX(SecCoreStartupWithStack)
+
+;
+; SecCore Entry Point
+;
+; Processor is in flat protected mode
+;
+; @param[in]  EAX   Initial value of the EAX register (BIST: Built-in Self Test)
+; @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
+; @param[in]  EBP   Pointer to the start of the Boot Firmware Volume
+;
+; @return     None  This routine does not return
+;
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+    ;
+    ; Load temporary RAM stack based on PCDs
+    ;
+    %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdSimicsSecPeiTempRamBase) + \
+                          FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
+    mov     eax, SEC_TOP_OF_STACK
+    mov     esp, eax
+    nop
+
+    ;
+    ; Setup parameters and call SecCoreStartupWithStack
+    ;   [esp]   return address for call
+    ;   [esp+4] BootFirmwareVolumePtr
+    ;   [esp+8] TopOfCurrentStack
+    ;
+    push    eax
+    push    ebp
+    call    ASM_PFX(SecCoreStartupWithStack)
+
diff --git a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
new file mode 100644
index 0000000000..ac993ac1ce
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
@@ -0,0 +1,71 @@
+## @file
+#  SEC Driver
+#
+# Copyright (c) 2008 - 2018 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecMain
+  FILE_GUID                      = e67f156f-54c5-47f3-a35d-07c045881e14
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SecMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  SecMain.c
+
+[Sources.IA32]
+  Ia32/SecEntry.nasm
+
+[Sources.X64]
+  X64/SecEntry.nasm
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  PeiServicesLib
+  PcdLib
+  UefiCpuLib
+  DebugAgentLib
+  IoLib
+  PeCoffLib
+  PeCoffGetEntryPointLib
+  PeCoffExtraActionLib
+  ExtractGuidedSectionLib
+  LocalApicLib
+  PciCf8Lib
+
+[Ppis]
+  gEfiTemporaryRamSupportPpiGuid                # PPI ALWAYS_PRODUCED
+
+[Pcd]
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+  gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+
+[FeaturePcd]
+  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
new file mode 100644
index 0000000000..0eb86ec2ca
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+#include <Base.h>
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(SecCoreStartupWithStack)
+
+;
+; SecCore Entry Point
+;
+; Processor is in flat protected mode
+;
+; @param[in]  RAX   Initial value of the EAX register (BIST: Built-in Self Test)
+; @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
+; @param[in]  RBP   Pointer to the start of the Boot Firmware Volume
+;
+; @return     None  This routine does not return
+;
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+    ;
+    ; Load temporary RAM stack based on PCDs
+    ;
+    %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdSimicsSecPeiTempRamBase) + \
+                          FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
+    mov     rsp, SEC_TOP_OF_STACK
+    nop
+
+    ;
+    ; Setup parameters and call SecCoreStartupWithStack
+    ;   rcx: BootFirmwareVolumePtr
+    ;   rdx: TopOfCurrentStack
+    ;
+    mov     rcx, rbp
+    mov     rdx, rsp
+    sub     rsp, 0x20
+    call    ASM_PFX(SecCoreStartupWithStack)
+
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
new file mode 100644
index 0000000000..0be8be4966
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
@@ -0,0 +1,18 @@
+## @file
+#  Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+  #
+  # SEC Phase modules
+  #
+  $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+  UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
+  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
new file mode 100644
index 0000000000..78eca21a43
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+#  Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
new file mode 100644
index 0000000000..9f037e99d4
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
@@ -0,0 +1,10 @@
+## @file
+#  Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
new file mode 100644
index 0000000000..596d633cd3
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
@@ -0,0 +1,17 @@
+## @file
+#  Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# SEC Phase modules
+#
+# The code in this FV handles the initial firmware startup, and
+# decompresses the PEI and DXE FVs which handles the rest of the boot sequence.
+#
+INF  RuleOverride=RESET_SECMAIN USE = IA32 $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf
+INF  RuleOverride=RESET_VECTOR USE = IA32 UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
new file mode 100644
index 0000000000..9004b9cb83
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
@@ -0,0 +1,16 @@
+## @file
+#  Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#INF  $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuArchDxe/CpuArchDxe.inf
+#INF  $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuMpDxe/CpuMpDxe.inf
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+  INF  $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf
+  INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+!endif
+INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
new file mode 100644
index 0000000000..2f630b4b95
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
@@ -0,0 +1,52 @@
+## @file
+# A DXE_DRIVER providing SMRAM access by producing EFI_SMM_ACCESS2_PROTOCOL.
+#
+# X58 TSEG is expected to have been verified and set up by the SmmAccessPei
+# driver.
+#
+# Copyright (C) 2013, 2015, Red Hat, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmAccess2Dxe
+  FILE_GUID                      = AC95AD3D-4366-44BF-9A62-E4B29D7A2206
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x00010400
+  ENTRY_POINT                    = SmmAccess2DxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  SmmAccess2Dxe.c
+  SmramInternal.c
+  SmramInternal.h
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  PcdLib
+  PciLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiSmmAccess2ProtocolGuid   ## PRODUCES
+
+[FeaturePcd]
+  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[Depex]
+  TRUE
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
new file mode 100644
index 0000000000..1d3b028c85
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
@@ -0,0 +1,64 @@
+## @file
+# A PEIM with the following responsibilities:
+#
+# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
+# - verify & configure the X58 TSEG in the entry point,
+# - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and expose
+#   it via the gEfiAcpiVariableGuid GUIDed HOB.
+#
+# Copyright (C) 2013, 2015, Red Hat, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmAccessPei
+  FILE_GUID                      = 6C0E75B4-B0B9-44D1-8210-3377D7B4E066
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmmAccessPeiEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  SmmAccessPei.c
+  SmramInternal.c
+  SmramInternal.h
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[Guids]
+  gEfiAcpiVariableGuid
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  IoLib
+  PcdLib
+  PciLib
+  PeiServicesLib
+  PeimEntryPoint
+
+[FeaturePcd]
+  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[FixedPcd]
+  gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
+
+[Ppis]
+  gPeiSmmAccessPpiGuid           ## PRODUCES
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
new file mode 100644
index 0000000000..43a79b295f
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
@@ -0,0 +1,81 @@
+/** @file
+  Functions and types shared by the SMM accessor PEI and DXE modules.
+
+  Copyright (C) 2015, Red Hat, Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Pi/PiMultiPhase.h>
+
+//
+// We'll have two SMRAM ranges.
+//
+// The first is a tiny one that hosts an SMM_S3_RESUME_STATE object, to be
+// filled in by the CPU SMM driver during normal boot, for the PEI instance of
+// the LockBox library (which will rely on the object during S3 resume).
+//
+// The other SMRAM range is the main one, for the SMM core and the SMM drivers.
+//
+typedef enum {
+  DescIdxSmmS3ResumeState = 0,
+  DescIdxMain             = 1,
+  DescIdxCount            = 2
+} DESCRIPTOR_INDEX;
+
+/**
+  Read the MCH_SMRAM and ESMRAMC registers, and update the LockState and
+  OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL object,
+  from the D_LCK and T_EN bits.
+
+  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can rely on
+  the LockState and OpenState fields being up-to-date on entry, and they need
+  to restore the same invariant on exit, if they touch the bits in question.
+
+  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff SMRAM is
+                         locked.
+  @param[out] OpenState  Reflects the inverse of the T_EN bit on output; TRUE
+                         iff SMRAM is open.
+**/
+VOID
+GetStates (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+  );
+
+//
+// The functions below follow the PEI_SMM_ACCESS_PPI and
+// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This
+// pointers are removed (TSEG doesn't depend on them), and so is the
+// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
+//
+// The LockState and OpenState members that are common to both
+// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated in
+// isolation from the rest of the (non-shared) members.
+//
+
+EFI_STATUS
+SmramAccessOpen (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+  );
+
+EFI_STATUS
+SmramAccessClose (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+  );
+
+EFI_STATUS
+SmramAccessLock (
+  OUT    BOOLEAN *LockState,
+  IN OUT BOOLEAN *OpenState
+  );
+
+EFI_STATUS
+SmramAccessGetCapabilities (
+  IN BOOLEAN                  LockState,
+  IN BOOLEAN                  OpenState,
+  IN OUT UINTN                *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+  );
-- 
2.16.2.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#45302): https://edk2.groups.io/g/devel/message/45302
Mute This Topic: https://groups.io/mt/32816095/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
Posted by Nate DeSimone 6 years, 4 months ago
Hi David,

Here are my comments:

1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c - Please fix all the interspersed trailing white-space.
4. Silicon/Intel/SimicsX58SktPkg/SktPei.dsc - line 2 reads like this "Component description file for the SkyLake SiPkg PEI drivers.". This is Simics, not Sky Lake, please update the comment.
5. Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf - lines 10 & 11 - please remove the commented out code.

Other than that, looks good! Please send an updated patch.

Thanks,
Nate

-----Original Message-----
From: Wei, David Y 
Sent: Friday, August 9, 2019 3:47 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58

Add CPU Pkg for SimicsX58. It is added for simics QSP project support

Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: David Wei <david.y.wei@intel.com>
---
 .../Override/UefiCpuPkg/SecCore/SecMain.c          | 956 +++++++++++++++++++++
 .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c     | 148 ++++
 .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c      | 353 ++++++++
 .../SimicsX58SktPkg/Smm/Access/SmramInternal.c     | 199 +++++
 .../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm |  45 +
 .../Override/UefiCpuPkg/SecCore/SecMain.inf        |  71 ++
 .../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm  |  45 +
 Silicon/Intel/SimicsX58SktPkg/SktPei.dsc           |  18 +
 .../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf |   9 +
 .../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf  |  10 +
 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf    |  17 +
 .../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf   |  16 +
 .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf   |  52 ++
 .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf    |  64 ++
 .../SimicsX58SktPkg/Smm/Access/SmramInternal.h     |  81 ++
 15 files changed, 2084 insertions(+)
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
 create mode 100644 Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h

diff --git a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
new file mode 100644
index 0000000000..c52d459ef2
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
@@ -0,0 +1,956 @@
+/** @file
+  Main SEC phase code.  Transitions to PEI.
+
+  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiPei.h>
+
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiCpuLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/PciCf8Lib.h>
+
+#include <Ppi/TemporaryRamSupport.h>
+#include <IndustryStandard/X58Ich10.h>
+
+#define SEC_IDT_ENTRY_COUNT  34
+
+typedef struct _SEC_IDT_TABLE {
+  EFI_PEI_SERVICES          *PeiService;
+  IA32_IDT_GATE_DESCRIPTOR  IdtTable[SEC_IDT_ENTRY_COUNT];
+} SEC_IDT_TABLE;
+
+VOID
+EFIAPI
+SecStartupPhase2 (
+  IN VOID                     *Context
+  );
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
+  IN UINTN                    CopySize
+  );
+
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+  TemporaryRamMigration
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
+  {
+    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+    &gEfiTemporaryRamSupportPpiGuid,
+    &mTemporaryRamSupportPpi
+  },
+};
+
+//
+// Template of an IDT entry pointing to 10:FFFFFFE4h.
+//
+IA32_IDT_GATE_DESCRIPTOR  mIdtEntryTemplate = {
+  {                                      // Bits
+    0xffe4,                              // OffsetLow
+    0x10,                                // Selector
+    0x0,                                 // Reserved_0
+    IA32_IDT_GATE_TYPE_INTERRUPT_32,     // GateType
+    0xffff                               // OffsetHigh
+  }
+};
+
+/**
+  Locates the main boot firmware volume.
+
+  @param[in,out]  BootFv  On input, the base of the BootFv
+                          On output, the decompressed main firmware volume
+
+  @retval EFI_SUCCESS    The main firmware volume was located and decompressed
+  @retval EFI_NOT_FOUND  The main firmware volume was not found
+
+**/
+EFI_STATUS
+FindMainFv (
+  IN OUT  EFI_FIRMWARE_VOLUME_HEADER   **BootFv
+  )
+{
+  EFI_FIRMWARE_VOLUME_HEADER  *Fv;
+  UINTN                       Distance;
+
+  ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
+
+  Fv = *BootFv;
+  Distance = (UINTN) (*BootFv)->FvLength;
+  do {
+    Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE);
+    Distance += EFI_PAGE_SIZE;
+    if (Distance > SIZE_32MB) {
+      return EFI_NOT_FOUND;
+    }
+
+    if (Fv->Signature != EFI_FVH_SIGNATURE) {
+      continue;
+    }
+
+    if ((UINTN) Fv->FvLength > Distance) {
+      continue;
+    }
+
+    *BootFv = Fv;
+    return EFI_SUCCESS;
+
+  } while (TRUE);
+}
+
+/**
+  Locates a section within a series of sections
+  with the specified section type.
+
+  The Instance parameter indicates which instance of the section
+  type to return. (0 is first instance, 1 is second...)
+
+  @param[in]   Sections        The sections to search
+  @param[in]   SizeOfSections  Total size of all sections
+  @param[in]   SectionType     The section type to locate
+  @param[in]   Instance        The section instance number
+  @param[out]  FoundSection    The FFS section if found
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInstance (
+  IN  VOID                             *Sections,
+  IN  UINTN                            SizeOfSections,
+  IN  EFI_SECTION_TYPE                 SectionType,
+  IN  UINTN                            Instance,
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
+  )
+{
+  EFI_PHYSICAL_ADDRESS        CurrentAddress;
+  UINT32                      Size;
+  EFI_PHYSICAL_ADDRESS        EndOfSections;
+  EFI_COMMON_SECTION_HEADER   *Section;
+  EFI_PHYSICAL_ADDRESS        EndOfSection;
+
+  //
+  // Loop through the FFS file sections within the PEI Core FFS file
+  //
+  EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
+  EndOfSections = EndOfSection + SizeOfSections;
+  for (;;) {
+    if (EndOfSection == EndOfSections) {
+      break;
+    }
+    CurrentAddress = (EndOfSection + 3) & ~(3ULL);
+    if (CurrentAddress >= EndOfSections) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+    DEBUG ((EFI_D_INFO, "Section->Type: 0x%x\n", Section->Type));
+
+    Size = SECTION_SIZE (Section);
+    if (Size < sizeof (*Section)) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    EndOfSection = CurrentAddress + Size;
+    if (EndOfSection > EndOfSections) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    //
+    // Look for the requested section type
+    //
+    if (Section->Type == SectionType) {
+      if (Instance == 0) {
+        *FoundSection = Section;
+        return EFI_SUCCESS;
+      } else {
+        Instance--;
+      }
+    }
+    DEBUG ((EFI_D_INFO, "Section->Type (0x%x) != SectionType (0x%x)\n", Section->Type, SectionType));
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Locates a section within a series of sections
+  with the specified section type.
+
+  @param[in]   Sections        The sections to search
+  @param[in]   SizeOfSections  Total size of all sections
+  @param[in]   SectionType     The section type to locate
+  @param[out]  FoundSection    The FFS section if found
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInSections (
+  IN  VOID                             *Sections,
+  IN  UINTN                            SizeOfSections,
+  IN  EFI_SECTION_TYPE                 SectionType,
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
+  )
+{
+  return FindFfsSectionInstance (
+           Sections,
+           SizeOfSections,
+           SectionType,
+           0,
+           FoundSection
+           );
+}
+
+/**
+  Locates a FFS file with the specified file type and a section
+  within that file with the specified section type.
+
+  @param[in]   Fv            The firmware volume to search
+  @param[in]   FileType      The file type to locate
+  @param[in]   SectionType   The section type to locate
+  @param[out]  FoundSection  The FFS section if found
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsFileAndSection (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
+  IN  EFI_FV_FILETYPE                  FileType,
+  IN  EFI_SECTION_TYPE                 SectionType,
+  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PHYSICAL_ADDRESS        CurrentAddress;
+  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
+  EFI_FFS_FILE_HEADER         *File;
+  UINT32                      Size;
+  EFI_PHYSICAL_ADDRESS        EndOfFile;
+
+  if (Fv->Signature != EFI_FVH_SIGNATURE) {
+    DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n", Fv));
+    return EFI_VOLUME_CORRUPTED;
+  }
+
+  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
+  EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
+
+  //
+  // Loop through the FFS files in the Boot Firmware Volume
+  //
+  for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
+
+    CurrentAddress = (EndOfFile + 7) & ~(7ULL);
+    if (CurrentAddress > EndOfFirmwareVolume) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+    Size = *(UINT32*) File->Size & 0xffffff;
+    if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+    DEBUG ((EFI_D_INFO, "File->Type: 0x%x\n", File->Type));
+
+    EndOfFile = CurrentAddress + Size;
+    if (EndOfFile > EndOfFirmwareVolume) {
+      return EFI_VOLUME_CORRUPTED;
+    }
+
+    //
+    // Look for the request file type
+    //
+    if (File->Type != FileType) {
+      DEBUG ((EFI_D_INFO, "File->Type (0x%x) != FileType (0x%x)\n", File->Type, FileType));
+      continue;
+    }
+
+    Status = FindFfsSectionInSections (
+               (VOID*) (File + 1),
+               (UINTN) EndOfFile - (UINTN) (File + 1),
+               SectionType,
+               FoundSection
+               );
+    if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
+      return Status;
+    }
+  }
+}
+
+/**
+  Locates the compressed main firmware volume and decompresses it.
+
+  @param[in,out]  Fv            On input, the firmware volume to search
+                                On output, the decompressed BOOT/PEI FV
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+DecompressMemFvs (
+  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **Fv
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_GUID_DEFINED_SECTION          *Section;
+  UINT32                            OutputBufferSize;
+  UINT32                            ScratchBufferSize;
+  UINT16                            SectionAttribute;
+  UINT32                            AuthenticationStatus;
+  VOID                              *OutputBuffer;
+  VOID                              *ScratchBuffer;
+  EFI_COMMON_SECTION_HEADER         *FvSection;
+  EFI_FIRMWARE_VOLUME_HEADER        *PeiMemFv;
+  EFI_FIRMWARE_VOLUME_HEADER        *DxeMemFv;
+  UINT32                            FvHeaderSize;
+  UINT32                            FvSectionSize;
+
+  FvSection = (EFI_COMMON_SECTION_HEADER*) NULL;
+
+  DEBUG ((EFI_D_INFO, "Find and decompress FV image.\n"));
+  Status = FindFfsFileAndSection (
+             *Fv,
+             EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
+             EFI_SECTION_GUID_DEFINED,
+             (EFI_COMMON_SECTION_HEADER**) &Section
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
+    return Status;
+  }
+
+  Status = ExtractGuidedSectionGetInfo (
+             Section,
+             &OutputBufferSize,
+             &ScratchBufferSize,
+             &SectionAttribute
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
+    return Status;
+  }
+
+  OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase) + SIZE_1MB);
+  ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB);
+  
+  DEBUG ((EFI_D_INFO, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32 (PcdSimicsDxeMemFvBase)));
+  DEBUG ((EFI_D_INFO, "OutputBuffer: 0x%x\n", OutputBuffer));
+  DEBUG ((EFI_D_INFO, "OutputBufferSize: 0x%x\n", OutputBufferSize));
+  DEBUG ((EFI_D_INFO, "ScratchBuffer: 0x%x\n", ScratchBuffer));
+  DEBUG ((EFI_D_INFO, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
+  DEBUG ((EFI_D_INFO, "PcdSimicsDecompressionScratchEnd: 0x%x\n", PcdGet32 (PcdSimicsDecompressionScratchEnd)));
+
+  DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "
+    "PcdSimicsDecompressionScratchEnd=0x%x\n", __FUNCTION__, OutputBuffer,
+    OutputBufferSize, ScratchBuffer, ScratchBufferSize,
+    PcdGet32 (PcdSimicsDecompressionScratchEnd)));
+  ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==
+    PcdGet32 (PcdSimicsDecompressionScratchEnd));
+
+  Status = ExtractGuidedSectionDecode (
+             Section,
+             &OutputBuffer,
+             ScratchBuffer,
+             &AuthenticationStatus
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
+    return Status;
+  }
+
+  Status = FindFfsSectionInstance (
+             OutputBuffer,
+             OutputBufferSize,
+             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
+             0,
+             &FvSection
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));
+    return Status;
+  }
+
+  ASSERT (SECTION_SIZE (FvSection) ==
+          (PcdGet32 (PcdSimicsPeiMemFvSize) + sizeof (*FvSection)));
+  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
+
+  PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsPeiMemFvBase);
+  CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32 (PcdSimicsPeiMemFvSize));
+
+  if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {
+    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", PeiMemFv));
+    CpuDeadLoop ();
+    return EFI_VOLUME_CORRUPTED;
+  }
+
+  Status = FindFfsSectionInstance (
+             OutputBuffer,
+             OutputBufferSize,
+             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
+             1,
+             &FvSection
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));
+    return Status;
+  }
+
+  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
+
+  if (IS_SECTION2 (FvSection)) {
+    FvSectionSize = SECTION2_SIZE (FvSection);
+    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
+  } else {
+    FvSectionSize = SECTION_SIZE (FvSection);
+    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
+  }
+
+  ASSERT (FvSectionSize == (PcdGet32 (PcdSimicsDxeMemFvSize) + FvHeaderSize));
+
+  DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsDxeMemFvBase);
+  CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize), PcdGet32 (PcdSimicsDxeMemFvSize));
+
+  if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
+    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv));
+    CpuDeadLoop ();
+    return EFI_VOLUME_CORRUPTED;
+  }
+
+  *Fv = PeiMemFv;
+  return EFI_SUCCESS;
+}
+
+/**
+  Locates the PEI Core entry point address
+
+  @param[in]  Fv                 The firmware volume to search
+  @param[out] PeiCoreEntryPoint  The entry point of the PEI Core image
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindPeiCoreImageBaseInFv (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
+  OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_COMMON_SECTION_HEADER   *Section;
+
+  DEBUG ((EFI_D_ERROR, "Find PEI Core image.\n"));
+  Status = FindFfsFileAndSection (
+             Fv,
+             EFI_FV_FILETYPE_PEI_CORE,
+             EFI_SECTION_PE32,
+             &Section
+             );
+  if (EFI_ERROR (Status)) {
+    Status = FindFfsFileAndSection (
+               Fv,
+               EFI_FV_FILETYPE_PEI_CORE,
+               EFI_SECTION_TE,
+               &Section
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
+      return Status;
+    }
+  }
+
+  *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
+  DEBUG ((EFI_D_INFO, "PEI core image base 0x%016LX.\n", *PeiCoreImageBase));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Reads 8-bits of CMOS data.
+
+  Reads the 8-bits of CMOS data at the location specified by Index.
+  The 8-bit read value is returned.
+
+  @param  Index  The CMOS location to read.
+
+  @return The value read.
+
+**/
+STATIC
+UINT8
+CmosRead8 (
+  IN UINTN        Index
+  )
+{
+  IoWrite8 (0x70, (UINT8) Index);
+  return IoRead8 (0x71);
+}
+
+
+STATIC
+BOOLEAN
+IsS3Resume (
+  VOID
+  )
+{
+  DEBUG((EFI_D_INFO, "modeValue = %x\n", IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
+  return (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5);
+}
+
+
+STATIC
+EFI_STATUS
+GetS3ResumePeiFv (
+  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **PeiFv
+  )
+{
+  *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdSimicsPeiMemFvBase);
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Locates the PEI Core entry point address
+
+  @param[in,out]  Fv                 The firmware volume to search
+  @param[out]     PeiCoreEntryPoint  The entry point of the PEI Core image
+
+  @retval EFI_SUCCESS           The file and section was found
+  @retval EFI_NOT_FOUND         The file and section was not found
+  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
+
+**/
+VOID
+FindPeiCoreImageBase (
+  IN OUT  EFI_FIRMWARE_VOLUME_HEADER       **BootFv,
+     OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
+  )
+{
+  BOOLEAN S3Resume;
+
+  *PeiCoreImageBase = 0;
+
+  S3Resume = IsS3Resume ();
+  if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
+    //
+    // A malicious runtime OS may have injected something into our previously
+    // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required.
+    //
+    DEBUG ((EFI_D_INFO, "SEC: S3 resume\n"));
+    GetS3ResumePeiFv (BootFv);
+  } else {
+    //
+    // We're either not resuming, or resuming "securely" -- we'll decompress
+    // both PEI FV and DXE FV from pristine flash.
+    //
+    DEBUG ((EFI_D_INFO, "SEC: %a\n",
+      S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"));
+    FindMainFv (BootFv);
+
+    DecompressMemFvs (BootFv);
+  }
+
+  FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
+}
+
+/**
+  Find core image base.
+
+**/
+EFI_STATUS
+FindImageBase (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
+  OUT EFI_PHYSICAL_ADDRESS             *SecCoreImageBase
+  )
+{
+  EFI_PHYSICAL_ADDRESS        CurrentAddress;
+  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
+  EFI_FFS_FILE_HEADER         *File;
+  UINT32                      Size;
+  EFI_PHYSICAL_ADDRESS        EndOfFile;
+  EFI_COMMON_SECTION_HEADER   *Section;
+  EFI_PHYSICAL_ADDRESS        EndOfSection;
+
+  *SecCoreImageBase = 0;
+
+  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
+  EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
+
+  //
+  // Loop through the FFS files in the Boot Firmware Volume
+  //
+  for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
+
+    CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
+    if (CurrentAddress > EndOfFirmwareVolume) {
+      return EFI_NOT_FOUND;
+    }
+
+    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+    Size = *(UINT32*) File->Size & 0xffffff;
+    if (Size < sizeof (*File)) {
+      return EFI_NOT_FOUND;
+    }
+
+    EndOfFile = CurrentAddress + Size;
+    if (EndOfFile > EndOfFirmwareVolume) {
+      return EFI_NOT_FOUND;
+    }
+
+    //
+    // Look for SEC Core
+    //
+    if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {
+      continue;
+    }
+
+    //
+    // Loop through the FFS file sections within the FFS file
+    //
+    EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1);
+    for (;;) {
+      CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
+      Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+
+      Size = *(UINT32*) Section->Size & 0xffffff;
+      if (Size < sizeof (*Section)) {
+        return EFI_NOT_FOUND;
+      }
+
+      EndOfSection = CurrentAddress + Size;
+      if (EndOfSection > EndOfFile) {
+        return EFI_NOT_FOUND;
+      }
+
+      //
+      // Look for executable sections
+      //
+      if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) {
+        if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
+          *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) (Section + 1);
+        }
+        break;
+      }
+    }
+
+    //
+    // SEC Core image found
+    //
+    if (*SecCoreImageBase != 0) {
+      return EFI_SUCCESS;
+    }
+  }
+}
+
+/*
+  Find and return Pei Core entry point.
+
+  It also find SEC and PEI Core file debug information. It will report them if
+  remote debug is enabled.
+
+**/
+VOID
+FindAndReportEntryPoints (
+  IN  EFI_FIRMWARE_VOLUME_HEADER       **BootFirmwareVolumePtr,
+  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_PHYSICAL_ADDRESS             SecCoreImageBase;
+  EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
+  PE_COFF_LOADER_IMAGE_CONTEXT     ImageContext;
+
+  //
+  // Find SEC Core and PEI Core image base
+   //
+  Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);
+  ASSERT_EFI_ERROR (Status);
+
+  FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
+  
+  ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
+  //
+  // Report SEC Core debug information when remote debug is enabled
+  //
+  ImageContext.ImageAddress = SecCoreImageBase;
+  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+  //
+  // Report PEI Core debug information when remote debug is enabled
+  //
+  ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
+  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+  //
+  // Find PEI Core entry point
+  //
+  Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
+  if (EFI_ERROR (Status)) {
+    *PeiCoreEntryPoint = 0;
+  }
+
+  return;
+}
+
+VOID
+EFIAPI
+SecCoreStartupWithStack (
+  IN EFI_FIRMWARE_VOLUME_HEADER       *BootFv,
+  IN VOID                             *TopOfCurrentStack
+  )
+{
+  EFI_SEC_PEI_HAND_OFF        SecCoreData;
+  SEC_IDT_TABLE               IdtTableInStack;
+  IA32_DESCRIPTOR             IdtDescriptor;
+  UINT32                      Index;
+  volatile UINT8              *Table;
+  
+  //
+  // Initialize floating point operating environment
+  // to be compliant with UEFI spec.
+  //
+  InitializeFloatingPointUnits ();
+
+  //
+  // Initialize the PCIe Configuration base register.
+  //
+  PciCf8Write32 (PCI_CF8_LIB_ADDRESS (0xFF, 0, 1, 0x50), 0xE0000001);
+
+  //
+  // To ensure SMM can't be compromised on S3 resume, we must force re-init of
+  // the BaseExtractGuidedSectionLib. Since this is before library contructors
+  // are called, we must use a loop rather than SetMem.
+  //
+  Table = (UINT8*)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);
+  for (Index = 0;
+       Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
+       ++Index) {
+    Table[Index] = 0;
+  }
+
+  ProcessLibraryConstructorList (NULL, NULL);
+
+  DEBUG ((EFI_D_INFO,
+    "SecCoreStartupWithStack(0x%x, 0x%x)\n",
+    (UINT32)(UINTN)BootFv,
+    (UINT32)(UINTN)TopOfCurrentStack
+    ));
+  
+  //
+  // Initialize IDT
+  //
+  IdtTableInStack.PeiService = NULL;
+  for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
+    CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof (mIdtEntryTemplate));
+  }
+
+  IdtDescriptor.Base  = (UINTN)&IdtTableInStack.IdtTable;
+  IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
+
+  AsmWriteIdtr (&IdtDescriptor);
+
+#if defined (MDE_CPU_X64)
+  //
+  // ASSERT that the Page Tables were set by the reset vector code to
+  // the address we expect.
+  //
+  ASSERT (AsmReadCr3 () == (UINTN) PcdGet32 (PcdSimicsSecPageTablesBase));
+#endif
+
+  //
+  // |-------------|       <-- TopOfCurrentStack
+  // |   Stack     | 32k
+  // |-------------|
+  // |    Heap     | 32k
+  // |-------------|       <-- SecCoreData.TemporaryRamBase
+  //
+
+  ASSERT ((UINTN) (PcdGet32 (PcdSimicsSecPeiTempRamBase) +
+                   PcdGet32 (PcdSimicsSecPeiTempRamSize)) ==
+          (UINTN) TopOfCurrentStack);
+
+  //
+  // Initialize SEC hand-off state
+  //
+  SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
+
+  SecCoreData.TemporaryRamSize       = (UINTN) PcdGet32 (PcdSimicsSecPeiTempRamSize);
+  SecCoreData.TemporaryRamBase       = (VOID*)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);
+
+  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
+  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize >> 1;
+
+  SecCoreData.StackBase              = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;
+  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize >> 1;
+
+  SecCoreData.BootFirmwareVolumeBase = BootFv;
+  SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+
+  //
+  // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
+  //
+  IoWrite8 (0x21, 0xff);
+  IoWrite8 (0xA1, 0xff);
+
+  //
+  // Initialize Local APIC Timer hardware and disable Local APIC Timer
+  // interrupts before initializing the Debug Agent and the debug timer is
+  // enabled.
+  //
+  InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
+  DisableApicTimerInterrupt ();
+
+  //
+  // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
+  //
+  InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);
+}
+
+/**
+  Caller provided function to be invoked at the end of InitializeDebugAgent().
+
+  Entry point to the C language phase of SEC. After the SEC assembly
+  code has initialized some temporary memory and set up the stack,
+  the control is transferred to this function.
+
+  @param[in] Context    The first input parameter of InitializeDebugAgent().
+
+**/
+VOID
+EFIAPI
+SecStartupPhase2(
+  IN VOID                     *Context
+  )
+{
+  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
+  EFI_FIRMWARE_VOLUME_HEADER  *BootFv;
+  EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
+  
+  SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
+
+  //
+  // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
+  // is enabled.
+  //
+  BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
+  FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
+  SecCoreData->BootFirmwareVolumeBase = BootFv;
+  SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+
+  //
+  // Transfer the control to the PEI core
+  //
+  (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
+  
+  //
+  // If we get here then the PEI Core returned, which is not recoverable.
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+}
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
+  IN UINTN                    CopySize
+  )
+{
+  IA32_DESCRIPTOR                  IdtDescriptor;
+  VOID                             *OldHeap;
+  VOID                             *NewHeap;
+  VOID                             *OldStack;
+  VOID                             *NewStack;
+  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  DebugAgentContext;
+  BOOLEAN                          OldStatus;
+  BASE_LIBRARY_JUMP_BUFFER         JumpBuffer;
+
+  DEBUG ((EFI_D_INFO,
+    "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
+    TemporaryMemoryBase,
+    PermanentMemoryBase,
+    (UINT64)CopySize
+    ));
+
+  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
+
+  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
+  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
+
+  DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
+  DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
+
+  OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
+  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
+
+  //
+  // Migrate Heap
+  //
+  CopyMem (NewHeap, OldHeap, CopySize >> 1);
+
+  //
+  // Migrate Stack
+  //
+  CopyMem (NewStack, OldStack, CopySize >> 1);
+  
+  //
+  // Rebase IDT table in permanent memory
+  //
+  AsmReadIdtr (&IdtDescriptor);
+  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
+
+  AsmWriteIdtr (&IdtDescriptor);
+
+  //
+  // Use SetJump()/LongJump() to switch to a new stack.
+  // 
+  if (SetJump (&JumpBuffer) == 0) {
+#if defined (MDE_CPU_IA32)
+    JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;
+#endif
+#if defined (MDE_CPU_X64)
+    JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;
+#endif
+    LongJump (&JumpBuffer, (UINTN)-1);
+  }
+
+  SaveAndSetDebugTimerInterrupt (OldStatus);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
new file mode 100644
index 0000000000..771fddb487
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
@@ -0,0 +1,148 @@
+/** @file
+  A DXE_DRIVER providing SMRAM access by producing EFI_SMM_ACCESS2_PROTOCOL.
+
+  X58 TSEG is expected to have been verified and set up by the SmmAccessPei
+  driver.
+
+  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
+  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/SmmAccess2.h>
+
+#include "SmramInternal.h"
+
+/**
+  Opens the SMRAM area to be accessible by a boot-service driver.
+
+  This function "opens" SMRAM so that it is visible while not inside of SMM.
+  The function should return EFI_UNSUPPORTED if the hardware does not support
+  hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the SMRAM
+  configuration is locked.
+
+  @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The operation was successful.
+  @retval EFI_UNSUPPORTED   The system does not support opening and closing of
+                            SMRAM.
+  @retval EFI_DEVICE_ERROR  SMRAM cannot be opened, perhaps because it is
+                            locked.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeOpen (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  return SmramAccessOpen (&This->LockState, &This->OpenState);
+}
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function "closes" SMRAM so that it is not visible while outside of SMM.
+  The function should return EFI_UNSUPPORTED if the hardware does not support
+  hiding of SMRAM.
+
+  @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The operation was successful.
+  @retval EFI_UNSUPPORTED   The system does not support opening and closing of
+                            SMRAM.
+  @retval EFI_DEVICE_ERROR  SMRAM cannot be closed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeClose (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  return SmramAccessClose (&This->LockState, &This->OpenState);
+}
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function prohibits access to the SMRAM region.  This function is usually
+  implemented such that it is a write-once operation.
+
+  @param[in] This          The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+  @retval EFI_SUCCESS      The device was successfully locked.
+  @retval EFI_UNSUPPORTED  The system does not support locking of SMRAM.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeLock (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  return SmramAccessLock (&This->LockState, &This->OpenState);
+}
+
+/**
+  Queries the memory controller for the possible regions that will support
+  SMRAM.
+
+  @param[in]     This           The EFI_SMM_ACCESS2_PROTOCOL instance.
+  @param[in,out] SmramMapSize   A pointer to the size, in bytes, of the
+                                SmramMemoryMap buffer.
+  @param[in,out] SmramMap       A pointer to the buffer in which firmware
+                                places the current memory map.
+
+  @retval EFI_SUCCESS           The chipset supported the given resource.
+  @retval EFI_BUFFER_TOO_SMALL  The SmramMap parameter was too small.  The
+                                current buffer size needed to hold the memory
+                                map is returned in SmramMapSize.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeGetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+{
+  return SmramAccessGetCapabilities (This->LockState, This->OpenState,
+           SmramMapSize, SmramMap);
+}
+
+//
+// LockState and OpenState will be filled in by the entry point.
+//
+STATIC EFI_SMM_ACCESS2_PROTOCOL mAccess2 = {
+  &SmmAccess2DxeOpen,
+  &SmmAccess2DxeClose,
+  &SmmAccess2DxeLock,
+  &SmmAccess2DxeGetCapabilities
+};
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+SmmAccess2DxeEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  //
+  // This module should only be included if SMRAM support is required.
+  //
+  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+  GetStates (&mAccess2.LockState, &mAccess2.OpenState);
+  return gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+                &gEfiSmmAccess2ProtocolGuid, &mAccess2,
+                NULL);
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
new file mode 100644
index 0000000000..d07d88142a
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
@@ -0,0 +1,353 @@
+/** @file
+  A PEIM with the following responsibilities:
+
+  - verify & configure the X58 TSEG in the entry point,
+  - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
+  - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and expose
+    it via the gEfiAcpiVariableGuid GUID HOB.
+
+  This PEIM runs from RAM, so we can write to variables with static storage
+  duration.
+
+  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Guid/AcpiS3Context.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Ppi/SmmAccess.h>
+
+#include <SimicsPlatforms.h>
+
+#include "SmramInternal.h"
+
+//
+// PEI_SMM_ACCESS_PPI implementation.
+//
+
+/**
+  Opens the SMRAM area to be accessible by a PEIM driver.
+
+  This function "opens" SMRAM so that it is visible while not inside of SMM.
+  The function should return EFI_UNSUPPORTED if the hardware does not support
+  hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the SMRAM
+  configuration is locked.
+
+  @param  PeiServices            General purpose services available to every
+                                 PEIM.
+  @param  This                   The pointer to the SMM Access Interface.
+  @param  DescriptorIndex        The region of SMRAM to Open.
+
+  @retval EFI_SUCCESS            The region was successfully opened.
+  @retval EFI_DEVICE_ERROR       The region could not be opened because locked
+                                 by chipset.
+  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiOpen (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  )
+{
+  if (DescriptorIndex >= DescIdxCount) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // According to current practice, DescriptorIndex is not considered at all,
+  // beyond validating it.
+  //
+  return SmramAccessOpen (&This->LockState, &This->OpenState);
+}
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function "closes" SMRAM so that it is not visible while outside of SMM.
+  The function should return EFI_UNSUPPORTED if the hardware does not support
+  hiding of SMRAM.
+
+  @param  PeiServices              General purpose services available to every
+                                   PEIM.
+  @param  This                     The pointer to the SMM Access Interface.
+  @param  DescriptorIndex          The region of SMRAM to Close.
+
+  @retval EFI_SUCCESS              The region was successfully closed.
+  @retval EFI_DEVICE_ERROR         The region could not be closed because
+                                   locked by chipset.
+  @retval EFI_INVALID_PARAMETER    The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiClose (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  )
+{
+  if (DescriptorIndex >= DescIdxCount) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // According to current practice, DescriptorIndex is not considered at all,
+  // beyond validating it.
+  //
+  return SmramAccessClose (&This->LockState, &This->OpenState);
+}
+
+/**
+  Inhibits access to the SMRAM.
+
+  This function prohibits access to the SMRAM region.  This function is usually
+  implemented such that it is a write-once operation.
+
+  @param  PeiServices              General purpose services available to every
+                                   PEIM.
+  @param  This                     The pointer to the SMM Access Interface.
+  @param  DescriptorIndex          The region of SMRAM to Close.
+
+  @retval EFI_SUCCESS            The region was successfully locked.
+  @retval EFI_DEVICE_ERROR       The region could not be locked because at
+                                 least one range is still open.
+  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiLock (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN UINTN                           DescriptorIndex
+  )
+{
+  if (DescriptorIndex >= DescIdxCount) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // According to current practice, DescriptorIndex is not considered at all,
+  // beyond validating it.
+  //
+  return SmramAccessLock (&This->LockState, &This->OpenState);
+}
+
+/**
+  Queries the memory controller for the possible regions that will support
+  SMRAM.
+
+  @param  PeiServices           General purpose services available to every
+                                PEIM.
+  @param This                   The pointer to the SmmAccessPpi Interface.
+  @param SmramMapSize           The pointer to the variable containing size of
+                                the buffer to contain the description
+                                information.
+  @param SmramMap               The buffer containing the data describing the
+                                Smram region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           The user provided a sufficiently-sized buffer.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+SmmAccessPeiGetCapabilities (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN PEI_SMM_ACCESS_PPI              *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+{
+  return SmramAccessGetCapabilities (This->LockState, This->OpenState,
+           SmramMapSize, SmramMap);
+}
+
+//
+// LockState and OpenState will be filled in by the entry point.
+//
+STATIC PEI_SMM_ACCESS_PPI mAccess = {
+  &SmmAccessPeiOpen,
+  &SmmAccessPeiClose,
+  &SmmAccessPeiLock,
+  &SmmAccessPeiGetCapabilities
+};
+
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gPeiSmmAccessPpiGuid, &mAccess
+  }
+};
+
+
+//
+// Utility functions.
+//
+STATIC
+UINT8
+CmosRead8 (
+  IN UINT8  Index
+  )
+{
+  IoWrite8 (0x70, Index);
+  return IoRead8 (0x71);
+}
+
+STATIC
+UINT32
+GetSystemMemorySizeBelow4gb (
+  VOID
+  )
+{
+  UINT32 Cmos0x34;
+  UINT32 Cmos0x35;
+
+  Cmos0x34 = CmosRead8 (0x34);
+  Cmos0x35 = CmosRead8 (0x35);
+
+  return ((Cmos0x35 << 8 | Cmos0x34) << 16) + SIZE_16MB;
+}
+
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+SmmAccessPeiEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  UINT16               HostBridgeDevId;
+  UINT32                EsmramcVal;
+  UINT32               TopOfLowRam, TopOfLowRamMb;
+  EFI_STATUS           Status;
+  UINTN                SmramMapSize;
+  EFI_SMRAM_DESCRIPTOR SmramMap[DescIdxCount];
+  VOID                 *GuidHob;
+
+  //
+  // This module should only be included if SMRAM support is required.
+  //
+  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
+
+  //
+  // Verify if we're running on a X58 machine type.
+  //
+  HostBridgeDevId = PciRead16 (SIMICS_HOSTBRIDGE_DID);
+  if (HostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
+    DEBUG ((EFI_D_ERROR, "%a: no SMRAM with host bridge DID=0x%04x; only "
+      "DID=0x%04x (X58) is supported\n", __FUNCTION__, HostBridgeDevId,
+      INTEL_ICH10_DEVICE_ID));
+    goto WrongConfig;
+  }
+
+  //
+  // Confirm if QEMU supports SMRAM.
+  //
+  // With no support for it, the ESMRAMC (Extended System Management RAM
+  // Control) register reads as zero. If there is support, the cache-enable
+  // bits are hard-coded as 1 by QEMU.
+  //
+
+  TopOfLowRam = GetSystemMemorySizeBelow4gb ();
+  ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
+  TopOfLowRamMb = TopOfLowRam >> 20;
+  DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x \n", TopOfLowRam, TopOfLowRamMb));
+
+
+  //
+  // Set Top of Low Usable DRAM.
+  //
+  PciWrite32 (DRAMC_REGISTER_X58(MCH_TOLUD),
+               TopOfLowRam);
+  DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));
+
+  //
+  // Set TSEG Memory Base.
+  //
+  EsmramcVal = (TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) << MCH_TSEGMB_MB_SHIFT;
+  //
+  // Set TSEG size, and disable TSEG visibility outside of SMM. Note that the
+  // T_EN bit has inverse meaning; when T_EN is set, then TSEG visibility is
+  // *restricted* to SMM.
+  //
+  EsmramcVal &= ~(UINT32)MCH_ESMRAMC_TSEG_MASK;
+  EsmramcVal |= FixedPcdGet8 (PcdX58TsegMbytes) == 8 ? MCH_ESMRAMC_TSEG_8MB :
+                FixedPcdGet8 (PcdX58TsegMbytes) == 2 ? MCH_ESMRAMC_TSEG_2MB :
+                MCH_ESMRAMC_TSEG_1MB;
+  EsmramcVal |= MCH_ESMRAMC_T_EN;
+  PciWrite32(DRAMC_REGISTER_X58(MCH_TSEGMB), EsmramcVal);
+  DEBUG((EFI_D_ERROR, "MCH_TSEGMB =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
+  DEBUG((EFI_D_ERROR, "MCH_TSEGMB_1 =0x%x; MCH_TSEGMB_2 =0x%x;\n", ((TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) << MCH_TSEGMB_MB_SHIFT), EsmramcVal));
+
+  //
+  // Create the GUID HOB and point it to the first SMRAM range.
+  //
+  GetStates (&mAccess.LockState, &mAccess.OpenState);
+  SmramMapSize = sizeof SmramMap;
+  Status = SmramAccessGetCapabilities (mAccess.LockState, mAccess.OpenState,
+             &SmramMapSize, SmramMap);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG_CODE_BEGIN ();
+  {
+    UINTN Count;
+    UINTN Idx;
+
+    Count = SmramMapSize / sizeof SmramMap[0];
+    DEBUG ((EFI_D_VERBOSE, "%a: SMRAM map follows, %d entries\n", __FUNCTION__,
+      (INT32)Count));
+    DEBUG ((EFI_D_VERBOSE, "% 20a % 20a % 20a % 20a\n", "PhysicalStart(0x)",
+      "PhysicalSize(0x)", "CpuStart(0x)", "RegionState(0x)"));
+    for (Idx = 0; Idx < Count; ++Idx) {
+      DEBUG ((EFI_D_VERBOSE, "% 20Lx % 20Lx % 20Lx % 20Lx\n",
+        SmramMap[Idx].PhysicalStart, SmramMap[Idx].PhysicalSize,
+        SmramMap[Idx].CpuStart, SmramMap[Idx].RegionState));
+    }
+  }
+  DEBUG_CODE_END ();
+
+  GuidHob = BuildGuidHob (&gEfiAcpiVariableGuid,
+    sizeof SmramMap[DescIdxSmmS3ResumeState]);
+  if (GuidHob == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  CopyMem (GuidHob, &SmramMap[DescIdxSmmS3ResumeState],
+    sizeof SmramMap[DescIdxSmmS3ResumeState]);
+
+  //
+  // We're done. The next step should succeed, but even if it fails, we can't
+  // roll back the above BuildGuidHob() allocation, because PEI doesn't support
+  // releasing memory.
+  //
+  return PeiServicesInstallPpi (mPpiList);
+
+WrongConfig:
+  //
+  // We really don't want to continue in this case.
+  //
+  ASSERT (FALSE);
+  CpuDeadLoop ();
+  return EFI_UNSUPPORTED;
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
new file mode 100644
index 0000000000..898fc25084
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
@@ -0,0 +1,199 @@
+/** @file
+  Functions and types shared by the SMM accessor PEI and DXE modules.
+
+  Copyright (C) 2015, Red Hat, Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Guid/AcpiS3Context.h>
+#include <IndustryStandard/X58Ich10.h>
+#include <Library/DebugLib.h>
+#include <Library/PciLib.h>
+
+#include "SmramInternal.h"
+
+BOOLEAN gLockState;
+BOOLEAN gOpenState;
+
+/**
+  Read the MCH_SMRAM and ESMRAMC registers, and update the LockState and
+  OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL object,
+  from the D_LCK and T_EN bits.
+
+  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can rely on
+  the LockState and OpenState fields being up-to-date on entry, and they need
+  to restore the same invariant on exit, if they touch the bits in question.
+
+  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff SMRAM is
+                         locked.
+  @param[out] OpenState  Reflects the inverse of the T_EN bit on output; TRUE
+                         iff SMRAM is open.
+**/
+VOID
+GetStates (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+)
+{
+  UINT8 EsmramcVal;
+
+  EsmramcVal = PciRead8(DRAMC_REGISTER_X58(MCH_TSEGMB));
+
+  *OpenState = !(EsmramcVal & MCH_ESMRAMC_T_EN);
+  *LockState = !*OpenState;
+
+  *OpenState = gOpenState;
+  *LockState = gLockState;
+}
+
+//
+// The functions below follow the PEI_SMM_ACCESS_PPI and
+// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This
+// pointers are removed (TSEG doesn't depend on them), and so is the
+// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
+//
+// The LockState and OpenState members that are common to both
+// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated in
+// isolation from the rest of the (non-shared) members.
+//
+
+EFI_STATUS
+SmramAccessOpen (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+  )
+{
+
+  //
+  // Open TSEG by clearing T_EN.
+  //
+  PciAnd8(DRAMC_REGISTER_X58(MCH_TSEGMB),
+    (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff));
+
+  gOpenState = TRUE;
+  gLockState = !gOpenState;
+
+  GetStates (LockState, OpenState);
+  if (!*OpenState) {
+    return EFI_DEVICE_ERROR;
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessClose (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+  )
+{
+  //
+  // Close TSEG by setting T_EN.
+  //
+  PciOr8(DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
+
+  gOpenState = FALSE;
+  gLockState = !gOpenState;
+
+  GetStates (LockState, OpenState);
+  if (*OpenState) {
+    return EFI_DEVICE_ERROR;
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessLock (
+  OUT    BOOLEAN *LockState,
+  IN OUT BOOLEAN *OpenState
+  )
+{
+  if (*OpenState) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Close & lock TSEG by setting T_EN and D_LCK.
+  //
+  PciOr8 (DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
+
+  gOpenState = FALSE;
+  gLockState = !gOpenState;
+
+  GetStates (LockState, OpenState);
+  if (*OpenState || !*LockState) {
+    return EFI_DEVICE_ERROR;
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmramAccessGetCapabilities (
+  IN BOOLEAN                  LockState,
+  IN BOOLEAN                  OpenState,
+  IN OUT UINTN                *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+  )
+{
+  UINTN  OriginalSize;
+  UINT32 TsegMemoryBaseMb, TsegMemoryBase;
+  UINT64 CommonRegionState;
+  UINT8  TsegSizeBits;
+
+  OriginalSize  = *SmramMapSize;
+  *SmramMapSize = DescIdxCount * sizeof *SmramMap;
+  if (OriginalSize < *SmramMapSize) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  //
+  // Read the TSEG Memory Base register.
+  //
+  TsegMemoryBaseMb = PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB));
+
+  TsegMemoryBaseMb = 0xDF800000;
+
+  TsegMemoryBase = (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) << 20;
+
+  //
+  // Precompute the region state bits that will be set for all regions.
+  //
+  CommonRegionState = (OpenState ? EFI_SMRAM_OPEN : EFI_SMRAM_CLOSED) |
+                      (LockState ? EFI_SMRAM_LOCKED : 0) |
+                      EFI_CACHEABLE;
+
+  //
+  // The first region hosts an SMM_S3_RESUME_STATE object. It is located at the
+  // start of TSEG. We round up the size to whole pages, and we report it as
+  // EFI_ALLOCATED, so that the SMM_CORE stays away from it.
+  //
+  SmramMap[DescIdxSmmS3ResumeState].PhysicalStart = TsegMemoryBase;
+  SmramMap[DescIdxSmmS3ResumeState].CpuStart      = TsegMemoryBase;
+  SmramMap[DescIdxSmmS3ResumeState].PhysicalSize  =
+    EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof (SMM_S3_RESUME_STATE)));
+  SmramMap[DescIdxSmmS3ResumeState].RegionState   =
+    CommonRegionState | EFI_ALLOCATED;
+
+  //
+  // Get the TSEG size bits from the ESMRAMC register.
+  //
+  TsegSizeBits = PciRead8 (DRAMC_REGISTER_X58(MCH_TSEGMB)) &
+                            MCH_ESMRAMC_TSEG_MASK;
+
+  TsegSizeBits = MCH_ESMRAMC_TSEG_8MB;
+
+  //
+  // The second region is the main one, following the first.
+  //
+  SmramMap[DescIdxMain].PhysicalStart =
+    SmramMap[DescIdxSmmS3ResumeState].PhysicalStart +
+    SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
+  SmramMap[DescIdxMain].CpuStart = SmramMap[DescIdxMain].PhysicalStart;
+  SmramMap[DescIdxMain].PhysicalSize =
+    (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB :
+     TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB :
+     SIZE_1MB) - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
+  SmramMap[DescIdxMain].RegionState = CommonRegionState;
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
new file mode 100644
index 0000000000..19ffb6f86d
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+#include <Base.h>
+
+    SECTION .text
+
+extern ASM_PFX(SecCoreStartupWithStack)
+
+;
+; SecCore Entry Point
+;
+; Processor is in flat protected mode
+;
+; @param[in]  EAX   Initial value of the EAX register (BIST: Built-in Self Test)
+; @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
+; @param[in]  EBP   Pointer to the start of the Boot Firmware Volume
+;
+; @return     None  This routine does not return
+;
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+    ;
+    ; Load temporary RAM stack based on PCDs
+    ;
+    %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdSimicsSecPeiTempRamBase) + \
+                          FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
+    mov     eax, SEC_TOP_OF_STACK
+    mov     esp, eax
+    nop
+
+    ;
+    ; Setup parameters and call SecCoreStartupWithStack
+    ;   [esp]   return address for call
+    ;   [esp+4] BootFirmwareVolumePtr
+    ;   [esp+8] TopOfCurrentStack
+    ;
+    push    eax
+    push    ebp
+    call    ASM_PFX(SecCoreStartupWithStack)
+
diff --git a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
new file mode 100644
index 0000000000..ac993ac1ce
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
@@ -0,0 +1,71 @@
+## @file
+#  SEC Driver
+#
+# Copyright (c) 2008 - 2018 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecMain
+  FILE_GUID                      = e67f156f-54c5-47f3-a35d-07c045881e14
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SecMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  SecMain.c
+
+[Sources.IA32]
+  Ia32/SecEntry.nasm
+
+[Sources.X64]
+  X64/SecEntry.nasm
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  BaseMemoryLib
+  PeiServicesLib
+  PcdLib
+  UefiCpuLib
+  DebugAgentLib
+  IoLib
+  PeCoffLib
+  PeCoffGetEntryPointLib
+  PeCoffExtraActionLib
+  ExtractGuidedSectionLib
+  LocalApicLib
+  PciCf8Lib
+
+[Ppis]
+  gEfiTemporaryRamSupportPpiGuid                # PPI ALWAYS_PRODUCED
+
+[Pcd]
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+  gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+
+[FeaturePcd]
+  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
new file mode 100644
index 0000000000..0eb86ec2ca
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+
+#include <Base.h>
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(SecCoreStartupWithStack)
+
+;
+; SecCore Entry Point
+;
+; Processor is in flat protected mode
+;
+; @param[in]  RAX   Initial value of the EAX register (BIST: Built-in Self Test)
+; @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
+; @param[in]  RBP   Pointer to the start of the Boot Firmware Volume
+;
+; @return     None  This routine does not return
+;
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+
+    ;
+    ; Load temporary RAM stack based on PCDs
+    ;
+    %define SEC_TOP_OF_STACK (FixedPcdGet32 (PcdSimicsSecPeiTempRamBase) + \
+                          FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
+    mov     rsp, SEC_TOP_OF_STACK
+    nop
+
+    ;
+    ; Setup parameters and call SecCoreStartupWithStack
+    ;   rcx: BootFirmwareVolumePtr
+    ;   rdx: TopOfCurrentStack
+    ;
+    mov     rcx, rbp
+    mov     rdx, rsp
+    sub     rsp, 0x20
+    call    ASM_PFX(SecCoreStartupWithStack)
+
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
new file mode 100644
index 0000000000..0be8be4966
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
@@ -0,0 +1,18 @@
+## @file
+#  Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+  #
+  # SEC Phase modules
+  #
+  $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+  UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
+  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
new file mode 100644
index 0000000000..78eca21a43
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+#  Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
new file mode 100644
index 0000000000..9f037e99d4
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
@@ -0,0 +1,10 @@
+## @file
+#  Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
new file mode 100644
index 0000000000..596d633cd3
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
@@ -0,0 +1,17 @@
+## @file
+#  Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#
+# SEC Phase modules
+#
+# The code in this FV handles the initial firmware startup, and
+# decompresses the PEI and DXE FVs which handles the rest of the boot sequence.
+#
+INF  RuleOverride=RESET_SECMAIN USE = IA32 $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf
+INF  RuleOverride=RESET_VECTOR USE = IA32 UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
new file mode 100644
index 0000000000..9004b9cb83
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
@@ -0,0 +1,16 @@
+## @file
+#  Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#INF  $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuArchDxe/CpuArchDxe.inf
+#INF  $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuMpDxe/CpuMpDxe.inf
+!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
+  INF  $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf
+  INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+!endif
+INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
new file mode 100644
index 0000000000..2f630b4b95
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
@@ -0,0 +1,52 @@
+## @file
+# A DXE_DRIVER providing SMRAM access by producing EFI_SMM_ACCESS2_PROTOCOL.
+#
+# X58 TSEG is expected to have been verified and set up by the SmmAccessPei
+# driver.
+#
+# Copyright (C) 2013, 2015, Red Hat, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmAccess2Dxe
+  FILE_GUID                      = AC95AD3D-4366-44BF-9A62-E4B29D7A2206
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x00010400
+  ENTRY_POINT                    = SmmAccess2DxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  SmmAccess2Dxe.c
+  SmramInternal.c
+  SmramInternal.h
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  PcdLib
+  PciLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiSmmAccess2ProtocolGuid   ## PRODUCES
+
+[FeaturePcd]
+  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[Depex]
+  TRUE
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
new file mode 100644
index 0000000000..1d3b028c85
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
@@ -0,0 +1,64 @@
+## @file
+# A PEIM with the following responsibilities:
+#
+# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
+# - verify & configure the X58 TSEG in the entry point,
+# - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and expose
+#   it via the gEfiAcpiVariableGuid GUIDed HOB.
+#
+# Copyright (C) 2013, 2015, Red Hat, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmAccessPei
+  FILE_GUID                      = 6C0E75B4-B0B9-44D1-8210-3377D7B4E066
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmmAccessPeiEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  SmmAccessPei.c
+  SmramInternal.c
+  SmramInternal.h
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[Guids]
+  gEfiAcpiVariableGuid
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  IoLib
+  PcdLib
+  PciLib
+  PeiServicesLib
+  PeimEntryPoint
+
+[FeaturePcd]
+  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[FixedPcd]
+  gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
+
+[Ppis]
+  gPeiSmmAccessPpiGuid           ## PRODUCES
+
+[Depex]
+  gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
new file mode 100644
index 0000000000..43a79b295f
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
@@ -0,0 +1,81 @@
+/** @file
+  Functions and types shared by the SMM accessor PEI and DXE modules.
+
+  Copyright (C) 2015, Red Hat, Inc.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Pi/PiMultiPhase.h>
+
+//
+// We'll have two SMRAM ranges.
+//
+// The first is a tiny one that hosts an SMM_S3_RESUME_STATE object, to be
+// filled in by the CPU SMM driver during normal boot, for the PEI instance of
+// the LockBox library (which will rely on the object during S3 resume).
+//
+// The other SMRAM range is the main one, for the SMM core and the SMM drivers.
+//
+typedef enum {
+  DescIdxSmmS3ResumeState = 0,
+  DescIdxMain             = 1,
+  DescIdxCount            = 2
+} DESCRIPTOR_INDEX;
+
+/**
+  Read the MCH_SMRAM and ESMRAMC registers, and update the LockState and
+  OpenState fields in the PEI_SMM_ACCESS_PPI / EFI_SMM_ACCESS2_PROTOCOL object,
+  from the D_LCK and T_EN bits.
+
+  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member functions can rely on
+  the LockState and OpenState fields being up-to-date on entry, and they need
+  to restore the same invariant on exit, if they touch the bits in question.
+
+  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff SMRAM is
+                         locked.
+  @param[out] OpenState  Reflects the inverse of the T_EN bit on output; TRUE
+                         iff SMRAM is open.
+**/
+VOID
+GetStates (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+  );
+
+//
+// The functions below follow the PEI_SMM_ACCESS_PPI and
+// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and This
+// pointers are removed (TSEG doesn't depend on them), and so is the
+// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
+//
+// The LockState and OpenState members that are common to both
+// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and updated in
+// isolation from the rest of the (non-shared) members.
+//
+
+EFI_STATUS
+SmramAccessOpen (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+  );
+
+EFI_STATUS
+SmramAccessClose (
+  OUT BOOLEAN *LockState,
+  OUT BOOLEAN *OpenState
+  );
+
+EFI_STATUS
+SmramAccessLock (
+  OUT    BOOLEAN *LockState,
+  IN OUT BOOLEAN *OpenState
+  );
+
+EFI_STATUS
+SmramAccessGetCapabilities (
+  IN BOOLEAN                  LockState,
+  IN BOOLEAN                  OpenState,
+  IN OUT UINTN                *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+  );
-- 
2.16.2.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#45697): https://edk2.groups.io/g/devel/message/45697
Mute This Topic: https://groups.io/mt/32816095/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
Posted by Kubacki, Michael A 6 years, 3 months ago
Feedback I could not find already noted elsewhere:

1. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c:
     There's some style issues throughout the file related to a missing space before opening parenthesis and parameters than span multiple lines.
     Some of these are pre-existing in OvmfPkg source. I don't think this is a must have.
2. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 265:
     "Confirm if QEMU supports SMRAM." to "Confirm if Simics supports SMRAM."
3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 275:
     "DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x \n", TopOfLowRam, TopOfLowRamMb));"
     Should be an informational message.
3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 283:
     "DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));"
     Should be an informational message.
4. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 300 & Line 301 - Should be informational messages as well.
5. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf: Is a dependency on OvmfPkg/OvmfPkg.dec required? This dependency should be avoided.
6. Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore: I don't think this should be an override but should exist in a similar manner
     as edk2/OvmfPkg/Sec. The code cannot be upstreamed as-is.
7. /Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c: Some of this messages should probably be verbose not informational.
8. /Silicon/Intel/SimicsX58SktPkg/SktPei.dsc: This file naming convention is unusual. SktPkgPei.dsc is more consistent. 

> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 PM
> To: devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Kubacki, Michael A
> <michael.a.kubacki@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for
> SimicsX58
> 
> Add CPU Pkg for SimicsX58. It is added for simics QSP project support
> 
> Cc: Hao Wu <hao.a.wu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Cc: Agyeman Prince <prince.agyeman@intel.com>
> Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> 
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
>  .../Override/UefiCpuPkg/SecCore/SecMain.c          | 956
> +++++++++++++++++++++
>  .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c     | 148 ++++
>  .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c      | 353 ++++++++
>  .../SimicsX58SktPkg/Smm/Access/SmramInternal.c     | 199 +++++
>  .../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm |  45 +
>  .../Override/UefiCpuPkg/SecCore/SecMain.inf        |  71 ++
>  .../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm  |  45 +
>  Silicon/Intel/SimicsX58SktPkg/SktPei.dsc           |  18 +
>  .../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf |   9 +
>  .../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf  |  10 +
>  Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf    |  17 +
>  .../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf   |  16 +
>  .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf   |  52 ++
>  .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf    |  64 ++
>  .../SimicsX58SktPkg/Smm/Access/SmramInternal.h     |  81 ++
>  15 files changed, 2084 insertions(+)
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nas
> m
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nas
> m
>  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
>  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
>  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
>  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
>  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> 
> diff --git
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> new file mode 100644
> index 0000000000..c52d459ef2
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> @@ -0,0 +1,956 @@
> +/** @file
> +  Main SEC phase code.  Transitions to PEI.
> +
> +  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiCpuLib.h>
> +#include <Library/DebugAgentLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeCoffLib.h>
> +#include <Library/PeCoffGetEntryPointLib.h>
> +#include <Library/PeCoffExtraActionLib.h>
> +#include <Library/ExtractGuidedSectionLib.h>
> +#include <Library/LocalApicLib.h>
> +#include <Library/PciCf8Lib.h>
> +
> +#include <Ppi/TemporaryRamSupport.h>
> +#include <IndustryStandard/X58Ich10.h>
> +
> +#define SEC_IDT_ENTRY_COUNT  34
> +
> +typedef struct _SEC_IDT_TABLE {
> +  EFI_PEI_SERVICES          *PeiService;
> +  IA32_IDT_GATE_DESCRIPTOR  IdtTable[SEC_IDT_ENTRY_COUNT];
> +} SEC_IDT_TABLE;
> +
> +VOID
> +EFIAPI
> +SecStartupPhase2 (
> +  IN VOID                     *Context
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamMigration (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> +  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> +  IN UINTN                    CopySize
> +  );
> +
> +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
> +  TemporaryRamMigration
> +};
> +
> +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
> +  {
> +    (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +    &gEfiTemporaryRamSupportPpiGuid,
> +    &mTemporaryRamSupportPpi
> +  },
> +};
> +
> +//
> +// Template of an IDT entry pointing to 10:FFFFFFE4h.
> +//
> +IA32_IDT_GATE_DESCRIPTOR  mIdtEntryTemplate = {
> +  {                                      // Bits
> +    0xffe4,                              // OffsetLow
> +    0x10,                                // Selector
> +    0x0,                                 // Reserved_0
> +    IA32_IDT_GATE_TYPE_INTERRUPT_32,     // GateType
> +    0xffff                               // OffsetHigh
> +  }
> +};
> +
> +/**
> +  Locates the main boot firmware volume.
> +
> +  @param[in,out]  BootFv  On input, the base of the BootFv
> +                          On output, the decompressed main firmware volume
> +
> +  @retval EFI_SUCCESS    The main firmware volume was located and
> decompressed
> +  @retval EFI_NOT_FOUND  The main firmware volume was not found
> +
> +**/
> +EFI_STATUS
> +FindMainFv (
> +  IN OUT  EFI_FIRMWARE_VOLUME_HEADER   **BootFv
> +  )
> +{
> +  EFI_FIRMWARE_VOLUME_HEADER  *Fv;
> +  UINTN                       Distance;
> +
> +  ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
> +
> +  Fv = *BootFv;
> +  Distance = (UINTN) (*BootFv)->FvLength;
> +  do {
> +    Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE);
> +    Distance += EFI_PAGE_SIZE;
> +    if (Distance > SIZE_32MB) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    if (Fv->Signature != EFI_FVH_SIGNATURE) {
> +      continue;
> +    }
> +
> +    if ((UINTN) Fv->FvLength > Distance) {
> +      continue;
> +    }
> +
> +    *BootFv = Fv;
> +    return EFI_SUCCESS;
> +
> +  } while (TRUE);
> +}
> +
> +/**
> +  Locates a section within a series of sections
> +  with the specified section type.
> +
> +  The Instance parameter indicates which instance of the section
> +  type to return. (0 is first instance, 1 is second...)
> +
> +  @param[in]   Sections        The sections to search
> +  @param[in]   SizeOfSections  Total size of all sections
> +  @param[in]   SectionType     The section type to locate
> +  @param[in]   Instance        The section instance number
> +  @param[out]  FoundSection    The FFS section if found
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsSectionInstance (
> +  IN  VOID                             *Sections,
> +  IN  UINTN                            SizeOfSections,
> +  IN  EFI_SECTION_TYPE                 SectionType,
> +  IN  UINTN                            Instance,
> +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> +  UINT32                      Size;
> +  EFI_PHYSICAL_ADDRESS        EndOfSections;
> +  EFI_COMMON_SECTION_HEADER   *Section;
> +  EFI_PHYSICAL_ADDRESS        EndOfSection;
> +
> +  //
> +  // Loop through the FFS file sections within the PEI Core FFS file
> +  //
> +  EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
> +  EndOfSections = EndOfSection + SizeOfSections;
> +  for (;;) {
> +    if (EndOfSection == EndOfSections) {
> +      break;
> +    }
> +    CurrentAddress = (EndOfSection + 3) & ~(3ULL);
> +    if (CurrentAddress >= EndOfSections) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> +    DEBUG ((EFI_D_INFO, "Section->Type: 0x%x\n", Section->Type));
> +
> +    Size = SECTION_SIZE (Section);
> +    if (Size < sizeof (*Section)) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    EndOfSection = CurrentAddress + Size;
> +    if (EndOfSection > EndOfSections) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    //
> +    // Look for the requested section type
> +    //
> +    if (Section->Type == SectionType) {
> +      if (Instance == 0) {
> +        *FoundSection = Section;
> +        return EFI_SUCCESS;
> +      } else {
> +        Instance--;
> +      }
> +    }
> +    DEBUG ((EFI_D_INFO, "Section->Type (0x%x) != SectionType (0x%x)\n",
> Section->Type, SectionType));
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  Locates a section within a series of sections
> +  with the specified section type.
> +
> +  @param[in]   Sections        The sections to search
> +  @param[in]   SizeOfSections  Total size of all sections
> +  @param[in]   SectionType     The section type to locate
> +  @param[out]  FoundSection    The FFS section if found
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsSectionInSections (
> +  IN  VOID                             *Sections,
> +  IN  UINTN                            SizeOfSections,
> +  IN  EFI_SECTION_TYPE                 SectionType,
> +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> +  )
> +{
> +  return FindFfsSectionInstance (
> +           Sections,
> +           SizeOfSections,
> +           SectionType,
> +           0,
> +           FoundSection
> +           );
> +}
> +
> +/**
> +  Locates a FFS file with the specified file type and a section
> +  within that file with the specified section type.
> +
> +  @param[in]   Fv            The firmware volume to search
> +  @param[in]   FileType      The file type to locate
> +  @param[in]   SectionType   The section type to locate
> +  @param[out]  FoundSection  The FFS section if found
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsFileAndSection (
> +  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
> +  IN  EFI_FV_FILETYPE                  FileType,
> +  IN  EFI_SECTION_TYPE                 SectionType,
> +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> +  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
> +  EFI_FFS_FILE_HEADER         *File;
> +  UINT32                      Size;
> +  EFI_PHYSICAL_ADDRESS        EndOfFile;
> +
> +  if (Fv->Signature != EFI_FVH_SIGNATURE) {
> +    DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n",
> Fv));
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> +
> +  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
> +  EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
> +
> +  //
> +  // Loop through the FFS files in the Boot Firmware Volume
> +  //
> +  for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
> +
> +    CurrentAddress = (EndOfFile + 7) & ~(7ULL);
> +    if (CurrentAddress > EndOfFirmwareVolume) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> +    Size = *(UINT32*) File->Size & 0xffffff;
> +    if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +    DEBUG ((EFI_D_INFO, "File->Type: 0x%x\n", File->Type));
> +
> +    EndOfFile = CurrentAddress + Size;
> +    if (EndOfFile > EndOfFirmwareVolume) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    //
> +    // Look for the request file type
> +    //
> +    if (File->Type != FileType) {
> +      DEBUG ((EFI_D_INFO, "File->Type (0x%x) != FileType (0x%x)\n", File->Type,
> FileType));
> +      continue;
> +    }
> +
> +    Status = FindFfsSectionInSections (
> +               (VOID*) (File + 1),
> +               (UINTN) EndOfFile - (UINTN) (File + 1),
> +               SectionType,
> +               FoundSection
> +               );
> +    if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
> +      return Status;
> +    }
> +  }
> +}
> +
> +/**
> +  Locates the compressed main firmware volume and decompresses it.
> +
> +  @param[in,out]  Fv            On input, the firmware volume to search
> +                                On output, the decompressed BOOT/PEI FV
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +DecompressMemFvs (
> +  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **Fv
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  EFI_GUID_DEFINED_SECTION          *Section;
> +  UINT32                            OutputBufferSize;
> +  UINT32                            ScratchBufferSize;
> +  UINT16                            SectionAttribute;
> +  UINT32                            AuthenticationStatus;
> +  VOID                              *OutputBuffer;
> +  VOID                              *ScratchBuffer;
> +  EFI_COMMON_SECTION_HEADER         *FvSection;
> +  EFI_FIRMWARE_VOLUME_HEADER        *PeiMemFv;
> +  EFI_FIRMWARE_VOLUME_HEADER        *DxeMemFv;
> +  UINT32                            FvHeaderSize;
> +  UINT32                            FvSectionSize;
> +
> +  FvSection = (EFI_COMMON_SECTION_HEADER*) NULL;
> +
> +  DEBUG ((EFI_D_INFO, "Find and decompress FV image.\n"));
> +  Status = FindFfsFileAndSection (
> +             *Fv,
> +             EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
> +             EFI_SECTION_GUID_DEFINED,
> +             (EFI_COMMON_SECTION_HEADER**) &Section
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
> +    return Status;
> +  }
> +
> +  Status = ExtractGuidedSectionGetInfo (
> +             Section,
> +             &OutputBufferSize,
> +             &ScratchBufferSize,
> +             &SectionAttribute
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
> +    return Status;
> +  }
> +
> +  OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32
> (PcdSimicsDxeMemFvBase) + SIZE_1MB);
> +  ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize,
> SIZE_1MB);
> +
> +  DEBUG ((EFI_D_INFO, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32
> (PcdSimicsDxeMemFvBase)));
> +  DEBUG ((EFI_D_INFO, "OutputBuffer: 0x%x\n", OutputBuffer));
> +  DEBUG ((EFI_D_INFO, "OutputBufferSize: 0x%x\n", OutputBufferSize));
> +  DEBUG ((EFI_D_INFO, "ScratchBuffer: 0x%x\n", ScratchBuffer));
> +  DEBUG ((EFI_D_INFO, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
> +  DEBUG ((EFI_D_INFO, "PcdSimicsDecompressionScratchEnd: 0x%x\n",
> PcdGet32 (PcdSimicsDecompressionScratchEnd)));
> +
> +  DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x
> ScratchBuffer@%p+0x%x "
> +    "PcdSimicsDecompressionScratchEnd=0x%x\n", __FUNCTION__,
> OutputBuffer,
> +    OutputBufferSize, ScratchBuffer, ScratchBufferSize,
> +    PcdGet32 (PcdSimicsDecompressionScratchEnd)));
> +  ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==
> +    PcdGet32 (PcdSimicsDecompressionScratchEnd));
> +
> +  Status = ExtractGuidedSectionDecode (
> +             Section,
> +             &OutputBuffer,
> +             ScratchBuffer,
> +             &AuthenticationStatus
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
> +    return Status;
> +  }
> +
> +  Status = FindFfsSectionInstance (
> +             OutputBuffer,
> +             OutputBufferSize,
> +             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
> +             0,
> +             &FvSection
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));
> +    return Status;
> +  }
> +
> +  ASSERT (SECTION_SIZE (FvSection) ==
> +          (PcdGet32 (PcdSimicsPeiMemFvSize) + sizeof (*FvSection)));
> +  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
> +
> +  PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> (PcdSimicsPeiMemFvBase);
> +  CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32
> (PcdSimicsPeiMemFvSize));
> +
> +  if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {
> +    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header
> signature\n", PeiMemFv));
> +    CpuDeadLoop ();
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> +
> +  Status = FindFfsSectionInstance (
> +             OutputBuffer,
> +             OutputBufferSize,
> +             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
> +             1,
> +             &FvSection
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));
> +    return Status;
> +  }
> +
> +  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
> +
> +  if (IS_SECTION2 (FvSection)) {
> +    FvSectionSize = SECTION2_SIZE (FvSection);
> +    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
> +  } else {
> +    FvSectionSize = SECTION_SIZE (FvSection);
> +    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
> +  }
> +
> +  ASSERT (FvSectionSize == (PcdGet32 (PcdSimicsDxeMemFvSize) +
> FvHeaderSize));
> +
> +  DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> (PcdSimicsDxeMemFvBase);
> +  CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize),
> PcdGet32 (PcdSimicsDxeMemFvSize));
> +
> +  if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
> +    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header
> signature\n", DxeMemFv));
> +    CpuDeadLoop ();
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> +
> +  *Fv = PeiMemFv;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Locates the PEI Core entry point address
> +
> +  @param[in]  Fv                 The firmware volume to search
> +  @param[out] PeiCoreEntryPoint  The entry point of the PEI Core image
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindPeiCoreImageBaseInFv (
> +  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
> +  OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_COMMON_SECTION_HEADER   *Section;
> +
> +  DEBUG ((EFI_D_ERROR, "Find PEI Core image.\n"));
> +  Status = FindFfsFileAndSection (
> +             Fv,
> +             EFI_FV_FILETYPE_PEI_CORE,
> +             EFI_SECTION_PE32,
> +             &Section
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Status = FindFfsFileAndSection (
> +               Fv,
> +               EFI_FV_FILETYPE_PEI_CORE,
> +               EFI_SECTION_TE,
> +               &Section
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
> +      return Status;
> +    }
> +  }
> +
> +  *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
> +  DEBUG ((EFI_D_INFO, "PEI core image base 0x%016LX.\n",
> *PeiCoreImageBase));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Reads 8-bits of CMOS data.
> +
> +  Reads the 8-bits of CMOS data at the location specified by Index.
> +  The 8-bit read value is returned.
> +
> +  @param  Index  The CMOS location to read.
> +
> +  @return The value read.
> +
> +**/
> +STATIC
> +UINT8
> +CmosRead8 (
> +  IN UINTN        Index
> +  )
> +{
> +  IoWrite8 (0x70, (UINT8) Index);
> +  return IoRead8 (0x71);
> +}
> +
> +
> +STATIC
> +BOOLEAN
> +IsS3Resume (
> +  VOID
> +  )
> +{
> +  DEBUG((EFI_D_INFO, "modeValue = %x\n",
> IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
> +  return (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5);
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +GetS3ResumePeiFv (
> +  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **PeiFv
> +  )
> +{
> +  *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> (PcdSimicsPeiMemFvBase);
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Locates the PEI Core entry point address
> +
> +  @param[in,out]  Fv                 The firmware volume to search
> +  @param[out]     PeiCoreEntryPoint  The entry point of the PEI Core image
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +VOID
> +FindPeiCoreImageBase (
> +  IN OUT  EFI_FIRMWARE_VOLUME_HEADER       **BootFv,
> +     OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> +  )
> +{
> +  BOOLEAN S3Resume;
> +
> +  *PeiCoreImageBase = 0;
> +
> +  S3Resume = IsS3Resume ();
> +  if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
> +    //
> +    // A malicious runtime OS may have injected something into our previously
> +    // decoded PEI FV, but we don't care about that unless SMM/SMRAM is
> required.
> +    //
> +    DEBUG ((EFI_D_INFO, "SEC: S3 resume\n"));
> +    GetS3ResumePeiFv (BootFv);
> +  } else {
> +    //
> +    // We're either not resuming, or resuming "securely" -- we'll decompress
> +    // both PEI FV and DXE FV from pristine flash.
> +    //
> +    DEBUG ((EFI_D_INFO, "SEC: %a\n",
> +      S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"));
> +    FindMainFv (BootFv);
> +
> +    DecompressMemFvs (BootFv);
> +  }
> +
> +  FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
> +}
> +
> +/**
> +  Find core image base.
> +
> +**/
> +EFI_STATUS
> +FindImageBase (
> +  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
> +  OUT EFI_PHYSICAL_ADDRESS             *SecCoreImageBase
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> +  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
> +  EFI_FFS_FILE_HEADER         *File;
> +  UINT32                      Size;
> +  EFI_PHYSICAL_ADDRESS        EndOfFile;
> +  EFI_COMMON_SECTION_HEADER   *Section;
> +  EFI_PHYSICAL_ADDRESS        EndOfSection;
> +
> +  *SecCoreImageBase = 0;
> +
> +  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)
> BootFirmwareVolumePtr;
> +  EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr-
> >FvLength;
> +
> +  //
> +  // Loop through the FFS files in the Boot Firmware Volume
> +  //
> +  for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ;
> ) {
> +
> +    CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
> +    if (CurrentAddress > EndOfFirmwareVolume) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> +    Size = *(UINT32*) File->Size & 0xffffff;
> +    if (Size < sizeof (*File)) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    EndOfFile = CurrentAddress + Size;
> +    if (EndOfFile > EndOfFirmwareVolume) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    //
> +    // Look for SEC Core
> +    //
> +    if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {
> +      continue;
> +    }
> +
> +    //
> +    // Loop through the FFS file sections within the FFS file
> +    //
> +    EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1);
> +    for (;;) {
> +      CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
> +      Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> +
> +      Size = *(UINT32*) Section->Size & 0xffffff;
> +      if (Size < sizeof (*Section)) {
> +        return EFI_NOT_FOUND;
> +      }
> +
> +      EndOfSection = CurrentAddress + Size;
> +      if (EndOfSection > EndOfFile) {
> +        return EFI_NOT_FOUND;
> +      }
> +
> +      //
> +      // Look for executable sections
> +      //
> +      if (Section->Type == EFI_SECTION_PE32 || Section->Type ==
> EFI_SECTION_TE) {
> +        if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
> +          *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) (Section + 1);
> +        }
> +        break;
> +      }
> +    }
> +
> +    //
> +    // SEC Core image found
> +    //
> +    if (*SecCoreImageBase != 0) {
> +      return EFI_SUCCESS;
> +    }
> +  }
> +}
> +
> +/*
> +  Find and return Pei Core entry point.
> +
> +  It also find SEC and PEI Core file debug information. It will report them if
> +  remote debug is enabled.
> +
> +**/
> +VOID
> +FindAndReportEntryPoints (
> +  IN  EFI_FIRMWARE_VOLUME_HEADER       **BootFirmwareVolumePtr,
> +  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  EFI_PHYSICAL_ADDRESS             SecCoreImageBase;
> +  EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
> +  PE_COFF_LOADER_IMAGE_CONTEXT     ImageContext;
> +
> +  //
> +  // Find SEC Core and PEI Core image base
> +   //
> +  Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
> +
> +  ZeroMem ((VOID *) &ImageContext, sizeof
> (PE_COFF_LOADER_IMAGE_CONTEXT));
> +  //
> +  // Report SEC Core debug information when remote debug is enabled
> +  //
> +  ImageContext.ImageAddress = SecCoreImageBase;
> +  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN)
> ImageContext.ImageAddress);
> +  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
> +
> +  //
> +  // Report PEI Core debug information when remote debug is enabled
> +  //
> +  ImageContext.ImageAddress =
> (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
> +  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN)
> ImageContext.ImageAddress);
> +  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
> +
> +  //
> +  // Find PEI Core entry point
> +  //
> +  Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase,
> (VOID**) PeiCoreEntryPoint);
> +  if (EFI_ERROR (Status)) {
> +    *PeiCoreEntryPoint = 0;
> +  }
> +
> +  return;
> +}
> +
> +VOID
> +EFIAPI
> +SecCoreStartupWithStack (
> +  IN EFI_FIRMWARE_VOLUME_HEADER       *BootFv,
> +  IN VOID                             *TopOfCurrentStack
> +  )
> +{
> +  EFI_SEC_PEI_HAND_OFF        SecCoreData;
> +  SEC_IDT_TABLE               IdtTableInStack;
> +  IA32_DESCRIPTOR             IdtDescriptor;
> +  UINT32                      Index;
> +  volatile UINT8              *Table;
> +
> +  //
> +  // Initialize floating point operating environment
> +  // to be compliant with UEFI spec.
> +  //
> +  InitializeFloatingPointUnits ();
> +
> +  //
> +  // Initialize the PCIe Configuration base register.
> +  //
> +  PciCf8Write32 (PCI_CF8_LIB_ADDRESS (0xFF, 0, 1, 0x50), 0xE0000001);
> +
> +  //
> +  // To ensure SMM can't be compromised on S3 resume, we must force re-init
> of
> +  // the BaseExtractGuidedSectionLib. Since this is before library contructors
> +  // are called, we must use a loop rather than SetMem.
> +  //
> +  Table = (UINT8*)(UINTN)FixedPcdGet64
> (PcdGuidedExtractHandlerTableAddress);
> +  for (Index = 0;
> +       Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
> +       ++Index) {
> +    Table[Index] = 0;
> +  }
> +
> +  ProcessLibraryConstructorList (NULL, NULL);
> +
> +  DEBUG ((EFI_D_INFO,
> +    "SecCoreStartupWithStack(0x%x, 0x%x)\n",
> +    (UINT32)(UINTN)BootFv,
> +    (UINT32)(UINTN)TopOfCurrentStack
> +    ));
> +
> +  //
> +  // Initialize IDT
> +  //
> +  IdtTableInStack.PeiService = NULL;
> +  for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
> +    CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof
> (mIdtEntryTemplate));
> +  }
> +
> +  IdtDescriptor.Base  = (UINTN)&IdtTableInStack.IdtTable;
> +  IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
> +
> +  AsmWriteIdtr (&IdtDescriptor);
> +
> +#if defined (MDE_CPU_X64)
> +  //
> +  // ASSERT that the Page Tables were set by the reset vector code to
> +  // the address we expect.
> +  //
> +  ASSERT (AsmReadCr3 () == (UINTN) PcdGet32
> (PcdSimicsSecPageTablesBase));
> +#endif
> +
> +  //
> +  // |-------------|       <-- TopOfCurrentStack
> +  // |   Stack     | 32k
> +  // |-------------|
> +  // |    Heap     | 32k
> +  // |-------------|       <-- SecCoreData.TemporaryRamBase
> +  //
> +
> +  ASSERT ((UINTN) (PcdGet32 (PcdSimicsSecPeiTempRamBase) +
> +                   PcdGet32 (PcdSimicsSecPeiTempRamSize)) ==
> +          (UINTN) TopOfCurrentStack);
> +
> +  //
> +  // Initialize SEC hand-off state
> +  //
> +  SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
> +
> +  SecCoreData.TemporaryRamSize       = (UINTN) PcdGet32
> (PcdSimicsSecPeiTempRamSize);
> +  SecCoreData.TemporaryRamBase       = (VOID*)((UINT8 *)TopOfCurrentStack
> - SecCoreData.TemporaryRamSize);
> +
> +  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
> +  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize >>
> 1;
> +
> +  SecCoreData.StackBase              = (UINT8 *)SecCoreData.TemporaryRamBase +
> SecCoreData.PeiTemporaryRamSize;
> +  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize >> 1;
> +
> +  SecCoreData.BootFirmwareVolumeBase = BootFv;
> +  SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> +
> +  //
> +  // Make sure the 8259 is masked before initializing the Debug Agent and the
> debug timer is enabled
> +  //
> +  IoWrite8 (0x21, 0xff);
> +  IoWrite8 (0xA1, 0xff);
> +
> +  //
> +  // Initialize Local APIC Timer hardware and disable Local APIC Timer
> +  // interrupts before initializing the Debug Agent and the debug timer is
> +  // enabled.
> +  //
> +  InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
> +  DisableApicTimerInterrupt ();
> +
> +  //
> +  // Initialize Debug Agent to support source level debug in SEC/PEI phases
> before memory ready.
> +  //
> +  InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData,
> SecStartupPhase2);
> +}
> +
> +/**
> +  Caller provided function to be invoked at the end of InitializeDebugAgent().
> +
> +  Entry point to the C language phase of SEC. After the SEC assembly
> +  code has initialized some temporary memory and set up the stack,
> +  the control is transferred to this function.
> +
> +  @param[in] Context    The first input parameter of InitializeDebugAgent().
> +
> +**/
> +VOID
> +EFIAPI
> +SecStartupPhase2(
> +  IN VOID                     *Context
> +  )
> +{
> +  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
> +  EFI_FIRMWARE_VOLUME_HEADER  *BootFv;
> +  EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
> +
> +  SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
> +
> +  //
> +  // Find PEI Core entry point. It will report SEC and Pei Core debug information
> if remote debug
> +  // is enabled.
> +  //
> +  BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData-
> >BootFirmwareVolumeBase;
> +  FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
> +  SecCoreData->BootFirmwareVolumeBase = BootFv;
> +  SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> +
> +  //
> +  // Transfer the control to the PEI core
> +  //
> +  (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR
> *)&mPrivateDispatchTable);
> +
> +  //
> +  // If we get here then the PEI Core returned, which is not recoverable.
> +  //
> +  ASSERT (FALSE);
> +  CpuDeadLoop ();
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamMigration (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> +  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> +  IN UINTN                    CopySize
> +  )
> +{
> +  IA32_DESCRIPTOR                  IdtDescriptor;
> +  VOID                             *OldHeap;
> +  VOID                             *NewHeap;
> +  VOID                             *OldStack;
> +  VOID                             *NewStack;
> +  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  DebugAgentContext;
> +  BOOLEAN                          OldStatus;
> +  BASE_LIBRARY_JUMP_BUFFER         JumpBuffer;
> +
> +  DEBUG ((EFI_D_INFO,
> +    "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
> +    TemporaryMemoryBase,
> +    PermanentMemoryBase,
> +    (UINT64)CopySize
> +    ));
> +
> +  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
> +  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
> +
> +  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
> +  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
> +
> +  DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap -
> (UINTN)OldHeap;
> +  DebugAgentContext.StackMigrateOffset = (UINTN)NewStack -
> (UINTN)OldStack;
> +
> +  OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
> +  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *)
> &DebugAgentContext, NULL);
> +
> +  //
> +  // Migrate Heap
> +  //
> +  CopyMem (NewHeap, OldHeap, CopySize >> 1);
> +
> +  //
> +  // Migrate Stack
> +  //
> +  CopyMem (NewStack, OldStack, CopySize >> 1);
> +
> +  //
> +  // Rebase IDT table in permanent memory
> +  //
> +  AsmReadIdtr (&IdtDescriptor);
> +  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack +
> (UINTN)NewStack;
> +
> +  AsmWriteIdtr (&IdtDescriptor);
> +
> +  //
> +  // Use SetJump()/LongJump() to switch to a new stack.
> +  //
> +  if (SetJump (&JumpBuffer) == 0) {
> +#if defined (MDE_CPU_IA32)
> +    JumpBuffer.Esp = JumpBuffer.Esp +
> DebugAgentContext.StackMigrateOffset;
> +#endif
> +#if defined (MDE_CPU_X64)
> +    JumpBuffer.Rsp = JumpBuffer.Rsp +
> DebugAgentContext.StackMigrateOffset;
> +#endif
> +    LongJump (&JumpBuffer, (UINTN)-1);
> +  }
> +
> +  SaveAndSetDebugTimerInterrupt (OldStatus);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> new file mode 100644
> index 0000000000..771fddb487
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> @@ -0,0 +1,148 @@
> +/** @file
> +  A DXE_DRIVER providing SMRAM access by producing
> EFI_SMM_ACCESS2_PROTOCOL.
> +
> +  X58 TSEG is expected to have been verified and set up by the SmmAccessPei
> +  driver.
> +
> +  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
> +  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/SmmAccess2.h>
> +
> +#include "SmramInternal.h"
> +
> +/**
> +  Opens the SMRAM area to be accessible by a boot-service driver.
> +
> +  This function "opens" SMRAM so that it is visible while not inside of SMM.
> +  The function should return EFI_UNSUPPORTED if the hardware does not
> support
> +  hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the
> SMRAM
> +  configuration is locked.
> +
> +  @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS       The operation was successful.
> +  @retval EFI_UNSUPPORTED   The system does not support opening and
> closing of
> +                            SMRAM.
> +  @retval EFI_DEVICE_ERROR  SMRAM cannot be opened, perhaps because it is
> +                            locked.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccess2DxeOpen (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  )
> +{
> +  return SmramAccessOpen (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Inhibits access to the SMRAM.
> +
> +  This function "closes" SMRAM so that it is not visible while outside of SMM.
> +  The function should return EFI_UNSUPPORTED if the hardware does not
> support
> +  hiding of SMRAM.
> +
> +  @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS       The operation was successful.
> +  @retval EFI_UNSUPPORTED   The system does not support opening and
> closing of
> +                            SMRAM.
> +  @retval EFI_DEVICE_ERROR  SMRAM cannot be closed.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccess2DxeClose (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  )
> +{
> +  return SmramAccessClose (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Inhibits access to the SMRAM.
> +
> +  This function prohibits access to the SMRAM region.  This function is usually
> +  implemented such that it is a write-once operation.
> +
> +  @param[in] This          The EFI_SMM_ACCESS2_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS      The device was successfully locked.
> +  @retval EFI_UNSUPPORTED  The system does not support locking of SMRAM.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccess2DxeLock (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  )
> +{
> +  return SmramAccessLock (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Queries the memory controller for the possible regions that will support
> +  SMRAM.
> +
> +  @param[in]     This           The EFI_SMM_ACCESS2_PROTOCOL instance.
> +  @param[in,out] SmramMapSize   A pointer to the size, in bytes, of the
> +                                SmramMemoryMap buffer.
> +  @param[in,out] SmramMap       A pointer to the buffer in which firmware
> +                                places the current memory map.
> +
> +  @retval EFI_SUCCESS           The chipset supported the given resource.
> +  @retval EFI_BUFFER_TOO_SMALL  The SmramMap parameter was too small.
> The
> +                                current buffer size needed to hold the memory
> +                                map is returned in SmramMapSize.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccess2DxeGetCapabilities (
> +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +{
> +  return SmramAccessGetCapabilities (This->LockState, This->OpenState,
> +           SmramMapSize, SmramMap);
> +}
> +
> +//
> +// LockState and OpenState will be filled in by the entry point.
> +//
> +STATIC EFI_SMM_ACCESS2_PROTOCOL mAccess2 = {
> +  &SmmAccess2DxeOpen,
> +  &SmmAccess2DxeClose,
> +  &SmmAccess2DxeLock,
> +  &SmmAccess2DxeGetCapabilities
> +};
> +
> +//
> +// Entry point of this driver.
> +//
> +EFI_STATUS
> +EFIAPI
> +SmmAccess2DxeEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  //
> +  // This module should only be included if SMRAM support is required.
> +  //
> +  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
> +
> +  GetStates (&mAccess2.LockState, &mAccess2.OpenState);
> +  return gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
> +                &gEfiSmmAccess2ProtocolGuid, &mAccess2,
> +                NULL);
> +}
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> new file mode 100644
> index 0000000000..d07d88142a
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> @@ -0,0 +1,353 @@
> +/** @file
> +  A PEIM with the following responsibilities:
> +
> +  - verify & configure the X58 TSEG in the entry point,
> +  - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
> +  - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and
> expose
> +    it via the gEfiAcpiVariableGuid GUID HOB.
> +
> +  This PEIM runs from RAM, so we can write to variables with static storage
> +  duration.
> +
> +  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
> +  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Guid/AcpiS3Context.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Ppi/SmmAccess.h>
> +
> +#include <SimicsPlatforms.h>
> +
> +#include "SmramInternal.h"
> +
> +//
> +// PEI_SMM_ACCESS_PPI implementation.
> +//
> +
> +/**
> +  Opens the SMRAM area to be accessible by a PEIM driver.
> +
> +  This function "opens" SMRAM so that it is visible while not inside of SMM.
> +  The function should return EFI_UNSUPPORTED if the hardware does not
> support
> +  hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the
> SMRAM
> +  configuration is locked.
> +
> +  @param  PeiServices            General purpose services available to every
> +                                 PEIM.
> +  @param  This                   The pointer to the SMM Access Interface.
> +  @param  DescriptorIndex        The region of SMRAM to Open.
> +
> +  @retval EFI_SUCCESS            The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR       The region could not be opened because
> locked
> +                                 by chipset.
> +  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccessPeiOpen (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  )
> +{
> +  if (DescriptorIndex >= DescIdxCount) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // According to current practice, DescriptorIndex is not considered at all,
> +  // beyond validating it.
> +  //
> +  return SmramAccessOpen (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Inhibits access to the SMRAM.
> +
> +  This function "closes" SMRAM so that it is not visible while outside of SMM.
> +  The function should return EFI_UNSUPPORTED if the hardware does not
> support
> +  hiding of SMRAM.
> +
> +  @param  PeiServices              General purpose services available to every
> +                                   PEIM.
> +  @param  This                     The pointer to the SMM Access Interface.
> +  @param  DescriptorIndex          The region of SMRAM to Close.
> +
> +  @retval EFI_SUCCESS              The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR         The region could not be closed because
> +                                   locked by chipset.
> +  @retval EFI_INVALID_PARAMETER    The descriptor index was out of bounds.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccessPeiClose (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  )
> +{
> +  if (DescriptorIndex >= DescIdxCount) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // According to current practice, DescriptorIndex is not considered at all,
> +  // beyond validating it.
> +  //
> +  return SmramAccessClose (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Inhibits access to the SMRAM.
> +
> +  This function prohibits access to the SMRAM region.  This function is usually
> +  implemented such that it is a write-once operation.
> +
> +  @param  PeiServices              General purpose services available to every
> +                                   PEIM.
> +  @param  This                     The pointer to the SMM Access Interface.
> +  @param  DescriptorIndex          The region of SMRAM to Close.
> +
> +  @retval EFI_SUCCESS            The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR       The region could not be locked because at
> +                                 least one range is still open.
> +  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccessPeiLock (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  )
> +{
> +  if (DescriptorIndex >= DescIdxCount) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // According to current practice, DescriptorIndex is not considered at all,
> +  // beyond validating it.
> +  //
> +  return SmramAccessLock (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Queries the memory controller for the possible regions that will support
> +  SMRAM.
> +
> +  @param  PeiServices           General purpose services available to every
> +                                PEIM.
> +  @param This                   The pointer to the SmmAccessPpi Interface.
> +  @param SmramMapSize           The pointer to the variable containing size of
> +                                the buffer to contain the description
> +                                information.
> +  @param SmramMap               The buffer containing the data describing the
> +                                Smram region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           The user provided a sufficiently-sized buffer.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccessPeiGetCapabilities (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +{
> +  return SmramAccessGetCapabilities (This->LockState, This->OpenState,
> +           SmramMapSize, SmramMap);
> +}
> +
> +//
> +// LockState and OpenState will be filled in by the entry point.
> +//
> +STATIC PEI_SMM_ACCESS_PPI mAccess = {
> +  &SmmAccessPeiOpen,
> +  &SmmAccessPeiClose,
> +  &SmmAccessPeiLock,
> +  &SmmAccessPeiGetCapabilities
> +};
> +
> +
> +STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +    &gPeiSmmAccessPpiGuid, &mAccess
> +  }
> +};
> +
> +
> +//
> +// Utility functions.
> +//
> +STATIC
> +UINT8
> +CmosRead8 (
> +  IN UINT8  Index
> +  )
> +{
> +  IoWrite8 (0x70, Index);
> +  return IoRead8 (0x71);
> +}
> +
> +STATIC
> +UINT32
> +GetSystemMemorySizeBelow4gb (
> +  VOID
> +  )
> +{
> +  UINT32 Cmos0x34;
> +  UINT32 Cmos0x35;
> +
> +  Cmos0x34 = CmosRead8 (0x34);
> +  Cmos0x35 = CmosRead8 (0x35);
> +
> +  return ((Cmos0x35 << 8 | Cmos0x34) << 16) + SIZE_16MB;
> +}
> +
> +
> +//
> +// Entry point of this driver.
> +//
> +EFI_STATUS
> +EFIAPI
> +SmmAccessPeiEntryPoint (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  UINT16               HostBridgeDevId;
> +  UINT32                EsmramcVal;
> +  UINT32               TopOfLowRam, TopOfLowRamMb;
> +  EFI_STATUS           Status;
> +  UINTN                SmramMapSize;
> +  EFI_SMRAM_DESCRIPTOR SmramMap[DescIdxCount];
> +  VOID                 *GuidHob;
> +
> +  //
> +  // This module should only be included if SMRAM support is required.
> +  //
> +  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
> +
> +  //
> +  // Verify if we're running on a X58 machine type.
> +  //
> +  HostBridgeDevId = PciRead16 (SIMICS_HOSTBRIDGE_DID);
> +  if (HostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
> +    DEBUG ((EFI_D_ERROR, "%a: no SMRAM with host bridge DID=0x%04x; only
> "
> +      "DID=0x%04x (X58) is supported\n", __FUNCTION__, HostBridgeDevId,
> +      INTEL_ICH10_DEVICE_ID));
> +    goto WrongConfig;
> +  }
> +
> +  //
> +  // Confirm if QEMU supports SMRAM.
> +  //
> +  // With no support for it, the ESMRAMC (Extended System Management RAM
> +  // Control) register reads as zero. If there is support, the cache-enable
> +  // bits are hard-coded as 1 by QEMU.
> +  //
> +
> +  TopOfLowRam = GetSystemMemorySizeBelow4gb ();
> +  ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
> +  TopOfLowRamMb = TopOfLowRam >> 20;
> +  DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x
> \n", TopOfLowRam, TopOfLowRamMb));
> +
> +
> +  //
> +  // Set Top of Low Usable DRAM.
> +  //
> +  PciWrite32 (DRAMC_REGISTER_X58(MCH_TOLUD),
> +               TopOfLowRam);
> +  DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n",
> PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));
> +
> +  //
> +  // Set TSEG Memory Base.
> +  //
> +  EsmramcVal = (TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) <<
> MCH_TSEGMB_MB_SHIFT;
> +  //
> +  // Set TSEG size, and disable TSEG visibility outside of SMM. Note that the
> +  // T_EN bit has inverse meaning; when T_EN is set, then TSEG visibility is
> +  // *restricted* to SMM.
> +  //
> +  EsmramcVal &= ~(UINT32)MCH_ESMRAMC_TSEG_MASK;
> +  EsmramcVal |= FixedPcdGet8 (PcdX58TsegMbytes) == 8 ?
> MCH_ESMRAMC_TSEG_8MB :
> +                FixedPcdGet8 (PcdX58TsegMbytes) == 2 ?
> MCH_ESMRAMC_TSEG_2MB :
> +                MCH_ESMRAMC_TSEG_1MB;
> +  EsmramcVal |= MCH_ESMRAMC_T_EN;
> +  PciWrite32(DRAMC_REGISTER_X58(MCH_TSEGMB), EsmramcVal);
> +  DEBUG((EFI_D_ERROR, "MCH_TSEGMB =0x%x; \n",
> PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
> +  DEBUG((EFI_D_ERROR, "MCH_TSEGMB_1 =0x%x; MCH_TSEGMB_2
> =0x%x;\n", ((TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) <<
> MCH_TSEGMB_MB_SHIFT), EsmramcVal));
> +
> +  //
> +  // Create the GUID HOB and point it to the first SMRAM range.
> +  //
> +  GetStates (&mAccess.LockState, &mAccess.OpenState);
> +  SmramMapSize = sizeof SmramMap;
> +  Status = SmramAccessGetCapabilities (mAccess.LockState,
> mAccess.OpenState,
> +             &SmramMapSize, SmramMap);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG_CODE_BEGIN ();
> +  {
> +    UINTN Count;
> +    UINTN Idx;
> +
> +    Count = SmramMapSize / sizeof SmramMap[0];
> +    DEBUG ((EFI_D_VERBOSE, "%a: SMRAM map follows, %d entries\n",
> __FUNCTION__,
> +      (INT32)Count));
> +    DEBUG ((EFI_D_VERBOSE, "% 20a % 20a % 20a % 20a\n",
> "PhysicalStart(0x)",
> +      "PhysicalSize(0x)", "CpuStart(0x)", "RegionState(0x)"));
> +    for (Idx = 0; Idx < Count; ++Idx) {
> +      DEBUG ((EFI_D_VERBOSE, "% 20Lx % 20Lx % 20Lx % 20Lx\n",
> +        SmramMap[Idx].PhysicalStart, SmramMap[Idx].PhysicalSize,
> +        SmramMap[Idx].CpuStart, SmramMap[Idx].RegionState));
> +    }
> +  }
> +  DEBUG_CODE_END ();
> +
> +  GuidHob = BuildGuidHob (&gEfiAcpiVariableGuid,
> +    sizeof SmramMap[DescIdxSmmS3ResumeState]);
> +  if (GuidHob == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  CopyMem (GuidHob, &SmramMap[DescIdxSmmS3ResumeState],
> +    sizeof SmramMap[DescIdxSmmS3ResumeState]);
> +
> +  //
> +  // We're done. The next step should succeed, but even if it fails, we can't
> +  // roll back the above BuildGuidHob() allocation, because PEI doesn't support
> +  // releasing memory.
> +  //
> +  return PeiServicesInstallPpi (mPpiList);
> +
> +WrongConfig:
> +  //
> +  // We really don't want to continue in this case.
> +  //
> +  ASSERT (FALSE);
> +  CpuDeadLoop ();
> +  return EFI_UNSUPPORTED;
> +}
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> new file mode 100644
> index 0000000000..898fc25084
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> @@ -0,0 +1,199 @@
> +/** @file
> +  Functions and types shared by the SMM accessor PEI and DXE modules.
> +
> +  Copyright (C) 2015, Red Hat, Inc.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Guid/AcpiS3Context.h>
> +#include <IndustryStandard/X58Ich10.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PciLib.h>
> +
> +#include "SmramInternal.h"
> +
> +BOOLEAN gLockState;
> +BOOLEAN gOpenState;
> +
> +/**
> +  Read the MCH_SMRAM and ESMRAMC registers, and update the LockState
> and
> +  OpenState fields in the PEI_SMM_ACCESS_PPI /
> EFI_SMM_ACCESS2_PROTOCOL object,
> +  from the D_LCK and T_EN bits.
> +
> +  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member
> functions can rely on
> +  the LockState and OpenState fields being up-to-date on entry, and they need
> +  to restore the same invariant on exit, if they touch the bits in question.
> +
> +  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff SMRAM is
> +                         locked.
> +  @param[out] OpenState  Reflects the inverse of the T_EN bit on output; TRUE
> +                         iff SMRAM is open.
> +**/
> +VOID
> +GetStates (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +)
> +{
> +  UINT8 EsmramcVal;
> +
> +  EsmramcVal = PciRead8(DRAMC_REGISTER_X58(MCH_TSEGMB));
> +
> +  *OpenState = !(EsmramcVal & MCH_ESMRAMC_T_EN);
> +  *LockState = !*OpenState;
> +
> +  *OpenState = gOpenState;
> +  *LockState = gLockState;
> +}
> +
> +//
> +// The functions below follow the PEI_SMM_ACCESS_PPI and
> +// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and
> This
> +// pointers are removed (TSEG doesn't depend on them), and so is the
> +// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
> +//
> +// The LockState and OpenState members that are common to both
> +// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and
> updated in
> +// isolation from the rest of the (non-shared) members.
> +//
> +
> +EFI_STATUS
> +SmramAccessOpen (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +  )
> +{
> +
> +  //
> +  // Open TSEG by clearing T_EN.
> +  //
> +  PciAnd8(DRAMC_REGISTER_X58(MCH_TSEGMB),
> +    (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff));
> +
> +  gOpenState = TRUE;
> +  gLockState = !gOpenState;
> +
> +  GetStates (LockState, OpenState);
> +  if (!*OpenState) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +SmramAccessClose (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +  )
> +{
> +  //
> +  // Close TSEG by setting T_EN.
> +  //
> +  PciOr8(DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
> +
> +  gOpenState = FALSE;
> +  gLockState = !gOpenState;
> +
> +  GetStates (LockState, OpenState);
> +  if (*OpenState) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +SmramAccessLock (
> +  OUT    BOOLEAN *LockState,
> +  IN OUT BOOLEAN *OpenState
> +  )
> +{
> +  if (*OpenState) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Close & lock TSEG by setting T_EN and D_LCK.
> +  //
> +  PciOr8 (DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
> +
> +  gOpenState = FALSE;
> +  gLockState = !gOpenState;
> +
> +  GetStates (LockState, OpenState);
> +  if (*OpenState || !*LockState) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +SmramAccessGetCapabilities (
> +  IN BOOLEAN                  LockState,
> +  IN BOOLEAN                  OpenState,
> +  IN OUT UINTN                *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
> +  )
> +{
> +  UINTN  OriginalSize;
> +  UINT32 TsegMemoryBaseMb, TsegMemoryBase;
> +  UINT64 CommonRegionState;
> +  UINT8  TsegSizeBits;
> +
> +  OriginalSize  = *SmramMapSize;
> +  *SmramMapSize = DescIdxCount * sizeof *SmramMap;
> +  if (OriginalSize < *SmramMapSize) {
> +    return EFI_BUFFER_TOO_SMALL;
> +  }
> +
> +  //
> +  // Read the TSEG Memory Base register.
> +  //
> +  TsegMemoryBaseMb = PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB));
> +
> +  TsegMemoryBaseMb = 0xDF800000;
> +
> +  TsegMemoryBase = (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) <<
> 20;
> +
> +  //
> +  // Precompute the region state bits that will be set for all regions.
> +  //
> +  CommonRegionState = (OpenState ? EFI_SMRAM_OPEN :
> EFI_SMRAM_CLOSED) |
> +                      (LockState ? EFI_SMRAM_LOCKED : 0) |
> +                      EFI_CACHEABLE;
> +
> +  //
> +  // The first region hosts an SMM_S3_RESUME_STATE object. It is located at
> the
> +  // start of TSEG. We round up the size to whole pages, and we report it as
> +  // EFI_ALLOCATED, so that the SMM_CORE stays away from it.
> +  //
> +  SmramMap[DescIdxSmmS3ResumeState].PhysicalStart = TsegMemoryBase;
> +  SmramMap[DescIdxSmmS3ResumeState].CpuStart      = TsegMemoryBase;
> +  SmramMap[DescIdxSmmS3ResumeState].PhysicalSize  =
> +    EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof
> (SMM_S3_RESUME_STATE)));
> +  SmramMap[DescIdxSmmS3ResumeState].RegionState   =
> +    CommonRegionState | EFI_ALLOCATED;
> +
> +  //
> +  // Get the TSEG size bits from the ESMRAMC register.
> +  //
> +  TsegSizeBits = PciRead8 (DRAMC_REGISTER_X58(MCH_TSEGMB)) &
> +                            MCH_ESMRAMC_TSEG_MASK;
> +
> +  TsegSizeBits = MCH_ESMRAMC_TSEG_8MB;
> +
> +  //
> +  // The second region is the main one, following the first.
> +  //
> +  SmramMap[DescIdxMain].PhysicalStart =
> +    SmramMap[DescIdxSmmS3ResumeState].PhysicalStart +
> +    SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
> +  SmramMap[DescIdxMain].CpuStart =
> SmramMap[DescIdxMain].PhysicalStart;
> +  SmramMap[DescIdxMain].PhysicalSize =
> +    (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB :
> +     TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB :
> +     SIZE_1MB) - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
> +  SmramMap[DescIdxMain].RegionState = CommonRegionState;
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.n
> asm
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.
> nasm
> new file mode 100644
> index 0000000000..19ffb6f86d
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.
> nasm
> @@ -0,0 +1,45 @@
> +; @file
> +; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> +#include <Base.h>
> +
> +    SECTION .text
> +
> +extern ASM_PFX(SecCoreStartupWithStack)
> +
> +;
> +; SecCore Entry Point
> +;
> +; Processor is in flat protected mode
> +;
> +; @param[in]  EAX   Initial value of the EAX register (BIST: Built-in Self Test)
> +; @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
> +; @param[in]  EBP   Pointer to the start of the Boot Firmware Volume
> +;
> +; @return     None  This routine does not return
> +;
> +global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> +
> +    ;
> +    ; Load temporary RAM stack based on PCDs
> +    ;
> +    %define SEC_TOP_OF_STACK (FixedPcdGet32
> (PcdSimicsSecPeiTempRamBase) + \
> +                          FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
> +    mov     eax, SEC_TOP_OF_STACK
> +    mov     esp, eax
> +    nop
> +
> +    ;
> +    ; Setup parameters and call SecCoreStartupWithStack
> +    ;   [esp]   return address for call
> +    ;   [esp+4] BootFirmwareVolumePtr
> +    ;   [esp+8] TopOfCurrentStack
> +    ;
> +    push    eax
> +    push    ebp
> +    call    ASM_PFX(SecCoreStartupWithStack)
> +
> diff --git
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> new file mode 100644
> index 0000000000..ac993ac1ce
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> @@ -0,0 +1,71 @@
> +## @file
> +#  SEC Driver
> +#
> +# Copyright (c) 2008 - 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SecMain
> +  FILE_GUID                      = e67f156f-54c5-47f3-a35d-07c045881e14
> +  MODULE_TYPE                    = SEC
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SecMain
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  SecMain.c
> +
> +[Sources.IA32]
> +  Ia32/SecEntry.nasm
> +
> +[Sources.X64]
> +  X64/SecEntry.nasm
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  BaseMemoryLib
> +  PeiServicesLib
> +  PcdLib
> +  UefiCpuLib
> +  DebugAgentLib
> +  IoLib
> +  PeCoffLib
> +  PeCoffGetEntryPointLib
> +  PeCoffExtraActionLib
> +  ExtractGuidedSectionLib
> +  LocalApicLib
> +  PciCf8Lib
> +
> +[Ppis]
> +  gEfiTemporaryRamSupportPpiGuid                # PPI ALWAYS_PRODUCED
> +
> +[Pcd]
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> +  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> +  gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> +
> +[FeaturePcd]
> +  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> diff --git
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> new file mode 100644
> index 0000000000..0eb86ec2ca
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> @@ -0,0 +1,45 @@
> +; @file
> +; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> +#include <Base.h>
> +
> +DEFAULT REL
> +SECTION .text
> +
> +extern ASM_PFX(SecCoreStartupWithStack)
> +
> +;
> +; SecCore Entry Point
> +;
> +; Processor is in flat protected mode
> +;
> +; @param[in]  RAX   Initial value of the EAX register (BIST: Built-in Self Test)
> +; @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
> +; @param[in]  RBP   Pointer to the start of the Boot Firmware Volume
> +;
> +; @return     None  This routine does not return
> +;
> +global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> +
> +    ;
> +    ; Load temporary RAM stack based on PCDs
> +    ;
> +    %define SEC_TOP_OF_STACK (FixedPcdGet32
> (PcdSimicsSecPeiTempRamBase) + \
> +                          FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
> +    mov     rsp, SEC_TOP_OF_STACK
> +    nop
> +
> +    ;
> +    ; Setup parameters and call SecCoreStartupWithStack
> +    ;   rcx: BootFirmwareVolumePtr
> +    ;   rdx: TopOfCurrentStack
> +    ;
> +    mov     rcx, rbp
> +    mov     rdx, rsp
> +    sub     rsp, 0x20
> +    call    ASM_PFX(SecCoreStartupWithStack)
> +
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> new file mode 100644
> index 0000000000..0be8be4966
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> @@ -0,0 +1,18 @@
> +## @file
> +#  Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +  #
> +  # SEC Phase modules
> +  #
> +  $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf {
> +    <LibraryClasses>
> +
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecom
> pressLib.inf
> +  }
> +  UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
> +  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> new file mode 100644
> index 0000000000..78eca21a43
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> @@ -0,0 +1,9 @@
> +## @file
> +#  Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> new file mode 100644
> index 0000000000..9f037e99d4
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> @@ -0,0 +1,10 @@
> +## @file
> +#  Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> new file mode 100644
> index 0000000000..596d633cd3
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> @@ -0,0 +1,17 @@
> +## @file
> +#  Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +#
> +# SEC Phase modules
> +#
> +# The code in this FV handles the initial firmware startup, and
> +# decompresses the PEI and DXE FVs which handles the rest of the boot
> sequence.
> +#
> +INF  RuleOverride=RESET_SECMAIN USE = IA32
> $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf
> +INF  RuleOverride=RESET_VECTOR USE = IA32
> UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> new file mode 100644
> index 0000000000..9004b9cb83
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> @@ -0,0 +1,16 @@
> +## @file
> +#  Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +#INF  $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuArchDxe/CpuArchDxe.inf
> +#INF  $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuMpDxe/CpuMpDxe.inf
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
> +  INF  $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf
> +  INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> +!endif
> +INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> new file mode 100644
> index 0000000000..2f630b4b95
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> @@ -0,0 +1,52 @@
> +## @file
> +# A DXE_DRIVER providing SMRAM access by producing
> EFI_SMM_ACCESS2_PROTOCOL.
> +#
> +# X58 TSEG is expected to have been verified and set up by the SmmAccessPei
> +# driver.
> +#
> +# Copyright (C) 2013, 2015, Red Hat, Inc.
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SmmAccess2Dxe
> +  FILE_GUID                      = AC95AD3D-4366-44BF-9A62-E4B29D7A2206
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x00010400
> +  ENTRY_POINT                    = SmmAccess2DxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  SmmAccess2Dxe.c
> +  SmramInternal.c
> +  SmramInternal.h
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +  PcdLib
> +  PciLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEfiSmmAccess2ProtocolGuid   ## PRODUCES
> +
> +[FeaturePcd]
> +  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> new file mode 100644
> index 0000000000..1d3b028c85
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> @@ -0,0 +1,64 @@
> +## @file
> +# A PEIM with the following responsibilities:
> +#
> +# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
> +# - verify & configure the X58 TSEG in the entry point,
> +# - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and
> expose
> +#   it via the gEfiAcpiVariableGuid GUIDed HOB.
> +#
> +# Copyright (C) 2013, 2015, Red Hat, Inc.
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SmmAccessPei
> +  FILE_GUID                      = 6C0E75B4-B0B9-44D1-8210-3377D7B4E066
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SmmAccessPeiEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  SmmAccessPei.c
> +  SmramInternal.c
> +  SmramInternal.h
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +
> +[Guids]
> +  gEfiAcpiVariableGuid
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  HobLib
> +  IoLib
> +  PcdLib
> +  PciLib
> +  PeiServicesLib
> +  PeimEntryPoint
> +
> +[FeaturePcd]
> +  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> +
> +[FixedPcd]
> +  gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
> +
> +[Ppis]
> +  gPeiSmmAccessPpiGuid           ## PRODUCES
> +
> +[Depex]
> +  gEfiPeiMemoryDiscoveredPpiGuid
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> new file mode 100644
> index 0000000000..43a79b295f
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> @@ -0,0 +1,81 @@
> +/** @file
> +  Functions and types shared by the SMM accessor PEI and DXE modules.
> +
> +  Copyright (C) 2015, Red Hat, Inc.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Pi/PiMultiPhase.h>
> +
> +//
> +// We'll have two SMRAM ranges.
> +//
> +// The first is a tiny one that hosts an SMM_S3_RESUME_STATE object, to be
> +// filled in by the CPU SMM driver during normal boot, for the PEI instance of
> +// the LockBox library (which will rely on the object during S3 resume).
> +//
> +// The other SMRAM range is the main one, for the SMM core and the SMM
> drivers.
> +//
> +typedef enum {
> +  DescIdxSmmS3ResumeState = 0,
> +  DescIdxMain             = 1,
> +  DescIdxCount            = 2
> +} DESCRIPTOR_INDEX;
> +
> +/**
> +  Read the MCH_SMRAM and ESMRAMC registers, and update the LockState
> and
> +  OpenState fields in the PEI_SMM_ACCESS_PPI /
> EFI_SMM_ACCESS2_PROTOCOL object,
> +  from the D_LCK and T_EN bits.
> +
> +  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member
> functions can rely on
> +  the LockState and OpenState fields being up-to-date on entry, and they need
> +  to restore the same invariant on exit, if they touch the bits in question.
> +
> +  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff SMRAM is
> +                         locked.
> +  @param[out] OpenState  Reflects the inverse of the T_EN bit on output; TRUE
> +                         iff SMRAM is open.
> +**/
> +VOID
> +GetStates (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +  );
> +
> +//
> +// The functions below follow the PEI_SMM_ACCESS_PPI and
> +// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and
> This
> +// pointers are removed (TSEG doesn't depend on them), and so is the
> +// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
> +//
> +// The LockState and OpenState members that are common to both
> +// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and
> updated in
> +// isolation from the rest of the (non-shared) members.
> +//
> +
> +EFI_STATUS
> +SmramAccessOpen (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +  );
> +
> +EFI_STATUS
> +SmramAccessClose (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +  );
> +
> +EFI_STATUS
> +SmramAccessLock (
> +  OUT    BOOLEAN *LockState,
> +  IN OUT BOOLEAN *OpenState
> +  );
> +
> +EFI_STATUS
> +SmramAccessGetCapabilities (
> +  IN BOOLEAN                  LockState,
> +  IN BOOLEAN                  OpenState,
> +  IN OUT UINTN                *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
> +  );
> --
> 2.16.2.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#46064): https://edk2.groups.io/g/devel/message/46064
Mute This Topic: https://groups.io/mt/32816095/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
Posted by David Wei 6 years, 3 months ago
Hi Mike,
Please see the updates online below. Please let me know if you have any more comments.

Thanks
David

-----Original Message-----
From: Kubacki, Michael A 
Sent: Monday, August 19, 2019 6:04 PM
To: Wei, David Y <david.y.wei@intel.com>; devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58

Feedback I could not find already noted elsewhere:

1. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c:
     There's some style issues throughout the file related to a missing space before opening parenthesis and parameters than span multiple lines.
     Some of these are pre-existing in OvmfPkg source. I don't think this is a must have.
Ydwei: done
2. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 265:
     "Confirm if QEMU supports SMRAM." to "Confirm if Simics supports SMRAM."
Ydwei: done
3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 275:
     "DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x \n", TopOfLowRam, TopOfLowRamMb));"
     Should be an informational message.
Ydwei: done
3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 283:
     "DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));"
     Should be an informational message.
Ydwei: done
4. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 300 & Line 301 - Should be informational messages as well.
Ydwei: done
5. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf: Is a dependency on OvmfPkg/OvmfPkg.dec required? This dependency should be avoided.
Ydwei: done
6. Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore: I don't think this should be an override but should exist in a similar manner
     as edk2/OvmfPkg/Sec. The code cannot be upstreamed as-is.
Ydwei: done
7. /Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c: Some of this messages should probably be verbose not informational.
Ydwei: done
8. /Silicon/Intel/SimicsX58SktPkg/SktPei.dsc: This file naming convention is unusual. SktPkgPei.dsc is more consistent. 
Ydwei: done
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 PM
> To: devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Kubacki, Michael A
> <michael.a.kubacki@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for
> SimicsX58
> 
> Add CPU Pkg for SimicsX58. It is added for simics QSP project support
> 
> Cc: Hao Wu <hao.a.wu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Cc: Agyeman Prince <prince.agyeman@intel.com>
> Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> 
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
>  .../Override/UefiCpuPkg/SecCore/SecMain.c          | 956
> +++++++++++++++++++++
>  .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c     | 148 ++++
>  .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c      | 353 ++++++++
>  .../SimicsX58SktPkg/Smm/Access/SmramInternal.c     | 199 +++++
>  .../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm |  45 +
>  .../Override/UefiCpuPkg/SecCore/SecMain.inf        |  71 ++
>  .../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm  |  45 +
>  Silicon/Intel/SimicsX58SktPkg/SktPei.dsc           |  18 +
>  .../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf |   9 +
>  .../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf  |  10 +
>  Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf    |  17 +
>  .../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf   |  16 +
>  .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf   |  52 ++
>  .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf    |  64 ++
>  .../SimicsX58SktPkg/Smm/Access/SmramInternal.h     |  81 ++
>  15 files changed, 2084 insertions(+)
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nas
> m
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nas
> m
>  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
>  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
>  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
>  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
>  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
>  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> 
> diff --git
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> new file mode 100644
> index 0000000000..c52d459ef2
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> @@ -0,0 +1,956 @@
> +/** @file
> +  Main SEC phase code.  Transitions to PEI.
> +
> +  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiCpuLib.h>
> +#include <Library/DebugAgentLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeCoffLib.h>
> +#include <Library/PeCoffGetEntryPointLib.h>
> +#include <Library/PeCoffExtraActionLib.h>
> +#include <Library/ExtractGuidedSectionLib.h>
> +#include <Library/LocalApicLib.h>
> +#include <Library/PciCf8Lib.h>
> +
> +#include <Ppi/TemporaryRamSupport.h>
> +#include <IndustryStandard/X58Ich10.h>
> +
> +#define SEC_IDT_ENTRY_COUNT  34
> +
> +typedef struct _SEC_IDT_TABLE {
> +  EFI_PEI_SERVICES          *PeiService;
> +  IA32_IDT_GATE_DESCRIPTOR  IdtTable[SEC_IDT_ENTRY_COUNT];
> +} SEC_IDT_TABLE;
> +
> +VOID
> +EFIAPI
> +SecStartupPhase2 (
> +  IN VOID                     *Context
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamMigration (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> +  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> +  IN UINTN                    CopySize
> +  );
> +
> +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
> +  TemporaryRamMigration
> +};
> +
> +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
> +  {
> +    (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> +    &gEfiTemporaryRamSupportPpiGuid,
> +    &mTemporaryRamSupportPpi
> +  },
> +};
> +
> +//
> +// Template of an IDT entry pointing to 10:FFFFFFE4h.
> +//
> +IA32_IDT_GATE_DESCRIPTOR  mIdtEntryTemplate = {
> +  {                                      // Bits
> +    0xffe4,                              // OffsetLow
> +    0x10,                                // Selector
> +    0x0,                                 // Reserved_0
> +    IA32_IDT_GATE_TYPE_INTERRUPT_32,     // GateType
> +    0xffff                               // OffsetHigh
> +  }
> +};
> +
> +/**
> +  Locates the main boot firmware volume.
> +
> +  @param[in,out]  BootFv  On input, the base of the BootFv
> +                          On output, the decompressed main firmware volume
> +
> +  @retval EFI_SUCCESS    The main firmware volume was located and
> decompressed
> +  @retval EFI_NOT_FOUND  The main firmware volume was not found
> +
> +**/
> +EFI_STATUS
> +FindMainFv (
> +  IN OUT  EFI_FIRMWARE_VOLUME_HEADER   **BootFv
> +  )
> +{
> +  EFI_FIRMWARE_VOLUME_HEADER  *Fv;
> +  UINTN                       Distance;
> +
> +  ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
> +
> +  Fv = *BootFv;
> +  Distance = (UINTN) (*BootFv)->FvLength;
> +  do {
> +    Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE);
> +    Distance += EFI_PAGE_SIZE;
> +    if (Distance > SIZE_32MB) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    if (Fv->Signature != EFI_FVH_SIGNATURE) {
> +      continue;
> +    }
> +
> +    if ((UINTN) Fv->FvLength > Distance) {
> +      continue;
> +    }
> +
> +    *BootFv = Fv;
> +    return EFI_SUCCESS;
> +
> +  } while (TRUE);
> +}
> +
> +/**
> +  Locates a section within a series of sections
> +  with the specified section type.
> +
> +  The Instance parameter indicates which instance of the section
> +  type to return. (0 is first instance, 1 is second...)
> +
> +  @param[in]   Sections        The sections to search
> +  @param[in]   SizeOfSections  Total size of all sections
> +  @param[in]   SectionType     The section type to locate
> +  @param[in]   Instance        The section instance number
> +  @param[out]  FoundSection    The FFS section if found
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsSectionInstance (
> +  IN  VOID                             *Sections,
> +  IN  UINTN                            SizeOfSections,
> +  IN  EFI_SECTION_TYPE                 SectionType,
> +  IN  UINTN                            Instance,
> +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> +  UINT32                      Size;
> +  EFI_PHYSICAL_ADDRESS        EndOfSections;
> +  EFI_COMMON_SECTION_HEADER   *Section;
> +  EFI_PHYSICAL_ADDRESS        EndOfSection;
> +
> +  //
> +  // Loop through the FFS file sections within the PEI Core FFS file
> +  //
> +  EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
> +  EndOfSections = EndOfSection + SizeOfSections;
> +  for (;;) {
> +    if (EndOfSection == EndOfSections) {
> +      break;
> +    }
> +    CurrentAddress = (EndOfSection + 3) & ~(3ULL);
> +    if (CurrentAddress >= EndOfSections) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> +    DEBUG ((EFI_D_INFO, "Section->Type: 0x%x\n", Section->Type));
> +
> +    Size = SECTION_SIZE (Section);
> +    if (Size < sizeof (*Section)) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    EndOfSection = CurrentAddress + Size;
> +    if (EndOfSection > EndOfSections) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    //
> +    // Look for the requested section type
> +    //
> +    if (Section->Type == SectionType) {
> +      if (Instance == 0) {
> +        *FoundSection = Section;
> +        return EFI_SUCCESS;
> +      } else {
> +        Instance--;
> +      }
> +    }
> +    DEBUG ((EFI_D_INFO, "Section->Type (0x%x) != SectionType (0x%x)\n",
> Section->Type, SectionType));
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  Locates a section within a series of sections
> +  with the specified section type.
> +
> +  @param[in]   Sections        The sections to search
> +  @param[in]   SizeOfSections  Total size of all sections
> +  @param[in]   SectionType     The section type to locate
> +  @param[out]  FoundSection    The FFS section if found
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsSectionInSections (
> +  IN  VOID                             *Sections,
> +  IN  UINTN                            SizeOfSections,
> +  IN  EFI_SECTION_TYPE                 SectionType,
> +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> +  )
> +{
> +  return FindFfsSectionInstance (
> +           Sections,
> +           SizeOfSections,
> +           SectionType,
> +           0,
> +           FoundSection
> +           );
> +}
> +
> +/**
> +  Locates a FFS file with the specified file type and a section
> +  within that file with the specified section type.
> +
> +  @param[in]   Fv            The firmware volume to search
> +  @param[in]   FileType      The file type to locate
> +  @param[in]   SectionType   The section type to locate
> +  @param[out]  FoundSection  The FFS section if found
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsFileAndSection (
> +  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
> +  IN  EFI_FV_FILETYPE                  FileType,
> +  IN  EFI_SECTION_TYPE                 SectionType,
> +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> +  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
> +  EFI_FFS_FILE_HEADER         *File;
> +  UINT32                      Size;
> +  EFI_PHYSICAL_ADDRESS        EndOfFile;
> +
> +  if (Fv->Signature != EFI_FVH_SIGNATURE) {
> +    DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n",
> Fv));
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> +
> +  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
> +  EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
> +
> +  //
> +  // Loop through the FFS files in the Boot Firmware Volume
> +  //
> +  for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
> +
> +    CurrentAddress = (EndOfFile + 7) & ~(7ULL);
> +    if (CurrentAddress > EndOfFirmwareVolume) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> +    Size = *(UINT32*) File->Size & 0xffffff;
> +    if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +    DEBUG ((EFI_D_INFO, "File->Type: 0x%x\n", File->Type));
> +
> +    EndOfFile = CurrentAddress + Size;
> +    if (EndOfFile > EndOfFirmwareVolume) {
> +      return EFI_VOLUME_CORRUPTED;
> +    }
> +
> +    //
> +    // Look for the request file type
> +    //
> +    if (File->Type != FileType) {
> +      DEBUG ((EFI_D_INFO, "File->Type (0x%x) != FileType (0x%x)\n", File->Type,
> FileType));
> +      continue;
> +    }
> +
> +    Status = FindFfsSectionInSections (
> +               (VOID*) (File + 1),
> +               (UINTN) EndOfFile - (UINTN) (File + 1),
> +               SectionType,
> +               FoundSection
> +               );
> +    if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
> +      return Status;
> +    }
> +  }
> +}
> +
> +/**
> +  Locates the compressed main firmware volume and decompresses it.
> +
> +  @param[in,out]  Fv            On input, the firmware volume to search
> +                                On output, the decompressed BOOT/PEI FV
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +DecompressMemFvs (
> +  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **Fv
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  EFI_GUID_DEFINED_SECTION          *Section;
> +  UINT32                            OutputBufferSize;
> +  UINT32                            ScratchBufferSize;
> +  UINT16                            SectionAttribute;
> +  UINT32                            AuthenticationStatus;
> +  VOID                              *OutputBuffer;
> +  VOID                              *ScratchBuffer;
> +  EFI_COMMON_SECTION_HEADER         *FvSection;
> +  EFI_FIRMWARE_VOLUME_HEADER        *PeiMemFv;
> +  EFI_FIRMWARE_VOLUME_HEADER        *DxeMemFv;
> +  UINT32                            FvHeaderSize;
> +  UINT32                            FvSectionSize;
> +
> +  FvSection = (EFI_COMMON_SECTION_HEADER*) NULL;
> +
> +  DEBUG ((EFI_D_INFO, "Find and decompress FV image.\n"));
> +  Status = FindFfsFileAndSection (
> +             *Fv,
> +             EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
> +             EFI_SECTION_GUID_DEFINED,
> +             (EFI_COMMON_SECTION_HEADER**) &Section
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
> +    return Status;
> +  }
> +
> +  Status = ExtractGuidedSectionGetInfo (
> +             Section,
> +             &OutputBufferSize,
> +             &ScratchBufferSize,
> +             &SectionAttribute
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
> +    return Status;
> +  }
> +
> +  OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32
> (PcdSimicsDxeMemFvBase) + SIZE_1MB);
> +  ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize,
> SIZE_1MB);
> +
> +  DEBUG ((EFI_D_INFO, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32
> (PcdSimicsDxeMemFvBase)));
> +  DEBUG ((EFI_D_INFO, "OutputBuffer: 0x%x\n", OutputBuffer));
> +  DEBUG ((EFI_D_INFO, "OutputBufferSize: 0x%x\n", OutputBufferSize));
> +  DEBUG ((EFI_D_INFO, "ScratchBuffer: 0x%x\n", ScratchBuffer));
> +  DEBUG ((EFI_D_INFO, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
> +  DEBUG ((EFI_D_INFO, "PcdSimicsDecompressionScratchEnd: 0x%x\n",
> PcdGet32 (PcdSimicsDecompressionScratchEnd)));
> +
> +  DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x
> ScratchBuffer@%p+0x%x "
> +    "PcdSimicsDecompressionScratchEnd=0x%x\n", __FUNCTION__,
> OutputBuffer,
> +    OutputBufferSize, ScratchBuffer, ScratchBufferSize,
> +    PcdGet32 (PcdSimicsDecompressionScratchEnd)));
> +  ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==
> +    PcdGet32 (PcdSimicsDecompressionScratchEnd));
> +
> +  Status = ExtractGuidedSectionDecode (
> +             Section,
> +             &OutputBuffer,
> +             ScratchBuffer,
> +             &AuthenticationStatus
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
> +    return Status;
> +  }
> +
> +  Status = FindFfsSectionInstance (
> +             OutputBuffer,
> +             OutputBufferSize,
> +             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
> +             0,
> +             &FvSection
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));
> +    return Status;
> +  }
> +
> +  ASSERT (SECTION_SIZE (FvSection) ==
> +          (PcdGet32 (PcdSimicsPeiMemFvSize) + sizeof (*FvSection)));
> +  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
> +
> +  PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> (PcdSimicsPeiMemFvBase);
> +  CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32
> (PcdSimicsPeiMemFvSize));
> +
> +  if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {
> +    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header
> signature\n", PeiMemFv));
> +    CpuDeadLoop ();
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> +
> +  Status = FindFfsSectionInstance (
> +             OutputBuffer,
> +             OutputBufferSize,
> +             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
> +             1,
> +             &FvSection
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));
> +    return Status;
> +  }
> +
> +  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
> +
> +  if (IS_SECTION2 (FvSection)) {
> +    FvSectionSize = SECTION2_SIZE (FvSection);
> +    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
> +  } else {
> +    FvSectionSize = SECTION_SIZE (FvSection);
> +    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
> +  }
> +
> +  ASSERT (FvSectionSize == (PcdGet32 (PcdSimicsDxeMemFvSize) +
> FvHeaderSize));
> +
> +  DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> (PcdSimicsDxeMemFvBase);
> +  CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize),
> PcdGet32 (PcdSimicsDxeMemFvSize));
> +
> +  if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
> +    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header
> signature\n", DxeMemFv));
> +    CpuDeadLoop ();
> +    return EFI_VOLUME_CORRUPTED;
> +  }
> +
> +  *Fv = PeiMemFv;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Locates the PEI Core entry point address
> +
> +  @param[in]  Fv                 The firmware volume to search
> +  @param[out] PeiCoreEntryPoint  The entry point of the PEI Core image
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindPeiCoreImageBaseInFv (
> +  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
> +  OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_COMMON_SECTION_HEADER   *Section;
> +
> +  DEBUG ((EFI_D_ERROR, "Find PEI Core image.\n"));
> +  Status = FindFfsFileAndSection (
> +             Fv,
> +             EFI_FV_FILETYPE_PEI_CORE,
> +             EFI_SECTION_PE32,
> +             &Section
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Status = FindFfsFileAndSection (
> +               Fv,
> +               EFI_FV_FILETYPE_PEI_CORE,
> +               EFI_SECTION_TE,
> +               &Section
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
> +      return Status;
> +    }
> +  }
> +
> +  *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
> +  DEBUG ((EFI_D_INFO, "PEI core image base 0x%016LX.\n",
> *PeiCoreImageBase));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Reads 8-bits of CMOS data.
> +
> +  Reads the 8-bits of CMOS data at the location specified by Index.
> +  The 8-bit read value is returned.
> +
> +  @param  Index  The CMOS location to read.
> +
> +  @return The value read.
> +
> +**/
> +STATIC
> +UINT8
> +CmosRead8 (
> +  IN UINTN        Index
> +  )
> +{
> +  IoWrite8 (0x70, (UINT8) Index);
> +  return IoRead8 (0x71);
> +}
> +
> +
> +STATIC
> +BOOLEAN
> +IsS3Resume (
> +  VOID
> +  )
> +{
> +  DEBUG((EFI_D_INFO, "modeValue = %x\n",
> IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
> +  return (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5);
> +}
> +
> +
> +STATIC
> +EFI_STATUS
> +GetS3ResumePeiFv (
> +  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **PeiFv
> +  )
> +{
> +  *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> (PcdSimicsPeiMemFvBase);
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Locates the PEI Core entry point address
> +
> +  @param[in,out]  Fv                 The firmware volume to search
> +  @param[out]     PeiCoreEntryPoint  The entry point of the PEI Core image
> +
> +  @retval EFI_SUCCESS           The file and section was found
> +  @retval EFI_NOT_FOUND         The file and section was not found
> +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> +
> +**/
> +VOID
> +FindPeiCoreImageBase (
> +  IN OUT  EFI_FIRMWARE_VOLUME_HEADER       **BootFv,
> +     OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> +  )
> +{
> +  BOOLEAN S3Resume;
> +
> +  *PeiCoreImageBase = 0;
> +
> +  S3Resume = IsS3Resume ();
> +  if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
> +    //
> +    // A malicious runtime OS may have injected something into our previously
> +    // decoded PEI FV, but we don't care about that unless SMM/SMRAM is
> required.
> +    //
> +    DEBUG ((EFI_D_INFO, "SEC: S3 resume\n"));
> +    GetS3ResumePeiFv (BootFv);
> +  } else {
> +    //
> +    // We're either not resuming, or resuming "securely" -- we'll decompress
> +    // both PEI FV and DXE FV from pristine flash.
> +    //
> +    DEBUG ((EFI_D_INFO, "SEC: %a\n",
> +      S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"));
> +    FindMainFv (BootFv);
> +
> +    DecompressMemFvs (BootFv);
> +  }
> +
> +  FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
> +}
> +
> +/**
> +  Find core image base.
> +
> +**/
> +EFI_STATUS
> +FindImageBase (
> +  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
> +  OUT EFI_PHYSICAL_ADDRESS             *SecCoreImageBase
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> +  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
> +  EFI_FFS_FILE_HEADER         *File;
> +  UINT32                      Size;
> +  EFI_PHYSICAL_ADDRESS        EndOfFile;
> +  EFI_COMMON_SECTION_HEADER   *Section;
> +  EFI_PHYSICAL_ADDRESS        EndOfSection;
> +
> +  *SecCoreImageBase = 0;
> +
> +  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)
> BootFirmwareVolumePtr;
> +  EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr-
> >FvLength;
> +
> +  //
> +  // Loop through the FFS files in the Boot Firmware Volume
> +  //
> +  for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ;
> ) {
> +
> +    CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
> +    if (CurrentAddress > EndOfFirmwareVolume) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> +    Size = *(UINT32*) File->Size & 0xffffff;
> +    if (Size < sizeof (*File)) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    EndOfFile = CurrentAddress + Size;
> +    if (EndOfFile > EndOfFirmwareVolume) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    //
> +    // Look for SEC Core
> +    //
> +    if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {
> +      continue;
> +    }
> +
> +    //
> +    // Loop through the FFS file sections within the FFS file
> +    //
> +    EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1);
> +    for (;;) {
> +      CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
> +      Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> +
> +      Size = *(UINT32*) Section->Size & 0xffffff;
> +      if (Size < sizeof (*Section)) {
> +        return EFI_NOT_FOUND;
> +      }
> +
> +      EndOfSection = CurrentAddress + Size;
> +      if (EndOfSection > EndOfFile) {
> +        return EFI_NOT_FOUND;
> +      }
> +
> +      //
> +      // Look for executable sections
> +      //
> +      if (Section->Type == EFI_SECTION_PE32 || Section->Type ==
> EFI_SECTION_TE) {
> +        if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
> +          *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) (Section + 1);
> +        }
> +        break;
> +      }
> +    }
> +
> +    //
> +    // SEC Core image found
> +    //
> +    if (*SecCoreImageBase != 0) {
> +      return EFI_SUCCESS;
> +    }
> +  }
> +}
> +
> +/*
> +  Find and return Pei Core entry point.
> +
> +  It also find SEC and PEI Core file debug information. It will report them if
> +  remote debug is enabled.
> +
> +**/
> +VOID
> +FindAndReportEntryPoints (
> +  IN  EFI_FIRMWARE_VOLUME_HEADER       **BootFirmwareVolumePtr,
> +  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
> +  )
> +{
> +  EFI_STATUS                       Status;
> +  EFI_PHYSICAL_ADDRESS             SecCoreImageBase;
> +  EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
> +  PE_COFF_LOADER_IMAGE_CONTEXT     ImageContext;
> +
> +  //
> +  // Find SEC Core and PEI Core image base
> +   //
> +  Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
> +
> +  ZeroMem ((VOID *) &ImageContext, sizeof
> (PE_COFF_LOADER_IMAGE_CONTEXT));
> +  //
> +  // Report SEC Core debug information when remote debug is enabled
> +  //
> +  ImageContext.ImageAddress = SecCoreImageBase;
> +  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN)
> ImageContext.ImageAddress);
> +  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
> +
> +  //
> +  // Report PEI Core debug information when remote debug is enabled
> +  //
> +  ImageContext.ImageAddress =
> (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
> +  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN)
> ImageContext.ImageAddress);
> +  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
> +
> +  //
> +  // Find PEI Core entry point
> +  //
> +  Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase,
> (VOID**) PeiCoreEntryPoint);
> +  if (EFI_ERROR (Status)) {
> +    *PeiCoreEntryPoint = 0;
> +  }
> +
> +  return;
> +}
> +
> +VOID
> +EFIAPI
> +SecCoreStartupWithStack (
> +  IN EFI_FIRMWARE_VOLUME_HEADER       *BootFv,
> +  IN VOID                             *TopOfCurrentStack
> +  )
> +{
> +  EFI_SEC_PEI_HAND_OFF        SecCoreData;
> +  SEC_IDT_TABLE               IdtTableInStack;
> +  IA32_DESCRIPTOR             IdtDescriptor;
> +  UINT32                      Index;
> +  volatile UINT8              *Table;
> +
> +  //
> +  // Initialize floating point operating environment
> +  // to be compliant with UEFI spec.
> +  //
> +  InitializeFloatingPointUnits ();
> +
> +  //
> +  // Initialize the PCIe Configuration base register.
> +  //
> +  PciCf8Write32 (PCI_CF8_LIB_ADDRESS (0xFF, 0, 1, 0x50), 0xE0000001);
> +
> +  //
> +  // To ensure SMM can't be compromised on S3 resume, we must force re-init
> of
> +  // the BaseExtractGuidedSectionLib. Since this is before library contructors
> +  // are called, we must use a loop rather than SetMem.
> +  //
> +  Table = (UINT8*)(UINTN)FixedPcdGet64
> (PcdGuidedExtractHandlerTableAddress);
> +  for (Index = 0;
> +       Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
> +       ++Index) {
> +    Table[Index] = 0;
> +  }
> +
> +  ProcessLibraryConstructorList (NULL, NULL);
> +
> +  DEBUG ((EFI_D_INFO,
> +    "SecCoreStartupWithStack(0x%x, 0x%x)\n",
> +    (UINT32)(UINTN)BootFv,
> +    (UINT32)(UINTN)TopOfCurrentStack
> +    ));
> +
> +  //
> +  // Initialize IDT
> +  //
> +  IdtTableInStack.PeiService = NULL;
> +  for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
> +    CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof
> (mIdtEntryTemplate));
> +  }
> +
> +  IdtDescriptor.Base  = (UINTN)&IdtTableInStack.IdtTable;
> +  IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
> +
> +  AsmWriteIdtr (&IdtDescriptor);
> +
> +#if defined (MDE_CPU_X64)
> +  //
> +  // ASSERT that the Page Tables were set by the reset vector code to
> +  // the address we expect.
> +  //
> +  ASSERT (AsmReadCr3 () == (UINTN) PcdGet32
> (PcdSimicsSecPageTablesBase));
> +#endif
> +
> +  //
> +  // |-------------|       <-- TopOfCurrentStack
> +  // |   Stack     | 32k
> +  // |-------------|
> +  // |    Heap     | 32k
> +  // |-------------|       <-- SecCoreData.TemporaryRamBase
> +  //
> +
> +  ASSERT ((UINTN) (PcdGet32 (PcdSimicsSecPeiTempRamBase) +
> +                   PcdGet32 (PcdSimicsSecPeiTempRamSize)) ==
> +          (UINTN) TopOfCurrentStack);
> +
> +  //
> +  // Initialize SEC hand-off state
> +  //
> +  SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
> +
> +  SecCoreData.TemporaryRamSize       = (UINTN) PcdGet32
> (PcdSimicsSecPeiTempRamSize);
> +  SecCoreData.TemporaryRamBase       = (VOID*)((UINT8 *)TopOfCurrentStack
> - SecCoreData.TemporaryRamSize);
> +
> +  SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
> +  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize >>
> 1;
> +
> +  SecCoreData.StackBase              = (UINT8 *)SecCoreData.TemporaryRamBase +
> SecCoreData.PeiTemporaryRamSize;
> +  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize >> 1;
> +
> +  SecCoreData.BootFirmwareVolumeBase = BootFv;
> +  SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> +
> +  //
> +  // Make sure the 8259 is masked before initializing the Debug Agent and the
> debug timer is enabled
> +  //
> +  IoWrite8 (0x21, 0xff);
> +  IoWrite8 (0xA1, 0xff);
> +
> +  //
> +  // Initialize Local APIC Timer hardware and disable Local APIC Timer
> +  // interrupts before initializing the Debug Agent and the debug timer is
> +  // enabled.
> +  //
> +  InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
> +  DisableApicTimerInterrupt ();
> +
> +  //
> +  // Initialize Debug Agent to support source level debug in SEC/PEI phases
> before memory ready.
> +  //
> +  InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData,
> SecStartupPhase2);
> +}
> +
> +/**
> +  Caller provided function to be invoked at the end of InitializeDebugAgent().
> +
> +  Entry point to the C language phase of SEC. After the SEC assembly
> +  code has initialized some temporary memory and set up the stack,
> +  the control is transferred to this function.
> +
> +  @param[in] Context    The first input parameter of InitializeDebugAgent().
> +
> +**/
> +VOID
> +EFIAPI
> +SecStartupPhase2(
> +  IN VOID                     *Context
> +  )
> +{
> +  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
> +  EFI_FIRMWARE_VOLUME_HEADER  *BootFv;
> +  EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
> +
> +  SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
> +
> +  //
> +  // Find PEI Core entry point. It will report SEC and Pei Core debug information
> if remote debug
> +  // is enabled.
> +  //
> +  BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData-
> >BootFirmwareVolumeBase;
> +  FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
> +  SecCoreData->BootFirmwareVolumeBase = BootFv;
> +  SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> +
> +  //
> +  // Transfer the control to the PEI core
> +  //
> +  (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR
> *)&mPrivateDispatchTable);
> +
> +  //
> +  // If we get here then the PEI Core returned, which is not recoverable.
> +  //
> +  ASSERT (FALSE);
> +  CpuDeadLoop ();
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamMigration (
> +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> +  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> +  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> +  IN UINTN                    CopySize
> +  )
> +{
> +  IA32_DESCRIPTOR                  IdtDescriptor;
> +  VOID                             *OldHeap;
> +  VOID                             *NewHeap;
> +  VOID                             *OldStack;
> +  VOID                             *NewStack;
> +  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  DebugAgentContext;
> +  BOOLEAN                          OldStatus;
> +  BASE_LIBRARY_JUMP_BUFFER         JumpBuffer;
> +
> +  DEBUG ((EFI_D_INFO,
> +    "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
> +    TemporaryMemoryBase,
> +    PermanentMemoryBase,
> +    (UINT64)CopySize
> +    ));
> +
> +  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
> +  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
> +
> +  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
> +  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
> +
> +  DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap -
> (UINTN)OldHeap;
> +  DebugAgentContext.StackMigrateOffset = (UINTN)NewStack -
> (UINTN)OldStack;
> +
> +  OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
> +  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *)
> &DebugAgentContext, NULL);
> +
> +  //
> +  // Migrate Heap
> +  //
> +  CopyMem (NewHeap, OldHeap, CopySize >> 1);
> +
> +  //
> +  // Migrate Stack
> +  //
> +  CopyMem (NewStack, OldStack, CopySize >> 1);
> +
> +  //
> +  // Rebase IDT table in permanent memory
> +  //
> +  AsmReadIdtr (&IdtDescriptor);
> +  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack +
> (UINTN)NewStack;
> +
> +  AsmWriteIdtr (&IdtDescriptor);
> +
> +  //
> +  // Use SetJump()/LongJump() to switch to a new stack.
> +  //
> +  if (SetJump (&JumpBuffer) == 0) {
> +#if defined (MDE_CPU_IA32)
> +    JumpBuffer.Esp = JumpBuffer.Esp +
> DebugAgentContext.StackMigrateOffset;
> +#endif
> +#if defined (MDE_CPU_X64)
> +    JumpBuffer.Rsp = JumpBuffer.Rsp +
> DebugAgentContext.StackMigrateOffset;
> +#endif
> +    LongJump (&JumpBuffer, (UINTN)-1);
> +  }
> +
> +  SaveAndSetDebugTimerInterrupt (OldStatus);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> new file mode 100644
> index 0000000000..771fddb487
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> @@ -0,0 +1,148 @@
> +/** @file
> +  A DXE_DRIVER providing SMRAM access by producing
> EFI_SMM_ACCESS2_PROTOCOL.
> +
> +  X58 TSEG is expected to have been verified and set up by the SmmAccessPei
> +  driver.
> +
> +  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
> +  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/SmmAccess2.h>
> +
> +#include "SmramInternal.h"
> +
> +/**
> +  Opens the SMRAM area to be accessible by a boot-service driver.
> +
> +  This function "opens" SMRAM so that it is visible while not inside of SMM.
> +  The function should return EFI_UNSUPPORTED if the hardware does not
> support
> +  hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the
> SMRAM
> +  configuration is locked.
> +
> +  @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS       The operation was successful.
> +  @retval EFI_UNSUPPORTED   The system does not support opening and
> closing of
> +                            SMRAM.
> +  @retval EFI_DEVICE_ERROR  SMRAM cannot be opened, perhaps because it is
> +                            locked.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccess2DxeOpen (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  )
> +{
> +  return SmramAccessOpen (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Inhibits access to the SMRAM.
> +
> +  This function "closes" SMRAM so that it is not visible while outside of SMM.
> +  The function should return EFI_UNSUPPORTED if the hardware does not
> support
> +  hiding of SMRAM.
> +
> +  @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS       The operation was successful.
> +  @retval EFI_UNSUPPORTED   The system does not support opening and
> closing of
> +                            SMRAM.
> +  @retval EFI_DEVICE_ERROR  SMRAM cannot be closed.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccess2DxeClose (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  )
> +{
> +  return SmramAccessClose (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Inhibits access to the SMRAM.
> +
> +  This function prohibits access to the SMRAM region.  This function is usually
> +  implemented such that it is a write-once operation.
> +
> +  @param[in] This          The EFI_SMM_ACCESS2_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS      The device was successfully locked.
> +  @retval EFI_UNSUPPORTED  The system does not support locking of SMRAM.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccess2DxeLock (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  )
> +{
> +  return SmramAccessLock (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Queries the memory controller for the possible regions that will support
> +  SMRAM.
> +
> +  @param[in]     This           The EFI_SMM_ACCESS2_PROTOCOL instance.
> +  @param[in,out] SmramMapSize   A pointer to the size, in bytes, of the
> +                                SmramMemoryMap buffer.
> +  @param[in,out] SmramMap       A pointer to the buffer in which firmware
> +                                places the current memory map.
> +
> +  @retval EFI_SUCCESS           The chipset supported the given resource.
> +  @retval EFI_BUFFER_TOO_SMALL  The SmramMap parameter was too small.
> The
> +                                current buffer size needed to hold the memory
> +                                map is returned in SmramMapSize.
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccess2DxeGetCapabilities (
> +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +{
> +  return SmramAccessGetCapabilities (This->LockState, This->OpenState,
> +           SmramMapSize, SmramMap);
> +}
> +
> +//
> +// LockState and OpenState will be filled in by the entry point.
> +//
> +STATIC EFI_SMM_ACCESS2_PROTOCOL mAccess2 = {
> +  &SmmAccess2DxeOpen,
> +  &SmmAccess2DxeClose,
> +  &SmmAccess2DxeLock,
> +  &SmmAccess2DxeGetCapabilities
> +};
> +
> +//
> +// Entry point of this driver.
> +//
> +EFI_STATUS
> +EFIAPI
> +SmmAccess2DxeEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  //
> +  // This module should only be included if SMRAM support is required.
> +  //
> +  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
> +
> +  GetStates (&mAccess2.LockState, &mAccess2.OpenState);
> +  return gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
> +                &gEfiSmmAccess2ProtocolGuid, &mAccess2,
> +                NULL);
> +}
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> new file mode 100644
> index 0000000000..d07d88142a
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> @@ -0,0 +1,353 @@
> +/** @file
> +  A PEIM with the following responsibilities:
> +
> +  - verify & configure the X58 TSEG in the entry point,
> +  - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
> +  - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and
> expose
> +    it via the gEfiAcpiVariableGuid GUID HOB.
> +
> +  This PEIM runs from RAM, so we can write to variables with static storage
> +  duration.
> +
> +  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
> +  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Guid/AcpiS3Context.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Ppi/SmmAccess.h>
> +
> +#include <SimicsPlatforms.h>
> +
> +#include "SmramInternal.h"
> +
> +//
> +// PEI_SMM_ACCESS_PPI implementation.
> +//
> +
> +/**
> +  Opens the SMRAM area to be accessible by a PEIM driver.
> +
> +  This function "opens" SMRAM so that it is visible while not inside of SMM.
> +  The function should return EFI_UNSUPPORTED if the hardware does not
> support
> +  hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the
> SMRAM
> +  configuration is locked.
> +
> +  @param  PeiServices            General purpose services available to every
> +                                 PEIM.
> +  @param  This                   The pointer to the SMM Access Interface.
> +  @param  DescriptorIndex        The region of SMRAM to Open.
> +
> +  @retval EFI_SUCCESS            The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR       The region could not be opened because
> locked
> +                                 by chipset.
> +  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccessPeiOpen (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  )
> +{
> +  if (DescriptorIndex >= DescIdxCount) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // According to current practice, DescriptorIndex is not considered at all,
> +  // beyond validating it.
> +  //
> +  return SmramAccessOpen (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Inhibits access to the SMRAM.
> +
> +  This function "closes" SMRAM so that it is not visible while outside of SMM.
> +  The function should return EFI_UNSUPPORTED if the hardware does not
> support
> +  hiding of SMRAM.
> +
> +  @param  PeiServices              General purpose services available to every
> +                                   PEIM.
> +  @param  This                     The pointer to the SMM Access Interface.
> +  @param  DescriptorIndex          The region of SMRAM to Close.
> +
> +  @retval EFI_SUCCESS              The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR         The region could not be closed because
> +                                   locked by chipset.
> +  @retval EFI_INVALID_PARAMETER    The descriptor index was out of bounds.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccessPeiClose (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  )
> +{
> +  if (DescriptorIndex >= DescIdxCount) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // According to current practice, DescriptorIndex is not considered at all,
> +  // beyond validating it.
> +  //
> +  return SmramAccessClose (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Inhibits access to the SMRAM.
> +
> +  This function prohibits access to the SMRAM region.  This function is usually
> +  implemented such that it is a write-once operation.
> +
> +  @param  PeiServices              General purpose services available to every
> +                                   PEIM.
> +  @param  This                     The pointer to the SMM Access Interface.
> +  @param  DescriptorIndex          The region of SMRAM to Close.
> +
> +  @retval EFI_SUCCESS            The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR       The region could not be locked because at
> +                                 least one range is still open.
> +  @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccessPeiLock (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN UINTN                           DescriptorIndex
> +  )
> +{
> +  if (DescriptorIndex >= DescIdxCount) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // According to current practice, DescriptorIndex is not considered at all,
> +  // beyond validating it.
> +  //
> +  return SmramAccessLock (&This->LockState, &This->OpenState);
> +}
> +
> +/**
> +  Queries the memory controller for the possible regions that will support
> +  SMRAM.
> +
> +  @param  PeiServices           General purpose services available to every
> +                                PEIM.
> +  @param This                   The pointer to the SmmAccessPpi Interface.
> +  @param SmramMapSize           The pointer to the variable containing size of
> +                                the buffer to contain the description
> +                                information.
> +  @param SmramMap               The buffer containing the data describing the
> +                                Smram region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           The user provided a sufficiently-sized buffer.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +SmmAccessPeiGetCapabilities (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN PEI_SMM_ACCESS_PPI              *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +{
> +  return SmramAccessGetCapabilities (This->LockState, This->OpenState,
> +           SmramMapSize, SmramMap);
> +}
> +
> +//
> +// LockState and OpenState will be filled in by the entry point.
> +//
> +STATIC PEI_SMM_ACCESS_PPI mAccess = {
> +  &SmmAccessPeiOpen,
> +  &SmmAccessPeiClose,
> +  &SmmAccessPeiLock,
> +  &SmmAccessPeiGetCapabilities
> +};
> +
> +
> +STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +    &gPeiSmmAccessPpiGuid, &mAccess
> +  }
> +};
> +
> +
> +//
> +// Utility functions.
> +//
> +STATIC
> +UINT8
> +CmosRead8 (
> +  IN UINT8  Index
> +  )
> +{
> +  IoWrite8 (0x70, Index);
> +  return IoRead8 (0x71);
> +}
> +
> +STATIC
> +UINT32
> +GetSystemMemorySizeBelow4gb (
> +  VOID
> +  )
> +{
> +  UINT32 Cmos0x34;
> +  UINT32 Cmos0x35;
> +
> +  Cmos0x34 = CmosRead8 (0x34);
> +  Cmos0x35 = CmosRead8 (0x35);
> +
> +  return ((Cmos0x35 << 8 | Cmos0x34) << 16) + SIZE_16MB;
> +}
> +
> +
> +//
> +// Entry point of this driver.
> +//
> +EFI_STATUS
> +EFIAPI
> +SmmAccessPeiEntryPoint (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  UINT16               HostBridgeDevId;
> +  UINT32                EsmramcVal;
> +  UINT32               TopOfLowRam, TopOfLowRamMb;
> +  EFI_STATUS           Status;
> +  UINTN                SmramMapSize;
> +  EFI_SMRAM_DESCRIPTOR SmramMap[DescIdxCount];
> +  VOID                 *GuidHob;
> +
> +  //
> +  // This module should only be included if SMRAM support is required.
> +  //
> +  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
> +
> +  //
> +  // Verify if we're running on a X58 machine type.
> +  //
> +  HostBridgeDevId = PciRead16 (SIMICS_HOSTBRIDGE_DID);
> +  if (HostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
> +    DEBUG ((EFI_D_ERROR, "%a: no SMRAM with host bridge DID=0x%04x; only
> "
> +      "DID=0x%04x (X58) is supported\n", __FUNCTION__, HostBridgeDevId,
> +      INTEL_ICH10_DEVICE_ID));
> +    goto WrongConfig;
> +  }
> +
> +  //
> +  // Confirm if QEMU supports SMRAM.
> +  //
> +  // With no support for it, the ESMRAMC (Extended System Management RAM
> +  // Control) register reads as zero. If there is support, the cache-enable
> +  // bits are hard-coded as 1 by QEMU.
> +  //
> +
> +  TopOfLowRam = GetSystemMemorySizeBelow4gb ();
> +  ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
> +  TopOfLowRamMb = TopOfLowRam >> 20;
> +  DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x
> \n", TopOfLowRam, TopOfLowRamMb));
> +
> +
> +  //
> +  // Set Top of Low Usable DRAM.
> +  //
> +  PciWrite32 (DRAMC_REGISTER_X58(MCH_TOLUD),
> +               TopOfLowRam);
> +  DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n",
> PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));
> +
> +  //
> +  // Set TSEG Memory Base.
> +  //
> +  EsmramcVal = (TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) <<
> MCH_TSEGMB_MB_SHIFT;
> +  //
> +  // Set TSEG size, and disable TSEG visibility outside of SMM. Note that the
> +  // T_EN bit has inverse meaning; when T_EN is set, then TSEG visibility is
> +  // *restricted* to SMM.
> +  //
> +  EsmramcVal &= ~(UINT32)MCH_ESMRAMC_TSEG_MASK;
> +  EsmramcVal |= FixedPcdGet8 (PcdX58TsegMbytes) == 8 ?
> MCH_ESMRAMC_TSEG_8MB :
> +                FixedPcdGet8 (PcdX58TsegMbytes) == 2 ?
> MCH_ESMRAMC_TSEG_2MB :
> +                MCH_ESMRAMC_TSEG_1MB;
> +  EsmramcVal |= MCH_ESMRAMC_T_EN;
> +  PciWrite32(DRAMC_REGISTER_X58(MCH_TSEGMB), EsmramcVal);
> +  DEBUG((EFI_D_ERROR, "MCH_TSEGMB =0x%x; \n",
> PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
> +  DEBUG((EFI_D_ERROR, "MCH_TSEGMB_1 =0x%x; MCH_TSEGMB_2
> =0x%x;\n", ((TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) <<
> MCH_TSEGMB_MB_SHIFT), EsmramcVal));
> +
> +  //
> +  // Create the GUID HOB and point it to the first SMRAM range.
> +  //
> +  GetStates (&mAccess.LockState, &mAccess.OpenState);
> +  SmramMapSize = sizeof SmramMap;
> +  Status = SmramAccessGetCapabilities (mAccess.LockState,
> mAccess.OpenState,
> +             &SmramMapSize, SmramMap);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  DEBUG_CODE_BEGIN ();
> +  {
> +    UINTN Count;
> +    UINTN Idx;
> +
> +    Count = SmramMapSize / sizeof SmramMap[0];
> +    DEBUG ((EFI_D_VERBOSE, "%a: SMRAM map follows, %d entries\n",
> __FUNCTION__,
> +      (INT32)Count));
> +    DEBUG ((EFI_D_VERBOSE, "% 20a % 20a % 20a % 20a\n",
> "PhysicalStart(0x)",
> +      "PhysicalSize(0x)", "CpuStart(0x)", "RegionState(0x)"));
> +    for (Idx = 0; Idx < Count; ++Idx) {
> +      DEBUG ((EFI_D_VERBOSE, "% 20Lx % 20Lx % 20Lx % 20Lx\n",
> +        SmramMap[Idx].PhysicalStart, SmramMap[Idx].PhysicalSize,
> +        SmramMap[Idx].CpuStart, SmramMap[Idx].RegionState));
> +    }
> +  }
> +  DEBUG_CODE_END ();
> +
> +  GuidHob = BuildGuidHob (&gEfiAcpiVariableGuid,
> +    sizeof SmramMap[DescIdxSmmS3ResumeState]);
> +  if (GuidHob == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  CopyMem (GuidHob, &SmramMap[DescIdxSmmS3ResumeState],
> +    sizeof SmramMap[DescIdxSmmS3ResumeState]);
> +
> +  //
> +  // We're done. The next step should succeed, but even if it fails, we can't
> +  // roll back the above BuildGuidHob() allocation, because PEI doesn't support
> +  // releasing memory.
> +  //
> +  return PeiServicesInstallPpi (mPpiList);
> +
> +WrongConfig:
> +  //
> +  // We really don't want to continue in this case.
> +  //
> +  ASSERT (FALSE);
> +  CpuDeadLoop ();
> +  return EFI_UNSUPPORTED;
> +}
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> new file mode 100644
> index 0000000000..898fc25084
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> @@ -0,0 +1,199 @@
> +/** @file
> +  Functions and types shared by the SMM accessor PEI and DXE modules.
> +
> +  Copyright (C) 2015, Red Hat, Inc.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Guid/AcpiS3Context.h>
> +#include <IndustryStandard/X58Ich10.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PciLib.h>
> +
> +#include "SmramInternal.h"
> +
> +BOOLEAN gLockState;
> +BOOLEAN gOpenState;
> +
> +/**
> +  Read the MCH_SMRAM and ESMRAMC registers, and update the LockState
> and
> +  OpenState fields in the PEI_SMM_ACCESS_PPI /
> EFI_SMM_ACCESS2_PROTOCOL object,
> +  from the D_LCK and T_EN bits.
> +
> +  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member
> functions can rely on
> +  the LockState and OpenState fields being up-to-date on entry, and they need
> +  to restore the same invariant on exit, if they touch the bits in question.
> +
> +  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff SMRAM is
> +                         locked.
> +  @param[out] OpenState  Reflects the inverse of the T_EN bit on output; TRUE
> +                         iff SMRAM is open.
> +**/
> +VOID
> +GetStates (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +)
> +{
> +  UINT8 EsmramcVal;
> +
> +  EsmramcVal = PciRead8(DRAMC_REGISTER_X58(MCH_TSEGMB));
> +
> +  *OpenState = !(EsmramcVal & MCH_ESMRAMC_T_EN);
> +  *LockState = !*OpenState;
> +
> +  *OpenState = gOpenState;
> +  *LockState = gLockState;
> +}
> +
> +//
> +// The functions below follow the PEI_SMM_ACCESS_PPI and
> +// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and
> This
> +// pointers are removed (TSEG doesn't depend on them), and so is the
> +// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
> +//
> +// The LockState and OpenState members that are common to both
> +// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and
> updated in
> +// isolation from the rest of the (non-shared) members.
> +//
> +
> +EFI_STATUS
> +SmramAccessOpen (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +  )
> +{
> +
> +  //
> +  // Open TSEG by clearing T_EN.
> +  //
> +  PciAnd8(DRAMC_REGISTER_X58(MCH_TSEGMB),
> +    (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff));
> +
> +  gOpenState = TRUE;
> +  gLockState = !gOpenState;
> +
> +  GetStates (LockState, OpenState);
> +  if (!*OpenState) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +SmramAccessClose (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +  )
> +{
> +  //
> +  // Close TSEG by setting T_EN.
> +  //
> +  PciOr8(DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
> +
> +  gOpenState = FALSE;
> +  gLockState = !gOpenState;
> +
> +  GetStates (LockState, OpenState);
> +  if (*OpenState) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +SmramAccessLock (
> +  OUT    BOOLEAN *LockState,
> +  IN OUT BOOLEAN *OpenState
> +  )
> +{
> +  if (*OpenState) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Close & lock TSEG by setting T_EN and D_LCK.
> +  //
> +  PciOr8 (DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
> +
> +  gOpenState = FALSE;
> +  gLockState = !gOpenState;
> +
> +  GetStates (LockState, OpenState);
> +  if (*OpenState || !*LockState) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +SmramAccessGetCapabilities (
> +  IN BOOLEAN                  LockState,
> +  IN BOOLEAN                  OpenState,
> +  IN OUT UINTN                *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
> +  )
> +{
> +  UINTN  OriginalSize;
> +  UINT32 TsegMemoryBaseMb, TsegMemoryBase;
> +  UINT64 CommonRegionState;
> +  UINT8  TsegSizeBits;
> +
> +  OriginalSize  = *SmramMapSize;
> +  *SmramMapSize = DescIdxCount * sizeof *SmramMap;
> +  if (OriginalSize < *SmramMapSize) {
> +    return EFI_BUFFER_TOO_SMALL;
> +  }
> +
> +  //
> +  // Read the TSEG Memory Base register.
> +  //
> +  TsegMemoryBaseMb = PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB));
> +
> +  TsegMemoryBaseMb = 0xDF800000;
> +
> +  TsegMemoryBase = (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) <<
> 20;
> +
> +  //
> +  // Precompute the region state bits that will be set for all regions.
> +  //
> +  CommonRegionState = (OpenState ? EFI_SMRAM_OPEN :
> EFI_SMRAM_CLOSED) |
> +                      (LockState ? EFI_SMRAM_LOCKED : 0) |
> +                      EFI_CACHEABLE;
> +
> +  //
> +  // The first region hosts an SMM_S3_RESUME_STATE object. It is located at
> the
> +  // start of TSEG. We round up the size to whole pages, and we report it as
> +  // EFI_ALLOCATED, so that the SMM_CORE stays away from it.
> +  //
> +  SmramMap[DescIdxSmmS3ResumeState].PhysicalStart = TsegMemoryBase;
> +  SmramMap[DescIdxSmmS3ResumeState].CpuStart      = TsegMemoryBase;
> +  SmramMap[DescIdxSmmS3ResumeState].PhysicalSize  =
> +    EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof
> (SMM_S3_RESUME_STATE)));
> +  SmramMap[DescIdxSmmS3ResumeState].RegionState   =
> +    CommonRegionState | EFI_ALLOCATED;
> +
> +  //
> +  // Get the TSEG size bits from the ESMRAMC register.
> +  //
> +  TsegSizeBits = PciRead8 (DRAMC_REGISTER_X58(MCH_TSEGMB)) &
> +                            MCH_ESMRAMC_TSEG_MASK;
> +
> +  TsegSizeBits = MCH_ESMRAMC_TSEG_8MB;
> +
> +  //
> +  // The second region is the main one, following the first.
> +  //
> +  SmramMap[DescIdxMain].PhysicalStart =
> +    SmramMap[DescIdxSmmS3ResumeState].PhysicalStart +
> +    SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
> +  SmramMap[DescIdxMain].CpuStart =
> SmramMap[DescIdxMain].PhysicalStart;
> +  SmramMap[DescIdxMain].PhysicalSize =
> +    (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB :
> +     TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB :
> +     SIZE_1MB) - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
> +  SmramMap[DescIdxMain].RegionState = CommonRegionState;
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.n
> asm
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.
> nasm
> new file mode 100644
> index 0000000000..19ffb6f86d
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.
> nasm
> @@ -0,0 +1,45 @@
> +; @file
> +; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> +#include <Base.h>
> +
> +    SECTION .text
> +
> +extern ASM_PFX(SecCoreStartupWithStack)
> +
> +;
> +; SecCore Entry Point
> +;
> +; Processor is in flat protected mode
> +;
> +; @param[in]  EAX   Initial value of the EAX register (BIST: Built-in Self Test)
> +; @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
> +; @param[in]  EBP   Pointer to the start of the Boot Firmware Volume
> +;
> +; @return     None  This routine does not return
> +;
> +global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> +
> +    ;
> +    ; Load temporary RAM stack based on PCDs
> +    ;
> +    %define SEC_TOP_OF_STACK (FixedPcdGet32
> (PcdSimicsSecPeiTempRamBase) + \
> +                          FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
> +    mov     eax, SEC_TOP_OF_STACK
> +    mov     esp, eax
> +    nop
> +
> +    ;
> +    ; Setup parameters and call SecCoreStartupWithStack
> +    ;   [esp]   return address for call
> +    ;   [esp+4] BootFirmwareVolumePtr
> +    ;   [esp+8] TopOfCurrentStack
> +    ;
> +    push    eax
> +    push    ebp
> +    call    ASM_PFX(SecCoreStartupWithStack)
> +
> diff --git
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> new file mode 100644
> index 0000000000..ac993ac1ce
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> @@ -0,0 +1,71 @@
> +## @file
> +#  SEC Driver
> +#
> +# Copyright (c) 2008 - 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SecMain
> +  FILE_GUID                      = e67f156f-54c5-47f3-a35d-07c045881e14
> +  MODULE_TYPE                    = SEC
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SecMain
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> +#
> +
> +[Sources]
> +  SecMain.c
> +
> +[Sources.IA32]
> +  Ia32/SecEntry.nasm
> +
> +[Sources.X64]
> +  X64/SecEntry.nasm
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  BaseMemoryLib
> +  PeiServicesLib
> +  PcdLib
> +  UefiCpuLib
> +  DebugAgentLib
> +  IoLib
> +  PeCoffLib
> +  PeCoffGetEntryPointLib
> +  PeCoffExtraActionLib
> +  ExtractGuidedSectionLib
> +  LocalApicLib
> +  PciCf8Lib
> +
> +[Ppis]
> +  gEfiTemporaryRamSupportPpiGuid                # PPI ALWAYS_PRODUCED
> +
> +[Pcd]
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> +  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> +  gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> +
> +[FeaturePcd]
> +  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> diff --git
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> new file mode 100644
> index 0000000000..0eb86ec2ca
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> @@ -0,0 +1,45 @@
> +; @file
> +; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +
> +#include <Base.h>
> +
> +DEFAULT REL
> +SECTION .text
> +
> +extern ASM_PFX(SecCoreStartupWithStack)
> +
> +;
> +; SecCore Entry Point
> +;
> +; Processor is in flat protected mode
> +;
> +; @param[in]  RAX   Initial value of the EAX register (BIST: Built-in Self Test)
> +; @param[in]  DI    'BP': boot-strap processor, or 'AP': application processor
> +; @param[in]  RBP   Pointer to the start of the Boot Firmware Volume
> +;
> +; @return     None  This routine does not return
> +;
> +global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> +
> +    ;
> +    ; Load temporary RAM stack based on PCDs
> +    ;
> +    %define SEC_TOP_OF_STACK (FixedPcdGet32
> (PcdSimicsSecPeiTempRamBase) + \
> +                          FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
> +    mov     rsp, SEC_TOP_OF_STACK
> +    nop
> +
> +    ;
> +    ; Setup parameters and call SecCoreStartupWithStack
> +    ;   rcx: BootFirmwareVolumePtr
> +    ;   rdx: TopOfCurrentStack
> +    ;
> +    mov     rcx, rbp
> +    mov     rdx, rsp
> +    sub     rsp, 0x20
> +    call    ASM_PFX(SecCoreStartupWithStack)
> +
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> new file mode 100644
> index 0000000000..0be8be4966
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> @@ -0,0 +1,18 @@
> +## @file
> +#  Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +  #
> +  # SEC Phase modules
> +  #
> +  $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf {
> +    <LibraryClasses>
> +
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecom
> pressLib.inf
> +  }
> +  UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
> +  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> new file mode 100644
> index 0000000000..78eca21a43
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> @@ -0,0 +1,9 @@
> +## @file
> +#  Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> new file mode 100644
> index 0000000000..9f037e99d4
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> @@ -0,0 +1,10 @@
> +## @file
> +#  Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> new file mode 100644
> index 0000000000..596d633cd3
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> @@ -0,0 +1,17 @@
> +## @file
> +#  Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +#
> +# SEC Phase modules
> +#
> +# The code in this FV handles the initial firmware startup, and
> +# decompresses the PEI and DXE FVs which handles the rest of the boot
> sequence.
> +#
> +INF  RuleOverride=RESET_SECMAIN USE = IA32
> $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf
> +INF  RuleOverride=RESET_VECTOR USE = IA32
> UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> new file mode 100644
> index 0000000000..9004b9cb83
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> @@ -0,0 +1,16 @@
> +## @file
> +#  Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +#INF  $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuArchDxe/CpuArchDxe.inf
> +#INF  $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuMpDxe/CpuMpDxe.inf
> +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
> +  INF  $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf
> +  INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> +!endif
> +INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> new file mode 100644
> index 0000000000..2f630b4b95
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> @@ -0,0 +1,52 @@
> +## @file
> +# A DXE_DRIVER providing SMRAM access by producing
> EFI_SMM_ACCESS2_PROTOCOL.
> +#
> +# X58 TSEG is expected to have been verified and set up by the SmmAccessPei
> +# driver.
> +#
> +# Copyright (C) 2013, 2015, Red Hat, Inc.
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SmmAccess2Dxe
> +  FILE_GUID                      = AC95AD3D-4366-44BF-9A62-E4B29D7A2206
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  PI_SPECIFICATION_VERSION       = 0x00010400
> +  ENTRY_POINT                    = SmmAccess2DxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  SmmAccess2Dxe.c
> +  SmramInternal.c
> +  SmramInternal.h
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +  PcdLib
> +  PciLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEfiSmmAccess2ProtocolGuid   ## PRODUCES
> +
> +[FeaturePcd]
> +  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> new file mode 100644
> index 0000000000..1d3b028c85
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> @@ -0,0 +1,64 @@
> +## @file
> +# A PEIM with the following responsibilities:
> +#
> +# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
> +# - verify & configure the X58 TSEG in the entry point,
> +# - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG, and
> expose
> +#   it via the gEfiAcpiVariableGuid GUIDed HOB.
> +#
> +# Copyright (C) 2013, 2015, Red Hat, Inc.
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SmmAccessPei
> +  FILE_GUID                      = 6C0E75B4-B0B9-44D1-8210-3377D7B4E066
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SmmAccessPeiEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  SmmAccessPei.c
> +  SmramInternal.c
> +  SmramInternal.h
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +
> +[Guids]
> +  gEfiAcpiVariableGuid
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  HobLib
> +  IoLib
> +  PcdLib
> +  PciLib
> +  PeiServicesLib
> +  PeimEntryPoint
> +
> +[FeaturePcd]
> +  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> +
> +[FixedPcd]
> +  gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
> +
> +[Ppis]
> +  gPeiSmmAccessPpiGuid           ## PRODUCES
> +
> +[Depex]
> +  gEfiPeiMemoryDiscoveredPpiGuid
> diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> new file mode 100644
> index 0000000000..43a79b295f
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> @@ -0,0 +1,81 @@
> +/** @file
> +  Functions and types shared by the SMM accessor PEI and DXE modules.
> +
> +  Copyright (C) 2015, Red Hat, Inc.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Pi/PiMultiPhase.h>
> +
> +//
> +// We'll have two SMRAM ranges.
> +//
> +// The first is a tiny one that hosts an SMM_S3_RESUME_STATE object, to be
> +// filled in by the CPU SMM driver during normal boot, for the PEI instance of
> +// the LockBox library (which will rely on the object during S3 resume).
> +//
> +// The other SMRAM range is the main one, for the SMM core and the SMM
> drivers.
> +//
> +typedef enum {
> +  DescIdxSmmS3ResumeState = 0,
> +  DescIdxMain             = 1,
> +  DescIdxCount            = 2
> +} DESCRIPTOR_INDEX;
> +
> +/**
> +  Read the MCH_SMRAM and ESMRAMC registers, and update the LockState
> and
> +  OpenState fields in the PEI_SMM_ACCESS_PPI /
> EFI_SMM_ACCESS2_PROTOCOL object,
> +  from the D_LCK and T_EN bits.
> +
> +  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member
> functions can rely on
> +  the LockState and OpenState fields being up-to-date on entry, and they need
> +  to restore the same invariant on exit, if they touch the bits in question.
> +
> +  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff SMRAM is
> +                         locked.
> +  @param[out] OpenState  Reflects the inverse of the T_EN bit on output; TRUE
> +                         iff SMRAM is open.
> +**/
> +VOID
> +GetStates (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +  );
> +
> +//
> +// The functions below follow the PEI_SMM_ACCESS_PPI and
> +// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices and
> This
> +// pointers are removed (TSEG doesn't depend on them), and so is the
> +// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
> +//
> +// The LockState and OpenState members that are common to both
> +// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken and
> updated in
> +// isolation from the rest of the (non-shared) members.
> +//
> +
> +EFI_STATUS
> +SmramAccessOpen (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +  );
> +
> +EFI_STATUS
> +SmramAccessClose (
> +  OUT BOOLEAN *LockState,
> +  OUT BOOLEAN *OpenState
> +  );
> +
> +EFI_STATUS
> +SmramAccessLock (
> +  OUT    BOOLEAN *LockState,
> +  IN OUT BOOLEAN *OpenState
> +  );
> +
> +EFI_STATUS
> +SmramAccessGetCapabilities (
> +  IN BOOLEAN                  LockState,
> +  IN BOOLEAN                  OpenState,
> +  IN OUT UINTN                *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
> +  );
> --
> 2.16.2.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#46242): https://edk2.groups.io/g/devel/message/46242
Mute This Topic: https://groups.io/mt/32816095/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
Posted by Kubacki, Michael A 6 years, 3 months ago
Thanks David. No more comments for this patch.

> -----Original Message-----
> From: Wei, David Y
> Sent: Thursday, August 22, 2019 3:31 PM
> To: Kubacki, Michael A <michael.a.kubacki@intel.com>; devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for
> SimicsX58
> 
> Hi Mike,
> Please see the updates online below. Please let me know if you have any more
> comments.
> 
> Thanks
> David
> 
> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Monday, August 19, 2019 6:04 PM
> To: Wei, David Y <david.y.wei@intel.com>; devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for
> SimicsX58
> 
> Feedback I could not find already noted elsewhere:
> 
> 1. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c:
>      There's some style issues throughout the file related to a missing space
> before opening parenthesis and parameters than span multiple lines.
>      Some of these are pre-existing in OvmfPkg source. I don't think this is a
> must have.
> Ydwei: done
> 2. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 265:
>      "Confirm if QEMU supports SMRAM." to "Confirm if Simics supports
> SMRAM."
> Ydwei: done
> 3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 275:
>      "DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x
> \n", TopOfLowRam, TopOfLowRamMb));"
>      Should be an informational message.
> Ydwei: done
> 3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 283:
>      "DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n",
> PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));"
>      Should be an informational message.
> Ydwei: done
> 4. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 300 &
> Line 301 - Should be informational messages as well.
> Ydwei: done
> 5. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf: Is a
> dependency on OvmfPkg/OvmfPkg.dec required? This dependency should be
> avoided.
> Ydwei: done
> 6. Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore: I don't think
> this should be an override but should exist in a similar manner
>      as edk2/OvmfPkg/Sec. The code cannot be upstreamed as-is.
> Ydwei: done
> 7. /Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c:
> Some of this messages should probably be verbose not informational.
> Ydwei: done
> 8. /Silicon/Intel/SimicsX58SktPkg/SktPei.dsc: This file naming convention is
> unusual. SktPkgPei.dsc is more consistent.
> Ydwei: done
> > -----Original Message-----
> > From: Wei, David Y
> > Sent: Friday, August 9, 2019 3:47 PM
> > To: devel@edk2.groups.io
> > Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> > Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> > <prince.agyeman@intel.com>; Kubacki, Michael A
> > <michael.a.kubacki@intel.com>; Desimone, Nathaniel L
> > <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> > <michael.d.kinney@intel.com>
> > Subject: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for
> > SimicsX58
> >
> > Add CPU Pkg for SimicsX58. It is added for simics QSP project support
> >
> > Cc: Hao Wu <hao.a.wu@intel.com>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Ankit Sinha <ankit.sinha@intel.com>
> > Cc: Agyeman Prince <prince.agyeman@intel.com>
> > Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
> > Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> >
> > Signed-off-by: David Wei <david.y.wei@intel.com>
> > ---
> >  .../Override/UefiCpuPkg/SecCore/SecMain.c          | 956
> > +++++++++++++++++++++
> >  .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c     | 148 ++++
> >  .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c      | 353 ++++++++
> >  .../SimicsX58SktPkg/Smm/Access/SmramInternal.c     | 199 +++++
> >  .../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm |  45 +
> >  .../Override/UefiCpuPkg/SecCore/SecMain.inf        |  71 ++
> >  .../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm  |  45 +
> >  Silicon/Intel/SimicsX58SktPkg/SktPei.dsc           |  18 +
> >  .../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf |   9 +
> >  .../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf  |  10 +
> >  Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf    |  17 +
> >  .../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf   |  16 +
> >  .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf   |  52 ++
> >  .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf    |  64 ++
> >  .../SimicsX58SktPkg/Smm/Access/SmramInternal.h     |  81 ++
> >  15 files changed, 2084 insertions(+)
> >  create mode 100644
> > Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> >  create mode 100644
> > Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> >  create mode 100644
> > Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> >  create mode 100644
> > Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> >  create mode 100644
> >
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.n
> as
> > m
> >  create mode 100644
> > Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> >  create mode 100644
> >
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> as
> > m
> >  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> >  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> >  create mode 100644
> Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> >  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> >  create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> >  create mode 100644
> > Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> >  create mode 100644
> > Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> >  create mode 100644
> > Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> >
> > diff --git
> > a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> > b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> > new file mode 100644
> > index 0000000000..c52d459ef2
> > --- /dev/null
> > +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> > @@ -0,0 +1,956 @@
> > +/** @file
> > +  Main SEC phase code.  Transitions to PEI.
> > +
> > +  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
> > +  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <PiPei.h>
> > +
> > +#include <Library/PeimEntryPoint.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/UefiCpuLib.h>
> > +#include <Library/DebugAgentLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Library/PeCoffLib.h>
> > +#include <Library/PeCoffGetEntryPointLib.h>
> > +#include <Library/PeCoffExtraActionLib.h>
> > +#include <Library/ExtractGuidedSectionLib.h>
> > +#include <Library/LocalApicLib.h>
> > +#include <Library/PciCf8Lib.h>
> > +
> > +#include <Ppi/TemporaryRamSupport.h>
> > +#include <IndustryStandard/X58Ich10.h>
> > +
> > +#define SEC_IDT_ENTRY_COUNT  34
> > +
> > +typedef struct _SEC_IDT_TABLE {
> > +  EFI_PEI_SERVICES          *PeiService;
> > +  IA32_IDT_GATE_DESCRIPTOR  IdtTable[SEC_IDT_ENTRY_COUNT];
> > +} SEC_IDT_TABLE;
> > +
> > +VOID
> > +EFIAPI
> > +SecStartupPhase2 (
> > +  IN VOID                     *Context
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +TemporaryRamMigration (
> > +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> > +  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> > +  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> > +  IN UINTN                    CopySize
> > +  );
> > +
> > +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
> > +  TemporaryRamMigration
> > +};
> > +
> > +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
> > +  {
> > +    (EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > +    &gEfiTemporaryRamSupportPpiGuid,
> > +    &mTemporaryRamSupportPpi
> > +  },
> > +};
> > +
> > +//
> > +// Template of an IDT entry pointing to 10:FFFFFFE4h.
> > +//
> > +IA32_IDT_GATE_DESCRIPTOR  mIdtEntryTemplate = {
> > +  {                                      // Bits
> > +    0xffe4,                              // OffsetLow
> > +    0x10,                                // Selector
> > +    0x0,                                 // Reserved_0
> > +    IA32_IDT_GATE_TYPE_INTERRUPT_32,     // GateType
> > +    0xffff                               // OffsetHigh
> > +  }
> > +};
> > +
> > +/**
> > +  Locates the main boot firmware volume.
> > +
> > +  @param[in,out]  BootFv  On input, the base of the BootFv
> > +                          On output, the decompressed main firmware volume
> > +
> > +  @retval EFI_SUCCESS    The main firmware volume was located and
> > decompressed
> > +  @retval EFI_NOT_FOUND  The main firmware volume was not found
> > +
> > +**/
> > +EFI_STATUS
> > +FindMainFv (
> > +  IN OUT  EFI_FIRMWARE_VOLUME_HEADER   **BootFv
> > +  )
> > +{
> > +  EFI_FIRMWARE_VOLUME_HEADER  *Fv;
> > +  UINTN                       Distance;
> > +
> > +  ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
> > +
> > +  Fv = *BootFv;
> > +  Distance = (UINTN) (*BootFv)->FvLength;
> > +  do {
> > +    Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv -
> EFI_PAGE_SIZE);
> > +    Distance += EFI_PAGE_SIZE;
> > +    if (Distance > SIZE_32MB) {
> > +      return EFI_NOT_FOUND;
> > +    }
> > +
> > +    if (Fv->Signature != EFI_FVH_SIGNATURE) {
> > +      continue;
> > +    }
> > +
> > +    if ((UINTN) Fv->FvLength > Distance) {
> > +      continue;
> > +    }
> > +
> > +    *BootFv = Fv;
> > +    return EFI_SUCCESS;
> > +
> > +  } while (TRUE);
> > +}
> > +
> > +/**
> > +  Locates a section within a series of sections
> > +  with the specified section type.
> > +
> > +  The Instance parameter indicates which instance of the section
> > +  type to return. (0 is first instance, 1 is second...)
> > +
> > +  @param[in]   Sections        The sections to search
> > +  @param[in]   SizeOfSections  Total size of all sections
> > +  @param[in]   SectionType     The section type to locate
> > +  @param[in]   Instance        The section instance number
> > +  @param[out]  FoundSection    The FFS section if found
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindFfsSectionInstance (
> > +  IN  VOID                             *Sections,
> > +  IN  UINTN                            SizeOfSections,
> > +  IN  EFI_SECTION_TYPE                 SectionType,
> > +  IN  UINTN                            Instance,
> > +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> > +  )
> > +{
> > +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> > +  UINT32                      Size;
> > +  EFI_PHYSICAL_ADDRESS        EndOfSections;
> > +  EFI_COMMON_SECTION_HEADER   *Section;
> > +  EFI_PHYSICAL_ADDRESS        EndOfSection;
> > +
> > +  //
> > +  // Loop through the FFS file sections within the PEI Core FFS file
> > +  //
> > +  EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
> > +  EndOfSections = EndOfSection + SizeOfSections;
> > +  for (;;) {
> > +    if (EndOfSection == EndOfSections) {
> > +      break;
> > +    }
> > +    CurrentAddress = (EndOfSection + 3) & ~(3ULL);
> > +    if (CurrentAddress >= EndOfSections) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> > +    DEBUG ((EFI_D_INFO, "Section->Type: 0x%x\n", Section->Type));
> > +
> > +    Size = SECTION_SIZE (Section);
> > +    if (Size < sizeof (*Section)) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    EndOfSection = CurrentAddress + Size;
> > +    if (EndOfSection > EndOfSections) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    //
> > +    // Look for the requested section type
> > +    //
> > +    if (Section->Type == SectionType) {
> > +      if (Instance == 0) {
> > +        *FoundSection = Section;
> > +        return EFI_SUCCESS;
> > +      } else {
> > +        Instance--;
> > +      }
> > +    }
> > +    DEBUG ((EFI_D_INFO, "Section->Type (0x%x) != SectionType (0x%x)\n",
> > Section->Type, SectionType));
> > +  }
> > +
> > +  return EFI_NOT_FOUND;
> > +}
> > +
> > +/**
> > +  Locates a section within a series of sections
> > +  with the specified section type.
> > +
> > +  @param[in]   Sections        The sections to search
> > +  @param[in]   SizeOfSections  Total size of all sections
> > +  @param[in]   SectionType     The section type to locate
> > +  @param[out]  FoundSection    The FFS section if found
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindFfsSectionInSections (
> > +  IN  VOID                             *Sections,
> > +  IN  UINTN                            SizeOfSections,
> > +  IN  EFI_SECTION_TYPE                 SectionType,
> > +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> > +  )
> > +{
> > +  return FindFfsSectionInstance (
> > +           Sections,
> > +           SizeOfSections,
> > +           SectionType,
> > +           0,
> > +           FoundSection
> > +           );
> > +}
> > +
> > +/**
> > +  Locates a FFS file with the specified file type and a section
> > +  within that file with the specified section type.
> > +
> > +  @param[in]   Fv            The firmware volume to search
> > +  @param[in]   FileType      The file type to locate
> > +  @param[in]   SectionType   The section type to locate
> > +  @param[out]  FoundSection  The FFS section if found
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindFfsFileAndSection (
> > +  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
> > +  IN  EFI_FV_FILETYPE                  FileType,
> > +  IN  EFI_SECTION_TYPE                 SectionType,
> > +  OUT EFI_COMMON_SECTION_HEADER        **FoundSection
> > +  )
> > +{
> > +  EFI_STATUS                  Status;
> > +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> > +  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
> > +  EFI_FFS_FILE_HEADER         *File;
> > +  UINT32                      Size;
> > +  EFI_PHYSICAL_ADDRESS        EndOfFile;
> > +
> > +  if (Fv->Signature != EFI_FVH_SIGNATURE) {
> > +    DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n",
> > Fv));
> > +    return EFI_VOLUME_CORRUPTED;
> > +  }
> > +
> > +  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
> > +  EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
> > +
> > +  //
> > +  // Loop through the FFS files in the Boot Firmware Volume
> > +  //
> > +  for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
> > +
> > +    CurrentAddress = (EndOfFile + 7) & ~(7ULL);
> > +    if (CurrentAddress > EndOfFirmwareVolume) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> > +    Size = *(UINT32*) File->Size & 0xffffff;
> > +    if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +    DEBUG ((EFI_D_INFO, "File->Type: 0x%x\n", File->Type));
> > +
> > +    EndOfFile = CurrentAddress + Size;
> > +    if (EndOfFile > EndOfFirmwareVolume) {
> > +      return EFI_VOLUME_CORRUPTED;
> > +    }
> > +
> > +    //
> > +    // Look for the request file type
> > +    //
> > +    if (File->Type != FileType) {
> > +      DEBUG ((EFI_D_INFO, "File->Type (0x%x) != FileType (0x%x)\n", File-
> >Type,
> > FileType));
> > +      continue;
> > +    }
> > +
> > +    Status = FindFfsSectionInSections (
> > +               (VOID*) (File + 1),
> > +               (UINTN) EndOfFile - (UINTN) (File + 1),
> > +               SectionType,
> > +               FoundSection
> > +               );
> > +    if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
> > +      return Status;
> > +    }
> > +  }
> > +}
> > +
> > +/**
> > +  Locates the compressed main firmware volume and decompresses it.
> > +
> > +  @param[in,out]  Fv            On input, the firmware volume to search
> > +                                On output, the decompressed BOOT/PEI FV
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +DecompressMemFvs (
> > +  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **Fv
> > +  )
> > +{
> > +  EFI_STATUS                        Status;
> > +  EFI_GUID_DEFINED_SECTION          *Section;
> > +  UINT32                            OutputBufferSize;
> > +  UINT32                            ScratchBufferSize;
> > +  UINT16                            SectionAttribute;
> > +  UINT32                            AuthenticationStatus;
> > +  VOID                              *OutputBuffer;
> > +  VOID                              *ScratchBuffer;
> > +  EFI_COMMON_SECTION_HEADER         *FvSection;
> > +  EFI_FIRMWARE_VOLUME_HEADER        *PeiMemFv;
> > +  EFI_FIRMWARE_VOLUME_HEADER        *DxeMemFv;
> > +  UINT32                            FvHeaderSize;
> > +  UINT32                            FvSectionSize;
> > +
> > +  FvSection = (EFI_COMMON_SECTION_HEADER*) NULL;
> > +
> > +  DEBUG ((EFI_D_INFO, "Find and decompress FV image.\n"));
> > +  Status = FindFfsFileAndSection (
> > +             *Fv,
> > +             EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
> > +             EFI_SECTION_GUID_DEFINED,
> > +             (EFI_COMMON_SECTION_HEADER**) &Section
> > +             );
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
> > +    return Status;
> > +  }
> > +
> > +  Status = ExtractGuidedSectionGetInfo (
> > +             Section,
> > +             &OutputBufferSize,
> > +             &ScratchBufferSize,
> > +             &SectionAttribute
> > +             );
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
> > +    return Status;
> > +  }
> > +
> > +  OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32
> > (PcdSimicsDxeMemFvBase) + SIZE_1MB);
> > +  ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer +
> OutputBufferSize,
> > SIZE_1MB);
> > +
> > +  DEBUG ((EFI_D_INFO, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32
> > (PcdSimicsDxeMemFvBase)));
> > +  DEBUG ((EFI_D_INFO, "OutputBuffer: 0x%x\n", OutputBuffer));
> > +  DEBUG ((EFI_D_INFO, "OutputBufferSize: 0x%x\n", OutputBufferSize));
> > +  DEBUG ((EFI_D_INFO, "ScratchBuffer: 0x%x\n", ScratchBuffer));
> > +  DEBUG ((EFI_D_INFO, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
> > +  DEBUG ((EFI_D_INFO, "PcdSimicsDecompressionScratchEnd: 0x%x\n",
> > PcdGet32 (PcdSimicsDecompressionScratchEnd)));
> > +
> > +  DEBUG ((EFI_D_VERBOSE, "%a: OutputBuffer@%p+0x%x
> > ScratchBuffer@%p+0x%x "
> > +    "PcdSimicsDecompressionScratchEnd=0x%x\n", __FUNCTION__,
> > OutputBuffer,
> > +    OutputBufferSize, ScratchBuffer, ScratchBufferSize,
> > +    PcdGet32 (PcdSimicsDecompressionScratchEnd)));
> > +  ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize ==
> > +    PcdGet32 (PcdSimicsDecompressionScratchEnd));
> > +
> > +  Status = ExtractGuidedSectionDecode (
> > +             Section,
> > +             &OutputBuffer,
> > +             ScratchBuffer,
> > +             &AuthenticationStatus
> > +             );
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
> > +    return Status;
> > +  }
> > +
> > +  Status = FindFfsSectionInstance (
> > +             OutputBuffer,
> > +             OutputBufferSize,
> > +             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
> > +             0,
> > +             &FvSection
> > +             );
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((EFI_D_ERROR, "Unable to find PEI FV section\n"));
> > +    return Status;
> > +  }
> > +
> > +  ASSERT (SECTION_SIZE (FvSection) ==
> > +          (PcdGet32 (PcdSimicsPeiMemFvSize) + sizeof (*FvSection)));
> > +  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
> > +
> > +  PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> > (PcdSimicsPeiMemFvBase);
> > +  CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32
> > (PcdSimicsPeiMemFvSize));
> > +
> > +  if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {
> > +    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header
> > signature\n", PeiMemFv));
> > +    CpuDeadLoop ();
> > +    return EFI_VOLUME_CORRUPTED;
> > +  }
> > +
> > +  Status = FindFfsSectionInstance (
> > +             OutputBuffer,
> > +             OutputBufferSize,
> > +             EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
> > +             1,
> > +             &FvSection
> > +             );
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((EFI_D_ERROR, "Unable to find DXE FV section\n"));
> > +    return Status;
> > +  }
> > +
> > +  ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
> > +
> > +  if (IS_SECTION2 (FvSection)) {
> > +    FvSectionSize = SECTION2_SIZE (FvSection);
> > +    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
> > +  } else {
> > +    FvSectionSize = SECTION_SIZE (FvSection);
> > +    FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
> > +  }
> > +
> > +  ASSERT (FvSectionSize == (PcdGet32 (PcdSimicsDxeMemFvSize) +
> > FvHeaderSize));
> > +
> > +  DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> > (PcdSimicsDxeMemFvBase);
> > +  CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize),
> > PcdGet32 (PcdSimicsDxeMemFvSize));
> > +
> > +  if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
> > +    DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header
> > signature\n", DxeMemFv));
> > +    CpuDeadLoop ();
> > +    return EFI_VOLUME_CORRUPTED;
> > +  }
> > +
> > +  *Fv = PeiMemFv;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Locates the PEI Core entry point address
> > +
> > +  @param[in]  Fv                 The firmware volume to search
> > +  @param[out] PeiCoreEntryPoint  The entry point of the PEI Core image
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindPeiCoreImageBaseInFv (
> > +  IN  EFI_FIRMWARE_VOLUME_HEADER       *Fv,
> > +  OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> > +  )
> > +{
> > +  EFI_STATUS                  Status;
> > +  EFI_COMMON_SECTION_HEADER   *Section;
> > +
> > +  DEBUG ((EFI_D_ERROR, "Find PEI Core image.\n"));
> > +  Status = FindFfsFileAndSection (
> > +             Fv,
> > +             EFI_FV_FILETYPE_PEI_CORE,
> > +             EFI_SECTION_PE32,
> > +             &Section
> > +             );
> > +  if (EFI_ERROR (Status)) {
> > +    Status = FindFfsFileAndSection (
> > +               Fv,
> > +               EFI_FV_FILETYPE_PEI_CORE,
> > +               EFI_SECTION_TE,
> > +               &Section
> > +               );
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
> > +      return Status;
> > +    }
> > +  }
> > +
> > +  *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
> > +  DEBUG ((EFI_D_INFO, "PEI core image base 0x%016LX.\n",
> > *PeiCoreImageBase));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Reads 8-bits of CMOS data.
> > +
> > +  Reads the 8-bits of CMOS data at the location specified by Index.
> > +  The 8-bit read value is returned.
> > +
> > +  @param  Index  The CMOS location to read.
> > +
> > +  @return The value read.
> > +
> > +**/
> > +STATIC
> > +UINT8
> > +CmosRead8 (
> > +  IN UINTN        Index
> > +  )
> > +{
> > +  IoWrite8 (0x70, (UINT8) Index);
> > +  return IoRead8 (0x71);
> > +}
> > +
> > +
> > +STATIC
> > +BOOLEAN
> > +IsS3Resume (
> > +  VOID
> > +  )
> > +{
> > +  DEBUG((EFI_D_INFO, "modeValue = %x\n",
> > IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12)));
> > +  return (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) == 0x5);
> > +}
> > +
> > +
> > +STATIC
> > +EFI_STATUS
> > +GetS3ResumePeiFv (
> > +  IN OUT EFI_FIRMWARE_VOLUME_HEADER       **PeiFv
> > +  )
> > +{
> > +  *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32
> > (PcdSimicsPeiMemFvBase);
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Locates the PEI Core entry point address
> > +
> > +  @param[in,out]  Fv                 The firmware volume to search
> > +  @param[out]     PeiCoreEntryPoint  The entry point of the PEI Core image
> > +
> > +  @retval EFI_SUCCESS           The file and section was found
> > +  @retval EFI_NOT_FOUND         The file and section was not found
> > +  @retval EFI_VOLUME_CORRUPTED  The firmware volume was corrupted
> > +
> > +**/
> > +VOID
> > +FindPeiCoreImageBase (
> > +  IN OUT  EFI_FIRMWARE_VOLUME_HEADER       **BootFv,
> > +     OUT  EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
> > +  )
> > +{
> > +  BOOLEAN S3Resume;
> > +
> > +  *PeiCoreImageBase = 0;
> > +
> > +  S3Resume = IsS3Resume ();
> > +  if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
> > +    //
> > +    // A malicious runtime OS may have injected something into our
> previously
> > +    // decoded PEI FV, but we don't care about that unless SMM/SMRAM is
> > required.
> > +    //
> > +    DEBUG ((EFI_D_INFO, "SEC: S3 resume\n"));
> > +    GetS3ResumePeiFv (BootFv);
> > +  } else {
> > +    //
> > +    // We're either not resuming, or resuming "securely" -- we'll decompress
> > +    // both PEI FV and DXE FV from pristine flash.
> > +    //
> > +    DEBUG ((EFI_D_INFO, "SEC: %a\n",
> > +      S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"));
> > +    FindMainFv (BootFv);
> > +
> > +    DecompressMemFvs (BootFv);
> > +  }
> > +
> > +  FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
> > +}
> > +
> > +/**
> > +  Find core image base.
> > +
> > +**/
> > +EFI_STATUS
> > +FindImageBase (
> > +  IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
> > +  OUT EFI_PHYSICAL_ADDRESS             *SecCoreImageBase
> > +  )
> > +{
> > +  EFI_PHYSICAL_ADDRESS        CurrentAddress;
> > +  EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
> > +  EFI_FFS_FILE_HEADER         *File;
> > +  UINT32                      Size;
> > +  EFI_PHYSICAL_ADDRESS        EndOfFile;
> > +  EFI_COMMON_SECTION_HEADER   *Section;
> > +  EFI_PHYSICAL_ADDRESS        EndOfSection;
> > +
> > +  *SecCoreImageBase = 0;
> > +
> > +  CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)
> > BootFirmwareVolumePtr;
> > +  EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr-
> > >FvLength;
> > +
> > +  //
> > +  // Loop through the FFS files in the Boot Firmware Volume
> > +  //
> > +  for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr-
> >HeaderLength; ;
> > ) {
> > +
> > +    CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
> > +    if (CurrentAddress > EndOfFirmwareVolume) {
> > +      return EFI_NOT_FOUND;
> > +    }
> > +
> > +    File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> > +    Size = *(UINT32*) File->Size & 0xffffff;
> > +    if (Size < sizeof (*File)) {
> > +      return EFI_NOT_FOUND;
> > +    }
> > +
> > +    EndOfFile = CurrentAddress + Size;
> > +    if (EndOfFile > EndOfFirmwareVolume) {
> > +      return EFI_NOT_FOUND;
> > +    }
> > +
> > +    //
> > +    // Look for SEC Core
> > +    //
> > +    if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {
> > +      continue;
> > +    }
> > +
> > +    //
> > +    // Loop through the FFS file sections within the FFS file
> > +    //
> > +    EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1);
> > +    for (;;) {
> > +      CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
> > +      Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> > +
> > +      Size = *(UINT32*) Section->Size & 0xffffff;
> > +      if (Size < sizeof (*Section)) {
> > +        return EFI_NOT_FOUND;
> > +      }
> > +
> > +      EndOfSection = CurrentAddress + Size;
> > +      if (EndOfSection > EndOfFile) {
> > +        return EFI_NOT_FOUND;
> > +      }
> > +
> > +      //
> > +      // Look for executable sections
> > +      //
> > +      if (Section->Type == EFI_SECTION_PE32 || Section->Type ==
> > EFI_SECTION_TE) {
> > +        if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
> > +          *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) (Section + 1);
> > +        }
> > +        break;
> > +      }
> > +    }
> > +
> > +    //
> > +    // SEC Core image found
> > +    //
> > +    if (*SecCoreImageBase != 0) {
> > +      return EFI_SUCCESS;
> > +    }
> > +  }
> > +}
> > +
> > +/*
> > +  Find and return Pei Core entry point.
> > +
> > +  It also find SEC and PEI Core file debug information. It will report them if
> > +  remote debug is enabled.
> > +
> > +**/
> > +VOID
> > +FindAndReportEntryPoints (
> > +  IN  EFI_FIRMWARE_VOLUME_HEADER       **BootFirmwareVolumePtr,
> > +  OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
> > +  )
> > +{
> > +  EFI_STATUS                       Status;
> > +  EFI_PHYSICAL_ADDRESS             SecCoreImageBase;
> > +  EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
> > +  PE_COFF_LOADER_IMAGE_CONTEXT     ImageContext;
> > +
> > +  //
> > +  // Find SEC Core and PEI Core image base
> > +   //
> > +  Status = FindImageBase (*BootFirmwareVolumePtr,
> &SecCoreImageBase);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
> > +
> > +  ZeroMem ((VOID *) &ImageContext, sizeof
> > (PE_COFF_LOADER_IMAGE_CONTEXT));
> > +  //
> > +  // Report SEC Core debug information when remote debug is enabled
> > +  //
> > +  ImageContext.ImageAddress = SecCoreImageBase;
> > +  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN)
> > ImageContext.ImageAddress);
> > +  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
> > +
> > +  //
> > +  // Report PEI Core debug information when remote debug is enabled
> > +  //
> > +  ImageContext.ImageAddress =
> > (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
> > +  ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN)
> > ImageContext.ImageAddress);
> > +  PeCoffLoaderRelocateImageExtraAction (&ImageContext);
> > +
> > +  //
> > +  // Find PEI Core entry point
> > +  //
> > +  Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase,
> > (VOID**) PeiCoreEntryPoint);
> > +  if (EFI_ERROR (Status)) {
> > +    *PeiCoreEntryPoint = 0;
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +VOID
> > +EFIAPI
> > +SecCoreStartupWithStack (
> > +  IN EFI_FIRMWARE_VOLUME_HEADER       *BootFv,
> > +  IN VOID                             *TopOfCurrentStack
> > +  )
> > +{
> > +  EFI_SEC_PEI_HAND_OFF        SecCoreData;
> > +  SEC_IDT_TABLE               IdtTableInStack;
> > +  IA32_DESCRIPTOR             IdtDescriptor;
> > +  UINT32                      Index;
> > +  volatile UINT8              *Table;
> > +
> > +  //
> > +  // Initialize floating point operating environment
> > +  // to be compliant with UEFI spec.
> > +  //
> > +  InitializeFloatingPointUnits ();
> > +
> > +  //
> > +  // Initialize the PCIe Configuration base register.
> > +  //
> > +  PciCf8Write32 (PCI_CF8_LIB_ADDRESS (0xFF, 0, 1, 0x50), 0xE0000001);
> > +
> > +  //
> > +  // To ensure SMM can't be compromised on S3 resume, we must force
> re-init
> > of
> > +  // the BaseExtractGuidedSectionLib. Since this is before library
> contructors
> > +  // are called, we must use a loop rather than SetMem.
> > +  //
> > +  Table = (UINT8*)(UINTN)FixedPcdGet64
> > (PcdGuidedExtractHandlerTableAddress);
> > +  for (Index = 0;
> > +       Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
> > +       ++Index) {
> > +    Table[Index] = 0;
> > +  }
> > +
> > +  ProcessLibraryConstructorList (NULL, NULL);
> > +
> > +  DEBUG ((EFI_D_INFO,
> > +    "SecCoreStartupWithStack(0x%x, 0x%x)\n",
> > +    (UINT32)(UINTN)BootFv,
> > +    (UINT32)(UINTN)TopOfCurrentStack
> > +    ));
> > +
> > +  //
> > +  // Initialize IDT
> > +  //
> > +  IdtTableInStack.PeiService = NULL;
> > +  for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
> > +    CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof
> > (mIdtEntryTemplate));
> > +  }
> > +
> > +  IdtDescriptor.Base  = (UINTN)&IdtTableInStack.IdtTable;
> > +  IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
> > +
> > +  AsmWriteIdtr (&IdtDescriptor);
> > +
> > +#if defined (MDE_CPU_X64)
> > +  //
> > +  // ASSERT that the Page Tables were set by the reset vector code to
> > +  // the address we expect.
> > +  //
> > +  ASSERT (AsmReadCr3 () == (UINTN) PcdGet32
> > (PcdSimicsSecPageTablesBase));
> > +#endif
> > +
> > +  //
> > +  // |-------------|       <-- TopOfCurrentStack
> > +  // |   Stack     | 32k
> > +  // |-------------|
> > +  // |    Heap     | 32k
> > +  // |-------------|       <-- SecCoreData.TemporaryRamBase
> > +  //
> > +
> > +  ASSERT ((UINTN) (PcdGet32 (PcdSimicsSecPeiTempRamBase) +
> > +                   PcdGet32 (PcdSimicsSecPeiTempRamSize)) ==
> > +          (UINTN) TopOfCurrentStack);
> > +
> > +  //
> > +  // Initialize SEC hand-off state
> > +  //
> > +  SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
> > +
> > +  SecCoreData.TemporaryRamSize       = (UINTN) PcdGet32
> > (PcdSimicsSecPeiTempRamSize);
> > +  SecCoreData.TemporaryRamBase       = (VOID*)((UINT8
> *)TopOfCurrentStack
> > - SecCoreData.TemporaryRamSize);
> > +
> > +  SecCoreData.PeiTemporaryRamBase    =
> SecCoreData.TemporaryRamBase;
> > +  SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize
> >>
> > 1;
> > +
> > +  SecCoreData.StackBase              = (UINT8
> *)SecCoreData.TemporaryRamBase +
> > SecCoreData.PeiTemporaryRamSize;
> > +  SecCoreData.StackSize              = SecCoreData.TemporaryRamSize >> 1;
> > +
> > +  SecCoreData.BootFirmwareVolumeBase = BootFv;
> > +  SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> > +
> > +  //
> > +  // Make sure the 8259 is masked before initializing the Debug Agent and
> the
> > debug timer is enabled
> > +  //
> > +  IoWrite8 (0x21, 0xff);
> > +  IoWrite8 (0xA1, 0xff);
> > +
> > +  //
> > +  // Initialize Local APIC Timer hardware and disable Local APIC Timer
> > +  // interrupts before initializing the Debug Agent and the debug timer is
> > +  // enabled.
> > +  //
> > +  InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
> > +  DisableApicTimerInterrupt ();
> > +
> > +  //
> > +  // Initialize Debug Agent to support source level debug in SEC/PEI phases
> > before memory ready.
> > +  //
> > +  InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData,
> > SecStartupPhase2);
> > +}
> > +
> > +/**
> > +  Caller provided function to be invoked at the end of
> InitializeDebugAgent().
> > +
> > +  Entry point to the C language phase of SEC. After the SEC assembly
> > +  code has initialized some temporary memory and set up the stack,
> > +  the control is transferred to this function.
> > +
> > +  @param[in] Context    The first input parameter of InitializeDebugAgent().
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +SecStartupPhase2(
> > +  IN VOID                     *Context
> > +  )
> > +{
> > +  EFI_SEC_PEI_HAND_OFF        *SecCoreData;
> > +  EFI_FIRMWARE_VOLUME_HEADER  *BootFv;
> > +  EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
> > +
> > +  SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
> > +
> > +  //
> > +  // Find PEI Core entry point. It will report SEC and Pei Core debug
> information
> > if remote debug
> > +  // is enabled.
> > +  //
> > +  BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData-
> > >BootFirmwareVolumeBase;
> > +  FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
> > +  SecCoreData->BootFirmwareVolumeBase = BootFv;
> > +  SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> > +
> > +  //
> > +  // Transfer the control to the PEI core
> > +  //
> > +  (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR
> > *)&mPrivateDispatchTable);
> > +
> > +  //
> > +  // If we get here then the PEI Core returned, which is not recoverable.
> > +  //
> > +  ASSERT (FALSE);
> > +  CpuDeadLoop ();
> > +}
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +TemporaryRamMigration (
> > +  IN CONST EFI_PEI_SERVICES   **PeiServices,
> > +  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
> > +  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
> > +  IN UINTN                    CopySize
> > +  )
> > +{
> > +  IA32_DESCRIPTOR                  IdtDescriptor;
> > +  VOID                             *OldHeap;
> > +  VOID                             *NewHeap;
> > +  VOID                             *OldStack;
> > +  VOID                             *NewStack;
> > +  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  DebugAgentContext;
> > +  BOOLEAN                          OldStatus;
> > +  BASE_LIBRARY_JUMP_BUFFER         JumpBuffer;
> > +
> > +  DEBUG ((EFI_D_INFO,
> > +    "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
> > +    TemporaryMemoryBase,
> > +    PermanentMemoryBase,
> > +    (UINT64)CopySize
> > +    ));
> > +
> > +  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
> > +  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
> > +
> > +  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
> > +  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
> > +
> > +  DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap -
> > (UINTN)OldHeap;
> > +  DebugAgentContext.StackMigrateOffset = (UINTN)NewStack -
> > (UINTN)OldStack;
> > +
> > +  OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
> > +  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *)
> > &DebugAgentContext, NULL);
> > +
> > +  //
> > +  // Migrate Heap
> > +  //
> > +  CopyMem (NewHeap, OldHeap, CopySize >> 1);
> > +
> > +  //
> > +  // Migrate Stack
> > +  //
> > +  CopyMem (NewStack, OldStack, CopySize >> 1);
> > +
> > +  //
> > +  // Rebase IDT table in permanent memory
> > +  //
> > +  AsmReadIdtr (&IdtDescriptor);
> > +  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack +
> > (UINTN)NewStack;
> > +
> > +  AsmWriteIdtr (&IdtDescriptor);
> > +
> > +  //
> > +  // Use SetJump()/LongJump() to switch to a new stack.
> > +  //
> > +  if (SetJump (&JumpBuffer) == 0) {
> > +#if defined (MDE_CPU_IA32)
> > +    JumpBuffer.Esp = JumpBuffer.Esp +
> > DebugAgentContext.StackMigrateOffset;
> > +#endif
> > +#if defined (MDE_CPU_X64)
> > +    JumpBuffer.Rsp = JumpBuffer.Rsp +
> > DebugAgentContext.StackMigrateOffset;
> > +#endif
> > +    LongJump (&JumpBuffer, (UINTN)-1);
> > +  }
> > +
> > +  SaveAndSetDebugTimerInterrupt (OldStatus);
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> > b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> > new file mode 100644
> > index 0000000000..771fddb487
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> > @@ -0,0 +1,148 @@
> > +/** @file
> > +  A DXE_DRIVER providing SMRAM access by producing
> > EFI_SMM_ACCESS2_PROTOCOL.
> > +
> > +  X58 TSEG is expected to have been verified and set up by the
> SmmAccessPei
> > +  driver.
> > +
> > +  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
> > +  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <Library/DebugLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Protocol/SmmAccess2.h>
> > +
> > +#include "SmramInternal.h"
> > +
> > +/**
> > +  Opens the SMRAM area to be accessible by a boot-service driver.
> > +
> > +  This function "opens" SMRAM so that it is visible while not inside of SMM.
> > +  The function should return EFI_UNSUPPORTED if the hardware does not
> > support
> > +  hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the
> > SMRAM
> > +  configuration is locked.
> > +
> > +  @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
> > +
> > +  @retval EFI_SUCCESS       The operation was successful.
> > +  @retval EFI_UNSUPPORTED   The system does not support opening and
> > closing of
> > +                            SMRAM.
> > +  @retval EFI_DEVICE_ERROR  SMRAM cannot be opened, perhaps because
> it is
> > +                            locked.
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccess2DxeOpen (
> > +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> > +  )
> > +{
> > +  return SmramAccessOpen (&This->LockState, &This->OpenState);
> > +}
> > +
> > +/**
> > +  Inhibits access to the SMRAM.
> > +
> > +  This function "closes" SMRAM so that it is not visible while outside of
> SMM.
> > +  The function should return EFI_UNSUPPORTED if the hardware does not
> > support
> > +  hiding of SMRAM.
> > +
> > +  @param[in] This           The EFI_SMM_ACCESS2_PROTOCOL instance.
> > +
> > +  @retval EFI_SUCCESS       The operation was successful.
> > +  @retval EFI_UNSUPPORTED   The system does not support opening and
> > closing of
> > +                            SMRAM.
> > +  @retval EFI_DEVICE_ERROR  SMRAM cannot be closed.
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccess2DxeClose (
> > +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> > +  )
> > +{
> > +  return SmramAccessClose (&This->LockState, &This->OpenState);
> > +}
> > +
> > +/**
> > +  Inhibits access to the SMRAM.
> > +
> > +  This function prohibits access to the SMRAM region.  This function is
> usually
> > +  implemented such that it is a write-once operation.
> > +
> > +  @param[in] This          The EFI_SMM_ACCESS2_PROTOCOL instance.
> > +
> > +  @retval EFI_SUCCESS      The device was successfully locked.
> > +  @retval EFI_UNSUPPORTED  The system does not support locking of
> SMRAM.
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccess2DxeLock (
> > +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> > +  )
> > +{
> > +  return SmramAccessLock (&This->LockState, &This->OpenState);
> > +}
> > +
> > +/**
> > +  Queries the memory controller for the possible regions that will support
> > +  SMRAM.
> > +
> > +  @param[in]     This           The EFI_SMM_ACCESS2_PROTOCOL instance.
> > +  @param[in,out] SmramMapSize   A pointer to the size, in bytes, of the
> > +                                SmramMemoryMap buffer.
> > +  @param[in,out] SmramMap       A pointer to the buffer in which firmware
> > +                                places the current memory map.
> > +
> > +  @retval EFI_SUCCESS           The chipset supported the given resource.
> > +  @retval EFI_BUFFER_TOO_SMALL  The SmramMap parameter was too
> small.
> > The
> > +                                current buffer size needed to hold the memory
> > +                                map is returned in SmramMapSize.
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccess2DxeGetCapabilities (
> > +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> > +  IN OUT UINTN                       *SmramMapSize,
> > +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> > +  )
> > +{
> > +  return SmramAccessGetCapabilities (This->LockState, This->OpenState,
> > +           SmramMapSize, SmramMap);
> > +}
> > +
> > +//
> > +// LockState and OpenState will be filled in by the entry point.
> > +//
> > +STATIC EFI_SMM_ACCESS2_PROTOCOL mAccess2 = {
> > +  &SmmAccess2DxeOpen,
> > +  &SmmAccess2DxeClose,
> > +  &SmmAccess2DxeLock,
> > +  &SmmAccess2DxeGetCapabilities
> > +};
> > +
> > +//
> > +// Entry point of this driver.
> > +//
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccess2DxeEntryPoint (
> > +  IN EFI_HANDLE       ImageHandle,
> > +  IN EFI_SYSTEM_TABLE *SystemTable
> > +  )
> > +{
> > +  //
> > +  // This module should only be included if SMRAM support is required.
> > +  //
> > +  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
> > +
> > +  GetStates (&mAccess2.LockState, &mAccess2.OpenState);
> > +  return gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
> > +                &gEfiSmmAccess2ProtocolGuid, &mAccess2,
> > +                NULL);
> > +}
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> > b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> > new file mode 100644
> > index 0000000000..d07d88142a
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> > @@ -0,0 +1,353 @@
> > +/** @file
> > +  A PEIM with the following responsibilities:
> > +
> > +  - verify & configure the X58 TSEG in the entry point,
> > +  - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
> > +  - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG,
> and
> > expose
> > +    it via the gEfiAcpiVariableGuid GUID HOB.
> > +
> > +  This PEIM runs from RAM, so we can write to variables with static storage
> > +  duration.
> > +
> > +  Copyright (C) 2013, 2015, Red Hat, Inc.<BR>
> > +  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <Guid/AcpiS3Context.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/PciLib.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <Ppi/SmmAccess.h>
> > +
> > +#include <SimicsPlatforms.h>
> > +
> > +#include "SmramInternal.h"
> > +
> > +//
> > +// PEI_SMM_ACCESS_PPI implementation.
> > +//
> > +
> > +/**
> > +  Opens the SMRAM area to be accessible by a PEIM driver.
> > +
> > +  This function "opens" SMRAM so that it is visible while not inside of SMM.
> > +  The function should return EFI_UNSUPPORTED if the hardware does not
> > support
> > +  hiding of SMRAM. The function should return EFI_DEVICE_ERROR if the
> > SMRAM
> > +  configuration is locked.
> > +
> > +  @param  PeiServices            General purpose services available to every
> > +                                 PEIM.
> > +  @param  This                   The pointer to the SMM Access Interface.
> > +  @param  DescriptorIndex        The region of SMRAM to Open.
> > +
> > +  @retval EFI_SUCCESS            The region was successfully opened.
> > +  @retval EFI_DEVICE_ERROR       The region could not be opened because
> > locked
> > +                                 by chipset.
> > +  @retval EFI_INVALID_PARAMETER  The descriptor index was out of
> bounds.
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccessPeiOpen (
> > +  IN EFI_PEI_SERVICES                **PeiServices,
> > +  IN PEI_SMM_ACCESS_PPI              *This,
> > +  IN UINTN                           DescriptorIndex
> > +  )
> > +{
> > +  if (DescriptorIndex >= DescIdxCount) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  //
> > +  // According to current practice, DescriptorIndex is not considered at all,
> > +  // beyond validating it.
> > +  //
> > +  return SmramAccessOpen (&This->LockState, &This->OpenState);
> > +}
> > +
> > +/**
> > +  Inhibits access to the SMRAM.
> > +
> > +  This function "closes" SMRAM so that it is not visible while outside of
> SMM.
> > +  The function should return EFI_UNSUPPORTED if the hardware does not
> > support
> > +  hiding of SMRAM.
> > +
> > +  @param  PeiServices              General purpose services available to every
> > +                                   PEIM.
> > +  @param  This                     The pointer to the SMM Access Interface.
> > +  @param  DescriptorIndex          The region of SMRAM to Close.
> > +
> > +  @retval EFI_SUCCESS              The region was successfully closed.
> > +  @retval EFI_DEVICE_ERROR         The region could not be closed because
> > +                                   locked by chipset.
> > +  @retval EFI_INVALID_PARAMETER    The descriptor index was out of
> bounds.
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccessPeiClose (
> > +  IN EFI_PEI_SERVICES                **PeiServices,
> > +  IN PEI_SMM_ACCESS_PPI              *This,
> > +  IN UINTN                           DescriptorIndex
> > +  )
> > +{
> > +  if (DescriptorIndex >= DescIdxCount) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  //
> > +  // According to current practice, DescriptorIndex is not considered at all,
> > +  // beyond validating it.
> > +  //
> > +  return SmramAccessClose (&This->LockState, &This->OpenState);
> > +}
> > +
> > +/**
> > +  Inhibits access to the SMRAM.
> > +
> > +  This function prohibits access to the SMRAM region.  This function is
> usually
> > +  implemented such that it is a write-once operation.
> > +
> > +  @param  PeiServices              General purpose services available to every
> > +                                   PEIM.
> > +  @param  This                     The pointer to the SMM Access Interface.
> > +  @param  DescriptorIndex          The region of SMRAM to Close.
> > +
> > +  @retval EFI_SUCCESS            The region was successfully locked.
> > +  @retval EFI_DEVICE_ERROR       The region could not be locked because at
> > +                                 least one range is still open.
> > +  @retval EFI_INVALID_PARAMETER  The descriptor index was out of
> bounds.
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccessPeiLock (
> > +  IN EFI_PEI_SERVICES                **PeiServices,
> > +  IN PEI_SMM_ACCESS_PPI              *This,
> > +  IN UINTN                           DescriptorIndex
> > +  )
> > +{
> > +  if (DescriptorIndex >= DescIdxCount) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  //
> > +  // According to current practice, DescriptorIndex is not considered at all,
> > +  // beyond validating it.
> > +  //
> > +  return SmramAccessLock (&This->LockState, &This->OpenState);
> > +}
> > +
> > +/**
> > +  Queries the memory controller for the possible regions that will support
> > +  SMRAM.
> > +
> > +  @param  PeiServices           General purpose services available to every
> > +                                PEIM.
> > +  @param This                   The pointer to the SmmAccessPpi Interface.
> > +  @param SmramMapSize           The pointer to the variable containing size
> of
> > +                                the buffer to contain the description
> > +                                information.
> > +  @param SmramMap               The buffer containing the data describing
> the
> > +                                Smram region descriptors.
> > +
> > +  @retval EFI_BUFFER_TOO_SMALL  The user did not provide a sufficient
> > buffer.
> > +  @retval EFI_SUCCESS           The user provided a sufficiently-sized buffer.
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccessPeiGetCapabilities (
> > +  IN EFI_PEI_SERVICES                **PeiServices,
> > +  IN PEI_SMM_ACCESS_PPI              *This,
> > +  IN OUT UINTN                       *SmramMapSize,
> > +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> > +  )
> > +{
> > +  return SmramAccessGetCapabilities (This->LockState, This->OpenState,
> > +           SmramMapSize, SmramMap);
> > +}
> > +
> > +//
> > +// LockState and OpenState will be filled in by the entry point.
> > +//
> > +STATIC PEI_SMM_ACCESS_PPI mAccess = {
> > +  &SmmAccessPeiOpen,
> > +  &SmmAccessPeiClose,
> > +  &SmmAccessPeiLock,
> > +  &SmmAccessPeiGetCapabilities
> > +};
> > +
> > +
> > +STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
> > +  {
> > +    EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> > +    &gPeiSmmAccessPpiGuid, &mAccess
> > +  }
> > +};
> > +
> > +
> > +//
> > +// Utility functions.
> > +//
> > +STATIC
> > +UINT8
> > +CmosRead8 (
> > +  IN UINT8  Index
> > +  )
> > +{
> > +  IoWrite8 (0x70, Index);
> > +  return IoRead8 (0x71);
> > +}
> > +
> > +STATIC
> > +UINT32
> > +GetSystemMemorySizeBelow4gb (
> > +  VOID
> > +  )
> > +{
> > +  UINT32 Cmos0x34;
> > +  UINT32 Cmos0x35;
> > +
> > +  Cmos0x34 = CmosRead8 (0x34);
> > +  Cmos0x35 = CmosRead8 (0x35);
> > +
> > +  return ((Cmos0x35 << 8 | Cmos0x34) << 16) + SIZE_16MB;
> > +}
> > +
> > +
> > +//
> > +// Entry point of this driver.
> > +//
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccessPeiEntryPoint (
> > +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> > +  IN CONST EFI_PEI_SERVICES     **PeiServices
> > +  )
> > +{
> > +  UINT16               HostBridgeDevId;
> > +  UINT32                EsmramcVal;
> > +  UINT32               TopOfLowRam, TopOfLowRamMb;
> > +  EFI_STATUS           Status;
> > +  UINTN                SmramMapSize;
> > +  EFI_SMRAM_DESCRIPTOR SmramMap[DescIdxCount];
> > +  VOID                 *GuidHob;
> > +
> > +  //
> > +  // This module should only be included if SMRAM support is required.
> > +  //
> > +  ASSERT (FeaturePcdGet (PcdSmmSmramRequire));
> > +
> > +  //
> > +  // Verify if we're running on a X58 machine type.
> > +  //
> > +  HostBridgeDevId = PciRead16 (SIMICS_HOSTBRIDGE_DID);
> > +  if (HostBridgeDevId != INTEL_ICH10_DEVICE_ID) {
> > +    DEBUG ((EFI_D_ERROR, "%a: no SMRAM with host bridge DID=0x%04x;
> only
> > "
> > +      "DID=0x%04x (X58) is supported\n", __FUNCTION__, HostBridgeDevId,
> > +      INTEL_ICH10_DEVICE_ID));
> > +    goto WrongConfig;
> > +  }
> > +
> > +  //
> > +  // Confirm if QEMU supports SMRAM.
> > +  //
> > +  // With no support for it, the ESMRAMC (Extended System Management
> RAM
> > +  // Control) register reads as zero. If there is support, the cache-enable
> > +  // bits are hard-coded as 1 by QEMU.
> > +  //
> > +
> > +  TopOfLowRam = GetSystemMemorySizeBelow4gb ();
> > +  ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
> > +  TopOfLowRamMb = TopOfLowRam >> 20;
> > +  DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x
> > \n", TopOfLowRam, TopOfLowRamMb));
> > +
> > +
> > +  //
> > +  // Set Top of Low Usable DRAM.
> > +  //
> > +  PciWrite32 (DRAMC_REGISTER_X58(MCH_TOLUD),
> > +               TopOfLowRam);
> > +  DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n",
> > PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));
> > +
> > +  //
> > +  // Set TSEG Memory Base.
> > +  //
> > +  EsmramcVal = (TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) <<
> > MCH_TSEGMB_MB_SHIFT;
> > +  //
> > +  // Set TSEG size, and disable TSEG visibility outside of SMM. Note that the
> > +  // T_EN bit has inverse meaning; when T_EN is set, then TSEG visibility is
> > +  // *restricted* to SMM.
> > +  //
> > +  EsmramcVal &= ~(UINT32)MCH_ESMRAMC_TSEG_MASK;
> > +  EsmramcVal |= FixedPcdGet8 (PcdX58TsegMbytes) == 8 ?
> > MCH_ESMRAMC_TSEG_8MB :
> > +                FixedPcdGet8 (PcdX58TsegMbytes) == 2 ?
> > MCH_ESMRAMC_TSEG_2MB :
> > +                MCH_ESMRAMC_TSEG_1MB;
> > +  EsmramcVal |= MCH_ESMRAMC_T_EN;
> > +  PciWrite32(DRAMC_REGISTER_X58(MCH_TSEGMB), EsmramcVal);
> > +  DEBUG((EFI_D_ERROR, "MCH_TSEGMB =0x%x; \n",
> > PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
> > +  DEBUG((EFI_D_ERROR, "MCH_TSEGMB_1 =0x%x; MCH_TSEGMB_2
> > =0x%x;\n", ((TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) <<
> > MCH_TSEGMB_MB_SHIFT), EsmramcVal));
> > +
> > +  //
> > +  // Create the GUID HOB and point it to the first SMRAM range.
> > +  //
> > +  GetStates (&mAccess.LockState, &mAccess.OpenState);
> > +  SmramMapSize = sizeof SmramMap;
> > +  Status = SmramAccessGetCapabilities (mAccess.LockState,
> > mAccess.OpenState,
> > +             &SmramMapSize, SmramMap);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  DEBUG_CODE_BEGIN ();
> > +  {
> > +    UINTN Count;
> > +    UINTN Idx;
> > +
> > +    Count = SmramMapSize / sizeof SmramMap[0];
> > +    DEBUG ((EFI_D_VERBOSE, "%a: SMRAM map follows, %d entries\n",
> > __FUNCTION__,
> > +      (INT32)Count));
> > +    DEBUG ((EFI_D_VERBOSE, "% 20a % 20a % 20a % 20a\n",
> > "PhysicalStart(0x)",
> > +      "PhysicalSize(0x)", "CpuStart(0x)", "RegionState(0x)"));
> > +    for (Idx = 0; Idx < Count; ++Idx) {
> > +      DEBUG ((EFI_D_VERBOSE, "% 20Lx % 20Lx % 20Lx % 20Lx\n",
> > +        SmramMap[Idx].PhysicalStart, SmramMap[Idx].PhysicalSize,
> > +        SmramMap[Idx].CpuStart, SmramMap[Idx].RegionState));
> > +    }
> > +  }
> > +  DEBUG_CODE_END ();
> > +
> > +  GuidHob = BuildGuidHob (&gEfiAcpiVariableGuid,
> > +    sizeof SmramMap[DescIdxSmmS3ResumeState]);
> > +  if (GuidHob == NULL) {
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  CopyMem (GuidHob, &SmramMap[DescIdxSmmS3ResumeState],
> > +    sizeof SmramMap[DescIdxSmmS3ResumeState]);
> > +
> > +  //
> > +  // We're done. The next step should succeed, but even if it fails, we can't
> > +  // roll back the above BuildGuidHob() allocation, because PEI doesn't
> support
> > +  // releasing memory.
> > +  //
> > +  return PeiServicesInstallPpi (mPpiList);
> > +
> > +WrongConfig:
> > +  //
> > +  // We really don't want to continue in this case.
> > +  //
> > +  ASSERT (FALSE);
> > +  CpuDeadLoop ();
> > +  return EFI_UNSUPPORTED;
> > +}
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> > b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> > new file mode 100644
> > index 0000000000..898fc25084
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> > @@ -0,0 +1,199 @@
> > +/** @file
> > +  Functions and types shared by the SMM accessor PEI and DXE modules.
> > +
> > +  Copyright (C) 2015, Red Hat, Inc.
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <Guid/AcpiS3Context.h>
> > +#include <IndustryStandard/X58Ich10.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PciLib.h>
> > +
> > +#include "SmramInternal.h"
> > +
> > +BOOLEAN gLockState;
> > +BOOLEAN gOpenState;
> > +
> > +/**
> > +  Read the MCH_SMRAM and ESMRAMC registers, and update the
> LockState
> > and
> > +  OpenState fields in the PEI_SMM_ACCESS_PPI /
> > EFI_SMM_ACCESS2_PROTOCOL object,
> > +  from the D_LCK and T_EN bits.
> > +
> > +  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member
> > functions can rely on
> > +  the LockState and OpenState fields being up-to-date on entry, and they
> need
> > +  to restore the same invariant on exit, if they touch the bits in question.
> > +
> > +  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff
> SMRAM is
> > +                         locked.
> > +  @param[out] OpenState  Reflects the inverse of the T_EN bit on output;
> TRUE
> > +                         iff SMRAM is open.
> > +**/
> > +VOID
> > +GetStates (
> > +  OUT BOOLEAN *LockState,
> > +  OUT BOOLEAN *OpenState
> > +)
> > +{
> > +  UINT8 EsmramcVal;
> > +
> > +  EsmramcVal = PciRead8(DRAMC_REGISTER_X58(MCH_TSEGMB));
> > +
> > +  *OpenState = !(EsmramcVal & MCH_ESMRAMC_T_EN);
> > +  *LockState = !*OpenState;
> > +
> > +  *OpenState = gOpenState;
> > +  *LockState = gLockState;
> > +}
> > +
> > +//
> > +// The functions below follow the PEI_SMM_ACCESS_PPI and
> > +// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices
> and
> > This
> > +// pointers are removed (TSEG doesn't depend on them), and so is the
> > +// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
> > +//
> > +// The LockState and OpenState members that are common to both
> > +// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken
> and
> > updated in
> > +// isolation from the rest of the (non-shared) members.
> > +//
> > +
> > +EFI_STATUS
> > +SmramAccessOpen (
> > +  OUT BOOLEAN *LockState,
> > +  OUT BOOLEAN *OpenState
> > +  )
> > +{
> > +
> > +  //
> > +  // Open TSEG by clearing T_EN.
> > +  //
> > +  PciAnd8(DRAMC_REGISTER_X58(MCH_TSEGMB),
> > +    (UINT8)((~(UINT32)MCH_ESMRAMC_T_EN) & 0xff));
> > +
> > +  gOpenState = TRUE;
> > +  gLockState = !gOpenState;
> > +
> > +  GetStates (LockState, OpenState);
> > +  if (!*OpenState) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +SmramAccessClose (
> > +  OUT BOOLEAN *LockState,
> > +  OUT BOOLEAN *OpenState
> > +  )
> > +{
> > +  //
> > +  // Close TSEG by setting T_EN.
> > +  //
> > +  PciOr8(DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
> > +
> > +  gOpenState = FALSE;
> > +  gLockState = !gOpenState;
> > +
> > +  GetStates (LockState, OpenState);
> > +  if (*OpenState) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +SmramAccessLock (
> > +  OUT    BOOLEAN *LockState,
> > +  IN OUT BOOLEAN *OpenState
> > +  )
> > +{
> > +  if (*OpenState) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Close & lock TSEG by setting T_EN and D_LCK.
> > +  //
> > +  PciOr8 (DRAMC_REGISTER_X58(MCH_TSEGMB), MCH_ESMRAMC_T_EN);
> > +
> > +  gOpenState = FALSE;
> > +  gLockState = !gOpenState;
> > +
> > +  GetStates (LockState, OpenState);
> > +  if (*OpenState || !*LockState) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +SmramAccessGetCapabilities (
> > +  IN BOOLEAN                  LockState,
> > +  IN BOOLEAN                  OpenState,
> > +  IN OUT UINTN                *SmramMapSize,
> > +  IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
> > +  )
> > +{
> > +  UINTN  OriginalSize;
> > +  UINT32 TsegMemoryBaseMb, TsegMemoryBase;
> > +  UINT64 CommonRegionState;
> > +  UINT8  TsegSizeBits;
> > +
> > +  OriginalSize  = *SmramMapSize;
> > +  *SmramMapSize = DescIdxCount * sizeof *SmramMap;
> > +  if (OriginalSize < *SmramMapSize) {
> > +    return EFI_BUFFER_TOO_SMALL;
> > +  }
> > +
> > +  //
> > +  // Read the TSEG Memory Base register.
> > +  //
> > +  TsegMemoryBaseMb =
> PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB));
> > +
> > +  TsegMemoryBaseMb = 0xDF800000;
> > +
> > +  TsegMemoryBase = (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT)
> <<
> > 20;
> > +
> > +  //
> > +  // Precompute the region state bits that will be set for all regions.
> > +  //
> > +  CommonRegionState = (OpenState ? EFI_SMRAM_OPEN :
> > EFI_SMRAM_CLOSED) |
> > +                      (LockState ? EFI_SMRAM_LOCKED : 0) |
> > +                      EFI_CACHEABLE;
> > +
> > +  //
> > +  // The first region hosts an SMM_S3_RESUME_STATE object. It is located
> at
> > the
> > +  // start of TSEG. We round up the size to whole pages, and we report it as
> > +  // EFI_ALLOCATED, so that the SMM_CORE stays away from it.
> > +  //
> > +  SmramMap[DescIdxSmmS3ResumeState].PhysicalStart =
> TsegMemoryBase;
> > +  SmramMap[DescIdxSmmS3ResumeState].CpuStart      =
> TsegMemoryBase;
> > +  SmramMap[DescIdxSmmS3ResumeState].PhysicalSize  =
> > +    EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof
> > (SMM_S3_RESUME_STATE)));
> > +  SmramMap[DescIdxSmmS3ResumeState].RegionState   =
> > +    CommonRegionState | EFI_ALLOCATED;
> > +
> > +  //
> > +  // Get the TSEG size bits from the ESMRAMC register.
> > +  //
> > +  TsegSizeBits = PciRead8 (DRAMC_REGISTER_X58(MCH_TSEGMB)) &
> > +                            MCH_ESMRAMC_TSEG_MASK;
> > +
> > +  TsegSizeBits = MCH_ESMRAMC_TSEG_8MB;
> > +
> > +  //
> > +  // The second region is the main one, following the first.
> > +  //
> > +  SmramMap[DescIdxMain].PhysicalStart =
> > +    SmramMap[DescIdxSmmS3ResumeState].PhysicalStart +
> > +    SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
> > +  SmramMap[DescIdxMain].CpuStart =
> > SmramMap[DescIdxMain].PhysicalStart;
> > +  SmramMap[DescIdxMain].PhysicalSize =
> > +    (TsegSizeBits == MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB :
> > +     TsegSizeBits == MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB :
> > +     SIZE_1MB) - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize;
> > +  SmramMap[DescIdxMain].RegionState = CommonRegionState;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry
> .n
> > asm
> >
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry
> .
> > nasm
> > new file mode 100644
> > index 0000000000..19ffb6f86d
> > --- /dev/null
> > +++
> >
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry
> .
> > nasm
> > @@ -0,0 +1,45 @@
> > +; @file
> > +; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> > +;
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +
> > +#include <Base.h>
> > +
> > +    SECTION .text
> > +
> > +extern ASM_PFX(SecCoreStartupWithStack)
> > +
> > +;
> > +; SecCore Entry Point
> > +;
> > +; Processor is in flat protected mode
> > +;
> > +; @param[in]  EAX   Initial value of the EAX register (BIST: Built-in Self Test)
> > +; @param[in]  DI    'BP': boot-strap processor, or 'AP': application
> processor
> > +; @param[in]  EBP   Pointer to the start of the Boot Firmware Volume
> > +;
> > +; @return     None  This routine does not return
> > +;
> > +global ASM_PFX(_ModuleEntryPoint)
> > +ASM_PFX(_ModuleEntryPoint):
> > +
> > +    ;
> > +    ; Load temporary RAM stack based on PCDs
> > +    ;
> > +    %define SEC_TOP_OF_STACK (FixedPcdGet32
> > (PcdSimicsSecPeiTempRamBase) + \
> > +                          FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
> > +    mov     eax, SEC_TOP_OF_STACK
> > +    mov     esp, eax
> > +    nop
> > +
> > +    ;
> > +    ; Setup parameters and call SecCoreStartupWithStack
> > +    ;   [esp]   return address for call
> > +    ;   [esp+4] BootFirmwareVolumePtr
> > +    ;   [esp+8] TopOfCurrentStack
> > +    ;
> > +    push    eax
> > +    push    ebp
> > +    call    ASM_PFX(SecCoreStartupWithStack)
> > +
> > diff --git
> > a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> > b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> > new file mode 100644
> > index 0000000000..ac993ac1ce
> > --- /dev/null
> > +++
> > b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> > @@ -0,0 +1,71 @@
> > +## @file
> > +#  SEC Driver
> > +#
> > +# Copyright (c) 2008 - 2018 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = SecMain
> > +  FILE_GUID                      = e67f156f-54c5-47f3-a35d-07c045881e14
> > +  MODULE_TYPE                    = SEC
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = SecMain
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64 EBC
> > +#
> > +
> > +[Sources]
> > +  SecMain.c
> > +
> > +[Sources.IA32]
> > +  Ia32/SecEntry.nasm
> > +
> > +[Sources.X64]
> > +  X64/SecEntry.nasm
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  UefiCpuPkg/UefiCpuPkg.dec
> > +  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  DebugLib
> > +  BaseMemoryLib
> > +  PeiServicesLib
> > +  PcdLib
> > +  UefiCpuLib
> > +  DebugAgentLib
> > +  IoLib
> > +  PeCoffLib
> > +  PeCoffGetEntryPointLib
> > +  PeCoffExtraActionLib
> > +  ExtractGuidedSectionLib
> > +  LocalApicLib
> > +  PciCf8Lib
> > +
> > +[Ppis]
> > +  gEfiTemporaryRamSupportPpiGuid                # PPI ALWAYS_PRODUCED
> > +
> > +[Pcd]
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> > +  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> > +  gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> > +
> > +[FeaturePcd]
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> > diff --git
> >
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.
> n
> > asm
> >
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.
> n
> > asm
> > new file mode 100644
> > index 0000000000..0eb86ec2ca
> > --- /dev/null
> > +++
> >
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.
> n
> > asm
> > @@ -0,0 +1,45 @@
> > +; @file
> > +; Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> > +;
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +
> > +#include <Base.h>
> > +
> > +DEFAULT REL
> > +SECTION .text
> > +
> > +extern ASM_PFX(SecCoreStartupWithStack)
> > +
> > +;
> > +; SecCore Entry Point
> > +;
> > +; Processor is in flat protected mode
> > +;
> > +; @param[in]  RAX   Initial value of the EAX register (BIST: Built-in Self Test)
> > +; @param[in]  DI    'BP': boot-strap processor, or 'AP': application
> processor
> > +; @param[in]  RBP   Pointer to the start of the Boot Firmware Volume
> > +;
> > +; @return     None  This routine does not return
> > +;
> > +global ASM_PFX(_ModuleEntryPoint)
> > +ASM_PFX(_ModuleEntryPoint):
> > +
> > +    ;
> > +    ; Load temporary RAM stack based on PCDs
> > +    ;
> > +    %define SEC_TOP_OF_STACK (FixedPcdGet32
> > (PcdSimicsSecPeiTempRamBase) + \
> > +                          FixedPcdGet32 (PcdSimicsSecPeiTempRamSize))
> > +    mov     rsp, SEC_TOP_OF_STACK
> > +    nop
> > +
> > +    ;
> > +    ; Setup parameters and call SecCoreStartupWithStack
> > +    ;   rcx: BootFirmwareVolumePtr
> > +    ;   rdx: TopOfCurrentStack
> > +    ;
> > +    mov     rcx, rbp
> > +    mov     rdx, rsp
> > +    sub     rsp, 0x20
> > +    call    ASM_PFX(SecCoreStartupWithStack)
> > +
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> > b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> > new file mode 100644
> > index 0000000000..0be8be4966
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> > @@ -0,0 +1,18 @@
> > +## @file
> > +#  Component description file for the SkyLake SiPkg PEI drivers.
> > +#
> > +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +  #
> > +  # SEC Phase modules
> > +  #
> > +  $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf {
> > +    <LibraryClasses>
> > +
> >
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDeco
> m
> > pressLib.inf
> > +  }
> > +  UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
> > +  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> > b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> > new file mode 100644
> > index 0000000000..78eca21a43
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> > @@ -0,0 +1,9 @@
> > +## @file
> > +#  Component description file for the SkyLake SiPkg DXE drivers.
> > +#
> > +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> > b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> > new file mode 100644
> > index 0000000000..9f037e99d4
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> > @@ -0,0 +1,10 @@
> > +## @file
> > +#  Component description file for the SkyLake SiPkg PEI drivers.
> > +#
> > +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> > b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> > new file mode 100644
> > index 0000000000..596d633cd3
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> > @@ -0,0 +1,17 @@
> > +## @file
> > +#  Component description file for the SkyLake SiPkg PEI drivers.
> > +#
> > +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +#
> > +# SEC Phase modules
> > +#
> > +# The code in this FV handles the initial firmware startup, and
> > +# decompresses the PEI and DXE FVs which handles the rest of the boot
> > sequence.
> > +#
> > +INF  RuleOverride=RESET_SECMAIN USE = IA32
> > $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf
> > +INF  RuleOverride=RESET_VECTOR USE = IA32
> > UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> > b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> > new file mode 100644
> > index 0000000000..9004b9cb83
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> > @@ -0,0 +1,16 @@
> > +## @file
> > +#  Component description file for the SkyLake SiPkg DXE drivers.
> > +#
> > +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +#INF
> $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuArchDxe/CpuArchDxe.inf
> > +#INF  $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuMpDxe/CpuMpDxe.inf
> > +!if gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly == FALSE
> > +  INF  $(SKT_PKG)/Smm/Access/SmmAccess2Dxe.inf
> > +  INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> > +!endif
> > +INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> > b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> > new file mode 100644
> > index 0000000000..2f630b4b95
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> > @@ -0,0 +1,52 @@
> > +## @file
> > +# A DXE_DRIVER providing SMRAM access by producing
> > EFI_SMM_ACCESS2_PROTOCOL.
> > +#
> > +# X58 TSEG is expected to have been verified and set up by the
> SmmAccessPei
> > +# driver.
> > +#
> > +# Copyright (C) 2013, 2015, Red Hat, Inc.
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = SmmAccess2Dxe
> > +  FILE_GUID                      = AC95AD3D-4366-44BF-9A62-E4B29D7A2206
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  PI_SPECIFICATION_VERSION       = 0x00010400
> > +  ENTRY_POINT                    = SmmAccess2DxeEntryPoint
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> > +[Sources]
> > +  SmmAccess2Dxe.c
> > +  SmramInternal.c
> > +  SmramInternal.h
> > +
> > +[Packages]
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  MdePkg/MdePkg.dec
> > +  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > +
> > +[LibraryClasses]
> > +  DebugLib
> > +  PcdLib
> > +  PciLib
> > +  UefiBootServicesTableLib
> > +  UefiDriverEntryPoint
> > +
> > +[Protocols]
> > +  gEfiSmmAccess2ProtocolGuid   ## PRODUCES
> > +
> > +[FeaturePcd]
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> > +
> > +[Depex]
> > +  TRUE
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> > b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> > new file mode 100644
> > index 0000000000..1d3b028c85
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> > @@ -0,0 +1,64 @@
> > +## @file
> > +# A PEIM with the following responsibilities:
> > +#
> > +# - provide SMRAM access by producing PEI_SMM_ACCESS_PPI,
> > +# - verify & configure the X58 TSEG in the entry point,
> > +# - set aside the SMM_S3_RESUME_STATE object at the bottom of TSEG,
> and
> > expose
> > +#   it via the gEfiAcpiVariableGuid GUIDed HOB.
> > +#
> > +# Copyright (C) 2013, 2015, Red Hat, Inc.
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = SmmAccessPei
> > +  FILE_GUID                      = 6C0E75B4-B0B9-44D1-8210-3377D7B4E066
> > +  MODULE_TYPE                    = PEIM
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = SmmAccessPeiEntryPoint
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> > +[Sources]
> > +  SmmAccessPei.c
> > +  SmramInternal.c
> > +  SmramInternal.h
> > +
> > +[Packages]
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  MdePkg/MdePkg.dec
> > +  SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > +  OvmfPkg/OvmfPkg.dec
> > +
> > +[Guids]
> > +  gEfiAcpiVariableGuid
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  BaseMemoryLib
> > +  DebugLib
> > +  HobLib
> > +  IoLib
> > +  PcdLib
> > +  PciLib
> > +  PeiServicesLib
> > +  PeimEntryPoint
> > +
> > +[FeaturePcd]
> > +  gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> > +
> > +[FixedPcd]
> > +  gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes
> > +
> > +[Ppis]
> > +  gPeiSmmAccessPpiGuid           ## PRODUCES
> > +
> > +[Depex]
> > +  gEfiPeiMemoryDiscoveredPpiGuid
> > diff --git a/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> > b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> > new file mode 100644
> > index 0000000000..43a79b295f
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> > @@ -0,0 +1,81 @@
> > +/** @file
> > +  Functions and types shared by the SMM accessor PEI and DXE modules.
> > +
> > +  Copyright (C) 2015, Red Hat, Inc.
> > +
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <Pi/PiMultiPhase.h>
> > +
> > +//
> > +// We'll have two SMRAM ranges.
> > +//
> > +// The first is a tiny one that hosts an SMM_S3_RESUME_STATE object, to
> be
> > +// filled in by the CPU SMM driver during normal boot, for the PEI instance
> of
> > +// the LockBox library (which will rely on the object during S3 resume).
> > +//
> > +// The other SMRAM range is the main one, for the SMM core and the
> SMM
> > drivers.
> > +//
> > +typedef enum {
> > +  DescIdxSmmS3ResumeState = 0,
> > +  DescIdxMain             = 1,
> > +  DescIdxCount            = 2
> > +} DESCRIPTOR_INDEX;
> > +
> > +/**
> > +  Read the MCH_SMRAM and ESMRAMC registers, and update the
> LockState
> > and
> > +  OpenState fields in the PEI_SMM_ACCESS_PPI /
> > EFI_SMM_ACCESS2_PROTOCOL object,
> > +  from the D_LCK and T_EN bits.
> > +
> > +  PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL member
> > functions can rely on
> > +  the LockState and OpenState fields being up-to-date on entry, and they
> need
> > +  to restore the same invariant on exit, if they touch the bits in question.
> > +
> > +  @param[out] LockState  Reflects the D_LCK bit on output; TRUE iff
> SMRAM is
> > +                         locked.
> > +  @param[out] OpenState  Reflects the inverse of the T_EN bit on output;
> TRUE
> > +                         iff SMRAM is open.
> > +**/
> > +VOID
> > +GetStates (
> > +  OUT BOOLEAN *LockState,
> > +  OUT BOOLEAN *OpenState
> > +  );
> > +
> > +//
> > +// The functions below follow the PEI_SMM_ACCESS_PPI and
> > +// EFI_SMM_ACCESS2_PROTOCOL member declarations. The PeiServices
> and
> > This
> > +// pointers are removed (TSEG doesn't depend on them), and so is the
> > +// DescriptorIndex parameter (TSEG doesn't support range-wise locking).
> > +//
> > +// The LockState and OpenState members that are common to both
> > +// PEI_SMM_ACCESS_PPI and EFI_SMM_ACCESS2_PROTOCOL are taken
> and
> > updated in
> > +// isolation from the rest of the (non-shared) members.
> > +//
> > +
> > +EFI_STATUS
> > +SmramAccessOpen (
> > +  OUT BOOLEAN *LockState,
> > +  OUT BOOLEAN *OpenState
> > +  );
> > +
> > +EFI_STATUS
> > +SmramAccessClose (
> > +  OUT BOOLEAN *LockState,
> > +  OUT BOOLEAN *OpenState
> > +  );
> > +
> > +EFI_STATUS
> > +SmramAccessLock (
> > +  OUT    BOOLEAN *LockState,
> > +  IN OUT BOOLEAN *OpenState
> > +  );
> > +
> > +EFI_STATUS
> > +SmramAccessGetCapabilities (
> > +  IN BOOLEAN                  LockState,
> > +  IN BOOLEAN                  OpenState,
> > +  IN OUT UINTN                *SmramMapSize,
> > +  IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
> > +  );
> > --
> > 2.16.2.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#46379): https://edk2.groups.io/g/devel/message/46379
Mute This Topic: https://groups.io/mt/32816095/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-