Add CPU Pkg for SimicsX58. It is added for simics QSP project support
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 +++++++++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 346 +++++++++++++++++++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 200 ++++++++++++
.../Include/Register/X58SmramSaveStateMap.h | 178 +++++++++++
Silicon/Intel/SimicsX58SktPkg/SktPkg.dec | 37 +++
Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc | 14 +
.../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
.../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 16 +
.../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 14 +
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 54 ++++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 65 ++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 82 +++++
13 files changed, 1173 insertions(+)
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/Include/Register/X58SmramSaveStateMap.h
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkgPei.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/Smm/Access/SmmAccess2Dxe.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
new file mode 100644
index 0000000000..5d3b2c14aa
--- /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 - 2019, 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..c54026b4d1
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
@@ -0,0 +1,346 @@
+/** @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 - 2019, 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 <Register/X58Ich10.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 Simics 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 Simics.
+ //
+
+ TopOfLowRam = GetSystemMemorySizeBelow4gb ();
+ ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
+ TopOfLowRamMb = TopOfLowRam >> 20;
+ DEBUG((EFI_D_INFO, "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_INFO, "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_INFO, "MCH_TSEGMB =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
+ DEBUG((EFI_D_INFO, "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..4b5a92f602
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
@@ -0,0 +1,200 @@
+/** @file
+ Functions and types shared by the SMM accessor PEI and DXE modules.
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Guid/AcpiS3Context.h>
+#include <Register/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/Include/Register/X58SmramSaveStateMap.h b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h
new file mode 100644
index 0000000000..a067d1488a
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h
@@ -0,0 +1,178 @@
+/** @file
+SMRAM Save State Map Definitions.
+
+SMRAM Save State Map definitions based on contents of the
+Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ Volume 3C, Section 34.4 SMRAM
+ Volume 3C, Section 34.5 SMI Handler Execution Environment
+ Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs
+
+and the AMD64 Architecture Programmer's Manual
+ Volume 2, Section 10.2 SMM Resources
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Red Hat, Inc.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __X58_SMRAM_SAVE_STATE_MAP_H__
+#define __X58_SMRAM_SAVE_STATE_MAP_H__
+
+#pragma pack (1)
+
+///
+/// 32-bit SMRAM Save State Map
+///
+typedef struct {
+ UINT8 Reserved0[0x200]; // 7c00h
+ UINT8 Reserved1[0xf8]; // 7e00h
+ UINT32 SMBASE; // 7ef8h
+ UINT32 SMMRevId; // 7efch
+ UINT16 IORestart; // 7f00h
+ UINT16 AutoHALTRestart; // 7f02h
+ UINT8 Reserved2[0x9C]; // 7f08h
+ UINT32 IOMemAddr; // 7fa0h
+ UINT32 IOMisc; // 7fa4h
+ UINT32 _ES; // 7fa8h
+ UINT32 _CS; // 7fach
+ UINT32 _SS; // 7fb0h
+ UINT32 _DS; // 7fb4h
+ UINT32 _FS; // 7fb8h
+ UINT32 _GS; // 7fbch
+ UINT32 Reserved3; // 7fc0h
+ UINT32 _TR; // 7fc4h
+ UINT32 _DR7; // 7fc8h
+ UINT32 _DR6; // 7fcch
+ UINT32 _EAX; // 7fd0h
+ UINT32 _ECX; // 7fd4h
+ UINT32 _EDX; // 7fd8h
+ UINT32 _EBX; // 7fdch
+ UINT32 _ESP; // 7fe0h
+ UINT32 _EBP; // 7fe4h
+ UINT32 _ESI; // 7fe8h
+ UINT32 _EDI; // 7fech
+ UINT32 _EIP; // 7ff0h
+ UINT32 _EFLAGS; // 7ff4h
+ UINT32 _CR3; // 7ff8h
+ UINT32 _CR0; // 7ffch
+} X58_SMRAM_SAVE_STATE_MAP32;
+
+///
+/// 64-bit SMRAM Save State Map
+///
+typedef struct {
+ UINT8 Reserved0[0x200]; // 7c00h
+
+ UINT16 _ES; // 7e00h
+ UINT16 _ESAccessRights; // 7e02h
+ UINT32 _ESLimit; // 7e04h
+ UINT64 _ESBase; // 7e08h
+
+ UINT16 _CS; // 7e10h
+ UINT16 _CSAccessRights; // 7e12h
+ UINT32 _CSLimit; // 7e14h
+ UINT64 _CSBase; // 7e18h
+
+ UINT16 _SS; // 7e20h
+ UINT16 _SSAccessRights; // 7e22h
+ UINT32 _SSLimit; // 7e24h
+ UINT64 _SSBase; // 7e28h
+
+ UINT16 _DS; // 7e30h
+ UINT16 _DSAccessRights; // 7e32h
+ UINT32 _DSLimit; // 7e34h
+ UINT64 _DSBase; // 7e38h
+
+ UINT16 _FS; // 7e40h
+ UINT16 _FSAccessRights; // 7e42h
+ UINT32 _FSLimit; // 7e44h
+ UINT64 _FSBase; // 7e48h
+
+ UINT16 _GS; // 7e50h
+ UINT16 _GSAccessRights; // 7e52h
+ UINT32 _GSLimit; // 7e54h
+ UINT64 _GSBase; // 7e58h
+
+ UINT32 _GDTRReserved1; // 7e60h
+ UINT16 _GDTRLimit; // 7e64h
+ UINT16 _GDTRReserved2; // 7e66h
+ UINT64 _GDTRBase; // 7e68h
+
+ UINT16 _LDTR; // 7e70h
+ UINT16 _LDTRAccessRights; // 7e72h
+ UINT32 _LDTRLimit; // 7e74h
+ UINT64 _LDTRBase; // 7e78h
+
+ UINT32 _IDTRReserved1; // 7e80h
+ UINT16 _IDTRLimit; // 7e84h
+ UINT16 _IDTRReserved2; // 7e86h
+ UINT64 _IDTRBase; // 7e88h
+
+ UINT16 _TR; // 7e90h
+ UINT16 _TRAccessRights; // 7e92h
+ UINT32 _TRLimit; // 7e94h
+ UINT64 _TRBase; // 7e98h
+
+ UINT64 IO_RIP; // 7ea0h
+ UINT64 IO_RCX; // 7ea8h
+ UINT64 IO_RSI; // 7eb0h
+ UINT64 IO_RDI; // 7eb8h
+ UINT32 IO_DWord; // 7ec0h
+ UINT8 Reserved1[0x04]; // 7ec4h
+ UINT8 IORestart; // 7ec8h
+ UINT8 AutoHALTRestart; // 7ec9h
+ UINT8 Reserved2[0x06]; // 7ecah
+
+ UINT64 IA32_EFER; // 7ed0h
+ UINT64 SVM_Guest; // 7ed8h
+ UINT64 SVM_GuestVMCB; // 7ee0h
+ UINT64 SVM_GuestVIntr; // 7ee8h
+ UINT8 Reserved3[0x0c]; // 7ef0h
+
+ UINT32 SMMRevId; // 7efch
+ UINT32 SMBASE; // 7f00h
+
+ UINT8 Reserved4[0x1c]; // 7f04h
+ UINT64 SVM_GuestPAT; // 7f20h
+ UINT64 SVM_HostIA32_EFER; // 7f28h
+ UINT64 SVM_HostCR4; // 7f30h
+ UINT64 SVM_HostCR3; // 7f38h
+ UINT64 SVM_HostCR0; // 7f40h
+
+ UINT64 _CR4; // 7f48h
+ UINT64 _CR3; // 7f50h
+ UINT64 _CR0; // 7f58h
+ UINT64 _DR7; // 7f60h
+ UINT64 _DR6; // 7f68h
+ UINT64 _RFLAGS; // 7f70h
+ UINT64 _RIP; // 7f78h
+ UINT64 _R15; // 7f80h
+ UINT64 _R14; // 7f88h
+ UINT64 _R13; // 7f90h
+ UINT64 _R12; // 7f98h
+ UINT64 _R11; // 7fa0h
+ UINT64 _R10; // 7fa8h
+ UINT64 _R9; // 7fb0h
+ UINT64 _R8; // 7fb8h
+ UINT64 _RDI; // 7fc0h
+ UINT64 _RSI; // 7fc8h
+ UINT64 _RBP; // 7fd0h
+ UINT64 _RSP; // 7fd8h
+ UINT64 _RBX; // 7fe0h
+ UINT64 _RDX; // 7fe8h
+ UINT64 _RCX; // 7ff0h
+ UINT64 _RAX; // 7ff8h
+} X58_SMRAM_SAVE_STATE_MAP64;
+
+///
+/// Union of 32-bit and 64-bit SMRAM Save State Maps
+///
+typedef union {
+ X58_SMRAM_SAVE_STATE_MAP32 x86;
+ X58_SMRAM_SAVE_STATE_MAP64 x64;
+} X58_SMRAM_SAVE_STATE_MAP;
+
+#pragma pack ()
+
+#endif
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
new file mode 100644
index 0000000000..9fbc546167
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
@@ -0,0 +1,37 @@
+## @file
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = SimicsX58SktPkg
+ PACKAGE_GUID = 070FEC45-BF03-41C1-8D46-8BBE032A7C0C
+ PACKAGE_VERSION = 0.91
+
+[Includes]
+ Include
+
+[Guids]
+ gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d, 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
+
+[PcdsFixedAtBuild]
+ ## The following setting controls how many megabytes we configure as TSEG on
+ # X58, for SMRAM purposes. Permitted values are: 1, 2, 8. Other values cause
+ # undefined behavior.
+ #
+ # This PCD is only consulted if PcdSmmSmramRequire is TRUE (see below).
+ gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes|8|UINT8|0x20
+
+[PcdsFeatureFlag]
+ ## This feature flag enables SMM/SMRAM support. Note that it also requires
+ # such support from the underlying QEMU instance; if that support is not
+ # present, the firmware will reject continuing after a certain point.
+ #
+ # The flag also acts as a general "security switch"; when TRUE, many
+ # components will change behavior, with the goal of preventing a malicious
+ # runtime OS from tampering with firmware structures (special memory ranges
+ # used by OVMF, the varstore pflash chip, LockBox etc).
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|FALSE|BOOLEAN|0x1e
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
new file mode 100644
index 0000000000..af83c380b8
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
@@ -0,0 +1,14 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+ #
+ # SEC Phase modules
+ #
+ 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..12e43e86d0
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 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..5b9cd9ee25
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
@@ -0,0 +1,10 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 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..5019e362e3
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
@@ -0,0 +1,16 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 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_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..b38c3b1108
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
@@ -0,0 +1,14 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+!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..eb8c8f93dd
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
@@ -0,0 +1,54 @@
+## @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.
+# Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# 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
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.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..2b6b14f437
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
@@ -0,0 +1,65 @@
+## @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.
+# Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# 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
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.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..81180a9c8e
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
@@ -0,0 +1,82 @@
+/** @file
+ Functions and types shared by the SMM accessor PEI and DXE modules.
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
+
+ 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 (#46631): https://edk2.groups.io/g/devel/message/46631
Mute This Topic: https://groups.io/mt/33084489/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 30, 2019 2:19 PM
To: devel@edk2.groups.io
Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>; Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Kubacki, Michael A <michael.a.kubacki@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [edk2-platforms PATCH v4 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
Add CPU Pkg for SimicsX58. It is added for simics QSP project support
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Cc: Agyeman Prince <prince.agyeman@intel.com>
Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 +++++++++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 346 +++++++++++++++++++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 200 ++++++++++++
.../Include/Register/X58SmramSaveStateMap.h | 178 +++++++++++
Silicon/Intel/SimicsX58SktPkg/SktPkg.dec | 37 +++
Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc | 14 +
.../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
.../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 16 +
.../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 14 +
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 54 ++++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 65 ++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 82 +++++
13 files changed, 1173 insertions(+)
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/Include/Register/X58SmramSaveStateMap.h
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkgPei.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/Smm/Access/SmmAccess2Dxe.c b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
new file mode 100644
index 0000000000..5d3b2c14aa
--- /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 -
+ 2019, 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..c54026b4d1
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
@@ -0,0 +1,346 @@
+/** @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 -
+ 2019, 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 <Register/X58Ich10.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 Simics 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 Simics.
+ //
+
+ TopOfLowRam = GetSystemMemorySizeBelow4gb (); ASSERT ((TopOfLowRam &
+ (SIZE_1MB - 1)) == 0); TopOfLowRamMb = TopOfLowRam >> 20;
+ DEBUG((EFI_D_INFO, "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_INFO, "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_INFO, "MCH_TSEGMB =0x%x; \n",
+ PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
+ DEBUG((EFI_D_INFO, "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..4b5a92f602
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
@@ -0,0 +1,200 @@
+/** @file
+ Functions and types shared by the SMM accessor PEI and DXE modules.
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Guid/AcpiS3Context.h>
+#include <Register/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/Include/Register/X58SmramSaveStateMap.h b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h
new file mode 100644
index 0000000000..a067d1488a
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMa
+++ p.h
@@ -0,0 +1,178 @@
+/** @file
+SMRAM Save State Map Definitions.
+
+SMRAM Save State Map definitions based on contents of the
+Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ Volume 3C, Section 34.4 SMRAM
+ Volume 3C, Section 34.5 SMI Handler Execution Environment
+ Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs
+
+and the AMD64 Architecture Programmer's Manual
+ Volume 2, Section 10.2 SMM Resources
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015, Red Hat, Inc.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#ifndef __X58_SMRAM_SAVE_STATE_MAP_H__
+#define __X58_SMRAM_SAVE_STATE_MAP_H__
+
+#pragma pack (1)
+
+///
+/// 32-bit SMRAM Save State Map
+///
+typedef struct {
+ UINT8 Reserved0[0x200]; // 7c00h
+ UINT8 Reserved1[0xf8]; // 7e00h
+ UINT32 SMBASE; // 7ef8h
+ UINT32 SMMRevId; // 7efch
+ UINT16 IORestart; // 7f00h
+ UINT16 AutoHALTRestart; // 7f02h
+ UINT8 Reserved2[0x9C]; // 7f08h
+ UINT32 IOMemAddr; // 7fa0h
+ UINT32 IOMisc; // 7fa4h
+ UINT32 _ES; // 7fa8h
+ UINT32 _CS; // 7fach
+ UINT32 _SS; // 7fb0h
+ UINT32 _DS; // 7fb4h
+ UINT32 _FS; // 7fb8h
+ UINT32 _GS; // 7fbch
+ UINT32 Reserved3; // 7fc0h
+ UINT32 _TR; // 7fc4h
+ UINT32 _DR7; // 7fc8h
+ UINT32 _DR6; // 7fcch
+ UINT32 _EAX; // 7fd0h
+ UINT32 _ECX; // 7fd4h
+ UINT32 _EDX; // 7fd8h
+ UINT32 _EBX; // 7fdch
+ UINT32 _ESP; // 7fe0h
+ UINT32 _EBP; // 7fe4h
+ UINT32 _ESI; // 7fe8h
+ UINT32 _EDI; // 7fech
+ UINT32 _EIP; // 7ff0h
+ UINT32 _EFLAGS; // 7ff4h
+ UINT32 _CR3; // 7ff8h
+ UINT32 _CR0; // 7ffch
+} X58_SMRAM_SAVE_STATE_MAP32;
+
+///
+/// 64-bit SMRAM Save State Map
+///
+typedef struct {
+ UINT8 Reserved0[0x200]; // 7c00h
+
+ UINT16 _ES; // 7e00h
+ UINT16 _ESAccessRights; // 7e02h
+ UINT32 _ESLimit; // 7e04h
+ UINT64 _ESBase; // 7e08h
+
+ UINT16 _CS; // 7e10h
+ UINT16 _CSAccessRights; // 7e12h
+ UINT32 _CSLimit; // 7e14h
+ UINT64 _CSBase; // 7e18h
+
+ UINT16 _SS; // 7e20h
+ UINT16 _SSAccessRights; // 7e22h
+ UINT32 _SSLimit; // 7e24h
+ UINT64 _SSBase; // 7e28h
+
+ UINT16 _DS; // 7e30h
+ UINT16 _DSAccessRights; // 7e32h
+ UINT32 _DSLimit; // 7e34h
+ UINT64 _DSBase; // 7e38h
+
+ UINT16 _FS; // 7e40h
+ UINT16 _FSAccessRights; // 7e42h
+ UINT32 _FSLimit; // 7e44h
+ UINT64 _FSBase; // 7e48h
+
+ UINT16 _GS; // 7e50h
+ UINT16 _GSAccessRights; // 7e52h
+ UINT32 _GSLimit; // 7e54h
+ UINT64 _GSBase; // 7e58h
+
+ UINT32 _GDTRReserved1; // 7e60h
+ UINT16 _GDTRLimit; // 7e64h
+ UINT16 _GDTRReserved2; // 7e66h
+ UINT64 _GDTRBase; // 7e68h
+
+ UINT16 _LDTR; // 7e70h
+ UINT16 _LDTRAccessRights; // 7e72h
+ UINT32 _LDTRLimit; // 7e74h
+ UINT64 _LDTRBase; // 7e78h
+
+ UINT32 _IDTRReserved1; // 7e80h
+ UINT16 _IDTRLimit; // 7e84h
+ UINT16 _IDTRReserved2; // 7e86h
+ UINT64 _IDTRBase; // 7e88h
+
+ UINT16 _TR; // 7e90h
+ UINT16 _TRAccessRights; // 7e92h
+ UINT32 _TRLimit; // 7e94h
+ UINT64 _TRBase; // 7e98h
+
+ UINT64 IO_RIP; // 7ea0h
+ UINT64 IO_RCX; // 7ea8h
+ UINT64 IO_RSI; // 7eb0h
+ UINT64 IO_RDI; // 7eb8h
+ UINT32 IO_DWord; // 7ec0h
+ UINT8 Reserved1[0x04]; // 7ec4h
+ UINT8 IORestart; // 7ec8h
+ UINT8 AutoHALTRestart; // 7ec9h
+ UINT8 Reserved2[0x06]; // 7ecah
+
+ UINT64 IA32_EFER; // 7ed0h
+ UINT64 SVM_Guest; // 7ed8h
+ UINT64 SVM_GuestVMCB; // 7ee0h
+ UINT64 SVM_GuestVIntr; // 7ee8h
+ UINT8 Reserved3[0x0c]; // 7ef0h
+
+ UINT32 SMMRevId; // 7efch
+ UINT32 SMBASE; // 7f00h
+
+ UINT8 Reserved4[0x1c]; // 7f04h
+ UINT64 SVM_GuestPAT; // 7f20h
+ UINT64 SVM_HostIA32_EFER; // 7f28h
+ UINT64 SVM_HostCR4; // 7f30h
+ UINT64 SVM_HostCR3; // 7f38h
+ UINT64 SVM_HostCR0; // 7f40h
+
+ UINT64 _CR4; // 7f48h
+ UINT64 _CR3; // 7f50h
+ UINT64 _CR0; // 7f58h
+ UINT64 _DR7; // 7f60h
+ UINT64 _DR6; // 7f68h
+ UINT64 _RFLAGS; // 7f70h
+ UINT64 _RIP; // 7f78h
+ UINT64 _R15; // 7f80h
+ UINT64 _R14; // 7f88h
+ UINT64 _R13; // 7f90h
+ UINT64 _R12; // 7f98h
+ UINT64 _R11; // 7fa0h
+ UINT64 _R10; // 7fa8h
+ UINT64 _R9; // 7fb0h
+ UINT64 _R8; // 7fb8h
+ UINT64 _RDI; // 7fc0h
+ UINT64 _RSI; // 7fc8h
+ UINT64 _RBP; // 7fd0h
+ UINT64 _RSP; // 7fd8h
+ UINT64 _RBX; // 7fe0h
+ UINT64 _RDX; // 7fe8h
+ UINT64 _RCX; // 7ff0h
+ UINT64 _RAX; // 7ff8h
+} X58_SMRAM_SAVE_STATE_MAP64;
+
+///
+/// Union of 32-bit and 64-bit SMRAM Save State Maps /// typedef union
+{
+ X58_SMRAM_SAVE_STATE_MAP32 x86;
+ X58_SMRAM_SAVE_STATE_MAP64 x64;
+} X58_SMRAM_SAVE_STATE_MAP;
+
+#pragma pack ()
+
+#endif
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
new file mode 100644
index 0000000000..9fbc546167
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
@@ -0,0 +1,37 @@
+## @file
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = SimicsX58SktPkg
+ PACKAGE_GUID = 070FEC45-BF03-41C1-8D46-8BBE032A7C0C
+ PACKAGE_VERSION = 0.91
+
+[Includes]
+ Include
+
+[Guids]
+ gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d, 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
+
+[PcdsFixedAtBuild]
+ ## The following setting controls how many megabytes we configure as
+TSEG on
+ # X58, for SMRAM purposes. Permitted values are: 1, 2, 8. Other
+values cause
+ # undefined behavior.
+ #
+ # This PCD is only consulted if PcdSmmSmramRequire is TRUE (see below).
+ gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes|8|UINT8|0x20
+
+[PcdsFeatureFlag]
+ ## This feature flag enables SMM/SMRAM support. Note that it also
+requires
+ # such support from the underlying QEMU instance; if that support is
+not
+ # present, the firmware will reject continuing after a certain point.
+ #
+ # The flag also acts as a general "security switch"; when TRUE, many
+ # components will change behavior, with the goal of preventing a
+malicious
+ # runtime OS from tampering with firmware structures (special memory
+ranges
+ # used by OVMF, the varstore pflash chip, LockBox etc).
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|FALSE|BOOLEAN|0x1e
diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
new file mode 100644
index 0000000000..af83c380b8
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
@@ -0,0 +1,14 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+ #
+ # SEC Phase modules
+ #
+ 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..12e43e86d0
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 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..5b9cd9ee25
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
@@ -0,0 +1,10 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 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..5019e362e3
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
@@ -0,0 +1,16 @@
+## @file
+# Component description file for the X58 SiPkg PEI drivers.
+#
+# Copyright (c) 2019 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_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..b38c3b1108
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
@@ -0,0 +1,14 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+!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..eb8c8f93dd
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
@@ -0,0 +1,54 @@
+## @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.
+# Copyright (C) 2019, Intel Corporation. All rights reserved.<BR> # #
+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
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.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..2b6b14f437
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
@@ -0,0 +1,65 @@
+## @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.
+# Copyright (C) 2019, Intel Corporation. All rights reserved.<BR> # #
+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
+ SimicsX58SktPkg/SktPkg.dec
+ SimicsIch10Pkg/Ich10Pkg.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..81180a9c8e
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
@@ -0,0 +1,82 @@
+/** @file
+ Functions and types shared by the SMM accessor PEI and DXE modules.
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
+
+ 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 (#46692): https://edk2.groups.io/g/devel/message/46692
Mute This Topic: https://groups.io/mt/33084489/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
The following files still have "SkyLake" in the comment at the top of the file. This needs to be changed.
* SktUefiBootInclude.fdf
* SktPostMemoryInclude.fdf
Given this is the first commit for Simics QSP, I think it would be helpful to expand the QSP acronym (Quick Start Package) in the commit message.
With those changes:
Reviewed-by: Michael Kubacki <michael.a.kubacki@intel.com>
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of David Wei
> Sent: Friday, August 30, 2019 2:19 PM
> To: devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Sinha, Ankit <ankit.sinha@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Kubacki, Michael A
> <michael.a.kubacki@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: [edk2-devel] [edk2-platforms PATCH v4 1/7] SimicsX58SktPkg: Add CPU
> Pkg for SimicsX58
>
> Add CPU Pkg for SimicsX58. It is added for simics QSP project support
>
> Cc: Hao Wu <hao.a.wu@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ankit Sinha <ankit.sinha@intel.com>
> Cc: Agyeman Prince <prince.agyeman@intel.com>
> Cc: Kubacki Michael A <michael.a.kubacki@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 +++++++++
> .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 346
> +++++++++++++++++++++
> .../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 200 ++++++++++++
> .../Include/Register/X58SmramSaveStateMap.h | 178 +++++++++++
> Silicon/Intel/SimicsX58SktPkg/SktPkg.dec | 37 +++
> Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc | 14 +
> .../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
> .../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
> Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 16 +
> .../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 14 +
> .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 54 ++++
> .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 65 ++++
> .../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 82 +++++
> 13 files changed, 1173 insertions(+)
> 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/Include/Register/X58SmramSaveStateMap.h
> create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
> create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPkgPei.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/Smm/Access/SmmAccess2Dxe.c
> b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c
> new file mode 100644
> index 0000000000..5d3b2c14aa
> --- /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 -
> + 2019, 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..c54026b4d1
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> @@ -0,0 +1,346 @@
> +/** @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 -
> + 2019, 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 <Register/X58Ich10.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 Simics 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 Simics.
> + //
> +
> + TopOfLowRam = GetSystemMemorySizeBelow4gb (); ASSERT
> ((TopOfLowRam &
> + (SIZE_1MB - 1)) == 0); TopOfLowRamMb = TopOfLowRam >> 20;
> + DEBUG((EFI_D_INFO, "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_INFO, "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_INFO, "MCH_TSEGMB =0x%x; \n",
> + PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
> + DEBUG((EFI_D_INFO, "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..4b5a92f602
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> @@ -0,0 +1,200 @@
> +/** @file
> + Functions and types shared by the SMM accessor PEI and DXE modules.
> +
> + Copyright (C) 2015, Red Hat, Inc.
> + Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#include <Guid/AcpiS3Context.h>
> +#include <Register/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/Include/Register/X58SmramSaveStateMap.h
> b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMap.h
> new file mode 100644
> index 0000000000..a067d1488a
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Include/Register/X58SmramSaveStateMa
> +++ p.h
> @@ -0,0 +1,178 @@
> +/** @file
> +SMRAM Save State Map Definitions.
> +
> +SMRAM Save State Map definitions based on contents of the
> +Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> + Volume 3C, Section 34.4 SMRAM
> + Volume 3C, Section 34.5 SMI Handler Execution Environment
> + Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs
> +
> +and the AMD64 Architecture Programmer's Manual
> + Volume 2, Section 10.2 SMM Resources
> +
> +Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2015, Red Hat, Inc.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#ifndef __X58_SMRAM_SAVE_STATE_MAP_H__
> +#define __X58_SMRAM_SAVE_STATE_MAP_H__
> +
> +#pragma pack (1)
> +
> +///
> +/// 32-bit SMRAM Save State Map
> +///
> +typedef struct {
> + UINT8 Reserved0[0x200]; // 7c00h
> + UINT8 Reserved1[0xf8]; // 7e00h
> + UINT32 SMBASE; // 7ef8h
> + UINT32 SMMRevId; // 7efch
> + UINT16 IORestart; // 7f00h
> + UINT16 AutoHALTRestart; // 7f02h
> + UINT8 Reserved2[0x9C]; // 7f08h
> + UINT32 IOMemAddr; // 7fa0h
> + UINT32 IOMisc; // 7fa4h
> + UINT32 _ES; // 7fa8h
> + UINT32 _CS; // 7fach
> + UINT32 _SS; // 7fb0h
> + UINT32 _DS; // 7fb4h
> + UINT32 _FS; // 7fb8h
> + UINT32 _GS; // 7fbch
> + UINT32 Reserved3; // 7fc0h
> + UINT32 _TR; // 7fc4h
> + UINT32 _DR7; // 7fc8h
> + UINT32 _DR6; // 7fcch
> + UINT32 _EAX; // 7fd0h
> + UINT32 _ECX; // 7fd4h
> + UINT32 _EDX; // 7fd8h
> + UINT32 _EBX; // 7fdch
> + UINT32 _ESP; // 7fe0h
> + UINT32 _EBP; // 7fe4h
> + UINT32 _ESI; // 7fe8h
> + UINT32 _EDI; // 7fech
> + UINT32 _EIP; // 7ff0h
> + UINT32 _EFLAGS; // 7ff4h
> + UINT32 _CR3; // 7ff8h
> + UINT32 _CR0; // 7ffch
> +} X58_SMRAM_SAVE_STATE_MAP32;
> +
> +///
> +/// 64-bit SMRAM Save State Map
> +///
> +typedef struct {
> + UINT8 Reserved0[0x200]; // 7c00h
> +
> + UINT16 _ES; // 7e00h
> + UINT16 _ESAccessRights; // 7e02h
> + UINT32 _ESLimit; // 7e04h
> + UINT64 _ESBase; // 7e08h
> +
> + UINT16 _CS; // 7e10h
> + UINT16 _CSAccessRights; // 7e12h
> + UINT32 _CSLimit; // 7e14h
> + UINT64 _CSBase; // 7e18h
> +
> + UINT16 _SS; // 7e20h
> + UINT16 _SSAccessRights; // 7e22h
> + UINT32 _SSLimit; // 7e24h
> + UINT64 _SSBase; // 7e28h
> +
> + UINT16 _DS; // 7e30h
> + UINT16 _DSAccessRights; // 7e32h
> + UINT32 _DSLimit; // 7e34h
> + UINT64 _DSBase; // 7e38h
> +
> + UINT16 _FS; // 7e40h
> + UINT16 _FSAccessRights; // 7e42h
> + UINT32 _FSLimit; // 7e44h
> + UINT64 _FSBase; // 7e48h
> +
> + UINT16 _GS; // 7e50h
> + UINT16 _GSAccessRights; // 7e52h
> + UINT32 _GSLimit; // 7e54h
> + UINT64 _GSBase; // 7e58h
> +
> + UINT32 _GDTRReserved1; // 7e60h
> + UINT16 _GDTRLimit; // 7e64h
> + UINT16 _GDTRReserved2; // 7e66h
> + UINT64 _GDTRBase; // 7e68h
> +
> + UINT16 _LDTR; // 7e70h
> + UINT16 _LDTRAccessRights; // 7e72h
> + UINT32 _LDTRLimit; // 7e74h
> + UINT64 _LDTRBase; // 7e78h
> +
> + UINT32 _IDTRReserved1; // 7e80h
> + UINT16 _IDTRLimit; // 7e84h
> + UINT16 _IDTRReserved2; // 7e86h
> + UINT64 _IDTRBase; // 7e88h
> +
> + UINT16 _TR; // 7e90h
> + UINT16 _TRAccessRights; // 7e92h
> + UINT32 _TRLimit; // 7e94h
> + UINT64 _TRBase; // 7e98h
> +
> + UINT64 IO_RIP; // 7ea0h
> + UINT64 IO_RCX; // 7ea8h
> + UINT64 IO_RSI; // 7eb0h
> + UINT64 IO_RDI; // 7eb8h
> + UINT32 IO_DWord; // 7ec0h
> + UINT8 Reserved1[0x04]; // 7ec4h
> + UINT8 IORestart; // 7ec8h
> + UINT8 AutoHALTRestart; // 7ec9h
> + UINT8 Reserved2[0x06]; // 7ecah
> +
> + UINT64 IA32_EFER; // 7ed0h
> + UINT64 SVM_Guest; // 7ed8h
> + UINT64 SVM_GuestVMCB; // 7ee0h
> + UINT64 SVM_GuestVIntr; // 7ee8h
> + UINT8 Reserved3[0x0c]; // 7ef0h
> +
> + UINT32 SMMRevId; // 7efch
> + UINT32 SMBASE; // 7f00h
> +
> + UINT8 Reserved4[0x1c]; // 7f04h
> + UINT64 SVM_GuestPAT; // 7f20h
> + UINT64 SVM_HostIA32_EFER; // 7f28h
> + UINT64 SVM_HostCR4; // 7f30h
> + UINT64 SVM_HostCR3; // 7f38h
> + UINT64 SVM_HostCR0; // 7f40h
> +
> + UINT64 _CR4; // 7f48h
> + UINT64 _CR3; // 7f50h
> + UINT64 _CR0; // 7f58h
> + UINT64 _DR7; // 7f60h
> + UINT64 _DR6; // 7f68h
> + UINT64 _RFLAGS; // 7f70h
> + UINT64 _RIP; // 7f78h
> + UINT64 _R15; // 7f80h
> + UINT64 _R14; // 7f88h
> + UINT64 _R13; // 7f90h
> + UINT64 _R12; // 7f98h
> + UINT64 _R11; // 7fa0h
> + UINT64 _R10; // 7fa8h
> + UINT64 _R9; // 7fb0h
> + UINT64 _R8; // 7fb8h
> + UINT64 _RDI; // 7fc0h
> + UINT64 _RSI; // 7fc8h
> + UINT64 _RBP; // 7fd0h
> + UINT64 _RSP; // 7fd8h
> + UINT64 _RBX; // 7fe0h
> + UINT64 _RDX; // 7fe8h
> + UINT64 _RCX; // 7ff0h
> + UINT64 _RAX; // 7ff8h
> +} X58_SMRAM_SAVE_STATE_MAP64;
> +
> +///
> +/// Union of 32-bit and 64-bit SMRAM Save State Maps /// typedef union
> +{
> + X58_SMRAM_SAVE_STATE_MAP32 x86;
> + X58_SMRAM_SAVE_STATE_MAP64 x64;
> +} X58_SMRAM_SAVE_STATE_MAP;
> +
> +#pragma pack ()
> +
> +#endif
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
> b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
> new file mode 100644
> index 0000000000..9fbc546167
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPkg.dec
> @@ -0,0 +1,37 @@
> +## @file
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> + DEC_SPECIFICATION = 0x00010005
> + PACKAGE_NAME = SimicsX58SktPkg
> + PACKAGE_GUID = 070FEC45-BF03-41C1-8D46-8BBE032A7C0C
> + PACKAGE_VERSION = 0.91
> +
> +[Includes]
> + Include
> +
> +[Guids]
> + gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d, 0x04,
> 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
> +
> +[PcdsFixedAtBuild]
> + ## The following setting controls how many megabytes we configure as
> +TSEG on
> + # X58, for SMRAM purposes. Permitted values are: 1, 2, 8. Other
> +values cause
> + # undefined behavior.
> + #
> + # This PCD is only consulted if PcdSmmSmramRequire is TRUE (see below).
> + gSimicsX58PkgTokenSpaceGuid.PcdX58TsegMbytes|8|UINT8|0x20
> +
> +[PcdsFeatureFlag]
> + ## This feature flag enables SMM/SMRAM support. Note that it also
> +requires
> + # such support from the underlying QEMU instance; if that support is
> +not
> + # present, the firmware will reject continuing after a certain point.
> + #
> + # The flag also acts as a general "security switch"; when TRUE, many
> + # components will change behavior, with the goal of preventing a
> +malicious
> + # runtime OS from tampering with firmware structures (special memory
> +ranges
> + # used by OVMF, the varstore pflash chip, LockBox etc).
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire|FALSE|BOOLEAN|0x1e
> diff --git a/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
> b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
> new file mode 100644
> index 0000000000..af83c380b8
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPkgPei.dsc
> @@ -0,0 +1,14 @@
> +## @file
> +# Component description file for the X58 SiPkg PEI drivers.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> + #
> + # SEC Phase modules
> + #
> + 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..12e43e86d0
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> @@ -0,0 +1,9 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2019 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..5b9cd9ee25
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> @@ -0,0 +1,10 @@
> +## @file
> +# Component description file for the X58 SiPkg PEI drivers.
> +#
> +# Copyright (c) 2019 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..5019e362e3
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> @@ -0,0 +1,16 @@
> +## @file
> +# Component description file for the X58 SiPkg PEI drivers.
> +#
> +# Copyright (c) 2019 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_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..b38c3b1108
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> @@ -0,0 +1,14 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +!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..eb8c8f93dd
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> @@ -0,0 +1,54 @@
> +## @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.
> +# Copyright (C) 2019, Intel Corporation. All rights reserved.<BR> # #
> +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
> + SimicsX58SktPkg/SktPkg.dec
> + SimicsIch10Pkg/Ich10Pkg.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..2b6b14f437
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> @@ -0,0 +1,65 @@
> +## @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.
> +# Copyright (C) 2019, Intel Corporation. All rights reserved.<BR> # #
> +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
> + SimicsX58SktPkg/SktPkg.dec
> + SimicsIch10Pkg/Ich10Pkg.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..81180a9c8e
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.h
> @@ -0,0 +1,82 @@
> +/** @file
> + Functions and types shared by the SMM accessor PEI and DXE modules.
> +
> + Copyright (C) 2015, Red Hat, Inc.
> + Copyright (C) 2019, Intel Corporation. All rights reserved.<BR>
> +
> + 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 (#46746): https://edk2.groups.io/g/devel/message/46746
Mute This Topic: https://groups.io/mt/33084489/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2026 Red Hat, Inc.