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.kuba...@intel.com>; devel@edk2.groups.io > Cc: Wu, Hao A <hao.a...@intel.com>; Gao, Liming <liming....@intel.com>; > Sinha, Ankit <ankit.si...@intel.com>; Agyeman, Prince > <prince.agye...@intel.com>; Desimone, Nathaniel L > <nathaniel.l.desim...@intel.com>; Kinney, Michael D > <michael.d.kin...@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....@intel.com>; devel@edk2.groups.io > Cc: Wu, Hao A <hao.a...@intel.com>; Gao, Liming <liming....@intel.com>; > Sinha, Ankit <ankit.si...@intel.com>; Agyeman, Prince > <prince.agye...@intel.com>; Desimone, Nathaniel L > <nathaniel.l.desim...@intel.com>; Kinney, Michael D > <michael.d.kin...@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...@intel.com>; Gao, Liming <liming....@intel.com>; > > Sinha, Ankit <ankit.si...@intel.com>; Agyeman, Prince > > <prince.agye...@intel.com>; Kubacki, Michael A > > <michael.a.kuba...@intel.com>; Desimone, Nathaniel L > > <nathaniel.l.desim...@intel.com>; Kinney, Michael D > > <michael.d.kin...@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...@intel.com> > > Cc: Liming Gao <liming....@intel.com> > > Cc: Ankit Sinha <ankit.si...@intel.com> > > Cc: Agyeman Prince <prince.agye...@intel.com> > > Cc: Kubacki Michael A <michael.a.kuba...@intel.com> > > Cc: Nate DeSimone <nathaniel.l.desim...@intel.com> > > Cc: Michael D Kinney <michael.d.kin...@intel.com> > > Contributed-under: TianoCore Contribution Agreement 1.0 > > > > Signed-off-by: David Wei <david.y....@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/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-