From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.120, mailfrom: michael.a.kubacki@intel.com) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by groups.io with SMTP; Mon, 19 Aug 2019 18:04:08 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Aug 2019 18:04:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,407,1559545200"; d="scan'208";a="378382745" Received: from orsmsx106.amr.corp.intel.com ([10.22.225.133]) by fmsmga006.fm.intel.com with ESMTP; 19 Aug 2019 18:04:07 -0700 Received: from orsmsx152.amr.corp.intel.com (10.22.226.39) by ORSMSX106.amr.corp.intel.com (10.22.225.133) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 19 Aug 2019 18:04:06 -0700 Received: from orsmsx122.amr.corp.intel.com ([169.254.11.68]) by ORSMSX152.amr.corp.intel.com ([169.254.8.159]) with mapi id 14.03.0439.000; Mon, 19 Aug 2019 18:04:06 -0700 From: "Kubacki, Michael A" To: "Wei, David Y" , "devel@edk2.groups.io" CC: "Wu, Hao A" , "Gao, Liming" , "Sinha, Ankit" , "Agyeman, Prince" , "Desimone, Nathaniel L" , "Kinney, Michael D" Subject: Re: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 Thread-Topic: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 Thread-Index: AQHVTwRYzj+i069K6E2ufDUbNkjOEqcDIByw Date: Tue, 20 Aug 2019 01:04:06 +0000 Message-ID: <49AB4ACB9627B8468F29D589A27B745588A4FFFF@ORSMSX122.amr.corp.intel.com> References: In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMTE1OTAwMWEtYjgzMS00ZmZjLWFlYjktYmQ5NjlkYWRjNjBiIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoidDhZVE1JNDVCN3ZvcnB2aHFOaWR1elwvY2M4T291djdjVGNwMGIyWmo4TmdEc3pDeXNEamc4YjgydTI3UGoxRHUifQ== x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [10.22.254.139] MIME-Version: 1.0 Return-Path: michael.a.kubacki@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable 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 spa= ce before opening parenthesis and parameters than span multiple lines. Some of these are pre-existing in OvmfPkg source. I don't think this i= s 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 =3D0x%x; TopOfLowRamMb =3D0x%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 =3D0x%x; \n", PciRead32(DRAMC_REGISTER= _X58(MCH_TOLUD))));" Should be an informational message. 4. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 300 & Lin= e 301 - Should be informational messages as well. 5. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf: Is a dependen= cy 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: So= me of this messages should probably be verbose not informational. 8. /Silicon/Intel/SimicsX58SktPkg/SktPei.dsc: This file naming convention i= s unusual. SktPkgPei.dsc is more consistent.=20 > -----Original Message----- > From: Wei, David Y > Sent: Friday, August 9, 2019 3:47 PM > To: devel@edk2.groups.io > Cc: Wu, Hao A ; Gao, Liming ; > Sinha, Ankit ; Agyeman, Prince > ; Kubacki, Michael A > ; Desimone, Nathaniel L > ; Kinney, Michael D > > Subject: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for > SimicsX58 >=20 > Add CPU Pkg for SimicsX58. It is added for simics QSP project support >=20 > Cc: Hao Wu > Cc: Liming Gao > Cc: Ankit Sinha > Cc: Agyeman Prince > Cc: Kubacki Michael A > Cc: Nate DeSimone > Cc: Michael D Kinney > Contributed-under: TianoCore Contribution Agreement 1.0 >=20 > Signed-off-by: David Wei > --- > .../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.na= s > m > create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.dsc > create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fd= f > 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 >=20 > 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.
> + (C) Copyright 2016 Hewlett Packard Enterprise Development LP
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#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 =3D { > + TemporaryRamMigration > +}; > + > +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] =3D { > + { > + (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 =3D { > + { // 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 volu= me > + > + @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) =3D=3D 0); > + > + Fv =3D *BootFv; > + Distance =3D (UINTN) (*BootFv)->FvLength; > + do { > + Fv =3D (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE); > + Distance +=3D EFI_PAGE_SIZE; > + if (Distance > SIZE_32MB) { > + return EFI_NOT_FOUND; > + } > + > + if (Fv->Signature !=3D EFI_FVH_SIGNATURE) { > + continue; > + } > + > + if ((UINTN) Fv->FvLength > Distance) { > + continue; > + } > + > + *BootFv =3D 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 =3D (EFI_PHYSICAL_ADDRESS)(UINTN) Sections; > + EndOfSections =3D EndOfSection + SizeOfSections; > + for (;;) { > + if (EndOfSection =3D=3D EndOfSections) { > + break; > + } > + CurrentAddress =3D (EndOfSection + 3) & ~(3ULL); > + if (CurrentAddress >=3D EndOfSections) { > + return EFI_VOLUME_CORRUPTED; > + } > + > + Section =3D (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress; > + DEBUG ((EFI_D_INFO, "Section->Type: 0x%x\n", Section->Type)); > + > + Size =3D SECTION_SIZE (Section); > + if (Size < sizeof (*Section)) { > + return EFI_VOLUME_CORRUPTED; > + } > + > + EndOfSection =3D CurrentAddress + Size; > + if (EndOfSection > EndOfSections) { > + return EFI_VOLUME_CORRUPTED; > + } > + > + // > + // Look for the requested section type > + // > + if (Section->Type =3D=3D SectionType) { > + if (Instance =3D=3D 0) { > + *FoundSection =3D Section; > + return EFI_SUCCESS; > + } else { > + Instance--; > + } > + } > + DEBUG ((EFI_D_INFO, "Section->Type (0x%x) !=3D 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 !=3D EFI_FVH_SIGNATURE) { > + DEBUG ((EFI_D_ERROR, "FV at %p does not have FV header signature\n", > Fv)); > + return EFI_VOLUME_CORRUPTED; > + } > + > + CurrentAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN) Fv; > + EndOfFirmwareVolume =3D CurrentAddress + Fv->FvLength; > + > + // > + // Loop through the FFS files in the Boot Firmware Volume > + // > + for (EndOfFile =3D CurrentAddress + Fv->HeaderLength; ; ) { > + > + CurrentAddress =3D (EndOfFile + 7) & ~(7ULL); > + if (CurrentAddress > EndOfFirmwareVolume) { > + return EFI_VOLUME_CORRUPTED; > + } > + > + File =3D (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress; > + Size =3D *(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 =3D CurrentAddress + Size; > + if (EndOfFile > EndOfFirmwareVolume) { > + return EFI_VOLUME_CORRUPTED; > + } > + > + // > + // Look for the request file type > + // > + if (File->Type !=3D FileType) { > + DEBUG ((EFI_D_INFO, "File->Type (0x%x) !=3D FileType (0x%x)\n", Fi= le->Type, > FileType)); > + continue; > + } > + > + Status =3D FindFfsSectionInSections ( > + (VOID*) (File + 1), > + (UINTN) EndOfFile - (UINTN) (File + 1), > + SectionType, > + FoundSection > + ); > + if (!EFI_ERROR (Status) || (Status =3D=3D 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 =3D (EFI_COMMON_SECTION_HEADER*) NULL; > + > + DEBUG ((EFI_D_INFO, "Find and decompress FV image.\n")); > + Status =3D 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 =3D ExtractGuidedSectionGetInfo ( > + Section, > + &OutputBufferSize, > + &ScratchBufferSize, > + &SectionAttribute > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n")); > + return Status; > + } > + > + OutputBuffer =3D (VOID*) ((UINT8*)(UINTN) PcdGet32 > (PcdSimicsDxeMemFvBase) + SIZE_1MB); > + ScratchBuffer =3D ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferS= ize, > 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=3D0x%x\n", __FUNCTION__, > OutputBuffer, > + OutputBufferSize, ScratchBuffer, ScratchBufferSize, > + PcdGet32 (PcdSimicsDecompressionScratchEnd))); > + ASSERT ((UINTN)ScratchBuffer + ScratchBufferSize =3D=3D > + PcdGet32 (PcdSimicsDecompressionScratchEnd)); > + > + Status =3D ExtractGuidedSectionDecode ( > + Section, > + &OutputBuffer, > + ScratchBuffer, > + &AuthenticationStatus > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n")); > + return Status; > + } > + > + Status =3D 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) =3D=3D > + (PcdGet32 (PcdSimicsPeiMemFvSize) + sizeof (*FvSection))); > + ASSERT (FvSection->Type =3D=3D EFI_SECTION_FIRMWARE_VOLUME_IMAGE); > + > + PeiMemFv =3D (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 > (PcdSimicsPeiMemFvBase); > + CopyMem (PeiMemFv, (VOID*) (FvSection + 1), PcdGet32 > (PcdSimicsPeiMemFvSize)); > + > + if (PeiMemFv->Signature !=3D 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 =3D 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 =3D=3D EFI_SECTION_FIRMWARE_VOLUME_IMAGE); > + > + if (IS_SECTION2 (FvSection)) { > + FvSectionSize =3D SECTION2_SIZE (FvSection); > + FvHeaderSize =3D sizeof (EFI_COMMON_SECTION_HEADER2); > + } else { > + FvSectionSize =3D SECTION_SIZE (FvSection); > + FvHeaderSize =3D sizeof (EFI_COMMON_SECTION_HEADER); > + } > + > + ASSERT (FvSectionSize =3D=3D (PcdGet32 (PcdSimicsDxeMemFvSize) + > FvHeaderSize)); > + > + DxeMemFv =3D (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 > (PcdSimicsDxeMemFvBase); > + CopyMem (DxeMemFv, (VOID*) ((UINTN)FvSection + FvHeaderSize), > PcdGet32 (PcdSimicsDxeMemFvSize)); > + > + if (DxeMemFv->Signature !=3D 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 =3D 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 =3D FindFfsFileAndSection ( > + Fv, > + EFI_FV_FILETYPE_PEI_CORE, > + EFI_SECTION_PE32, > + &Section > + ); > + if (EFI_ERROR (Status)) { > + Status =3D 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 =3D (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 =3D %x\n", > IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12))); > + return (IoBitFieldRead16(ICH10_PMBASE_IO + 4, 10, 12) =3D=3D 0x5); > +} > + > + > +STATIC > +EFI_STATUS > +GetS3ResumePeiFv ( > + IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv > + ) > +{ > + *PeiFv =3D (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 ima= ge > + > + @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 =3D 0; > + > + S3Resume =3D IsS3Resume (); > + if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) { > + // > + // A malicious runtime OS may have injected something into our previ= ously > + // 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 decomp= ress > + // 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 =3D 0; > + > + CurrentAddress =3D (EFI_PHYSICAL_ADDRESS)(UINTN) > BootFirmwareVolumePtr; > + EndOfFirmwareVolume =3D CurrentAddress + BootFirmwareVolumePtr- > >FvLength; > + > + // > + // Loop through the FFS files in the Boot Firmware Volume > + // > + for (EndOfFile =3D CurrentAddress + BootFirmwareVolumePtr->HeaderLengt= h; ; > ) { > + > + CurrentAddress =3D (EndOfFile + 7) & 0xfffffffffffffff8ULL; > + if (CurrentAddress > EndOfFirmwareVolume) { > + return EFI_NOT_FOUND; > + } > + > + File =3D (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress; > + Size =3D *(UINT32*) File->Size & 0xffffff; > + if (Size < sizeof (*File)) { > + return EFI_NOT_FOUND; > + } > + > + EndOfFile =3D CurrentAddress + Size; > + if (EndOfFile > EndOfFirmwareVolume) { > + return EFI_NOT_FOUND; > + } > + > + // > + // Look for SEC Core > + // > + if (File->Type !=3D EFI_FV_FILETYPE_SECURITY_CORE) { > + continue; > + } > + > + // > + // Loop through the FFS file sections within the FFS file > + // > + EndOfSection =3D (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1); > + for (;;) { > + CurrentAddress =3D (EndOfSection + 3) & 0xfffffffffffffffcULL; > + Section =3D (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress; > + > + Size =3D *(UINT32*) Section->Size & 0xffffff; > + if (Size < sizeof (*Section)) { > + return EFI_NOT_FOUND; > + } > + > + EndOfSection =3D CurrentAddress + Size; > + if (EndOfSection > EndOfFile) { > + return EFI_NOT_FOUND; > + } > + > + // > + // Look for executable sections > + // > + if (Section->Type =3D=3D EFI_SECTION_PE32 || Section->Type =3D=3D > EFI_SECTION_TE) { > + if (File->Type =3D=3D EFI_FV_FILETYPE_SECURITY_CORE) { > + *SecCoreImageBase =3D (PHYSICAL_ADDRESS) (UINTN) (Section + 1)= ; > + } > + break; > + } > + } > + > + // > + // SEC Core image found > + // > + if (*SecCoreImageBase !=3D 0) { > + return EFI_SUCCESS; > + } > + } > +} > + > +/* > + Find and return Pei Core entry point. > + > + It also find SEC and PEI Core file debug information. It will report t= hem 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 =3D 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 =3D SecCoreImageBase; > + ImageContext.PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) > ImageContext.ImageAddress); > + PeCoffLoaderRelocateImageExtraAction (&ImageContext); > + > + // > + // Report PEI Core debug information when remote debug is enabled > + // > + ImageContext.ImageAddress =3D > (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase; > + ImageContext.PdbPointer =3D PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) > ImageContext.ImageAddress); > + PeCoffLoaderRelocateImageExtraAction (&ImageContext); > + > + // > + // Find PEI Core entry point > + // > + Status =3D PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBas= e, > (VOID**) PeiCoreEntryPoint); > + if (EFI_ERROR (Status)) { > + *PeiCoreEntryPoint =3D 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-i= nit > of > + // the BaseExtractGuidedSectionLib. Since this is before library contr= uctors > + // are called, we must use a loop rather than SetMem. > + // > + Table =3D (UINT8*)(UINTN)FixedPcdGet64 > (PcdGuidedExtractHandlerTableAddress); > + for (Index =3D 0; > + Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize); > + ++Index) { > + Table[Index] =3D 0; > + } > + > + ProcessLibraryConstructorList (NULL, NULL); > + > + DEBUG ((EFI_D_INFO, > + "SecCoreStartupWithStack(0x%x, 0x%x)\n", > + (UINT32)(UINTN)BootFv, > + (UINT32)(UINTN)TopOfCurrentStack > + )); > + > + // > + // Initialize IDT > + // > + IdtTableInStack.PeiService =3D NULL; > + for (Index =3D 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) { > + CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeo= f > (mIdtEntryTemplate)); > + } > + > + IdtDescriptor.Base =3D (UINTN)&IdtTableInStack.IdtTable; > + IdtDescriptor.Limit =3D (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 () =3D=3D (UINTN) PcdGet32 > (PcdSimicsSecPageTablesBase)); > +#endif > + > + // > + // |-------------| <-- TopOfCurrentStack > + // | Stack | 32k > + // |-------------| > + // | Heap | 32k > + // |-------------| <-- SecCoreData.TemporaryRamBase > + // > + > + ASSERT ((UINTN) (PcdGet32 (PcdSimicsSecPeiTempRamBase) + > + PcdGet32 (PcdSimicsSecPeiTempRamSize)) =3D=3D > + (UINTN) TopOfCurrentStack); > + > + // > + // Initialize SEC hand-off state > + // > + SecCoreData.DataSize =3D sizeof(EFI_SEC_PEI_HAND_OFF); > + > + SecCoreData.TemporaryRamSize =3D (UINTN) PcdGet32 > (PcdSimicsSecPeiTempRamSize); > + SecCoreData.TemporaryRamBase =3D (VOID*)((UINT8 *)TopOfCurrentSt= ack > - SecCoreData.TemporaryRamSize); > + > + SecCoreData.PeiTemporaryRamBase =3D SecCoreData.TemporaryRamBase; > + SecCoreData.PeiTemporaryRamSize =3D SecCoreData.TemporaryRamSize >> > 1; > + > + SecCoreData.StackBase =3D (UINT8 *)SecCoreData.TemporaryR= amBase + > SecCoreData.PeiTemporaryRamSize; > + SecCoreData.StackSize =3D SecCoreData.TemporaryRamSize >>= 1; > + > + SecCoreData.BootFirmwareVolumeBase =3D BootFv; > + SecCoreData.BootFirmwareVolumeSize =3D (UINTN) BootFv->FvLength; > + > + // > + // Make sure the 8259 is masked before initializing the Debug Agent an= d 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 pha= ses > before memory ready. > + // > + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, > SecStartupPhase2); > +} > + > +/** > + Caller provided function to be invoked at the end of InitializeDebugAg= ent(). > + > + 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 InitializeDebugAgen= t(). > + > +**/ > +VOID > +EFIAPI > +SecStartupPhase2( > + IN VOID *Context > + ) > +{ > + EFI_SEC_PEI_HAND_OFF *SecCoreData; > + EFI_FIRMWARE_VOLUME_HEADER *BootFv; > + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint; > + > + SecCoreData =3D (EFI_SEC_PEI_HAND_OFF *) Context; > + > + // > + // Find PEI Core entry point. It will report SEC and Pei Core debug in= formation > if remote debug > + // is enabled. > + // > + BootFv =3D (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData- > >BootFirmwareVolumeBase; > + FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint); > + SecCoreData->BootFirmwareVolumeBase =3D BootFv; > + SecCoreData->BootFirmwareVolumeSize =3D (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 =3D (VOID*)(UINTN)TemporaryMemoryBase; > + NewHeap =3D (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1)); > + > + OldStack =3D (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1)); > + NewStack =3D (VOID*)(UINTN)PermanentMemoryBase; > + > + DebugAgentContext.HeapMigrateOffset =3D (UINTN)NewHeap - > (UINTN)OldHeap; > + DebugAgentContext.StackMigrateOffset =3D (UINTN)NewStack - > (UINTN)OldStack; > + > + OldStatus =3D 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 =3D IdtDescriptor.Base - (UINTN)OldStack + > (UINTN)NewStack; > + > + AsmWriteIdtr (&IdtDescriptor); > + > + // > + // Use SetJump()/LongJump() to switch to a new stack. > + // > + if (SetJump (&JumpBuffer) =3D=3D 0) { > +#if defined (MDE_CPU_IA32) > + JumpBuffer.Esp =3D JumpBuffer.Esp + > DebugAgentContext.StackMigrateOffset; > +#endif > +#if defined (MDE_CPU_X64) > + JumpBuffer.Rsp =3D 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 SmmAccess= Pei > + driver. > + > + Copyright (C) 2013, 2015, Red Hat, Inc.
> + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > + > +#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 i= s > + 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 o= f 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 suppo= rt > + 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 firmwar= e > + 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 m= emory > + 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 =3D { > + &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 stor= age > + duration. > + > + Copyright (C) 2013, 2015, Red Hat, Inc.
> + Copyright (c) 2010, Intel Corporation. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#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 e= very > + 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 >=3D 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 o= f 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 Interfa= ce. > + @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 becaus= e > + locked by chipset. > + @retval EFI_INVALID_PARAMETER The descriptor index was out of bound= s. > + > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +SmmAccessPeiClose ( > + IN EFI_PEI_SERVICES **PeiServices, > + IN PEI_SMM_ACCESS_PPI *This, > + IN UINTN DescriptorIndex > + ) > +{ > + if (DescriptorIndex >=3D 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 Interfa= ce. > + @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 >=3D 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 suppo= rt > + SMRAM. > + > + @param PeiServices General purpose services available to ev= ery > + PEIM. > + @param This The pointer to the SmmAccessPpi Interfac= e. > + @param SmramMapSize The pointer to the variable containing s= ize of > + the buffer to contain the description > + information. > + @param SmramMap The buffer containing the data describin= g 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 b= uffer. > + > +**/ > +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 =3D { > + &SmmAccessPeiOpen, > + &SmmAccessPeiClose, > + &SmmAccessPeiLock, > + &SmmAccessPeiGetCapabilities > +}; > + > + > +STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList[] =3D { > + { > + 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 =3D CmosRead8 (0x34); > + Cmos0x35 =3D 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 =3D PciRead16 (SIMICS_HOSTBRIDGE_DID); > + if (HostBridgeDevId !=3D INTEL_ICH10_DEVICE_ID) { > + DEBUG ((EFI_D_ERROR, "%a: no SMRAM with host bridge DID=3D0x%04x; on= ly > " > + "DID=3D0x%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-ena= ble > + // bits are hard-coded as 1 by QEMU. > + // > + > + TopOfLowRam =3D GetSystemMemorySizeBelow4gb (); > + ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) =3D=3D 0); > + TopOfLowRamMb =3D TopOfLowRam >> 20; > + DEBUG((EFI_D_ERROR, "TopOfLowRam =3D0x%x; TopOfLowRamMb =3D0x%x > \n", TopOfLowRam, TopOfLowRamMb)); > + > + > + // > + // Set Top of Low Usable DRAM. > + // > + PciWrite32 (DRAMC_REGISTER_X58(MCH_TOLUD), > + TopOfLowRam); > + DEBUG((EFI_D_ERROR, "MCH_TOLUD =3D0x%x; \n", > PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD)))); > + > + // > + // Set TSEG Memory Base. > + // > + EsmramcVal =3D (TopOfLowRamMb - FixedPcdGet8(PcdX58TsegMbytes)) << > MCH_TSEGMB_MB_SHIFT; > + // > + // Set TSEG size, and disable TSEG visibility outside of SMM. Note tha= t the > + // T_EN bit has inverse meaning; when T_EN is set, then TSEG visibilit= y is > + // *restricted* to SMM. > + // > + EsmramcVal &=3D ~(UINT32)MCH_ESMRAMC_TSEG_MASK; > + EsmramcVal |=3D FixedPcdGet8 (PcdX58TsegMbytes) =3D=3D 8 ? > MCH_ESMRAMC_TSEG_8MB : > + FixedPcdGet8 (PcdX58TsegMbytes) =3D=3D 2 ? > MCH_ESMRAMC_TSEG_2MB : > + MCH_ESMRAMC_TSEG_1MB; > + EsmramcVal |=3D MCH_ESMRAMC_T_EN; > + PciWrite32(DRAMC_REGISTER_X58(MCH_TSEGMB), EsmramcVal); > + DEBUG((EFI_D_ERROR, "MCH_TSEGMB =3D0x%x; \n", > PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB)))); > + DEBUG((EFI_D_ERROR, "MCH_TSEGMB_1 =3D0x%x; MCH_TSEGMB_2 > =3D0x%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 =3D sizeof SmramMap; > + Status =3D SmramAccessGetCapabilities (mAccess.LockState, > mAccess.OpenState, > + &SmramMapSize, SmramMap); > + ASSERT_EFI_ERROR (Status); > + > + DEBUG_CODE_BEGIN (); > + { > + UINTN Count; > + UINTN Idx; > + > + Count =3D 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 =3D 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 =3D BuildGuidHob (&gEfiAcpiVariableGuid, > + sizeof SmramMap[DescIdxSmmS3ResumeState]); > + if (GuidHob =3D=3D 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 > +#include > +#include > +#include > + > +#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 quest= ion. > + > + @param[out] LockState Reflects the D_LCK bit on output; TRUE iff SMRA= M 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 =3D PciRead8(DRAMC_REGISTER_X58(MCH_TSEGMB)); > + > + *OpenState =3D !(EsmramcVal & MCH_ESMRAMC_T_EN); > + *LockState =3D !*OpenState; > + > + *OpenState =3D gOpenState; > + *LockState =3D 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 =3D TRUE; > + gLockState =3D !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 =3D FALSE; > + gLockState =3D !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 =3D FALSE; > + gLockState =3D !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 =3D *SmramMapSize; > + *SmramMapSize =3D DescIdxCount * sizeof *SmramMap; > + if (OriginalSize < *SmramMapSize) { > + return EFI_BUFFER_TOO_SMALL; > + } > + > + // > + // Read the TSEG Memory Base register. > + // > + TsegMemoryBaseMb =3D PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB)); > + > + TsegMemoryBaseMb =3D 0xDF800000; > + > + TsegMemoryBase =3D (TsegMemoryBaseMb >> MCH_TSEGMB_MB_SHIFT) << > 20; > + > + // > + // Precompute the region state bits that will be set for all regions. > + // > + CommonRegionState =3D (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 i= t as > + // EFI_ALLOCATED, so that the SMM_CORE stays away from it. > + // > + SmramMap[DescIdxSmmS3ResumeState].PhysicalStart =3D TsegMemoryBase; > + SmramMap[DescIdxSmmS3ResumeState].CpuStart =3D TsegMemoryBase; > + SmramMap[DescIdxSmmS3ResumeState].PhysicalSize =3D > + EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (sizeof > (SMM_S3_RESUME_STATE))); > + SmramMap[DescIdxSmmS3ResumeState].RegionState =3D > + CommonRegionState | EFI_ALLOCATED; > + > + // > + // Get the TSEG size bits from the ESMRAMC register. > + // > + TsegSizeBits =3D PciRead8 (DRAMC_REGISTER_X58(MCH_TSEGMB)) & > + MCH_ESMRAMC_TSEG_MASK; > + > + TsegSizeBits =3D MCH_ESMRAMC_TSEG_8MB; > + > + // > + // The second region is the main one, following the first. > + // > + SmramMap[DescIdxMain].PhysicalStart =3D > + SmramMap[DescIdxSmmS3ResumeState].PhysicalStart + > + SmramMap[DescIdxSmmS3ResumeState].PhysicalSize; > + SmramMap[DescIdxMain].CpuStart =3D > SmramMap[DescIdxMain].PhysicalStart; > + SmramMap[DescIdxMain].PhysicalSize =3D > + (TsegSizeBits =3D=3D MCH_ESMRAMC_TSEG_8MB ? SIZE_8MB : > + TsegSizeBits =3D=3D MCH_ESMRAMC_TSEG_2MB ? SIZE_2MB : > + SIZE_1MB) - SmramMap[DescIdxSmmS3ResumeState].PhysicalSize; > + SmramMap[DescIdxMain].RegionState =3D 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.
> +; > +; SPDX-License-Identifier: BSD-2-Clause-Patent > +; > + > +#include > + > + 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 Se= lf Test) > +; @param[in] DI 'BP': boot-strap processor, or 'AP': application pro= cessor > +; @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.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x00010005 > + BASE_NAME =3D SecMain > + FILE_GUID =3D e67f156f-54c5-47f3-a35d-07c045881e1= 4 > + MODULE_TYPE =3D SEC > + VERSION_STRING =3D 1.0 > + ENTRY_POINT =3D SecMain > + > +# > +# The following information is for reference only and not required by th= e build > tools. > +# > +# VALID_ARCHITECTURES =3D 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.
> +; > +; SPDX-License-Identifier: BSD-2-Clause-Patent > +; > + > +#include > + > +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 Se= lf Test) > +; @param[in] DI 'BP': boot-strap processor, or 'AP': application pro= cessor > +; @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.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > + # > + # SEC Phase modules > + # > + $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf { > + > + > 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.
> +# > +# 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.
> +# > +# 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.
> +# > +# 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=3DRESET_SECMAIN USE =3D IA32 > $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf > +INF RuleOverride=3DRESET_VECTOR USE =3D 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.
> +# > +# 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 =3D=3D 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 SmmAccess= Pei > +# driver. > +# > +# Copyright (C) 2013, 2015, Red Hat, Inc. > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x00010005 > + BASE_NAME =3D SmmAccess2Dxe > + FILE_GUID =3D AC95AD3D-4366-44BF-9A62-E4B29D7A220= 6 > + MODULE_TYPE =3D DXE_DRIVER > + VERSION_STRING =3D 1.0 > + PI_SPECIFICATION_VERSION =3D 0x00010400 > + ENTRY_POINT =3D SmmAccess2DxeEntryPoint > + > +# > +# The following information is for reference only and not required by th= e build > tools. > +# > +# VALID_ARCHITECTURES =3D 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 =3D 0x00010005 > + BASE_NAME =3D SmmAccessPei > + FILE_GUID =3D 6C0E75B4-B0B9-44D1-8210-3377D7B4E06= 6 > + MODULE_TYPE =3D PEIM > + VERSION_STRING =3D 1.0 > + ENTRY_POINT =3D SmmAccessPeiEntryPoint > + > +# > +# The following information is for reference only and not required by th= e build > tools. > +# > +# VALID_ARCHITECTURES =3D 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 > + > +// > +// 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 insta= nce 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 =3D 0, > + DescIdxMain =3D 1, > + DescIdxCount =3D 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 quest= ion. > + > + @param[out] LockState Reflects the D_LCK bit on output; TRUE iff SMRA= M 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