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]
-=-=-=-=-=-=-=-=-=-=-=-
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]
-=-=-=-=-=-=-=-=-=-=-=-
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]
-=-=-=-=-=-=-=-=-=-=-=-
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]
-=-=-=-=-=-=-=-=-=-=-=-
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]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2025 Red Hat, Inc.