From: "Kubacki, Michael A" <michael.a.kubacki@intel.com>
To: devel@edk2.groups.io
Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>,
Chasel Chiu <chasel.chiu@intel.com>,
Nate DeSimone <nathaniel.l.desimone@intel.com>,
Liming Gao <liming.gao@intel.com>,
Michael D Kinney <michael.d.kinney@intel.com>,
Ankit Sinha <ankit.sinha@intel.com>
Subject: [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules
Date: Fri, 16 Aug 2019 17:15:52 -0700 [thread overview]
Message-ID: <20190817001603.30632-27-michael.a.kubacki@intel.com> (raw)
In-Reply-To: <20190817001603.30632-1-michael.a.kubacki@intel.com>
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2082
* PchInitDxeCnl - Generic DXE PCH initialization.
* PchInitDxeFspCnl - Generic DXE PCH FSP initialization.
* PchInitSmm - Generic SMM PCH initialization.
* SmmControl - Produces an instance of EFI_SMM_CONTROL2_PROTOCOL.
Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ankit Sinha <ankit.sinha@intel.com>
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf | 99 ++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf | 77 +++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf | 101 ++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf | 54 ++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf | 45 ++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h | 223 ++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h | 187 +++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h | 132 +++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c | 451 ++++++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c | 33 ++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c | 323 ++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c | 554 ++++++++++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c | 382 ++++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c | 85 +++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c | 89 ++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c | 57 ++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c | 156 ++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c | 156 ++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c | 179 +++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c | 298 +++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c | 436 +++++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c | 69 +++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c | 399 ++++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c | 310 +++++++++++
24 files changed, 4895 insertions(+)
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
new file mode 100644
index 0000000000..5e0cf06cb6
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeCnl.inf
@@ -0,0 +1,99 @@
+## @file
+# Component description file for Pch Initialization driver
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PchInitDxe
+FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE823
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = PchInitEntryPointDxe
+
+
+[LibraryClasses]
+S3BootScriptLib
+PchCycleDecodingLib
+PchPcieRpLib
+PchPcrLib
+PchInfoLib
+PchPciExpressHelpersLib
+UefiBootServicesTableLib
+DebugLib
+IoLib
+TimerLib
+HobLib
+BaseMemoryLib
+MemoryAllocationLib
+UefiLib
+DxeServicesTableLib
+UefiDriverEntryPoint
+UefiRuntimeServicesTableLib
+AslUpdateLib
+CpuPlatformLib
+GpioLib
+PchSerialIoLib
+PchHdaLib
+PchInitCommonLib
+ConfigBlockLib
+PmcLib
+PmcPrivateLib
+PmcPrivateLibWithS3
+SataLib
+PchDmiWithS3Lib
+PchGbeLib
+SiScheduleResetLib
+BiosLockLib
+DxeSaPolicyLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr
+
+
+[Sources]
+PchInitDxe.c
+PchInit.h
+PchInit.c
+PchSata.c
+PchSerialIo.c
+PchSerialIoDxe.c
+PchHdaAcpi.c
+PchCnviAcpi.c
+PchAcpi.c
+
+[Protocols]
+gPchNvsAreaProtocolGuid ## PRODUCES
+gPchEmmcTuningProtocolGuid ## PRODUCES
+gEfiPciIoProtocolGuid ## CONSUMES
+gEfiAcpiTableProtocolGuid ## CONSUMES
+gEfiBlockIoProtocolGuid ## CONSUMES
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+gPchPcieIoTrapProtocolGuid ## CONSUMES
+gPchPolicyProtocolGuid ## CONSUMES
+
+
+[Guids]
+gEfiEndOfDxeEventGroupGuid
+gEfiAcpiTableGuid
+gSiConfigHobGuid ## CONSUMES
+gPchConfigHobGuid ## CONSUMES
+gPchRstHobGuid ## CONSUMES
+gHdAudioDxeConfigGuid ## CONSUMES
+gGpioDxeConfigGuid ## CONSUMES
+
+
+[Depex]
+gEfiPciHostBridgeResourceAllocationProtocolGuid ## This is to ensure that PCI MMIO and IO resource has been prepared and available for this driver to allocate.
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
new file mode 100644
index 0000000000..528cfd0296
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxeFspCnl.inf
@@ -0,0 +1,77 @@
+## @file
+# Component description file for Pch Initialization driver for FSP package
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010005
+BASE_NAME = PchInitDxe
+FILE_GUID = 5AA5031E-4CB6-43D4-B219-FE50FF5D116C
+MODULE_TYPE = PEIM
+VERSION_STRING = 1.0
+ENTRY_POINT = PchInitEntryPointFsp
+
+
+[LibraryClasses]
+PeimEntryPoint
+PchCycleDecodingLib
+PchPcieRpLib
+PchPcrLib
+PchInfoLib
+PchPciExpressHelpersLib
+DebugLib
+IoLib
+TimerLib
+HobLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+GpioLib
+PchSerialIoLib
+PchInitCommonLib
+S3BootScriptLib # NULL library
+ConfigBlockLib
+PmcLib
+PmcPrivateLib
+PmcPrivateLibWithS3
+UsbInitLib
+PchDmiWithS3Lib
+PchGbeLib
+SiScheduleResetLib
+BiosLockLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+
+[Sources]
+PchInitFsp.c
+PchInit.h
+PchInit.c
+PchSata.c
+PchSerialIo.c
+
+
+[Protocols]
+gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
+
+
+[Guids]
+gEfiEventReadyToBootGuid
+gSiConfigHobGuid ## CONSUMES
+gPchConfigHobGuid ## CONSUMES
+
+
+[Depex]
+ gEfiPeiMemoryDiscoveredPpiGuid
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
new file mode 100644
index 0000000000..308da65385
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
@@ -0,0 +1,101 @@
+## @file
+# Component description file for PchInitSmm driver
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PchInitSmm
+FILE_GUID = D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_SMM_DRIVER
+PI_SPECIFICATION_VERSION = 1.10
+ENTRY_POINT = PchInitSmmEntryPoint
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+
+[LibraryClasses]
+UefiBootServicesTableLib
+UefiDriverEntryPoint
+DxeServicesTableLib
+IoLib
+DebugLib
+BaseLib
+BaseMemoryLib
+S3BootScriptLib
+PchPciExpressHelpersLib
+SmmServicesTableLib
+PciSegmentLib
+HobLib
+GpioLib
+GpioPrivateLib
+ReportStatusCodeLib
+DevicePathLib
+PmcLib
+PchPcieRpLib
+PchInfoLib
+TimerLib
+ConfigBlockLib
+PmcPrivateLib
+SataLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMin
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempPciBusMax
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemBaseAddr
+gSiPkgTokenSpaceGuid.PcdSiliconInitTempMemSize
+
+
+[Sources]
+PchInitSmm.c
+PchPcieSmm.c
+PchLanSxSmm.c
+PchInitSmm.h
+PchBiosWriteProtect.c
+PchSpiAsync.c
+
+
+[Protocols]
+gEfiSmmIoTrapDispatch2ProtocolGuid ## CONSUMES
+gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES
+gPchSmmIoTrapControlGuid ## CONSUMES
+gEfiSmmCpuProtocolGuid ## CONSUMES
+gPchNvsAreaProtocolGuid ## CONSUMES
+gPchPcieSmiDispatchProtocolGuid ## CONSUMES
+gPchTcoSmiDispatchProtocolGuid ## CONSUMES
+gPchSmiDispatchProtocolGuid ## CONSUMES
+gPchEspiSmiDispatchProtocolGuid ## CONSUMES
+gPchPcieIoTrapProtocolGuid ## PRODUCES
+
+
+[Guids]
+gSiConfigHobGuid ## CONSUMES
+gPchConfigHobGuid ## CONSUMES
+gPchDeviceTableHobGuid
+
+
+[Depex]
+gEfiSmmIoTrapDispatch2ProtocolGuid AND
+gEfiSmmSxDispatch2ProtocolGuid AND
+gPchSmmIoTrapControlGuid AND
+gPchPcieSmiDispatchProtocolGuid AND
+gPchTcoSmiDispatchProtocolGuid AND
+gEfiSmmCpuProtocolGuid AND
+gPchNvsAreaProtocolGuid AND
+gEfiPciHostBridgeResourceAllocationProtocolGuid AND # This is to ensure that PCI MMIO resource has been prepared and available for this driver to allocate.
+gEfiSmmBase2ProtocolGuid # This is for SmmServicesTableLib
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf
new file mode 100644
index 0000000000..ff712f8635
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControl.inf
@@ -0,0 +1,54 @@
+## @file
+# Component description file for SmmControl module
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SmmControl
+FILE_GUID = A0BAD9F7-AB78-491b-B583-C52B7F84B9E0
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_RUNTIME_DRIVER
+ENTRY_POINT = SmmControlDriverEntryInit
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+
+
+[LibraryClasses]
+IoLib
+UefiDriverEntryPoint
+DebugLib
+UefiBootServicesTableLib
+UefiRuntimeServicesTableLib
+PmcLib
+GpioLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+SmmControlDriver.h
+SmmControlDriver.c
+
+
+[Protocols]
+gEfiSmmControl2ProtocolGuid ## PRODUCES
+
+
+[Guids]
+gEfiEventVirtualAddressChangeGuid
+
+
+[Depex]
+TRUE
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
new file mode 100644
index 0000000000..77bd3ad72b
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpiSmm.inf
@@ -0,0 +1,45 @@
+## @file
+# Component description file for the SPI SMM driver.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PchSpiSmm
+FILE_GUID = 27F4917B-A707-4aad-9676-26DF168CBF0D
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_SMM_DRIVER
+PI_SPECIFICATION_VERSION = 1.10
+ENTRY_POINT = InstallPchSpi
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+UefiDriverEntryPoint
+UefiBootServicesTableLib
+BaseLib
+SmmServicesTableLib
+PchSpiCommonLib
+SmmPchPrivateLib
+
+[Packages]
+MdePkg/MdePkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PchSpi.c
+
+
+[Protocols]
+gPchSmmSpiProtocolGuid ## PRODUCES
+gEfiSmmCpuProtocolGuid ## CONSUMES
+
+[Depex]
+gEfiSmmBase2ProtocolGuid AND # This is for SmmServicesTableLib
+gEfiSmmCpuProtocolGuid # This is for CpuSmmDisableBiosWriteProtect()
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
new file mode 100644
index 0000000000..b84c574a2e
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.h
@@ -0,0 +1,223 @@
+/** @file
+ Header file for PCH Initialization Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_INIT_DXE_H_
+#define _PCH_INIT_DXE_H_
+
+#include <Protocol/PchEmmcTuning.h>
+#include <SiConfigHob.h>
+#include <Private/PchConfigHob.h>
+#include <Private/Protocol/PchNvsArea.h>
+
+//
+// Data definitions
+//
+extern EFI_HANDLE mImageHandle;
+
+//
+// Pch NVS area definition
+//
+extern PCH_NVS_AREA_PROTOCOL mPchNvsAreaProtocol;
+
+extern PCH_CONFIG_HOB *mPchConfigHob;
+extern SI_CONFIG_HOB_DATA *mSiConfigHobData;
+
+//
+// Function Prototype
+//
+
+//
+// Local function prototypes
+//
+/**
+ Initialize the PCH device according to the PCH Policy HOB
+ and install PCH info instance.
+
+**/
+VOID
+InitializePchDevice (
+ VOID
+ );
+
+/**
+ Common PchInit Module Entry Point
+**/
+VOID
+PchInitEntryPointCommon (
+ VOID
+ );
+
+/**
+ Common PCH initialization on PCI enumeration complete.
+**/
+VOID
+PchOnPciEnumCompleteCommon (
+ VOID
+ );
+
+/**
+ Configures Serial IO Controllers
+
+**/
+EFI_STATUS
+ConfigureSerialIoAtBoot (
+ VOID
+ );
+
+/**
+ Creates device handles for SerialIo devices in ACPI mode
+
+**/
+VOID
+CreateSerialIoHandles (
+ VOID
+ );
+
+/**
+ Mark memory used by SerialIo devices in ACPI mode as allocated
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+AllocateSerialIoMemory (
+ VOID
+ );
+
+/**
+ Puts all SerialIo controllers (except UARTs in debug mode) in D3.
+ Clears MemoryEnable for all PCI-mode controllers on S3 resume
+**/
+VOID
+ConfigureSerialIoAtS3Resume (
+ VOID
+ );
+
+/**
+ Update ASL definitions for SerialIo devices.
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+UpdateSerialIoAcpiData (
+ VOID
+ );
+
+/**
+ Initialize PCIE SRC clocks in ICC subsystem
+
+ @param[in] GbePortNumber Number of PCIE rootport assigned to GbE adapter
+
+**/
+VOID
+ConfigurePchPcieClocks (
+ IN UINTN GbePortNumber
+ );
+
+/**
+ Initialize Intel High Definition Audio ACPI Tables
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_LOAD_ERROR ACPI table cannot be installed
+ @retval EFI_UNSUPPORTED ACPI table not set because DSP is disabled
+**/
+EFI_STATUS
+PchHdAudioAcpiInit (
+ VOID
+ );
+
+/**
+ Configure eMMC in HS400 Mode
+
+ @param[in] This A pointer to PCH_EMMC_TUNING_PROTOCOL structure
+ @param[in] Revision Revision parameter used to verify the layout of EMMC_INFO and TUNINGDATA.
+ @param[in] EmmcInfo A pointer to EMMC_INFO structure
+ @param[out] EmmcTuningData A pointer to EMMC_TUNING_DATA structure
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_NOT_FOUND The item was not found
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER A parameter was incorrect.
+ @retval EFI_DEVICE_ERROR Hardware Error
+ @retval EFI_NO_MEDIA No media
+ @retval EFI_MEDIA_CHANGED Media Change
+ @retval EFI_BAD_BUFFER_SIZE Buffer size is bad
+ @retval EFI_CRC_ERROR Command or Data CRC Error
+**/
+EFI_STATUS
+EFIAPI
+ConfigureEmmcHs400Mode (
+ IN PCH_EMMC_TUNING_PROTOCOL *This,
+ IN UINT8 Revision,
+ IN EMMC_INFO *EmmcInfo,
+ OUT EMMC_TUNING_DATA *EmmcTuningData
+ );
+
+/**
+ Get eMMC PCI cfg space address
+
+ @return UINT64 PCI base address
+**/
+UINT64
+ScsGetEmmcBaseAddress (
+ VOID
+ );
+
+/**
+ Perform the remaining configuration on PCH SATA to perform device detection,
+ then set the SATA SPD and PxE corresponding, and set the Register Lock on PCH SATA
+
+ @retval None
+**/
+VOID
+ConfigurePchSataOnEndOfDxe (
+ VOID
+ );
+
+/**
+ Update ASL data for CNVI Device.
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+UpdateCnviAcpiData (
+ VOID
+ );
+
+/**
+ Initialize Pch acpi
+ @param[in] ImageHandle Handle for the image of this driver
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+PchAcpiInit (
+ IN EFI_HANDLE ImageHandle
+ );
+
+/**
+ Update ASL object before Boot
+
+ @retval EFI_STATUS
+ @retval EFI_NOT_READY The Acpi protocols are not ready.
+**/
+EFI_STATUS
+PchUpdateNvsArea (
+ VOID
+ );
+
+/**
+ Initialize PCH Nvs Area opeartion region.
+
+**/
+VOID
+PatchPchNvsAreaAddress (
+ VOID
+ );
+
+#endif // _PCH_INIT_DXE_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
new file mode 100644
index 0000000000..693c5d3f50
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.h
@@ -0,0 +1,187 @@
+/** @file
+ Header file for PCH Init SMM Handler
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PCH_INIT_SMM_H_
+#define _PCH_INIT_SMM_H_
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmIoTrapDispatch2.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/HobLib.h>
+#include <Protocol/SmmCpu.h>
+#include <Library/TimerLib.h>
+
+#include <IndustryStandard/Pci30.h>
+#include <Library/PmcLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/SataLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/PchEspiLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Private/Library/PchPciExpressHelpersLib.h>
+#include <Protocol/PchPcieSmiDispatch.h>
+#include <Protocol/PchTcoSmiDispatch.h>
+#include <Protocol/PchSmiDispatch.h>
+#include <Protocol/PchEspiSmiDispatch.h>
+#include <Protocol/PchSmmIoTrapControl.h>
+#include <Private/Protocol/PchNvsArea.h>
+#include <Private/Protocol/PcieIoTrap.h>
+#include <SiConfigHob.h>
+#include <Private/PchConfigHob.h>
+#include <Private/Library/PmcPrivateLib.h>
+
+extern EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *mPchIoTrap;
+extern EFI_SMM_SX_DISPATCH2_PROTOCOL *mSxDispatch;
+
+extern PCH_NVS_AREA *mPchNvsArea;
+extern UINT16 mAcpiBaseAddr;
+
+extern EFI_PHYSICAL_ADDRESS mResvMmioBaseAddr;
+extern UINTN mResvMmioSize;
+
+//
+// NOTE: The module variables of policy here are only valid in post time, but not runtime time.
+//
+extern PCH_CONFIG_HOB *mPchConfigHob;
+extern SI_CONFIG_HOB_DATA *mSiConfigHobData;
+
+/**
+ Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling
+
+ @param[in] ImageHandle The image handle of this module
+ @param[in] SystemTable The EFI System Table
+
+ @retval EFI_SUCCESS The function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InitializePchPcieSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ PCIE Hotplug SMI call back function for each Root port
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] RpContext Rootport context, which contains RootPort Index,
+ and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieSmiRpHandlerFunction (
+ IN EFI_HANDLE DispatchHandle,
+ IN PCH_PCIE_SMI_RP_CONTEXT *RpContext
+ );
+
+/**
+ PCIE Link Active State Change Hotplug SMI call back function for all Root ports
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] RpContext Rootport context, which contains RootPort Index,
+ and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieLinkActiveStateChange (
+ IN EFI_HANDLE DispatchHandle,
+ IN PCH_PCIE_SMI_RP_CONTEXT *RpContext
+ );
+
+/**
+ PCIE Link Equalization Request SMI call back function for all Root ports
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] RpContext Rootport context, which contains RootPort Index,
+ and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieLinkEqHandlerFunction (
+ IN EFI_HANDLE DispatchHandle,
+ IN PCH_PCIE_SMI_RP_CONTEXT *RpContext
+ );
+
+/**
+ An IoTrap callback to config PCIE power management settings
+
+ @param[in] DispatchHandle - The handle of this callback, obtained when registering
+ @param[in] DispatchContext - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT
+
+**/
+VOID
+EFIAPI
+PchPcieIoTrapSmiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_IO_TRAP_CONTEXT *CallbackContext,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommBufferSize
+ );
+
+/**
+ Initializes the PCH SMM handler for PCH save and restore
+
+ @param[in] ImageHandle - Handle for the image of this driver
+ @param[in] SystemTable - Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS - PCH SMM handler was installed
+**/
+EFI_STATUS
+EFIAPI
+PchInitLateSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Register dispatch function to handle GPIO pads Sx isolation
+**/
+VOID
+InitializeGpioSxIsolationSmm (
+ VOID
+ );
+
+/**
+ Entry point for Pch Bios Write Protect driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchBiosWriteProtect (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ This fuction install SPI ASYNC SMI handler.
+
+ @retval EFI_SUCCESS Initialization complete.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpiAsyncSmiHandler (
+ VOID
+ );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h
new file mode 100644
index 0000000000..08e64fa5a7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.h
@@ -0,0 +1,132 @@
+/** @file
+ Header file for SMM Control Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _SMM_CONTROL_DRIVER_H_
+#define _SMM_CONTROL_DRIVER_H_
+
+#include <Protocol/SmmControl2.h>
+
+
+#define SMM_CONTROL_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('i', '4', 's', 'c')
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_SMM_CONTROL2_PROTOCOL SmmControl;
+} SMM_CONTROL_PRIVATE_DATA;
+
+#define SMM_CONTROL_PRIVATE_DATA_FROM_THIS(a) CR (a, SMM_CONTROL_PRIVATE_DATA, SmmControl, SMM_CONTROL_DEV_SIGNATURE)
+
+//
+// Prototypes
+//
+
+/**
+ <b>SmmControl DXE RUNTIME Module Entry Point</b>\n
+ - <b>Introduction</b>\n
+ The SmmControl module is a DXE RUNTIME driver that provides a standard way
+ for other drivers to trigger software SMIs.
+
+ - @pre
+ - PCH Power Management I/O space base address has already been programmed.
+ If SmmControl Runtime DXE driver is run before Status Code Runtime Protocol
+ is installed and there is the need to use Status code in the driver, it will
+ be necessary to add EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID to the dependency file.
+ - EFI_SMM_BASE2_PROTOCOL
+ - Documented in the System Management Mode Core Interface Specification.
+
+ - @result
+ The SmmControl driver produces the EFI_SMM_CONTROL_PROTOCOL documented in
+ System Management Mode Core Interface Specification.
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_STATUS Results of the installation of the SMM Control Protocol
+**/
+EFI_STATUS
+EFIAPI
+SmmControlDriverEntryInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Trigger the software SMI
+
+ @param[in] Data The value to be set on the software SMI data port
+
+ @retval EFI_SUCCESS Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+ UINT8 Data
+ );
+
+/**
+ Clear the SMI status
+
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_DEVICE_ERROR Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmmClear (
+ VOID
+ );
+
+/**
+ This routine generates an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in, out] ArgumentBuffer The buffer of argument
+ @param[in, out] ArgumentBufferSize The size of the argument buffer
+ @param[in] Periodic Periodic or not
+ @param[in] ActivationInterval Interval of periodic SMI
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Activate (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN OUT UINT8 *ArgumentBuffer OPTIONAL,
+ IN OUT UINT8 *ArgumentBufferSize OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ );
+
+/**
+ This routine clears an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in] Periodic Periodic or not
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Deactivate (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN BOOLEAN Periodic OPTIONAL
+ );
+/**
+ Disable all pending SMIs
+
+**/
+VOID
+EFIAPI
+DisablePendingSmis (
+ VOID
+ );
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
new file mode 100644
index 0000000000..bcbdb12dc3
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchAcpi.c
@@ -0,0 +1,451 @@
+/** @file
+ This is the driver that initializes the Intel PCH.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <IndustryStandard/Pci.h>
+
+#include "PchInit.h"
+#include <Protocol/PchPolicy.h>
+#include <ConfigBlock/GpioDevConfig.h>
+#include <ConfigBlock/ScsConfig.h>
+#include <Library/AslUpdateLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/GpioLib.h>
+#include <Library/GpioNativeLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchSerialIoLib.h>
+#include <Library/PchGbeLib.h>
+#include <Private/PchRstHob.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/SataLib.h>
+#include <Register/PchRegsSata.h>
+#include <TraceHubCommonConfig.h>
+#include <PchReservedResources.h>
+#include <Register/PchRegsTraceHub.h>
+
+//
+// Module variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_NVS_AREA_PROTOCOL mPchNvsAreaProtocol;
+
+/**
+ Retrieve interrupt information about a PCH device from policy
+
+ @param[in] Device PCI device number
+
+ @retval PCH_DEVICE_INTERRUPT_CONFIG structure with device's interrupt information
+**/
+PCH_DEVICE_INTERRUPT_CONFIG
+GetInterruptPolicy (
+ IN PCH_SERIAL_IO_CONTROLLER Device
+ )
+{
+ PCH_DEVICE_INTERRUPT_CONFIG EmptyRecord;
+ UINT8 DevNum;
+ UINT8 FuncNum;
+ UINT8 Index;
+
+ ZeroMem (&EmptyRecord, sizeof (PCH_DEVICE_INTERRUPT_CONFIG));
+ DevNum = GetSerialIoDeviceNumber (Device);
+ FuncNum = GetSerialIoFunctionNumber (Device);
+
+ for (Index = 0; Index < mPchConfigHob->Interrupt.NumOfDevIntConfig; Index++) {
+ if ((mPchConfigHob->Interrupt.DevIntConfig[Index].Device == DevNum) &&
+ (mPchConfigHob->Interrupt.DevIntConfig[Index].Function == FuncNum)) {
+ return mPchConfigHob->Interrupt.DevIntConfig[Index];
+ }
+ }
+ return EmptyRecord;
+}
+
+/**
+ Update ASL definitions for SerialIo devices.
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+UpdateSerialIoAcpiData (
+ VOID
+ )
+{
+ PCH_SERIAL_IO_CONTROLLER Index;
+
+ for (Index = 0; Index < GetPchMaxSerialIoControllersNum (); Index++) {
+ mPchNvsAreaProtocol.Area->SMD[Index] = mPchConfigHob->SerialIo.DevMode[Index];
+ mPchNvsAreaProtocol.Area->SIR[Index] = (GetInterruptPolicy (Index)).Irq;
+ mPchNvsAreaProtocol.Area->SB0[Index] = (UINT32) FindSerialIoBar (Index, 0);
+ mPchNvsAreaProtocol.Area->SB1[Index] = (UINT32) FindSerialIoBar (Index, 1);
+ }
+ if (IsPchH ()) {
+ mPchNvsAreaProtocol.Area->SMD[PchSerialIoIndexI2C4] = PchSerialIoDisabled;
+ mPchNvsAreaProtocol.Area->SMD[PchSerialIoIndexI2C5] = PchSerialIoDisabled;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Update NVS Area after RST PCIe Storage Remapping and before Boot
+**/
+VOID
+PchUpdateNvsAreaAfterRemapping (
+ VOID
+ )
+{
+ UINTN Index;
+ VOID *Hob;
+ PCH_RST_HOB *RstHob;
+
+ Hob = GetFirstGuidHob (&gPchRstHobGuid);
+ if (Hob == NULL) {
+ DEBUG (( DEBUG_INFO , "PchUpdateNvsAreaAfterRemapping: cannot fetch RstHob" ));
+ return;
+ }
+
+ RstHob = (PCH_RST_HOB *) GET_GUID_HOB_DATA (Hob);
+
+ for (Index = 0; Index < PCH_MAX_RST_PCIE_STORAGE_CR; Index++) {
+ mPchNvsAreaProtocol.Area->RstPcieStorageInterfaceType[Index] = RstHob->RstCrConfiguration[Index].DeviceInterface;
+ mPchNvsAreaProtocol.Area->RstPcieStoragePmCapPtr[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].PmCapPtr;
+ mPchNvsAreaProtocol.Area->RstPcieStoragePcieCapPtr[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].PcieCapPtr;
+ mPchNvsAreaProtocol.Area->RstPcieStorageL1ssCapPtr[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].L1ssCapPtr;
+ mPchNvsAreaProtocol.Area->RstPcieStorageEpL1ssControl2[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointL1ssControl2;
+ mPchNvsAreaProtocol.Area->RstPcieStorageEpL1ssControl1[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointL1ssControl1;
+ mPchNvsAreaProtocol.Area->RstPcieStorageLtrCapPtr[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].LtrCapPtr;
+ mPchNvsAreaProtocol.Area->RstPcieStorageEpLtrData[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointLtrData;
+ mPchNvsAreaProtocol.Area->RstPcieStorageEpLctlData16[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointLctlData16;
+ mPchNvsAreaProtocol.Area->RstPcieStorageEpDctlData16[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointDctlData16;
+ mPchNvsAreaProtocol.Area->RstPcieStorageEpDctl2Data16[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].EndpointDctl2Data16;
+ mPchNvsAreaProtocol.Area->RstPcieStorageRpDctl2Data16[Index] = RstHob->SavedRemapedDeviceConfigSpace[Index].RootPortDctl2Data16;
+ mPchNvsAreaProtocol.Area->RstPcieStorageUniqueTableBar[Index] = RstHob->RstCrConfiguration[Index].EndPointUniqueMsixTableBar;
+ mPchNvsAreaProtocol.Area->RstPcieStorageUniqueTableBarValue[Index] = RstHob->RstCrConfiguration[Index].EndPointUniqueMsixTableBarValue;
+ mPchNvsAreaProtocol.Area->RstPcieStorageUniquePbaBar[Index] = RstHob->RstCrConfiguration[Index].EndPointUniqueMsixPbaBar;
+ mPchNvsAreaProtocol.Area->RstPcieStorageUniquePbaBarValue[Index] = RstHob->RstCrConfiguration[Index].EndPointUniqueMsixPbaBarValue;
+ mPchNvsAreaProtocol.Area->RstPcieStorageRootPortNum[Index] = RstHob->RstCrConfiguration[Index].RootPortNum;
+ }
+}
+
+/**
+ PCH ACPI initialization before Boot Sript Table is closed
+ It update ACPI table and ACPI NVS area.
+
+ @param[in] Event A pointer to the Event that triggered the callback.
+ @param[in] Context A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+PchAcpiOnEndOfDxe (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "PchAcpiOnEndOfDxe() Start\n"));
+
+ ///
+ /// Closed the event to avoid call twice when launch shell
+ ///
+ gBS->CloseEvent (Event);
+
+ //
+ // Init HDA Audio ACPI tables
+ //
+ PchHdAudioAcpiInit ();
+
+ //
+ // Update ASL definitions for SerialIo devices.
+ //
+ UpdateSerialIoAcpiData ();
+ UpdateCnviAcpiData ();
+
+ //
+ // Update Pch Nvs Area
+ //
+ Status = PchUpdateNvsArea ();
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ DEBUG ((DEBUG_INFO, "PchAcpiOnEndOfDxe() End\n"));
+
+ return;
+}
+
+/**
+ Initialize Pch acpi
+ @param[in] ImageHandle Handle for the image of this driver
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+PchAcpiInit (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT EndOfDxeEvent;
+
+ DEBUG ((DEBUG_INFO, "Install PCH NVS protocol\n"));
+
+ Status = (gBS->AllocatePool) (EfiACPIMemoryNVS, sizeof (PCH_NVS_AREA), (VOID **) &mPchNvsAreaProtocol.Area);
+ ASSERT_EFI_ERROR (Status);
+
+ ZeroMem ((VOID *) mPchNvsAreaProtocol.Area, sizeof (PCH_NVS_AREA));
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gPchNvsAreaProtocolGuid,
+ &mPchNvsAreaProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Update the NVS Area after RST PCIe Storage Remapping
+ ///
+ PchUpdateNvsAreaAfterRemapping ();
+
+ //
+ // Register an end of DXE event for PCH ACPI to do tasks before invoking any UEFI drivers,
+ // applications, or connecting consoles,...
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ PchAcpiOnEndOfDxe,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Update ASL object before Boot
+
+ @retval EFI_STATUS
+ @retval EFI_NOT_READY The Acpi protocols are not ready.
+**/
+EFI_STATUS
+PchUpdateNvsArea (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT32 HpetBaseAdress;
+ GPIO_GROUP GroupToGpeDwX[3];
+ UINT32 GroupDw[3];
+ UINTN RpDev;
+ UINTN RpFun;
+ UINT32 Data32;
+ PCH_POLICY_PROTOCOL *PchPolicy;
+ PCH_GPIO_DXE_CONFIG *GpioDxeConfig;
+
+ ///
+ /// Get PCH Policy Protocol
+ ///
+ Status = gBS->LocateProtocol (&gPchPolicyProtocolGuid, NULL, (VOID **)&PchPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Get GPIO DXE Config Block
+ ///
+ Status = GetConfigBlock ((VOID *)PchPolicy, &gGpioDxeConfigGuid, (VOID *)&GpioDxeConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update ASL PCIE port address according to root port device and function
+ //
+ for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+ Status = GetPchPcieRpDevFun (Index, &RpDev, &RpFun);
+ ASSERT_EFI_ERROR (Status);
+
+ Data32 = ((UINT8) RpDev << 16) | (UINT8) RpFun;
+ mPchNvsAreaProtocol.Area->RpAddress[Index] = Data32;
+
+ //
+ // Update Maximum Snoop Latency and Maximum No-Snoop Latency values for PCIE
+ //
+ mPchNvsAreaProtocol.Area->PcieLtrMaxSnoopLatency[Index] = mPchConfigHob->PcieRp.RootPort[Index].LtrMaxSnoopLatency;
+ mPchNvsAreaProtocol.Area->PcieLtrMaxNoSnoopLatency[Index] = mPchConfigHob->PcieRp.RootPort[Index].LtrMaxNoSnoopLatency;
+ }
+
+ //
+ // Update PCHS.
+ //
+ mPchNvsAreaProtocol.Area->PchSeries = PchSeries ();
+ //
+ // Update PCHG.
+ //
+ mPchNvsAreaProtocol.Area->PchGeneration = (UINT16) PchGeneration ();
+ //
+ // Update PSTP.
+ //
+ mPchNvsAreaProtocol.Area->PchStepping = (UINT16) PchStepping ();
+ //
+ // Update HPET base address.
+ //
+ PchHpetBaseGet (&HpetBaseAdress);
+ mPchNvsAreaProtocol.Area->HPTE = TRUE; // @todo remove the NVS, since it's always enabled.
+ mPchNvsAreaProtocol.Area->HPTB = HpetBaseAdress;
+ //
+ // Update SBREG_BAR.
+ //
+ mPchNvsAreaProtocol.Area->SBRG = PCH_PCR_BASE_ADDRESS;
+
+ //
+ // Update PMC ACPIBASE and PWRMBASE
+ //
+ mPchNvsAreaProtocol.Area->PMBS = PmcGetAcpiBase ();
+
+ mPchNvsAreaProtocol.Area->PWRM = PmcGetPwrmBase ();
+
+ //
+ // Update GPIO device ACPI variables
+ //
+ mPchNvsAreaProtocol.Area->SGIR = mPchConfigHob->Interrupt.GpioIrqRoute;
+ mPchNvsAreaProtocol.Area->GPHD = (UINT8)GpioDxeConfig->HideGpioAcpiDevice;
+
+ //
+ // Update GPP_X to GPE_DWX mapping.
+ //
+ GpioGetGroupDwToGpeDwX (
+ &GroupToGpeDwX[0], &GroupDw[0],
+ &GroupToGpeDwX[1], &GroupDw[1],
+ &GroupToGpeDwX[2], &GroupDw[2]
+ );
+
+ //
+ // GEI0/1/2 and GED0/1/2 are objects for informing how GPIO groups are mapped to GPE0.
+ // If Group is mapped to 1-Tier GPE information is also stored on what Group DW
+ // is mapped to GPE_DWx. Because GPE_DWx register is 32 bits large if groups have more than
+ // 32 pads only part of it can be mapped.
+ //
+ // GEIx - GroupIndex mapped to GPE0_DWx
+ // GEDx - DoubleWorld part of Group: 0 - pins 31-0, 1 - pins 63-32, ...
+ //
+ mPchNvsAreaProtocol.Area->GEI0 = (UINT8) GpioGetGroupIndexFromGroup (GroupToGpeDwX[0]);
+ mPchNvsAreaProtocol.Area->GEI1 = (UINT8) GpioGetGroupIndexFromGroup (GroupToGpeDwX[1]);
+ mPchNvsAreaProtocol.Area->GEI2 = (UINT8) GpioGetGroupIndexFromGroup (GroupToGpeDwX[2]);
+ mPchNvsAreaProtocol.Area->GED0 = (UINT8) GroupDw[0];
+ mPchNvsAreaProtocol.Area->GED1 = (UINT8) GroupDw[1];
+ mPchNvsAreaProtocol.Area->GED2 = (UINT8) GroupDw[2];
+
+ //
+ // SCS Configuration
+ //
+ // Update eMMC HS400 mode enablement
+ //
+ mPchNvsAreaProtocol.Area->EMH4 = (UINT8) mPchConfigHob->Scs.ScsEmmcHs400Enabled;
+ mPchNvsAreaProtocol.Area->EmmcEnabled = (UINT8) mPchConfigHob->Scs.ScsEmmcEnabled;
+
+ //
+ // Update eMMC Driver Strength
+ // Per eMMC 5.01 JEDEC Specification (JESD84-B50.1, Table 186)
+ // Nominal Impedance - Driver Type Values:
+ // 50 Ohm 0x0
+ // 33 Ohm 0x1
+ // 40 Ohm 0x4
+ //
+ switch (mPchConfigHob->Scs.ScsEmmcHs400DriverStrength) {
+ case DriverStrength33Ohm:
+ mPchNvsAreaProtocol.Area->EMDS = 0x1;
+ break;
+ case DriverStrength40Ohm:
+ mPchNvsAreaProtocol.Area->EMDS = 0x4;
+ break;
+ case DriverStrength50Ohm:
+ default:
+ mPchNvsAreaProtocol.Area->EMDS = 0x0;
+ }
+
+ mPchNvsAreaProtocol.Area->SdPowerEnableActiveHigh = (UINT8) mPchConfigHob->Scs.ScsSdPowerEnableActiveHigh;
+ mPchNvsAreaProtocol.Area->SdCardEnabled = (UINT8) mPchConfigHob->Scs.ScsSdCardEnabled;
+
+ //
+ // SATA configuration.
+ //
+ if (PciSegmentRead16 (GetSataRegBase (SATA_1_CONTROLLER_INDEX) + PCI_DEVICE_ID_OFFSET) == 0xFFFF) {
+ mPchNvsAreaProtocol.Area->SataPortPresence = 0;
+ } else {
+ mPchNvsAreaProtocol.Area->SataPortPresence = PciSegmentRead8 (GetSataRegBase (SATA_1_CONTROLLER_INDEX) + R_SATA_CFG_PCS + 2);
+ }
+
+ //
+ // CPU SKU
+ //
+ mPchNvsAreaProtocol.Area->CpuSku = GetCpuSku ();
+
+ mPchNvsAreaProtocol.Area->SlpS0VmRuntimeControl = (UINT8)mPchConfigHob->Pm.SlpS0VmRuntimeControl;
+ mPchNvsAreaProtocol.Area->SlpS0Vm070VSupport = (UINT8)mPchConfigHob->Pm.SlpS0Vm070VSupport;
+ mPchNvsAreaProtocol.Area->SlpS0Vm075VSupport = (UINT8)mPchConfigHob->Pm.SlpS0Vm075VSupport;
+ mPchNvsAreaProtocol.Area->PsOnEnable = (UINT8)mPchConfigHob->Pm.PsOnEnable;
+
+ for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+ mPchNvsAreaProtocol.Area->LtrEnable[Index] = (UINT8)mPchConfigHob->PcieRp.RootPort[Index].LtrEnable;
+ }
+
+ mPchNvsAreaProtocol.Area->GBES = PchIsGbePresent ();
+
+ //
+ // Update PCH Trace Hub Mode
+ //
+ mPchNvsAreaProtocol.Area->PchTraceHubMode = (UINT8) mPchConfigHob->PchTraceHub.PchTraceHubMode;
+ //
+ // if SCRPD0[24] is set, force TH to be host debugger mode.
+ //
+ if (MmioRead32 (PCH_TRACE_HUB_MTB_BASE_ADDRESS) != 0xFFFFFFFF) {
+ if (MmioRead32 (PCH_TRACE_HUB_MTB_BASE_ADDRESS + R_TRACE_HUB_MEM_CSR_MTB_SCRATCHPAD0) & BIT24) {
+ mPchNvsAreaProtocol.Area->PchTraceHubMode = TraceHubModeHostDebugger;
+ }
+ }
+
+ //
+ // Update TWMB, Temp memory base address
+ //
+ mPchNvsAreaProtocol.Area->TempRsvdMemBase = (UINT32) PcdGet32 (PcdSiliconInitTempMemBaseAddr);
+
+ return Status;
+}
+
+/**
+ Initialize PCH Nvs Area opeartion region.
+
+**/
+VOID
+PatchPchNvsAreaAddress (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Address;
+ UINT16 Length;
+
+ Status = InitializeAslUpdateLib ();
+ ASSERT_EFI_ERROR (Status);
+
+ Address = (UINT32) (UINTN) mPchNvsAreaProtocol.Area;
+ Length = (UINT16) sizeof (PCH_NVS_AREA);
+ DEBUG ((DEBUG_INFO, "PatchPchNvsAreaAddress: PCH NVS Address %x Length %x\n", Address, Length));
+ Status = UpdateNameAslCode (SIGNATURE_32 ('P','N','V','B'), &Address, sizeof (Address));
+ ASSERT_EFI_ERROR (Status);
+ Status = UpdateNameAslCode (SIGNATURE_32 ('P','N','V','L'), &Length, sizeof (Length));
+ ASSERT_EFI_ERROR (Status);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
new file mode 100644
index 0000000000..4e38db1027
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchCnviAcpi.c
@@ -0,0 +1,33 @@
+/** @file
+ Initializes PCH CNVi device ACPI data.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include "PchInit.h"
+#include <Library/DxeSaPolicyLib.h>
+
+/**
+ Update ASL definitions for CNVi device.
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+UpdateCnviAcpiData (
+ VOID
+ )
+{
+
+ DEBUG ((DEBUG_INFO, "UpdateCnviAcpiData() Start\n"));
+
+ mPchNvsAreaProtocol.Area->CnviMode = (UINT8) mPchConfigHob->Cnvi.Mode;
+
+ DEBUG ((DEBUG_INFO, "UpdateCnviAcpiData() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
new file mode 100644
index 0000000000..57f2e1dca0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchHdaAcpi.c
@@ -0,0 +1,323 @@
+/** @file
+ Initializes the PCH HD Audio ACPI Tables.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/AcpiTable.h>
+
+#include "PchInit.h"
+#include <Protocol/PchPolicy.h>
+#include <ConfigBlock/HdAudioConfig.h>
+#include <Private/PchConfigHob.h>
+#include <Library/PchInfoLib.h>
+#include <Private/Library/PchHdaLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsHda.h>
+
+PCH_HDA_NHLT_ENDPOINTS mPchHdaNhltEndpoints[HdaEndpointMax] =
+{
+ {HdaDmicX1, B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT, 0, FALSE},
+ {HdaDmicX2, (B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT | B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT), 0, FALSE},
+ {HdaDmicX4, (B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT | B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT), 0, FALSE},
+ {HdaBtRender, (B_HDA_BT_NARROWBAND_FORMAT | B_HDA_BT_WIDEBAND_FORMAT | B_HDA_BT_A2DP_FORMAT), 0, FALSE},
+ {HdaBtCapture, (B_HDA_BT_NARROWBAND_FORMAT | B_HDA_BT_WIDEBAND_FORMAT), 0, FALSE},
+ {HdaI2sRender1, B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_RENDER_DEVICE_INFO, FALSE},
+ {HdaI2sRender2, B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_RENDER_DEVICE_INFO, FALSE},
+ {HdaI2sCapture, B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT, B_HDA_I2S_CAPTURE_DEVICE_INFO, FALSE}
+};
+
+#define DSP_FW_STOLEN_MEMORY_SIZE 0x400000 //4MB
+/**
+ Allocates 4MB of memory for DSP FW usage.
+
+ @retval EFI_PHYSICAL_ADDRESS Allocated memory address
+**/
+EFI_PHYSICAL_ADDRESS
+AllocateAudioDspStolenMemory (
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS DspStolenMemBaseAddress;
+
+ DspStolenMemBaseAddress = 0;
+
+ DEBUG ((DEBUG_INFO, "AllocateAudioDspStolenMemory()\n"));
+
+ //
+ // Reserve memory to store Acpi Debug data.
+ //
+ DspStolenMemBaseAddress = 0xFFFFFFFF;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES (DSP_FW_STOLEN_MEMORY_SIZE),
+ &DspStolenMemBaseAddress
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ ZeroMem ((VOID *) (UINTN) DspStolenMemBaseAddress, DSP_FW_STOLEN_MEMORY_SIZE);
+
+ mPchNvsAreaProtocol.Area->DSPM = (UINT32) DspStolenMemBaseAddress;
+ DEBUG ((DEBUG_INFO, "mPchNvsAreaProtocol.Area->DSPM = 0x%016x\n", mPchNvsAreaProtocol.Area->DSPM));
+
+ return DspStolenMemBaseAddress;
+}
+
+/**
+ Retrieves address of NHLT table from XSDT/RSDT.
+
+ @retval NHLT_ACPI_TABLE* Pointer to NHLT table if found
+ @retval NULL NHLT could not be found
+**/
+NHLT_ACPI_TABLE *
+LocateNhltAcpiTable (
+ VOID
+ )
+{
+ EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
+ EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
+ NHLT_ACPI_TABLE *Nhlt;
+ UINTN Index;
+ UINT64 Data64;
+ EFI_STATUS Status;
+ Rsdp = NULL;
+ Xsdt = NULL;
+ Nhlt = NULL;
+
+ ///
+ /// Find the AcpiSupport protocol returns RSDP (or RSD PTR) address.
+ ///
+ DEBUG ((DEBUG_INFO, "LocateNhltAcpiTable() Start\n"));
+
+ Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID *) &Rsdp);
+ if (EFI_ERROR (Status) || (Rsdp == NULL)) {
+ DEBUG ((DEBUG_ERROR, "EFI_ERROR or Rsdp == NULL\n"));
+ return NULL;
+ }
+
+ Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress;
+ if (Xsdt == NULL || Xsdt->Signature != EFI_ACPI_5_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+ // If XSDT has not been found, check RSDT
+ Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;
+ if (Xsdt == NULL || Xsdt->Signature != EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, "XSDT/RSDT == NULL or wrong signature\n"));
+ return NULL;
+ }
+ }
+
+ for (Index = sizeof (EFI_ACPI_DESCRIPTION_HEADER); Index < Xsdt->Length; Index = Index + sizeof (UINT64)) {
+ Data64 = *(UINT64 *) ((UINT8 *) Xsdt + Index);
+ Nhlt = (NHLT_ACPI_TABLE *) (UINTN) Data64;
+ if (Nhlt->Header.Signature == NHLT_ACPI_TABLE_SIGNATURE) {
+ break;
+ }
+ }
+
+ if (Nhlt == NULL || Nhlt->Header.Signature != NHLT_ACPI_TABLE_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, "Nhlt == NULL or wrong signature\n"));
+ return NULL;
+ }
+
+ DEBUG ((DEBUG_INFO, "Found NhltTable, Address = 0x%016x\n", Nhlt));
+
+ return Nhlt;
+}
+
+/**
+ Constructs and installs NHLT table.
+
+ @retval EFI_SUCCESS ACPI Table installed successfully
+ @retval EFI_UNSUPPORTED ACPI Table protocol not found
+**/
+EFI_STATUS
+PublishNhltAcpiTable (
+ VOID
+ )
+{
+ UINTN AcpiTableKey;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ NHLT_ACPI_TABLE *NhltTable;
+ UINT32 TableLength;
+ EFI_STATUS Status;
+
+ AcpiTable = NULL;
+ NhltTable = NULL;
+ AcpiTableKey = 0;
+
+ DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() Start\n"));
+
+ //
+ // Locate ACPI support protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);
+ if ( EFI_ERROR (Status) || AcpiTable == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ NhltConstructor (mPchHdaNhltEndpoints, &NhltTable, &TableLength);
+ NhltAcpiHeaderConstructor (NhltTable, TableLength);
+
+ Status = AcpiTable->InstallAcpiTable (AcpiTable, NhltTable, NhltTable->Header.Length, &AcpiTableKey);
+
+ DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() End\n"));
+ return Status;
+}
+
+/**
+ Sets NVS ACPI variables for HDAS._DSM and SNDW._DSD accordingly to policy.
+
+ @param[in] NhltAcpiTableAddress
+ @param[in] NhltAcpiTableLength
+ @param[in] *HdAudioConfigHob
+ @param[in] *HdAudioDxeConfig
+**/
+VOID
+UpdateHdaAcpiData (
+ IN UINT64 NhltAcpiTableAddress,
+ IN UINT32 NhltAcpiTableLength,
+ IN CONST HDAUDIO_HOB *HdAudioConfigHob,
+ IN CONST PCH_HDAUDIO_DXE_CONFIG *HdAudioDxeConfig
+ )
+{
+ DEBUG ((DEBUG_INFO, "UpdateHdaAcpiData():\n NHLT Address = 0x%016x, Length = 0x%08x\n", NhltAcpiTableAddress, NhltAcpiTableLength));
+ DEBUG ((DEBUG_INFO, " FeatureMask = 0x%08x\n", HdAudioDxeConfig->DspFeatureMask));
+
+ mPchNvsAreaProtocol.Area->NHLA = NhltAcpiTableAddress;
+ mPchNvsAreaProtocol.Area->NHLL = NhltAcpiTableLength;
+ mPchNvsAreaProtocol.Area->ADFM = HdAudioDxeConfig->DspFeatureMask;
+ mPchNvsAreaProtocol.Area->SWQ0 = HdAudioConfigHob->AudioLinkSndw1 ? 0 : BIT1;
+ mPchNvsAreaProtocol.Area->SWQ1 = HdAudioConfigHob->AudioLinkSndw2 ? 0 : BIT1;
+ mPchNvsAreaProtocol.Area->SWQ2 = HdAudioConfigHob->AudioLinkSndw3 ? 0 : BIT1;
+ mPchNvsAreaProtocol.Area->SWQ3 = HdAudioConfigHob->AudioLinkSndw4 ? 0 : BIT1;
+}
+
+/**
+ Initialize and publish NHLT (Non-HDA Link Table), update NVS variables.
+
+ @param[in] *HdAudioConfigHob
+ @param[in] *HdAudioDxeConfig
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SetHdaAcpiTable (
+ IN CONST HDAUDIO_HOB *HdAudioConfigHob,
+ IN CONST PCH_HDAUDIO_DXE_CONFIG *HdAudioDxeConfig
+ )
+{
+ NHLT_ACPI_TABLE *NhltTable;
+ EFI_STATUS Status;
+ NhltTable = NULL;
+
+ Status = EFI_SUCCESS;
+
+ if (HdAudioDxeConfig->NhltDefaultFlow == TRUE) {
+ switch (HdAudioDxeConfig->DspEndpointDmic) {
+ case PchHdaDmic1chArray:
+ mPchHdaNhltEndpoints[HdaDmicX1].Enable = TRUE;
+ break;
+ case PchHdaDmic2chArray:
+ mPchHdaNhltEndpoints[HdaDmicX2].Enable = TRUE;
+ break;
+ case PchHdaDmic4chArray:
+ mPchHdaNhltEndpoints[HdaDmicX4].Enable = TRUE;
+ break;
+ case PchHdaDmicDisabled:
+ default:
+ mPchHdaNhltEndpoints[HdaDmicX2].Enable = FALSE;
+ mPchHdaNhltEndpoints[HdaDmicX4].Enable = FALSE;
+ }
+
+ if (HdAudioDxeConfig->DspEndpointBluetooth) {
+ mPchHdaNhltEndpoints[HdaBtRender].Enable = TRUE;
+ mPchHdaNhltEndpoints[HdaBtCapture].Enable = TRUE;
+ }
+
+ if (HdAudioDxeConfig->DspEndpointI2s) {
+ mPchHdaNhltEndpoints[HdaI2sRender1].Enable = TRUE;
+ mPchHdaNhltEndpoints[HdaI2sRender2].Enable = TRUE;
+ mPchHdaNhltEndpoints[HdaI2sCapture].Enable = TRUE;
+ }
+
+ Status = PublishNhltAcpiTable ();
+ }
+ NhltTable = LocateNhltAcpiTable ();
+ if (NhltTable == NULL) {
+ return EFI_LOAD_ERROR;
+ }
+
+ UpdateHdaAcpiData ((UINT64) (UINTN) NhltTable, (UINT32) (NhltTable->Header.Length), HdAudioConfigHob, HdAudioDxeConfig);
+
+ if (IsPchLp () && (PchStepping () < PCH_B0)) {
+ AllocateAudioDspStolenMemory ();
+ }
+
+ DEBUG_CODE ( NhltAcpiTableDump (NhltTable); );
+ return Status;
+}
+
+/**
+ Initialize Intel High Definition Audio ACPI Tables
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_LOAD_ERROR ACPI table cannot be installed
+ @retval EFI_UNSUPPORTED ACPI table not set because DSP is disabled
+**/
+EFI_STATUS
+PchHdAudioAcpiInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT64 HdaPciBase;
+ CONST HDAUDIO_HOB *HdAudioConfigHob;
+ PCH_POLICY_PROTOCOL *PchPolicy;
+ PCH_HDAUDIO_DXE_CONFIG *HdAudioDxeConfig;
+
+
+ DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() Start\n"));
+
+ HdAudioConfigHob = &mPchConfigHob->HdAudio;
+
+ ///
+ /// Get PCH Policy Protocol
+ ///
+ Status = gBS->LocateProtocol (&gPchPolicyProtocolGuid, NULL, (VOID **)&PchPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Get HD Audio DXE Config Block
+ ///
+ Status = GetConfigBlock ((VOID *)PchPolicy, &gHdAudioDxeConfigGuid, (VOID *)&HdAudioDxeConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ HdaPciBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_HDA,
+ PCI_FUNCTION_NUMBER_PCH_HDA,
+ 0
+ );
+
+ if ((PciSegmentRead16 (HdaPciBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) || (HdAudioConfigHob->DspEnable == FALSE)) {
+ // Do not set ACPI tables if HDAudio is Function disabled or DSP is disabled
+ DEBUG ((DEBUG_INFO, "AudioDSP: Non-HDAudio ACPI Table (NHLT) not set!\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = SetHdaAcpiTable (HdAudioConfigHob, HdAudioDxeConfig);
+
+ DEBUG ((DEBUG_INFO, "PchHdAudioAcpiInit() End - Status = %r\n", Status));
+ return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
new file mode 100644
index 0000000000..55f1e086fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInit.c
@@ -0,0 +1,554 @@
+/** @file
+ This is the Common driver that initializes the Intel PCH.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/TimerLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/HobLib.h>
+
+#include "PchInit.h"
+#include <PchPolicyCommon.h>
+#include <Private/Library/PchSpiCommonLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Private/Library/PchDmiLib.h>
+#include <Private/Library/SiScheduleResetLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/BiosLockLib.h>
+#include <Library/PchPcrLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcr.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsPsth.h>
+#include <Register/PchRegsPmc.h>
+
+//
+// Module variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_CONFIG_HOB *mPchConfigHob;
+GLOBAL_REMOVE_IF_UNREFERENCED SI_CONFIG_HOB_DATA *mSiConfigHobData;
+
+//
+// EFI_EVENT
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_EVENT mHeciEvent;
+
+/**
+ Common PchInit Module Entry Point
+**/
+VOID
+PchInitEntryPointCommon (
+ VOID
+ )
+{
+ EFI_PEI_HOB_POINTERS HobPtr;
+
+ DEBUG ((DEBUG_INFO, "PchInitEntryPointCommon() Start\n"));
+
+ //
+ // Get PCH Config HOB.
+ //
+ HobPtr.Guid = GetFirstGuidHob (&gPchConfigHobGuid);
+ ASSERT (HobPtr.Guid != NULL);
+ mPchConfigHob = (PCH_CONFIG_HOB *) GET_GUID_HOB_DATA (HobPtr.Guid);
+
+ //
+ // Get Silicon Config data HOB
+ //
+ HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
+ ASSERT (HobPtr.Guid != NULL);
+ mSiConfigHobData = (SI_CONFIG_HOB_DATA *) GET_GUID_HOB_DATA (HobPtr.Guid);
+
+ DEBUG ((DEBUG_INFO, "PchInitEntryPointCommon() End\n"));
+
+ return;
+}
+
+/**
+ Lock SPI register before boot
+**/
+VOID
+LockSpiConfiguration (
+ VOID
+ )
+{
+ UINTN Index;
+ UINT16 Data16;
+ UINT16 Data16And;
+ UINT16 Data16Or;
+ UINT32 Data32;
+ UINT32 DlockValue;
+ UINT64 PciSpiRegBase;
+ UINT32 PchSpiBar0;
+ UINT32 Timer;
+
+ PciSpiRegBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SPI,
+ PCI_FUNCTION_NUMBER_PCH_SPI,
+ 0
+ );
+
+ //
+ // Check for SPI controller presence before programming
+ //
+ if (PciSegmentRead32 (PciSpiRegBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ return;
+ }
+
+ //
+ // Make sure SPI BAR0 has fixed address before writing to boot script.
+ // The same base address is set in PEI and will be used during resume.
+ //
+ PchSpiBar0 = PCH_SPI_BASE_ADDRESS;
+
+ PciSegmentAnd8 (PciSpiRegBase + PCI_COMMAND_OFFSET, (UINT8) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+ PciSegmentWrite32 (PciSpiRegBase + R_SPI_CFG_BAR0, PchSpiBar0);
+ PciSegmentOr8 (PciSpiRegBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+ //
+ // Program the Flash Protection Range Register based on policy
+ //
+ DlockValue = MmioRead32 (PchSpiBar0 + R_SPI_MEM_DLOCK);
+ for (Index = 0; Index < PCH_FLASH_PROTECTED_RANGES; ++Index) {
+ if ((mPchConfigHob->ProtectRange[Index].WriteProtectionEnable ||
+ mPchConfigHob->ProtectRange[Index].ReadProtectionEnable) != TRUE) {
+ continue;
+ }
+
+ //
+ // Proceed to program the register after ensure it is enabled
+ //
+ Data32 = 0;
+ Data32 |= (mPchConfigHob->ProtectRange[Index].WriteProtectionEnable == TRUE) ? B_SPI_MEM_PRX_WPE : 0;
+ Data32 |= (mPchConfigHob->ProtectRange[Index].ReadProtectionEnable == TRUE) ? B_SPI_MEM_PRX_RPE : 0;
+ Data32 |= ((UINT32) mPchConfigHob->ProtectRange[Index].ProtectedRangeLimit << N_SPI_MEM_PRX_PRL) & B_SPI_MEM_PRX_PRL_MASK;
+ Data32 |= ((UINT32) mPchConfigHob->ProtectRange[Index].ProtectedRangeBase << N_SPI_MEM_PRX_PRB) & B_SPI_MEM_PRX_PRB_MASK;
+ DEBUG ((DEBUG_INFO, "Protected range %d: 0x%08x \n", Index, Data32));
+
+ DlockValue |= (UINT32) (B_SPI_MEM_DLOCK_PR0LOCKDN << Index);
+ MmioWrite32 ((UINTN) (PchSpiBar0 + (R_SPI_MEM_PR0 + (Index * S_SPI_MEM_PRX))), Data32);
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint32,
+ (UINTN) (PchSpiBar0 + (R_SPI_MEM_PR0 + (Index * S_SPI_MEM_PRX))),
+ 1,
+ (VOID *) (UINTN) (PchSpiBar0 + (R_SPI_MEM_PR0 + (Index * S_SPI_MEM_PRX)))
+ );
+ }
+ //
+ // Program DLOCK register
+ //
+ MmioWrite32 ((UINTN) (PchSpiBar0 + R_SPI_MEM_DLOCK), DlockValue);
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint32,
+ (UINTN) (PchSpiBar0 + R_SPI_MEM_DLOCK),
+ 1,
+ (VOID *) (UINTN) (PchSpiBar0 + R_SPI_MEM_DLOCK)
+ );
+
+ ///
+ /// PCH BIOS Spec Section 3.6 Flash Security Recommendation
+ /// In PCH SPI controller the BIOS should set the Flash Configuration Lock-Down bit
+ /// (SPI_BAR0 + 04[15]) at end of post. When set to 1, those Flash Program Registers
+ /// that are locked down by this FLOCKDN bit cannot be written.
+ /// Please refer to the EDS for which program registers are impacted.
+ /// Additionally BIOS must program SPI_BAR0 + 0x04 BIT11 (WRSDIS) to disable Write Status in HW sequencing
+ ///
+
+ //
+ // Ensure there is no pending SPI trasaction before setting lock bits
+ //
+ Timer = 0;
+ while (MmioRead16 (PchSpiBar0 + R_SPI_MEM_HSFSC) & B_SPI_MEM_HSFSC_SCIP) {
+ if (Timer > SPI_WAIT_TIME) {
+ //
+ // SPI transaction is pending too long at this point, exit with error.
+ //
+ DEBUG ((DEBUG_ERROR, "SPI Cycle timeout\n"));
+ ASSERT (FALSE);
+ break;
+ }
+ MicroSecondDelay (SPI_WAIT_PERIOD);
+ Timer += SPI_WAIT_PERIOD;
+ }
+
+ Data16And = B_SPI_MEM_HSFSC_SCIP;
+ Data16 = 0;
+ S3BootScriptSaveMemPoll (
+ S3BootScriptWidthUint16,
+ PchSpiBar0 + R_SPI_MEM_HSFSC,
+ &Data16And,
+ &Data16,
+ SPI_WAIT_PERIOD,
+ SPI_WAIT_TIME / SPI_WAIT_PERIOD
+ );
+
+ //
+ // Clear any outstanding status
+ //
+ Data16Or = B_SPI_MEM_HSFSC_SAF_DLE
+ | B_SPI_MEM_HSFSC_SAF_ERROR
+ | B_SPI_MEM_HSFSC_AEL
+ | B_SPI_MEM_HSFSC_FCERR
+ | B_SPI_MEM_HSFSC_FDONE;
+ Data16And = 0xFFFF;
+ MmioAndThenOr16 (PchSpiBar0 + R_SPI_MEM_HSFSC, Data16And, Data16Or);
+ S3BootScriptSaveMemReadWrite (
+ S3BootScriptWidthUint16,
+ PchSpiBar0 + R_SPI_MEM_HSFSC,
+ &Data16Or,
+ &Data16And
+ );
+
+ //
+ // Set WRSDIS
+ //
+ Data16Or = B_SPI_MEM_HSFSC_WRSDIS;
+ Data16And = 0xFFFF;
+ MmioAndThenOr16 (PchSpiBar0 + R_SPI_MEM_HSFSC, Data16And, Data16Or);
+ S3BootScriptSaveMemReadWrite (
+ S3BootScriptWidthUint16,
+ PchSpiBar0 + R_SPI_MEM_HSFSC,
+ &Data16Or,
+ &Data16And
+ );
+
+ //
+ // Set FLOCKDN
+ //
+ Data16Or = B_SPI_MEM_HSFSC_FLOCKDN;
+ Data16And = 0xFFFF;
+ MmioAndThenOr16 (PchSpiBar0 + R_SPI_MEM_HSFSC, Data16And, Data16Or);
+ S3BootScriptSaveMemReadWrite (
+ S3BootScriptWidthUint16,
+ PchSpiBar0 + R_SPI_MEM_HSFSC,
+ &Data16Or,
+ &Data16And
+ );
+
+ ///
+ /// SPI Flash Programming Guide Section 5.5.2 Vendor Component Lock
+ /// It is strongly recommended that BIOS sets the Vendor Component Lock (VCL) bits. VCL applies
+ /// the lock to both VSCC0 and VSCC1 even if VSCC0 is not used. Without the VCL bits set, it is
+ /// possible to make Host/GbE VSCC register(s) changes in that can cause undesired host and
+ /// integrated GbE Serial Flash functionality.
+ ///
+ MmioOr32 ((UINTN) (PchSpiBar0 + R_SPI_MEM_SFDP0_VSCC0), B_SPI_MEM_SFDP0_VSCC0_VCL);
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint32,
+ (UINTN) (PchSpiBar0 + R_SPI_MEM_SFDP0_VSCC0),
+ 1,
+ (VOID *) (UINTN) (PchSpiBar0 + R_SPI_MEM_SFDP0_VSCC0)
+ );
+}
+
+/**
+ Process all the lock downs
+**/
+VOID
+ProcessAllLocks (
+ VOID
+ )
+{
+ UINT8 Data8;
+ UINT16 Data16And;
+ UINT16 Data16Or;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT64 PciLpcRegBase;
+ UINT16 TcoBase;
+ UINT64 PciSpiRegBase;
+
+ PciLpcRegBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ PciSpiRegBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SPI,
+ PCI_FUNCTION_NUMBER_PCH_SPI,
+ 0
+ );
+
+ PchTcoBaseGet (&TcoBase);
+
+ //
+ // Lock function disable (ST and NST PG) register fields.
+ //
+ PmcLockFunctionDisableConfigWithS3BootScript ();
+
+ ///
+ /// PCH BWG Additional PCH DMI and OP-DMI Programming Steps
+ /// Lock DMI.
+ ///
+ PchDmiSetLockWithS3BootScript ();
+
+ //
+ // Lock SPI register before boot.
+ //
+ LockSpiConfiguration ();
+
+ ///
+ /// Additional Power Management Programming
+ /// Step 3
+ /// Lock configuration after stretch and ACPI base programming completed.
+ ///
+ PmcLockSlpSxStretchingPolicyWithS3BootScript ();
+
+ //
+ // Set BiosLock.
+ //
+ if (mPchConfigHob->LockDown.BiosLock == TRUE) {
+ BiosLockEnable ();
+ }
+
+ ///
+ /// PCH BIOS Spec Section 3.6 Flash Security Recommendation
+ /// BIOS also needs to set the BIOS Interface Lock Down bit in multiple locations
+ /// (PCR[DMI] + 274Ch[0], LPC/eSPI PCI offset DCh[7] and SPI PCI offset DCh[7]).
+ /// Setting these bits will prevent writes to the Top Swap bit (under their respective locations)
+ /// and the Boot BIOS Straps. Enabling this bit will mitigate malicious software
+ /// attempts to replace the system BIOS option ROM with its own code.
+ ///
+ if (mPchConfigHob->LockDown.BiosInterface == TRUE) {
+ //
+ // LPC
+ //
+ PciSegmentOr8 ((UINT64) (PciLpcRegBase + R_LPC_CFG_BC), (UINT32) B_LPC_CFG_BC_BILD);
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint8,
+ PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase + R_LPC_CFG_BC,
+ 1,
+ (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase + R_LPC_CFG_BC)
+ );
+
+ //
+ // Reads back for posted write to take effect
+ //
+ Data8 = PciSegmentRead8 ((UINTN) (PciLpcRegBase + R_LPC_CFG_BC));
+ S3BootScriptSaveMemPoll (
+ S3BootScriptWidthUint8,
+ PcdGet64 (PcdPciExpressBaseAddress) + PciLpcRegBase + R_LPC_CFG_BC,
+ &Data8, // BitMask
+ &Data8, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+
+ //
+ // SPI
+ //
+ PciSegmentOr8 ((UINT64) (PciSpiRegBase + R_SPI_CFG_BC), (UINT32) B_SPI_CFG_BC_BILD);
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint8,
+ PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC,
+ 1,
+ (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC)
+ );
+
+ //
+ // Reads back for posted write to take effect
+ //
+ Data8 = PciSegmentRead8 ((UINT64) (PciSpiRegBase + R_SPI_CFG_BC));
+ S3BootScriptSaveMemPoll (
+ S3BootScriptWidthUint8,
+ PcdGet64 (PcdPciExpressBaseAddress) + PciSpiRegBase + R_SPI_CFG_BC,
+ &Data8, // BitMask
+ &Data8, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+
+ ///
+ /// Set BIOS interface Lock-Down
+ ///
+ PchDmiSetBiosLockDownWithS3BootScript ();
+ }
+
+ ///
+ /// PCH BIOS Spec on using RTC RAM
+ /// Regardless of BUC.TS being updated or not, BIOS must set RC.BILD bit PCR[RTC] + 3400h[31] before exit
+ /// For Data integrity protection, set RTC Memory locks (Upper 128 Byte Lock and
+ /// Lower 128 Byte Lock) at PCR[RTC] + 3400h[4] and PCR[RTC] + 3400h[3].
+ /// Note once locked bytes 0x38 - 0x3F in each of the Upper and Lower Byte blocks, respectively,
+ /// cannot be unlocked until next reset.
+ ///
+ Data32And = 0xFFFFFFFF;
+ Data32Or = 0x0;
+
+ if (mPchConfigHob->LockDown.BiosInterface == TRUE) {
+ Data32Or = B_RTC_PCR_CONF_BILD;
+ }
+ if (mPchConfigHob->LockDown.RtcMemoryLock == TRUE) {
+ Data32Or |= (B_RTC_PCR_CONF_UCMOS_LOCK | B_RTC_PCR_CONF_LCMOS_LOCK);
+ }
+ PchPcrAndThenOr32 (
+ PID_RTC_HOST, R_RTC_PCR_CONF,
+ Data32And,
+ Data32Or
+ );
+ PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+ S3BootScriptWidthUint32,
+ PID_RTC_HOST, R_RTC_PCR_CONF,
+ &Data32Or,
+ &Data32And
+ );
+
+ ///
+ /// Remove access to RTC PCRs
+ ///
+ Data32And = (UINT32)~(BIT0);
+ Data32Or = 0;
+ PchPcrAndThenOr32 (
+ PID_RTC_HOST, R_RTC_PCR_PG1_AC_LO,
+ Data32And,
+ Data32Or
+ );
+ PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+ S3BootScriptWidthUint32,
+ PID_RTC_HOST, R_RTC_PCR_PG1_AC_LO,
+ &Data32Or,
+ &Data32And
+ );
+ PchPcrAndThenOr32 (
+ PID_RTC_HOST, R_RTC_PCR_PG1_CP_LO,
+ Data32And,
+ Data32Or
+ );
+ PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+ S3BootScriptWidthUint32,
+ PID_RTC_HOST, R_RTC_PCR_PG1_CP_LO,
+ &Data32Or,
+ &Data32And
+ );
+
+ //
+ // Lock Down TCO
+ //
+ Data16And = 0xFFFF;
+ Data16Or = B_TCO_IO_TCO1_CNT_LOCK;
+ IoOr16 (TcoBase + R_TCO_IO_TCO1_CNT, Data16Or);
+ S3BootScriptSaveIoReadWrite (
+ S3BootScriptWidthUint16,
+ (UINTN) (TcoBase + R_TCO_IO_TCO1_CNT),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+ ///
+ /// PCH BIOS Spec Section 5.15.1 Additional Chipset Initialization
+ /// Step 1
+ /// Lock PMC Set Strap Message Interface
+ ///
+ PmcLockSetStrapMsgInterfaceWithS3BootScript ();
+ //
+ // Lock Down PMC
+ //
+ PmcLockWithS3BootScript ();
+}
+
+/**
+ Set eSPI BME bit
+**/
+VOID
+ConfigureEspiBme (
+ VOID
+ )
+{
+ UINT64 EspiPciBase;
+
+ EspiPciBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+
+ if (PciSegmentRead16 (EspiPciBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ return;
+ }
+ if ((PciSegmentRead32 (EspiPciBase + R_ESPI_CFG_PCBC) & B_ESPI_CFG_PCBC_ESPI_EN) == 0) {
+ return;
+ }
+
+ //
+ // Refer to PCH BWG.
+ // To enable eSPI bus mastering BIOS must enable BME in eSPI controller
+ // and also set BME bit in the respective slave devices through Configuration
+ // and Capabilities register of each slave using Get_Configuration and Set_Configuration functionality.
+ //
+ // NOTE: The setting is also done in PEI, but might be cleared by PCI bus during PCI enumeration.
+ // Therefore, reeable it after PCI enumeration done.
+ //
+ if (mPchConfigHob->Espi.BmeMasterSlaveEnabled == TRUE) {
+ PciSegmentOr8 (EspiPciBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_BUS_MASTER);
+ }
+}
+
+/**
+ Common PCH initialization before Boot Sript Table is closed
+
+**/
+VOID
+PchOnPciEnumCompleteCommon (
+ VOID
+ )
+{
+ UINT32 Data32Or;
+ UINT32 Data32And;
+ BOOLEAN ResetStatus;
+
+ DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteCommon() Start\n"));
+
+ if (SiScheduleResetIsRequired ()) {
+ ResetStatus = SiScheduleResetPerformReset ();
+ ASSERT (!ResetStatus);
+ }
+
+ ProcessAllLocks ();
+
+ //
+ // Perform remaining configuration for PCH SATA on End of DXE
+ //
+ ConfigurePchSataOnEndOfDxe ();
+ //
+ // PSTHCTL (0xD00h[2]) = 1, PSTH IOSF Primary Trunk Clock Gating Enable (PSTHIOSFPTCGE)
+ //
+ Data32And = 0xFFFFFFFF;
+ Data32Or = B_PSTH_PCR_PSTHIOSFPTCGE;
+ PchPcrAndThenOr32 (PID_PSTH, R_PSTH_PCR_PSTHCTL, Data32And, Data32Or);
+ PCH_PCR_BOOT_SCRIPT_READ_WRITE (
+ S3BootScriptWidthUint32,
+ PID_PSTH, R_PSTH_PCR_PSTHCTL,
+ &Data32Or,
+ &Data32And
+ );
+
+ //
+ // Set eSPI BME after PCI enumeration
+ //
+ ConfigureEspiBme ();
+
+ ///
+ /// Clear Global Reset Status, Power Failure and Host Reset Status bits
+ ///
+ PmcClearGlobalResetStatus ();
+ PmcClearPowerFailureStatus ();
+ PmcClearHostResetStatus ();
+
+ DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteCommon() End\n"));
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
new file mode 100644
index 0000000000..b106c849e9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitDxe.c
@@ -0,0 +1,382 @@
+/** @file
+ This is the Uefi driver that initializes the Intel PCH.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include "PchInit.h"
+#include <PchPolicyCommon.h>
+#include <Private/Protocol/PcieIoTrap.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchPcieRpLib.h>
+#include <Private/Library/PmcPrivateLib.h>
+#include <Private/Library/PchPciExpressHelpersLib.h>
+#include <PcieRegs.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcie.h>
+#include <Register/PchRegsPmc.h>
+#include <Register/PchRegsThermalCnl.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_HANDLE mImageHandle;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPcieIoTrapAddress;
+
+VOID
+EFIAPI
+PchOnBootToOs (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+
+VOID
+EFIAPI
+PchOnExitBootServices (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+
+VOID
+EFIAPI
+PchOnReadyToBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Process all the lock downs
+**/
+VOID
+ProcessSmiLocks (
+ VOID
+ )
+{
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT16 ABase;
+
+ ///
+ /// PCH BIOS Spec Section 3.6 Flash Security Recommendation
+ /// BIOS needs to enables SMI_LOCK (PMC PCI offset A0h[4] = 1b) which prevent writes
+ /// to the Global SMI Enable bit (GLB_SMI_EN ABASE + 30h[0]). Enabling this bit will
+ /// mitigate malicious software attempts to gain system management mode privileges.
+ ///
+ if (mPchConfigHob->LockDown.GlobalSmi == TRUE) {
+ ///
+ /// Save Global SMI Enable bit setting before BIOS enables SMI_LOCK during S3 resume
+ ///
+ ABase = PmcGetAcpiBase ();
+ Data32Or = IoRead32 ((UINTN) (ABase + R_ACPI_IO_SMI_EN));
+ if ((Data32Or & B_ACPI_IO_SMI_EN_GBL_SMI) != 0) {
+ Data32And = 0xFFFFFFFF;
+ Data32Or |= B_ACPI_IO_SMI_EN_GBL_SMI;
+ S3BootScriptSaveIoReadWrite (
+ S3BootScriptWidthUint32,
+ (UINTN) (ABase + R_ACPI_IO_SMI_EN),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+ PmcLockSmiWithS3BootScript ();
+ }
+}
+
+/**
+ Do PCIE power management while resume from S3
+**/
+VOID
+ReconfigurePciePowerManagementForS3 (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Data32;
+ PCH_PCIE_IOTRAP_PROTOCOL *PchPcieIoTrapProtocol;
+
+ Status = gBS->LocateProtocol (&gPchPcieIoTrapProtocolGuid, NULL, (VOID **) &PchPcieIoTrapProtocol);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ mPcieIoTrapAddress = PchPcieIoTrapProtocol->PcieTrapAddress;
+ DEBUG ((DEBUG_INFO, "PcieIoTrapAddress: %0x\n", mPcieIoTrapAddress));
+
+ if (mPcieIoTrapAddress != 0) {
+ //
+ // Save PCH PCIE IoTrap address to re-config PCIE power management setting after resume from S3
+ //
+ Data32 = PciePmTrap;
+ S3BootScriptSaveIoWrite (
+ S3BootScriptWidthUint32,
+ (UINTN) (mPcieIoTrapAddress),
+ 1,
+ &Data32
+ );
+ } else {
+ ASSERT (FALSE);
+ }
+}
+
+/**
+ This is the callback function for PCI ENUMERATION COMPLETE.
+**/
+VOID
+EFIAPI
+PchOnPciEnumComplete (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ VOID *ProtocolPointer;
+ UINT64 ThermalPciBase;
+
+ ///
+ /// Check if this is first time called by EfiCreateProtocolNotifyEvent() or not,
+ /// if it is, we will skip it until real event is triggered
+ ///
+ Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, (VOID **) &ProtocolPointer);
+ if (EFI_SUCCESS != Status) {
+ return;
+ }
+ gBS->CloseEvent (Event);
+
+ //
+ // Enable Thermal MSE
+ //
+ ThermalPciBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_THERMAL,
+ PCI_FUNCTION_NUMBER_PCH_THERMAL,
+ 0
+ );
+ if (PciSegmentRead16 (ThermalPciBase + PCI_VENDOR_ID_OFFSET) != 0xFFFF) {
+ if (((PciSegmentRead32 (ThermalPciBase + R_THERMAL_CFG_MEM_TBAR) & B_THERMAL_CFG_MEM_TBAR_MASK) != 0) ||
+ ((PciSegmentRead32 (ThermalPciBase + R_THERMAL_CFG_MEM_TBARH) != 0))) {
+ PciSegmentOr8 (ThermalPciBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+ }
+ }
+
+ ReconfigurePciePowerManagementForS3 ();
+ ProcessSmiLocks ();
+#ifndef FSP_WRAPPER_FLAG
+ PchOnPciEnumCompleteCommon ();
+#endif
+ ConfigureSerialIoAtS3Resume ();
+}
+
+/**
+ Register callback functions for PCH DXE.
+**/
+VOID
+PchRegisterNotifications (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT LegacyBootEvent;
+ EFI_EVENT ExitBootServicesEvent;
+ VOID *Registration;
+
+ ///
+ /// Create PCI Enumeration Completed callback for PCH
+ ///
+ EfiCreateProtocolNotifyEvent (
+ &gEfiPciEnumerationCompleteProtocolGuid,
+ TPL_CALLBACK,
+ PchOnPciEnumComplete,
+ NULL,
+ &Registration
+ );
+
+ //
+ // Create events for PCH to do the task before ExitBootServices/LegacyBoot.
+ // It is guaranteed that only one of two events below will be signalled
+ //
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ PchOnExitBootServices,
+ NULL,
+ &ExitBootServicesEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = EfiCreateEventLegacyBootEx (
+ TPL_CALLBACK,
+ PchOnBootToOs,
+ NULL,
+ &LegacyBootEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Initialize the PCH device according to the PCH Policy HOB
+ and install PCH info instance.
+**/
+VOID
+InitializePchDevice (
+ VOID
+ )
+{
+ DEBUG ((DEBUG_INFO, "InitializePchDevice() Start\n"));
+
+ DEBUG ((DEBUG_INFO, "InitializePchDevice() End\n"));
+}
+/**
+ <b>PchInit DXE Module Entry Point</b>\n
+ - <b>Introduction</b>\n
+ The PchInit module is a DXE driver that initializes the Intel Platform Controller Hub
+ following the PCH BIOS specification and EDS requirements and recommendations. It consumes
+ the PCH_POLICY_HOB SI_POLICY_HOB for expected configurations per policy.
+ This is the standard EFI driver point that detects whether there is an supported PCH in
+ the system and if so, initializes the chipset.
+
+ - <b>Details</b>\n
+ This module is required for initializing the Intel Platform Controller Hub to
+ follow the PCH BIOS specification and EDS.
+ This includes some initialization sequences, enabling and disabling PCH devices,
+ configuring clock gating, RST PCIe Storage Remapping, SATA controller, ASPM of PCIE devices. Right before end of DXE,
+ it's responsible to lock down registers for security requirement.
+
+ - @pre
+ - PCH PCR base address configured
+ - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ - This is to ensure that PCI MMIO and IO resource has been prepared and available for this driver to allocate.
+
+ - @result
+ - Publishes the @link _PCH_INFO_PROTOCOL PCH_INFO_PROTOCOL @endlink
+ - Publishes the @link _PCH_EMMC_TUNING_PROTOCOL PCH_EMMC_TUNING_PROTOCOL @endlink
+
+ - <b>References</b>\n
+ - @link _PCH_POLICY PCH_POLICY_HOB @endlink.
+ - @link _SI_POLICY_STRUCT SI_POLICY_HOB @endlink.
+
+ - <b>Integration Checklists</b>\n
+ - Verify prerequisites are met. Porting Recommendations.
+ - No modification of this module should be necessary
+ - Any modification of this module should follow the PCH BIOS Specification and EDS
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchInitEntryPointDxe (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "PchInitEntryPointDxe() Start\n"));
+
+ mImageHandle = ImageHandle;
+
+ PchInitEntryPointCommon ();
+
+ InitializePchDevice ();
+
+ Status = PchAcpiInit (ImageHandle);
+
+ CreateSerialIoHandles ();
+
+ PchRegisterNotifications ();
+
+ DEBUG ((DEBUG_INFO, "PchInitEntryPointDxe() End\n"));
+
+ return Status;
+}
+
+/**
+ PCH initialization before ExitBootServices / LegacyBoot events
+ Useful for operations which must happen later than at EndOfPost event
+
+ @param[in] Event A pointer to the Event that triggered the callback.
+ @param[in] Context A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+PchOnBootToOs (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ ///
+ /// Closed the event to avoid call twice
+ ///
+ if (Event != NULL) {
+ gBS->CloseEvent (Event);
+ }
+
+ ConfigureSerialIoAtBoot ();
+
+ return;
+}
+
+/**
+ PCH initialization on ExitBootService. This event is used if only ExitBootService is used
+ and not in legacy boot
+
+ @param[in] Event A pointer to the Event that triggered the callback.
+ @param[in] Context A pointer to private data registered with the callback function.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchOnExitBootServices (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ PchOnBootToOs (NULL, NULL);
+
+ return;
+}
+
+/**
+ PCH initialization before boot to OS
+
+ @param[in] Event A pointer to the Event that triggered the callback.
+ @param[in] Context A pointer to private data registered with the callback function.
+**/
+VOID
+EFIAPI
+PchOnReadyToBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ DEBUG ((DEBUG_INFO, "Uefi PchOnReadyToBoot() Start\n"));
+
+ if (Event != NULL) {
+ gBS->CloseEvent (Event);
+ }
+
+ //
+ // Trigger an Iotrap SMI to config PCIE power management setting after PCI enumrate is done
+ //
+ if (mPcieIoTrapAddress != 0) {
+ IoWrite32 ((UINTN) mPcieIoTrapAddress, PciePmTrap);
+ } else {
+ ASSERT (FALSE);
+ }
+
+ DEBUG ((DEBUG_INFO, "Uefi PchOnReadyToBoot() End\n"));
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
new file mode 100644
index 0000000000..15fe4628fb
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchInitFsp.c
@@ -0,0 +1,85 @@
+/** @file
+ This is the FSP driver that initializes the Intel PCH.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include "PchInit.h"
+
+EFI_STATUS
+EFIAPI
+PchOnPciEnumCompleteFsp (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+STATIC
+EFI_PEI_NOTIFY_DESCRIPTOR mPchOnPciEnumCompleteNotifyList[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPciEnumerationCompleteProtocolGuid,
+ PchOnPciEnumCompleteFsp
+ }
+};
+
+/**
+ <b>FSP PchInit Module Entry Point for FSP</b>\n
+
+ @param[in] FileHandle PEIM's file handle
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchInitEntryPointFsp (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "PchInitEntryPointFsp() Start\n"));
+
+ PchInitEntryPointCommon ();
+
+ Status = PeiServicesNotifyPpi (mPchOnPciEnumCompleteNotifyList);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, "PchInitEntryPointFsp() End\n"));
+
+ return Status;
+}
+
+/**
+ Fsp PCH initialization on PCI enumeration complete
+
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.
+ @param[in] Ppi Address of the PPI that was installed.
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchOnPciEnumCompleteFsp (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteFsp() Start\n"));
+
+ PchOnPciEnumCompleteCommon ();
+
+ DEBUG ((DEBUG_INFO, "PchOnPciEnumCompleteFsp() End\n"));
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
new file mode 100644
index 0000000000..6e30280fa7
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSata.c
@@ -0,0 +1,89 @@
+/** @file
+ Perform related functions for PCH Sata in DXE phase
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/S3BootScriptLib.h>
+
+#include "PchInit.h"
+#include <Library/SataLib.h>
+#include <Register/PchRegsSata.h>
+
+/**
+ Perform the remaining configuration on PCH SATA to perform device detection,
+ then set the SATA SPD and PxE corresponding, and set the Register Lock on PCH SATA
+
+ @retval None
+**/
+VOID
+ConfigurePchSataOnEndOfDxe (
+ VOID
+ )
+{
+ UINT64 PciSataRegBase;
+ UINT16 SataPortsEnabled;
+ UINT32 DwordReg;
+ UINTN Index;
+ UINT32 SataCtrlIndex;
+
+ for (SataCtrlIndex = 0; SataCtrlIndex < GetPchMaxSataControllerNum (); SataCtrlIndex++) {
+ ///
+ /// SATA PCS: Enable the port in any of below condition:
+ /// i.) Hot plug is enabled
+ /// ii.) A device is attached
+ /// iii.) Test mode is enabled
+ /// iv.) Configured as eSATA port
+ ///
+ PciSataRegBase = GetSataRegBase (SataCtrlIndex);
+ SataPortsEnabled = 0;
+
+ DwordReg = PciSegmentRead32 (PciSataRegBase + R_SATA_CFG_PCS);
+ for (Index = 0; Index < GetPchMaxSataPortNum (SataCtrlIndex); Index++) {
+ if ((mPchConfigHob->Sata[SataCtrlIndex].PortSettings[Index].HotPlug == TRUE) ||
+ (DwordReg & (B_SATA_CFG_PCS_P0P << Index)) ||
+ (mPchConfigHob->Sata[SataCtrlIndex].TestMode == TRUE) ||
+ (mPchConfigHob->Sata[SataCtrlIndex].PortSettings[Index].External == TRUE)) {
+ SataPortsEnabled |= (mPchConfigHob->Sata[SataCtrlIndex].PortSettings[Index].Enable << Index);
+ }
+ }
+
+ ///
+ /// Set MAP."Sata PortX Disable", SATA PCI offset 90h[23:16] to 1b if SATA Port 0/1/2/3/4/5/6/7 is disabled
+ ///
+ PciSegmentOr32 (PciSataRegBase + R_SATA_CFG_MAP, (~SataPortsEnabled << N_SATA_CFG_MAP_SPD));
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint32,
+ PcdGet64 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_MAP,
+ 1,
+ (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_MAP)
+ );
+
+ ///
+ /// Program PCS "Port X Enabled", SATA PCI offset 94h[7:0] = Port 0~7 Enabled bit as per SataPortsEnabled value.
+ ///
+ PciSegmentOr16 (PciSataRegBase + R_SATA_CFG_PCS, SataPortsEnabled);
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint16,
+ PcdGet64 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_PCS,
+ 1,
+ (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_PCS)
+ );
+
+ ///
+ /// Step 14
+ /// Program SATA PCI offset 9Ch [31] to 1b
+ ///
+ PciSegmentOr32 ((UINTN) (PciSataRegBase + R_SATA_CFG_SATAGC), BIT31);
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint32,
+ PcdGet64 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_SATAGC,
+ 1,
+ (VOID *) (UINTN) (PcdGet64 (PcdPciExpressBaseAddress) + PciSataRegBase + R_SATA_CFG_SATAGC)
+ );
+ }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
new file mode 100644
index 0000000000..d0f4b4fa56
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIo.c
@@ -0,0 +1,57 @@
+/** @file
+ Initializes Serial IO Controllers.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include "PchInit.h"
+#include <Library/PchSerialIoLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegsSerialIo.h>
+
+/**
+ Puts all SerialIo controllers (except UARTs in debug mode) in D3
+ Clears MemoryEnable for all PCI-mode controllers
+**/
+EFI_STATUS
+ConfigureSerialIoAtBoot (
+ VOID
+ )
+{
+ PCH_SERIAL_IO_CONTROLLER Index;
+ UINTN PciCfgBase;
+
+ for (Index = 0; Index < PchSerialIoIndexMax; Index++) {
+ if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoDisabled) {
+ if (IsSerialIoFunctionZero (Index)) {
+ if (IsSerialIoDeviceEnabled (GetSerialIoDeviceNumber (Index), GetSerialIoFunctionNumber (Index))) {
+ PciCfgBase = FindSerialIoBar (Index,1);
+ MmioOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST);
+ }
+ }
+ continue;
+ }
+ if ((Index >= PchSerialIoIndexUart0) &&
+ (mPchConfigHob->SerialIo.EnableDebugUartAfterPost) &&
+ (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0))) {
+ continue;
+ }
+ PciCfgBase = FindSerialIoBar (Index,1);
+ MmioOr32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST);
+ MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
+ if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoPci) {
+ MmioAnd32 (PciCfgBase + PCI_COMMAND_OFFSET, (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER) );
+ if (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0)) {
+ continue;
+ }
+ MmioWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_LOW, 0);
+ MmioWrite32 (PciCfgBase + R_SERIAL_IO_CFG_BAR0_HIGH, 0);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
new file mode 100644
index 0000000000..5563d82076
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Dxe/PchSerialIoDxe.c
@@ -0,0 +1,156 @@
+/** @file
+ Initializes Serial IO Controllers.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DxeServicesTableLib.h>
+
+#include "PchInit.h"
+#include <Library/PchSerialIoLib.h>
+#include <Library/DevicePathLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegsSerialIo.h>
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH RootPort;
+ ACPI_EXTENDED_HID_DEVICE_PATH AcpiDev;
+ CHAR8 HidString[8];
+ CHAR8 UidString;
+ CHAR8 CidString;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} SERIALIO_DEVICE_PATH;
+
+#define gPciRootBridge {{ACPI_DEVICE_PATH, ACPI_DP, {(UINT8)(sizeof(ACPI_HID_DEVICE_PATH)), 0}}, EISA_PNP_ID (0x0A03), 0}
+#define gAcpiDev {{ACPI_DEVICE_PATH,ACPI_EXTENDED_DP,{(UINT8)(sizeof(ACPI_EXTENDED_HID_DEVICE_PATH)+SERIALIO_TOTAL_ID_LENGTH),0}},0,0,0}
+#define gEndEntire {END_DEVICE_PATH_TYPE,END_ENTIRE_DEVICE_PATH_SUBTYPE,{END_DEVICE_PATH_LENGTH,0}}
+
+GLOBAL_REMOVE_IF_UNREFERENCED SERIALIO_DEVICE_PATH gSerialIoPath = {
+ gPciRootBridge,
+ gAcpiDev,
+ "\0\0\0\0\0\0\0",
+ '\0',
+ '\0',
+ gEndEntire
+};
+
+/**
+Mark memory used by SerialIo devices in ACPI mode as allocated
+
+@retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+AllocateSerialIoMemory (
+ VOID
+ )
+{
+ PCH_SERIAL_IO_CONTROLLER i;
+ UINT8 BarNumber;
+ UINTN Bar;
+ EFI_STATUS Status;
+
+ for (i=0; i<PchSerialIoIndexMax; i++) {
+ if (mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoHidden ||
+ mPchConfigHob->SerialIo.DevMode[i] == PchSerialIoAcpi) {
+ for (BarNumber = 0; BarNumber<=1; BarNumber++) {
+ Bar = FindSerialIoBar (i,BarNumber);
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeReserved,
+ Bar,
+ V_SERIAL_IO_CFG_BAR_SIZE,
+ 0
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeReserved,
+ N_SERIAL_IO_CFG_BAR_ALIGNMENT,
+ V_SERIAL_IO_CFG_BAR_SIZE,
+ &Bar,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+VOID
+CreateSerialIoHandles (
+ VOID
+ )
+{
+ EFI_HANDLE NewHandle;
+ EFI_DEVICE_PATH_PROTOCOL *NewPath;
+ UINT32 Controller;
+
+ for (Controller = 0; Controller < PchSerialIoIndexMax; Controller++) {
+ if (mPchConfigHob->SerialIo.DevMode[Controller] == PchSerialIoAcpi) {
+ NewHandle = NULL;
+ CopyMem (gSerialIoPath.HidString, GetSerialIoAcpiHid (Controller), SERIALIO_HID_LENGTH);
+ NewPath = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*)&gSerialIoPath);
+ gBS->InstallMultipleProtocolInterfaces (
+ &NewHandle,
+ &gEfiDevicePathProtocolGuid,
+ NewPath,
+ NULL );
+ }
+ }
+}
+
+/**
+ Puts all SerialIo controllers (except UARTs in debug mode) in D3.
+ Clears MemoryEnable for all PCI-mode controllers on S3 resume
+**/
+VOID
+ConfigureSerialIoAtS3Resume (
+ VOID
+ )
+{
+ PCH_SERIAL_IO_CONTROLLER Index;
+ UINTN PciCfgBase;
+ UINT32 Data32;
+
+ for (Index = 0; Index < PchSerialIoIndexMax; Index++) {
+ if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoDisabled) {
+ if (IsSerialIoFunctionZero (Index)) {
+ if (IsSerialIoDeviceEnabled (GetSerialIoDeviceNumber (Index), GetSerialIoFunctionNumber (Index))) {
+ PciCfgBase = FindSerialIoBar (Index,1);
+ Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
+ Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST;
+ S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32);
+ }
+ }
+ continue;
+ }
+ if ((Index >= PchSerialIoIndexUart0) &&
+ (mPchConfigHob->SerialIo.EnableDebugUartAfterPost) &&
+ (mPchConfigHob->SerialIo.DebugUartNumber == (UINT32) (Index - PchSerialIoIndexUart0))) {
+ continue;
+ }
+ PciCfgBase = FindSerialIoBar (Index,1);
+ Data32 = MmioRead32 (PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS);
+ Data32 |= B_SERIAL_IO_CFG_PME_CTRL_STS_PWR_ST;
+ S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + R_SERIAL_IO_CFG_PME_CTRL_STS, 1, &Data32);
+ if (mPchConfigHob->SerialIo.DevMode[Index] == PchSerialIoPci) {
+ Data32 = MmioRead32 (PciCfgBase + PCI_COMMAND_OFFSET);
+ Data32 &= (UINT32)~(EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
+ S3BootScriptSaveMemWrite (S3BootScriptWidthUint32, PciCfgBase + PCI_COMMAND_OFFSET, 1, &Data32);
+ }
+ }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
new file mode 100644
index 0000000000..7fe1567c9f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchBiosWriteProtect.c
@@ -0,0 +1,156 @@
+/** @file
+ PCH BIOS Write Protect Driver.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchInitSmm.h"
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+
+//
+// Global variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_TCO_SMI_DISPATCH_PROTOCOL *mPchTcoSmiDispatchProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64 mSpiRegBase;
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_ESPI_SMI_DISPATCH_PROTOCOL *mEspiSmmDispatchProtocol;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64 mLpcRegBase;
+
+/**
+ This hardware SMI handler will be run every time the BIOS Write Enable bit is set.
+
+ @param[in] DispatchHandle Not used
+
+**/
+VOID
+EFIAPI
+PchSpiBiosWpCallback (
+ IN EFI_HANDLE DispatchHandle
+ )
+{
+ //
+ // Disable BIOSWE bit to protect BIOS
+ //
+ PciSegmentAnd8 ((UINTN) (mSpiRegBase + R_SPI_CFG_BC), (UINT8) ~B_SPI_CFG_BC_WPD);
+}
+
+/**
+ This hardware SMI handler will be run every time the BIOS Write Enable bit is set.
+
+ @param[in] DispatchHandle Not used
+
+**/
+VOID
+EFIAPI
+PchLpcBiosWpCallback (
+ IN EFI_HANDLE DispatchHandle
+ )
+{
+ //
+ // Disable BIOSWE bit to protect BIOS
+ //
+ PciSegmentAnd8 ((UINTN) (mLpcRegBase + R_LPC_CFG_BC), (UINT8) ~B_LPC_CFG_BC_WPD);
+}
+
+/**
+ Entry point for Pch Bios Write Protect driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchBiosWriteProtect (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ DEBUG ((DEBUG_INFO, "InstallPchBiosWriteProtect()\n"));
+
+ if (mPchConfigHob->LockDown.BiosLock != TRUE) {
+ return EFI_SUCCESS;
+ }
+
+ mSpiRegBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SPI,
+ PCI_FUNCTION_NUMBER_PCH_SPI,
+ 0
+ );
+
+ mLpcRegBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+
+ DEBUG ((DEBUG_INFO, "Installing BIOS Write Protect SMI handler\n"));
+ //
+ // Get the PCH TCO SMM dispatch protocol
+ //
+ mPchTcoSmiDispatchProtocol = NULL;
+ Status = gSmst->SmmLocateProtocol (&gPchTcoSmiDispatchProtocolGuid, NULL, (VOID **) &mPchTcoSmiDispatchProtocol);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Always register an SPI BiosWp callback function to handle TCO BIOSWR SMI
+ // NOTE: No matter the BIOS resides behind SPI or not, it needs to handle the SPI BIOS WP SMI
+ // to avoid SMI deadloop on SPI WPD write.
+ //
+ Handle = NULL;
+ Status = mPchTcoSmiDispatchProtocol->SpiBiosWpRegister (
+ mPchTcoSmiDispatchProtocol,
+ PchSpiBiosWpCallback,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Always register an LPC/eSPI BiosWp callback function to handle TCO BIOSWR SMI
+ // NOTE: No matter the BIOS resides behind LPC/eSPI or not, it needs to handle the BIOS WP SMI
+ // to avoid SMI deadloop on LPC/eSPI WPD write.
+ //
+ if (IsEspiEnabled ()) {
+ //
+ // Get the PCH ESPI SMM dispatch protocol
+ //
+ mEspiSmmDispatchProtocol = NULL;
+ Status = gSmst->SmmLocateProtocol (&gPchEspiSmiDispatchProtocolGuid, NULL, (VOID **) &mEspiSmmDispatchProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register an ESpiBiosWp callback function to handle BIOSWR SMI
+ //
+ Handle = NULL;
+ Status = mEspiSmmDispatchProtocol->BiosWrProtectRegister (
+ mEspiSmmDispatchProtocol,
+ PchLpcBiosWpCallback,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ //
+ // Register an LPC BiosWp callback function to handle TCO BIOSWR SMI
+ //
+ Handle = NULL;
+ Status = mPchTcoSmiDispatchProtocol->LpcBiosWpRegister (
+ mPchTcoSmiDispatchProtocol,
+ PchLpcBiosWpCallback,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
new file mode 100644
index 0000000000..e9f4c91ed4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.c
@@ -0,0 +1,179 @@
+/** @file
+ PCH Init Smm module for PCH specific SMI handlers.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchInitSmm.h"
+#include <Register/PchRegs.h>
+#include <Register/RegsUsb.h>
+#include <Register/PchRegsSmbus.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL *mPchIoTrap;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_SX_DISPATCH2_PROTOCOL *mSxDispatch;
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_NVS_AREA *mPchNvsArea;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mAcpiBaseAddr;
+
+//
+// NOTE: The module variables of policy here are only valid in post time, but not runtime time.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_CONFIG_HOB *mPchConfigHob;
+GLOBAL_REMOVE_IF_UNREFERENCED SI_CONFIG_HOB_DATA *mSiConfigHobData;
+
+//
+// The reserved MMIO range to be used in Sx handler
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS mResvMmioBaseAddr;
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN mResvMmioSize;
+
+/**
+ SMBUS Sx entry SMI handler.
+**/
+VOID
+SmbusSxCallback (
+ VOID
+ )
+{
+ UINT64 SmbusRegBase;
+ UINT16 SmbusIoBase;
+
+ SmbusRegBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SMBUS,
+ PCI_FUNCTION_NUMBER_PCH_SMBUS,
+ 0
+ );
+
+ if (PciSegmentRead32 (SmbusRegBase) == 0xFFFFFFFF) {
+ return;
+ }
+
+ SmbusIoBase = PciSegmentRead16 (SmbusRegBase + R_SMBUS_CFG_BASE) & B_SMBUS_CFG_BASE_BAR;
+ if (SmbusIoBase == 0) {
+ return;
+ }
+
+ PciSegmentOr8 (SmbusRegBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_IO_SPACE);
+ //
+ // Clear SMBUS status and SMB_WAK_STS of GPE0
+ //
+ IoWrite8 (SmbusIoBase + R_SMBUS_IO_HSTS, B_SMBUS_IO_SMBALERT_STS);
+ IoWrite32 (mAcpiBaseAddr + R_ACPI_IO_GPE0_STS_127_96, B_ACPI_IO_GPE0_STS_127_96_SMB_WAK);
+}
+
+/**
+ Allocates reserved MMIO for Sx SMI handler use.
+**/
+VOID
+AllocateReservedMmio (
+ VOID
+ )
+{
+ mResvMmioBaseAddr = PcdGet32 (PcdSiliconInitTempMemBaseAddr);
+ mResvMmioSize = PcdGet32 (PcdSiliconInitTempMemSize);
+ DEBUG ((DEBUG_INFO, "mResvMmioBaseAddr %x, mResvMmioSize %x\n", mResvMmioBaseAddr, mResvMmioSize));
+}
+
+/**
+ Initializes the PCH SMM handler for for PCIE hot plug support
+ <b>PchInit SMM Module Entry Point</b>\n
+ - <b>Introduction</b>\n
+ The PchInitSmm module is a SMM driver that initializes the Intel Platform Controller Hub
+ SMM requirements and services. It consumes the PCH_POLICY_HOB and SI_POLICY_HOB for expected
+ configurations per policy.
+
+ - <b>Details</b>\n
+ This module provides SMI handlers to services PCIE HotPlug SMI, LinkActive SMI, and LinkEq SMI.
+ And also provides port 0x61 emulation support, registers BIOS WP handler to process BIOSWP status,
+ and registers SPI Async SMI handler to handler SPI Async SMI.
+ This module also registers Sx SMI callback function to detail with GPIO Sx Isolation and LAN requirement.
+
+ - @pre
+ - PCH PCR base address configured
+ - EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+ - This is to ensure that PCI MMIO and IO resource has been prepared and available for this driver to allocate.
+ - EFI_SMM_BASE2_PROTOCOL
+ - EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL
+ - EFI_SMM_SX_DISPATCH2_PROTOCOL
+ - EFI_SMM_CPU_PROTOCOL
+ - @link _PCH_SMM_IO_TRAP_CONTROL_PROTOCOL PCH_SMM_IO_TRAP_CONTROL_PROTOCOL @endlink
+ - @link _PCH_SMI_DISPATCH_PROTOCOL PCH_SMI_DISPATCH_PROTOCOL @endlink
+ - @link _PCH_PCIE_SMI_DISPATCH_PROTOCOL PCH_PCIE_SMI_DISPATCH_PROTOCOL @endlink
+ - @link _PCH_TCO_SMI_DISPATCH_PROTOCOL PCH_TCO_SMI_DISPATCH_PROTOCOL @endlink
+ - @link _PCH_ESPI_SMI_DISPATCH_PROTOCOL PCH_ESPI_SMI_DISPATCH_PROTOCOL @endlink
+
+ - <b>References</b>\n
+ - @link _PCH_POLICY PCH_POLICY_HOB @endlink.
+ - @link _SI_POLICY_STRUCT SI_POLICY_HOB @endlink.
+
+ - <b>Integration Checklists</b>\n
+ - Verify prerequisites are met. Porting Recommendations.
+ - No modification of this module should be necessary
+ - Any modification of this module should follow the PCH BIOS Specification and EDS
+
+ @param[in] ImageHandle - Handle for the image of this driver
+ @param[in] SystemTable - Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS - PCH SMM handler was installed
+**/
+EFI_STATUS
+EFIAPI
+PchInitSmmEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ PCH_NVS_AREA_PROTOCOL *PchNvsAreaProtocol;
+ EFI_PEI_HOB_POINTERS HobPtr;
+
+ DEBUG ((DEBUG_INFO, "PchInitSmmEntryPoint()\n"));
+
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmIoTrapDispatch2ProtocolGuid,
+ NULL,
+ (VOID **) &mPchIoTrap
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmSxDispatch2ProtocolGuid,
+ NULL,
+ (VOID**) &mSxDispatch
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (&gPchNvsAreaProtocolGuid, NULL, (VOID **) &PchNvsAreaProtocol);
+ ASSERT_EFI_ERROR (Status);
+ mPchNvsArea = PchNvsAreaProtocol->Area;
+
+ //
+ // Get PCH Data HOB.
+ //
+ HobPtr.Guid = GetFirstGuidHob (&gPchConfigHobGuid);
+ ASSERT (HobPtr.Guid != NULL);
+ mPchConfigHob = (PCH_CONFIG_HOB *) GET_GUID_HOB_DATA (HobPtr.Guid);
+
+ HobPtr.Guid = GetFirstGuidHob (&gSiConfigHobGuid);
+ ASSERT (HobPtr.Guid != NULL);
+ mSiConfigHobData = (SI_CONFIG_HOB_DATA *) GET_GUID_HOB_DATA (HobPtr.Guid);
+
+ mAcpiBaseAddr = PmcGetAcpiBase ();
+
+ AllocateReservedMmio ();
+
+ Status = InitializePchPcieSmm (ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = InstallPchBiosWriteProtect (ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = InstallPchSpiAsyncSmiHandler ();
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
new file mode 100644
index 0000000000..4a2d1f9cea
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchLanSxSmm.c
@@ -0,0 +1,298 @@
+/** @file
+ PCH LAN Sx handler implementation.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/TimerLib.h>
+#include "PchInitSmm.h"
+#include <Private/Library/PmcPrivateLib.h>
+#include <Library/GbeMdiLib.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsLan.h>
+
+/**
+ Checks if Lan is Enabled or Disabled
+
+ @retval BOOLEAN TRUE if device is enabled, FALSE otherwise.
+**/
+BOOLEAN
+IsGbeEnabled (
+ VOID
+ )
+{
+ UINT64 GbePciBase;
+
+ GbePciBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LAN,
+ PCI_FUNCTION_NUMBER_PCH_LAN,
+ 0
+ );
+
+ if (PciSegmentRead32 (GbePciBase) != 0xFFFFFFFF) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Configure WOL during Sx entry.
+
+ @param [in] GbeBar GbE MMIO space
+**/
+VOID
+GbeWolWorkaround (
+ IN UINT32 GbeBar
+ )
+{
+ UINT32 RAL0;
+ UINT32 RAH0;
+ UINT16 WUC;
+ EFI_STATUS Status;
+ UINT16 Data16;
+
+ //
+ // 1. Set page to 769 Port Control Registers
+ // 2. Wait 4 mSec
+ //
+ Status = GbeMdiSetPage (GbeBar, PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 3. Set registry to 17 Port General Configuration
+ // 4. Copy all settings from Port General Configuration
+ //
+ Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_17_PGC), &Data16);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 5. Modify BIT 4 and BIT 2 to disable host wake up and set MACPD
+ //
+ Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_17_PGC), (Data16 | B_PHY_MDI_PAGE_769_REGISETER_17_PGC_MACPD_ENABLE) & (~B_PHY_MDI_PAGE_769_REGISETER_17_PGC_HOST_WAKE_UP));
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 6. Read Receive Address Low and Receive Address High from MMIO
+ //
+ RAL0 = MmioRead32 (GbeBar + R_LAN_MEM_CSR_RAL);
+ RAH0 = MmioRead32 (GbeBar + R_LAN_MEM_CSR_RAH);
+
+ //
+ // 7. Set page to 800 Wake Up Registers
+ // 8. Wait 4 mSec
+ //
+ Status = GbeMdiSetPage (GbeBar, PHY_MDI_PAGE_800_WAKE_UP_REGISTERS);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 9. Set registry to 16 Receive Address Low 1/2
+ //
+ Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_800_REGISETER_16_RAL0);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 10. Program first 16 bits [0:15] out of 48 in Receive Address Low 1/2
+ //
+ Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, (RAL0 & 0xFFFF));
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 11. Set registry to 17 Receive Address Low 2/2
+ //
+ Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_800_REGISETER_17_RAL1);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 12. Program second 16 bits [16:31] out of 48 in Receive Address Low 2/2
+ //
+ Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, (RAL0 >> 16));
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 13. Set registry to 18 Receive Address High 1/2
+ //
+ Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_800_REGISETER_18_RAH0);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 14. Program last 16 bits [32:47] out of 48
+ //
+ Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, (RAH0 & B_LAN_MEM_CSR_RAH_RAH));
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 15. Set registry to 19 Receive Address High 2/2
+ //
+ Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_800_REGISETER_19_RAH1);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 16. Set Address Valid
+ //
+ Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, B_PHY_MDI_PAGE_800_REGISETER_19_RAH1_ADDRESS_VALID);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 17. Set Wake Up Control Register 1
+ //
+ Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_800_REGISETER_1_WUC);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 18. Copy WakeUp Control from MAC MMIO
+ //
+ WUC = (UINT16) MmioRead32 (GbeBar + R_LAN_MEM_CSR_WUC);
+
+ //
+ // 19. Store WakeUp Contorl into LCD
+ // Modify APME bit to enable APM wake up
+ //
+ Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, (WUC & 0xFFFF));
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 20. Set page to 803 Host Wol Packet
+ // 21. Wait 4 mSec
+ //
+ Status = GbeMdiSetPage (GbeBar, PHY_MDI_PAGE_803_HOST_WOL_PACKET);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 22. Set registry to 66 Host WoL Packet Clear
+ //
+ Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_803_REGISETER_66_HWPC);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 23. Clear WOL Packet
+ //
+ Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, R_PHY_MDI_PHY_REG_DATA_READ_WRITE, 0);
+ if (EFI_ERROR (Status)) return;
+ //
+ // 24. Set page to 769 Port Control Registers
+ // 25. Wait 4 mSec
+ //
+ Status = GbeMdiSetPage (GbeBar, PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 26. Set registry to 17 Port General Configuration
+ //
+ Status = GbeMdiSetRegister (GbeBar, R_PHY_MDI_PAGE_769_REGISETER_17_PGC);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 27. Copy all settings from Port General Configuration
+ //
+ Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_17_PGC), &Data16);
+ if (EFI_ERROR (Status)) return;
+
+ //
+ // 28. Modify BIT 4 and BIT 2 to enable host wake up and clear MACPD
+ //
+ Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_17_PGC), (Data16 | B_PHY_MDI_PAGE_769_REGISETER_17_PGC_HOST_WAKE_UP) & (~B_PHY_MDI_PAGE_769_REGISETER_17_PGC_MACPD_ENABLE));
+ if (EFI_ERROR (Status)) return;
+}
+
+/**
+ Additional Internal GbE Controller special cases WOL Support.
+
+ System BIOS is required perform additional steps upon S0 to S3,4,5 transition
+ when ME is off and GbE device in D0. This is needed to enable LAN wake
+ in particular when platform is shut-down from EFI.
+**/
+VOID
+GbeSxWorkaround (
+ VOID
+ )
+{
+ UINT64 LanRegBase;
+ UINT32 GbeBar;
+ EFI_STATUS Status;
+
+ LanRegBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LAN,
+ PCI_FUNCTION_NUMBER_PCH_LAN,
+ 0
+ );
+
+ if (PciSegmentRead16 (LanRegBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ return;
+ }
+
+ //
+ // Check if GbE device is in D0
+ //
+ if ((PciSegmentRead16 (LanRegBase + R_LAN_CFG_PMCS) & B_LAN_CFG_PMCS_PS) != V_LAN_CFG_PMCS_PS0) {
+ return;
+ }
+
+ ASSERT (mResvMmioSize >= (1 << N_LAN_CFG_MBARA_ALIGN));
+ GbeBar = (UINT32) mResvMmioBaseAddr;
+ if (GbeBar == 0) {
+ ASSERT (FALSE);
+ return;
+ }
+
+ //
+ // Enable MMIO decode using reserved range.
+ //
+ PciSegmentAnd16 (LanRegBase + PCI_COMMAND_OFFSET, (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+ PciSegmentWrite32 (LanRegBase + R_LAN_CFG_MBARA, GbeBar);
+ PciSegmentOr16 (LanRegBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+
+ //
+ // If MBARA offset 5800h [0] = 1b then proceed with the w/a
+ //
+ if (MmioRead32 (GbeBar + R_LAN_MEM_CSR_WUC) & B_LAN_MEM_CSR_WUC_APME) {
+ Status = GbeMdiAcquireMdio (GbeBar);
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ GbeWolWorkaround (GbeBar);
+ GbeMdiReleaseMdio (GbeBar);
+ }
+ }
+
+ //
+ // Disable MMIO decode.
+ //
+ PciSegmentAnd16 (LanRegBase + PCI_COMMAND_OFFSET, (UINT16) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+ PciSegmentWrite32 (LanRegBase + R_LAN_CFG_MBARA, 0);
+}
+
+/**
+ Enable platform wake from LAN when in DeepSx if platform supports it.
+ Called upon Sx entry.
+**/
+VOID
+GbeConfigureDeepSxWake (
+ VOID
+ )
+{
+ if (PmcIsLanDeepSxWakeEnabled ()) {
+ IoOr32 ((UINTN) (mAcpiBaseAddr + R_ACPI_IO_GPE0_EN_127_96), (UINT32) B_ACPI_IO_GPE0_EN_127_96_LAN_WAKE);
+ }
+}
+
+/**
+ GbE Sx entry handler
+**/
+VOID
+PchLanSxCallback (
+ VOID
+ )
+{
+ if (IsGbeEnabled ()) {
+ GbeSxWorkaround ();
+ GbeConfigureDeepSxWake ();
+
+ }
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
new file mode 100644
index 0000000000..eac2e1c3ec
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchPcieSmm.c
@@ -0,0 +1,436 @@
+/** @file
+ PCH Pcie SMM Driver Entry
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchInitSmm.h"
+#include <PcieRegs.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsPcie.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_PCIE_DEVICE_OVERRIDE *mDevAspmOverride;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mNumOfDevAspmOverride;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPchBusNumber;
+//
+// @note:
+// These temp bus numbers cannot be used in runtime (hot-plug).
+// These can be used only during boot.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mTempRootPortBusNumMin;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mTempRootPortBusNumMax;
+
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_PCIE_ROOT_PORT_CONFIG mPcieRootPortConfig[PCH_MAX_PCIE_ROOT_PORTS];
+
+GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mPciePmTrapExecuted = FALSE;
+
+extern EFI_GUID gPchDeviceTableHobGuid;
+
+/**
+ Program Common Clock and ASPM of Downstream Devices
+
+ @param[in] PortIndex Pcie Root Port Number
+ @param[in] RpDevice Pcie Root Pci Device Number
+ @param[in] RpFunction Pcie Root Pci Function Number
+**/
+STATIC
+VOID
+PchPcieSmi (
+ IN UINT8 PortIndex,
+ IN UINT8 RpDevice,
+ IN UINT8 RpFunction
+ )
+{
+ UINT8 SecBus;
+ UINT8 SubBus;
+ UINT64 RpBase;
+ UINT64 EpBase;
+ UINT8 EpPcieCapPtr;
+ UINT8 EpMaxSpeed;
+ BOOLEAN DownstreamDevicePresent;
+ UINT32 Timeout;
+
+ RpBase = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ mPchBusNumber,
+ (UINT32) RpDevice,
+ (UINT32) RpFunction,
+ 0
+ );
+
+ if (PciSegmentRead16 (RpBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ return;
+ }
+ //
+ // Check presence detect state. Here the endpoint must be detected using PDS rather than
+ // the usual LinkActive check, because PDS changes immediately and LA takes a few milliseconds to stabilize
+ //
+ DownstreamDevicePresent = !!(PciSegmentRead16 (RpBase + R_PCH_PCIE_CFG_SLSTS) & B_PCIE_SLSTS_PDS);
+
+ if (DownstreamDevicePresent) {
+ ///
+ /// Make sure the link is active before trying to talk to device behind it
+ /// Wait up to 100ms, according to PCIE spec chapter 6.7.3.3
+ ///
+ Timeout = 100 * 1000;
+ while ((PciSegmentRead16 (RpBase + R_PCH_PCIE_CFG_LSTS) & B_PCIE_LSTS_LA) == 0 ) {
+ MicroSecondDelay (10);
+ Timeout-=10;
+ if (Timeout == 0) {
+ return;
+ }
+ }
+ SecBus = PciSegmentRead8 (RpBase + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+ SubBus = PciSegmentRead8 (RpBase + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
+ ASSERT (SecBus != 0 && SubBus != 0);
+ RootportDownstreamConfiguration (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ RpDevice,
+ RpFunction,
+ mTempRootPortBusNumMin,
+ mTempRootPortBusNumMax
+ );
+ RootportDownstreamPmConfiguration (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ RpDevice,
+ RpFunction,
+ mTempRootPortBusNumMin,
+ mTempRootPortBusNumMax,
+ &mPcieRootPortConfig[PortIndex],
+ mNumOfDevAspmOverride,
+ mDevAspmOverride
+ );
+ //
+ // Perform Equalization
+ //
+ EpBase = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, SecBus, 0, 0, 0);
+ EpPcieCapPtr = PcieFindCapId (DEFAULT_PCI_SEGMENT_NUMBER_PCH, SecBus, 0, 0, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ EpMaxSpeed = PciSegmentRead8 (EpBase + EpPcieCapPtr + R_PCIE_LCAP_OFFSET) & B_PCIE_LCAP_MLS;
+ if (EpMaxSpeed >= 3) {
+ PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_EX_LCTL3, B_PCIE_EX_LCTL3_PE);
+ PciSegmentOr32 (RpBase + R_PCH_PCIE_CFG_LCTL, B_PCIE_LCTL_RL);
+ }
+ }
+}
+
+/**
+ PCIE Hotplug SMI call back function for each Root port
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] RpContext Rootport context, which contains RootPort Index,
+ and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieSmiRpHandlerFunction (
+ IN EFI_HANDLE DispatchHandle,
+ IN PCH_PCIE_SMI_RP_CONTEXT *RpContext
+ )
+{
+ PchPcieSmi (RpContext->RpIndex, RpContext->DevNum, RpContext->FuncNum);
+}
+
+/**
+ PCIE Link Active State Change Hotplug SMI call back function for all Root ports
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] RpContext Rootport context, which contains RootPort Index,
+ and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieLinkActiveStateChange (
+ IN EFI_HANDLE DispatchHandle,
+ IN PCH_PCIE_SMI_RP_CONTEXT *RpContext
+ )
+{
+ return;
+}
+
+/**
+ PCIE Link Equalization Request SMI call back function for all Root ports
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] RpContext Rootport context, which contains RootPort Index,
+ and RootPort PCI BDF.
+**/
+VOID
+EFIAPI
+PchPcieLinkEqHandlerFunction (
+ IN EFI_HANDLE DispatchHandle,
+ IN PCH_PCIE_SMI_RP_CONTEXT *RpContext
+ )
+{
+ ///
+ /// From PCI Express specification, the PCIe device can request for Link Equalization. When the
+ /// Link Equalization is requested by the device, an SMI will be generated by PCIe RP when
+ /// enabled and the SMI subroutine would invoke the Software Preset/Coefficient Search
+ /// software to re-equalize the link.
+ ///
+
+ return;
+
+}
+
+/**
+ An IoTrap callback to config PCIE power management settings
+**/
+VOID
+PchPciePmIoTrapSmiCallback (
+ VOID
+ )
+{
+ UINT32 PortIndex;
+ UINT64 RpBase;
+ UINT8 MaxPciePortNum;
+ UINTN RpDevice;
+ UINTN RpFunction;
+
+ MaxPciePortNum = GetPchMaxPciePortNum ();
+
+ for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+ GetPchPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
+ RpBase = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, (UINT32) RpDevice, (UINT32) RpFunction, 0);
+
+ if (PciSegmentRead16 (RpBase) != 0xFFFF) {
+ RootportDownstreamPmConfiguration (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ (UINT8)RpDevice,
+ (UINT8)RpFunction,
+ mTempRootPortBusNumMin,
+ mTempRootPortBusNumMax,
+ &mPcieRootPortConfig[PortIndex],
+ mNumOfDevAspmOverride,
+ mDevAspmOverride
+ );
+
+ }
+ }
+}
+
+/**
+ An IoTrap callback to config PCIE power management settings
+
+ @param[in] DispatchHandle - The handle of this callback, obtained when registering
+ @param[in] DispatchContext - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT
+
+**/
+VOID
+EFIAPI
+PchPcieIoTrapSmiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_IO_TRAP_CONTEXT *CallbackContext,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommBufferSize
+ )
+{
+ if (CallbackContext->WriteData == PciePmTrap) {
+ if (mPciePmTrapExecuted == FALSE) {
+ PchPciePmIoTrapSmiCallback ();
+ mPciePmTrapExecuted = TRUE;
+ }
+ } else {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ }
+}
+
+/**
+ This function clear the Io trap executed flag before enter S3
+
+ @param[in] Handle Handle of the callback
+ @param[in] Context The dispatch context
+
+ @retval EFI_SUCCESS PCH register saved
+**/
+EFI_STATUS
+EFIAPI
+PchPcieS3EntryCallBack (
+ IN EFI_HANDLE Handle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+{
+ mPciePmTrapExecuted = FALSE;
+ return EFI_SUCCESS;
+}
+/**
+ Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling
+
+ @param[in] ImageHandle The image handle of this module
+ @param[in] SystemTable The EFI System Table
+
+ @retval EFI_SUCCESS The function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InitializePchPcieSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT8 PortIndex;
+ UINT8 Data8;
+ UINT32 Data32Or;
+ UINT32 Data32And;
+ UINT64 RpBase;
+ UINTN RpDevice;
+ UINTN RpFunction;
+ EFI_HANDLE PcieHandle;
+ PCH_PCIE_SMI_DISPATCH_PROTOCOL *PchPcieSmiDispatchProtocol;
+ EFI_HOB_GUID_TYPE* Hob;
+ UINT32 DevTableSize;
+ EFI_HANDLE PchIoTrapHandle;
+ EFI_SMM_IO_TRAP_REGISTER_CONTEXT PchIoTrapContext;
+ EFI_SMM_SX_REGISTER_CONTEXT SxDispatchContext;
+ PCH_PCIE_IOTRAP_PROTOCOL *PchPcieIoTrapProtocol;
+ EFI_HANDLE SxDispatchHandle;
+ UINT8 MaxPciePortNum;
+
+ DEBUG ((DEBUG_INFO, "InitializePchPcieSmm () Start\n"));
+
+ MaxPciePortNum = GetPchMaxPciePortNum ();
+
+ //
+ // Locate Pch Pcie Smi Dispatch Protocol
+ //
+ Status = gSmst->SmmLocateProtocol (&gPchPcieSmiDispatchProtocolGuid, NULL, (VOID**)&PchPcieSmiDispatchProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ mPchBusNumber = DEFAULT_PCI_BUS_NUMBER_PCH;
+ mTempRootPortBusNumMin = PcdGet8 (PcdSiliconInitTempPciBusMin);
+ mTempRootPortBusNumMax = PcdGet8 (PcdSiliconInitTempPciBusMax);
+
+ ASSERT (sizeof mPcieRootPortConfig == sizeof mPchConfigHob->PcieRp.RootPort);
+ CopyMem (
+ mPcieRootPortConfig,
+ &(mPchConfigHob->PcieRp.RootPort),
+ sizeof (mPcieRootPortConfig)
+ );
+
+ mDevAspmOverride = NULL;
+ mNumOfDevAspmOverride = 0;
+
+ Hob = GetFirstGuidHob (&gPchDeviceTableHobGuid);
+ if (Hob != NULL) {
+ DevTableSize = GET_GUID_HOB_DATA_SIZE (Hob);
+ ASSERT ((DevTableSize % sizeof (PCH_PCIE_DEVICE_OVERRIDE)) == 0);
+ mNumOfDevAspmOverride = DevTableSize / sizeof (PCH_PCIE_DEVICE_OVERRIDE);
+ DEBUG ((DEBUG_INFO, "Found PcieDeviceTable HOB (%d entries)\n", mNumOfDevAspmOverride));
+ Status = gSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ DevTableSize,
+ (VOID **) &mDevAspmOverride
+ );
+ CopyMem (mDevAspmOverride, GET_GUID_HOB_DATA (Hob), DevTableSize);
+ }
+
+ //
+ // Throught all PCIE root port function and register the SMI Handler for enabled ports.
+ //
+ for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) {
+ GetPchPcieRpDevFun (PortIndex, &RpDevice, &RpFunction);
+ RpBase = PCI_SEGMENT_LIB_ADDRESS (DEFAULT_PCI_SEGMENT_NUMBER_PCH, DEFAULT_PCI_BUS_NUMBER_PCH, (UINT32) RpDevice, (UINT32) RpFunction, 0);
+ //
+ // Skip the root port function which is not enabled
+ //
+ if (PciSegmentRead32 (RpBase) == 0xFFFFFFFF) {
+ continue;
+ }
+
+ //
+ // Register SMI Handlers for Hot Plug and Link Active State Change
+ //
+ Data8 = PciSegmentRead8 (RpBase + R_PCH_PCIE_CFG_SLCAP);
+ if (Data8 & B_PCIE_SLCAP_HPC) {
+ PcieHandle = NULL;
+ Status = PchPcieSmiDispatchProtocol->HotPlugRegister (
+ PchPcieSmiDispatchProtocol,
+ PchPcieSmiRpHandlerFunction,
+ PortIndex,
+ &PcieHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PchPcieSmiDispatchProtocol->LinkActiveRegister (
+ PchPcieSmiDispatchProtocol,
+ PchPcieLinkActiveStateChange,
+ PortIndex,
+ &PcieHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Data32Or = B_PCH_PCIE_CFG_MPC_HPME;
+ Data32And = (UINT32) ~B_PCH_PCIE_CFG_MPC_HPME;
+ S3BootScriptSaveMemReadWrite (
+ S3BootScriptWidthUint32,
+ PcdGet64 (PcdPciExpressBaseAddress) + RpBase + R_PCH_PCIE_CFG_MPC,
+ &Data32Or, /// Data to be ORed
+ &Data32And /// Data to be ANDed
+ );
+ }
+
+ //
+ // Register SMI Handler for Link Equalization Request from Gen 3 Devices.
+ //
+ Data8 = PciSegmentRead8 (RpBase + R_PCH_PCIE_CFG_LCAP);
+ if ((Data8 & B_PCIE_LCAP_MLS) == V_PCIE_LCAP_MLS_GEN3) {
+ Status = PchPcieSmiDispatchProtocol->LinkEqRegister (
+ PchPcieSmiDispatchProtocol,
+ PchPcieLinkEqHandlerFunction,
+ PortIndex,
+ &PcieHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ ASSERT_EFI_ERROR (Status);
+
+ PchIoTrapContext.Type = WriteTrap;
+ PchIoTrapContext.Length = 4;
+ PchIoTrapContext.Address = 0;
+ Status = mPchIoTrap->Register (
+ mPchIoTrap,
+ (EFI_SMM_HANDLER_ENTRY_POINT2) PchPcieIoTrapSmiCallback,
+ &PchIoTrapContext,
+ &PchIoTrapHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install the PCH Pcie IoTrap protocol
+ //
+ (gBS->AllocatePool) (EfiBootServicesData, sizeof (PCH_PCIE_IOTRAP_PROTOCOL), (VOID **)&PchPcieIoTrapProtocol);
+ PchPcieIoTrapProtocol->PcieTrapAddress = PchIoTrapContext.Address;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gPchPcieIoTrapProtocolGuid,
+ PchPcieIoTrapProtocol,
+ NULL
+ );
+
+ //
+ // Register the callback for S3 entry
+ //
+ SxDispatchContext.Type = SxS3;
+ SxDispatchContext.Phase = SxEntry;
+ Status = mSxDispatch->Register (
+ mSxDispatch,
+ PchPcieS3EntryCallBack,
+ &SxDispatchContext,
+ &SxDispatchHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, "InitializePchPcieSmm, IoTrap @ %x () End\n", PchIoTrapContext.Address));
+
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
new file mode 100644
index 0000000000..3c843616e4
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchSpiAsync.c
@@ -0,0 +1,69 @@
+/** @file
+ PCH SPI Async SMI handler.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PchInitSmm.h"
+
+///
+/// Global variables
+///
+GLOBAL_REMOVE_IF_UNREFERENCED PCH_SMI_DISPATCH_PROTOCOL *mPchSmiDispatchProtocol;
+
+/**
+ This hardware SMI handler will be run every time the flash write/earse happens.
+
+ @param[in] DispatchHandle Not used
+
+**/
+VOID
+EFIAPI
+PchSpiAsyncCallback (
+ IN EFI_HANDLE DispatchHandle
+ )
+{
+ //
+ // Dummy SMI handler
+ //
+}
+
+/**
+ This fuction install SPI ASYNC SMI handler.
+
+ @retval EFI_SUCCESS Initialization complete.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpiAsyncSmiHandler (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ DEBUG ((DEBUG_INFO, "InstallPchSpiAsyncSmiHandler()\n"));
+
+ ///
+ /// Get the PCH SMM dispatch protocol
+ ///
+ mPchSmiDispatchProtocol = NULL;
+ Status = gSmst->SmmLocateProtocol (&gPchSmiDispatchProtocolGuid, NULL, (VOID **) &mPchSmiDispatchProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Register an SpiAsync callback function
+ ///
+ Handle = NULL;
+ Status = mPchSmiDispatchProtocol->SpiAsyncRegister (
+ mPchSmiDispatchProtocol,
+ PchSpiAsyncCallback,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c
new file mode 100644
index 0000000000..d843de3ad8
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/SmmControl/RuntimeDxe/SmmControlDriver.c
@@ -0,0 +1,399 @@
+/** @file
+ This is the driver that publishes the SMM Control Protocol.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/EventGroup.h>
+#include <Library/PmcLib.h>
+#include <Library/GpioLib.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegsLpc.h>
+#include <Register/PchRegsSpi.h>
+#include <Register/PchRegsPmc.h>
+#include "SmmControlDriver.h"
+
+STATIC SMM_CONTROL_PRIVATE_DATA mSmmControl;
+GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mABase;
+
+VOID
+EFIAPI
+DisablePendingSmis (
+ VOID
+ );
+
+/**
+ Fixup internal data pointers so that the services can be called in virtual mode.
+
+ @param[in] Event The event registered.
+ @param[in] Context Event context.
+
+**/
+VOID
+EFIAPI
+SmmControlVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gRT->ConvertPointer (0, (VOID *) &(mSmmControl.SmmControl.Trigger));
+ gRT->ConvertPointer (0, (VOID *) &(mSmmControl.SmmControl.Clear));
+}
+
+/**
+ <b>SmmControl DXE RUNTIME Module Entry Point</b>\n
+ - <b>Introduction</b>\n
+ The SmmControl module is a DXE RUNTIME driver that provides a standard way
+ for other drivers to trigger software SMIs.
+
+ - @pre
+ - PCH Power Management I/O space base address has already been programmed.
+ If SmmControl Runtime DXE driver is run before Status Code Runtime Protocol
+ is installed and there is the need to use Status code in the driver, it will
+ be necessary to add EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID to the dependency file.
+ - EFI_SMM_BASE2_PROTOCOL
+ - Documented in the System Management Mode Core Interface Specification.
+
+ - @result
+ The SmmControl driver produces the EFI_SMM_CONTROL_PROTOCOL documented in
+ System Management Mode Core Interface Specification.
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_STATUS Results of the installation of the SMM Control Protocol
+**/
+EFI_STATUS
+EFIAPI
+SmmControlDriverEntryInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ DEBUG ((DEBUG_INFO, "SmmControlDriverEntryInit() Start\n"));
+
+ //
+ // Get the Power Management I/O space base address. We assume that
+ // this base address has already been programmed if this driver is
+ // being run.
+ //
+ mABase = PmcGetAcpiBase ();
+
+ Status = EFI_SUCCESS;
+ if (mABase != 0) {
+ //
+ // Install the instance of the protocol
+ //
+ mSmmControl.Signature = SMM_CONTROL_PRIVATE_DATA_SIGNATURE;
+ mSmmControl.Handle = ImageHandle;
+
+ mSmmControl.SmmControl.Trigger = Activate;
+ mSmmControl.SmmControl.Clear = Deactivate;
+ mSmmControl.SmmControl.MinimumTriggerPeriod = 0;
+
+ //
+ // Install our protocol interfaces on the device's handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmmControl.Handle,
+ &gEfiSmmControl2ProtocolGuid,
+ &mSmmControl.SmmControl,
+ NULL
+ );
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ return Status;
+ }
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ SmmControlVirtualAddressChangeEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &Event
+ );
+ //
+ // Disable any PCH SMIs that, for whatever reason, are asserted after the boot.
+ //
+ DisablePendingSmis ();
+
+ DEBUG ((DEBUG_INFO, "SmmControlDriverEntryInit() End\n"));
+
+ return Status;
+}
+
+/**
+ Trigger the software SMI
+
+ @param[in] Data The value to be set on the software SMI data port
+
+ @retval EFI_SUCCESS Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+ IN UINT8 Data
+ )
+{
+ UINT32 OutputData;
+ UINT32 OutputPort;
+
+ //
+ // Enable the APMC SMI
+ //
+ OutputPort = mABase + R_ACPI_IO_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= (B_ACPI_IO_SMI_EN_APMC | B_ACPI_IO_SMI_EN_GBL_SMI);
+ DEBUG (
+ (DEBUG_EVENT,
+ "The SMI Control Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ OutputPort = R_PCH_IO_APM_CNT;
+ OutputData = Data;
+
+ //
+ // Generate the APMC SMI
+ //
+ IoWrite8 (
+ (UINTN) OutputPort,
+ (UINT8) (OutputData)
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Clear the SMI status
+
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_DEVICE_ERROR Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmmClear (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 OutputData;
+ UINT32 OutputPort;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Clear the Power Button Override Status Bit, it gates EOS from being set.
+ //
+ OutputPort = mABase + R_ACPI_IO_PM1_STS;
+ OutputData = B_ACPI_IO_PM1_STS_PRBTNOR;
+ DEBUG (
+ (DEBUG_EVENT,
+ "The PM1 Status Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite16 (
+ (UINTN) OutputPort,
+ (UINT16) (OutputData)
+ );
+
+ //
+ // Clear the APM SMI Status Bit
+ //
+ OutputPort = mABase + R_ACPI_IO_SMI_STS;
+ OutputData = B_ACPI_IO_SMI_STS_APM;
+ DEBUG (
+ (DEBUG_EVENT,
+ "The SMI Status Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ //
+ // Set the EOS Bit
+ //
+ OutputPort = mABase + R_ACPI_IO_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= B_ACPI_IO_SMI_EN_EOS;
+ DEBUG (
+ (DEBUG_EVENT,
+ "The SMI Control Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ //
+ // There is no need to read EOS back and check if it is set.
+ // This can lead to a reading of zero if an SMI occurs right after the SMI_EN port read
+ // but before the data is returned to the CPU.
+ // SMM Dispatcher should make sure that EOS is set after all SMI sources are processed.
+ //
+ return Status;
+}
+
+/**
+ This routine generates an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in, out] CommandPort The buffer contains data to the command port
+ @param[in, out] DataPort The buffer contains data to the data port
+ @param[in] Periodic Periodic or not
+ @param[in] ActivationInterval Interval of periodic SMI
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Activate (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL * This,
+ IN OUT UINT8 *CommandPort OPTIONAL,
+ IN OUT UINT8 *DataPort OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Data;
+
+ if (Periodic) {
+ DEBUG ((DEBUG_WARN, "Invalid parameter\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (CommandPort == NULL) {
+ Data = 0xFF;
+ } else {
+ Data = *CommandPort;
+ }
+ //
+ // Clear any pending the APM SMI
+ //
+ Status = SmmClear ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return SmmTrigger (Data);
+}
+
+/**
+ This routine clears an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in] Periodic Periodic or not
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Deactivate (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN BOOLEAN Periodic OPTIONAL
+ )
+{
+ if (Periodic) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SmmClear ();
+}
+/**
+ Disable all pending SMIs
+
+**/
+VOID
+EFIAPI
+DisablePendingSmis (
+ VOID
+ )
+{
+ UINT32 Data;
+ BOOLEAN SciEn;
+
+ //
+ // Determine whether an ACPI OS is present (via the SCI_EN bit)
+ //
+ Data = IoRead16 ((UINTN) mABase + R_ACPI_IO_PM1_CNT);
+ SciEn = (BOOLEAN) ((Data & B_ACPI_IO_PM1_CNT_SCI_EN) == B_ACPI_IO_PM1_CNT_SCI_EN);
+
+ if (!SciEn) {
+ //
+ // Clear any SMIs that double as SCIs (when SCI_EN==0)
+ //
+ IoWrite16 ((UINTN) mABase + R_ACPI_IO_PM1_STS, 0xFFFF);
+ IoWrite16 ((UINTN) mABase + R_ACPI_IO_PM1_EN, 0);
+ IoWrite16 ((UINTN) mABase + R_ACPI_IO_PM1_CNT, 0);
+ IoWrite32 (
+ (UINTN) mABase + R_ACPI_IO_GPE0_STS_127_96,
+ (UINT32)( B_ACPI_IO_GPE0_STS_127_96_USB_CON_DSX_STS |
+ B_ACPI_IO_GPE0_STS_127_96_LAN_WAKE |
+ B_ACPI_IO_GPE0_STS_127_96_PME_B0 |
+ B_ACPI_IO_GPE0_STS_127_96_PME |
+ B_ACPI_IO_GPE0_STS_127_96_BATLOW |
+ B_ACPI_IO_GPE0_STS_127_96_RI |
+ B_ACPI_IO_GPE0_STS_127_96_SWGPE)
+ );
+ //
+ // Disable WADT_EN by default can avoid the WADT SMI during POST time when the WADT_STS is set as a wake source.
+ // BIOS disable WADT_EN and keep WADT_STS into OS so OS can be aware of the wake source.
+ //
+ IoAnd32 ((UINTN) mABase + R_ACPI_IO_GPE0_EN_127_96, (UINT32) ~B_ACPI_IO_GPE0_EN_127_96_WADT);
+ }
+ //
+ // Clear and disable all SMIs that are unaffected by SCI_EN
+ //
+ GpioDisableAllGpiSmi ();
+
+ GpioClearAllGpiSmiSts ();
+
+ IoWrite32 ((UINTN) mABase + R_ACPI_IO_DEVACT_STS, 0x0000FFFF);
+
+ IoWrite32 ((UINTN) mABase + R_ACPI_IO_SMI_STS, ~0u);
+
+ //
+ // (Make sure to write this register last -- EOS re-enables SMIs for the PCH)
+ //
+ Data = IoRead32 ((UINTN) mABase + R_ACPI_IO_SMI_EN);
+ //
+ // clear all bits except those tied to SCI_EN
+ //
+ Data &= B_ACPI_IO_SMI_EN_BIOS_RLS;
+ //
+ // enable SMIs and specifically enable writes to APM_CNT.
+ //
+ Data |= B_ACPI_IO_SMI_EN_GBL_SMI | B_ACPI_IO_SMI_EN_APMC;
+ //
+ // NOTE: Default value of EOS is set in PCH, it will be automatically cleared Once the PCH asserts SMI# low,
+ // we don't need to do anything to clear it
+ //
+ IoWrite32 ((UINTN) mABase + R_ACPI_IO_SMI_EN, Data);
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
new file mode 100644
index 0000000000..458d137e4f
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Spi/Smm/PchSpi.c
@@ -0,0 +1,310 @@
+/** @file
+ PCH SPI SMM Driver implements the SPI Host Controller Compatibility Interface.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Protocol/Spi.h>
+#include <Protocol/SmmCpu.h>
+#include <Private/Library/PchSpiCommonLib.h>
+#include <Private/Library/SmmPchPrivateLib.h>
+#include <PchReservedResources.h>
+#include <IndustryStandard/Pci30.h>
+#include <Register/PchRegs.h>
+#include <Register/PchRegsSpi.h>
+
+//
+// Global variables
+//
+GLOBAL_REMOVE_IF_UNREFERENCED SPI_INSTANCE *mSpiInstance;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_CPU_PROTOCOL *mSmmCpuProtocol;
+//
+// mPchSpiResvMmioAddr keeps the reserved MMIO range assiged to SPI.
+// In SMM it always set back the reserved MMIO address to SPI BAR0 to ensure the MMIO range
+// won't overlap with SMRAM range, and trusted.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mSpiResvMmioAddr;
+
+/**
+ <b>SPI Runtime SMM Module Entry Point</b>\n
+ - <b>Introduction</b>\n
+ The SPI SMM module provide a standard way for other modules to use the PCH SPI Interface in SMM.
+
+ - @pre
+ - EFI_SMM_BASE2_PROTOCOL
+ - Documented in System Management Mode Core Interface Specification .
+
+ - @result
+ The SPI SMM driver produces @link _PCH_SPI_PROTOCOL PCH_SPI_PROTOCOL @endlink with GUID
+ gPchSmmSpiProtocolGuid which is different from SPI RUNTIME driver.
+
+ - <b>Integration Check List</b>\n
+ - This driver supports Descriptor Mode only.
+ - This driver supports Hardware Sequence only.
+ - When using SMM SPI Protocol to perform flash access in an SMI handler,
+ and the SMI occurrence is asynchronous to normal mode code execution,
+ proper synchronization mechanism must be applied, e.g. disable SMI before
+ the normal mode SendSpiCmd() starts and re-enable SMI after
+ the normal mode SendSpiCmd() completes.
+ @note The implementation of SendSpiCmd() uses GBL_SMI_EN in
+ SMI_EN register (ABase + 30h) to disable and enable SMIs. But this may
+ not be effective as platform may well set the SMI_LOCK bit (i.e., PMC PCI Offset A0h [4]).
+ So the synchronization at caller level is likely needed.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpi (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Init PCH spi reserved MMIO address.
+ //
+ mSpiResvMmioAddr = PCH_SPI_BASE_ADDRESS;
+
+ ///
+ /// Allocate pool for SPI protocol instance
+ ///
+ Status = gSmst->SmmAllocatePool (
+ EfiRuntimeServicesData, /// MemoryType don't care
+ sizeof (SPI_INSTANCE),
+ (VOID **) &mSpiInstance
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (mSpiInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem ((VOID *) mSpiInstance, sizeof (SPI_INSTANCE));
+ ///
+ /// Initialize the SPI protocol instance
+ ///
+ Status = SpiProtocolConstructor (mSpiInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Install the SMM PCH_SPI_PROTOCOL interface
+ ///
+ Status = gSmst->SmmInstallProtocolInterface (
+ &(mSpiInstance->Handle),
+ &gPchSmmSpiProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &(mSpiInstance->SpiProtocol)
+ );
+ if (EFI_ERROR (Status)) {
+ gSmst->SmmFreePool (mSpiInstance);
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Acquire PCH spi mmio address.
+ If it is ever different from the preallocated address, reassign it back.
+ In SMM, it always override the BAR0 and returns the reserved MMIO range for SPI.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval PchSpiBar0 return SPI MMIO address
+**/
+UINTN
+AcquireSpiBar0 (
+ IN SPI_INSTANCE *SpiInstance
+ )
+{
+ UINT32 SpiBar0;
+ //
+ // Save original SPI physical MMIO address
+ //
+ SpiBar0 = PciSegmentRead32 (SpiInstance->PchSpiBase + R_SPI_CFG_BAR0) & ~(B_SPI_CFG_BAR0_MASK);
+
+ if (SpiBar0 != mSpiResvMmioAddr) {
+ //
+ // Temporary disable MSE, and override with SPI reserved MMIO address, then enable MSE.
+ //
+ PciSegmentAnd8 (SpiInstance->PchSpiBase + PCI_COMMAND_OFFSET, (UINT8) ~EFI_PCI_COMMAND_MEMORY_SPACE);
+ PciSegmentWrite32 (SpiInstance->PchSpiBase + R_SPI_CFG_BAR0, mSpiResvMmioAddr);
+ PciSegmentOr8 (SpiInstance->PchSpiBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);
+ }
+ //
+ // SPIBAR0 will be different before and after PCI enum so need to get it from SPI BAR0 reg.
+ //
+ return mSpiResvMmioAddr;
+}
+
+/**
+ Release pch spi mmio address. Do nothing.
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval None
+**/
+VOID
+ReleaseSpiBar0 (
+ IN SPI_INSTANCE *SpiInstance
+ )
+{
+}
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @retval EFI_ACCESS_DENIED The BIOS Region can only be updated in SMM phase
+
+**/
+EFI_STATUS
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ )
+{
+ UINT64 SpiBaseAddress;
+
+ SpiBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SPI,
+ PCI_FUNCTION_NUMBER_PCH_SPI,
+ 0
+ );
+ // Write clear BC_SYNC_SS prior to change WPD from 0 to 1.
+ //
+ PciSegmentOr8 (
+ SpiBaseAddress + R_SPI_CFG_BC + 1,
+ (B_SPI_CFG_BC_SYNC_SS >> 8)
+ );
+ ///
+ /// Set BIOSWE bit (SPI PCI Offset DCh [0]) = 1b
+ /// Enable the access to the BIOS space for both read and write cycles
+ ///
+ PciSegmentOr8 (
+ SpiBaseAddress + R_SPI_CFG_BC,
+ B_SPI_CFG_BC_WPD
+ );
+
+ ///
+ /// PCH BIOS Spec Section 3.7 BIOS Region SMM Protection Enabling
+ /// If the following steps are implemented:
+ /// - Set the EISS bit (SPI PCI Offset DCh [5]) = 1b
+ /// - Follow the 1st recommendation in section 3.6
+ /// the BIOS Region can only be updated by following the steps bellow:
+ /// - Once all threads enter SMM
+ /// - Read memory location FED30880h OR with 00000001h, place the result in EAX,
+ /// and write data to lower 32 bits of MSR 1FEh (sample code available)
+ /// - Set BIOSWE bit (SPI PCI Offset DCh [0]) = 1b
+ /// - Modify BIOS Region
+ /// - Clear BIOSWE bit (SPI PCI Offset DCh [0]) = 0b
+ ///
+ if ((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC) & B_SPI_CFG_BC_EISS) != 0) {
+ PchSetInSmmSts ();
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ )
+{
+ UINT64 SpiBaseAddress;
+
+ SpiBaseAddress = PCI_SEGMENT_LIB_ADDRESS (
+ DEFAULT_PCI_SEGMENT_NUMBER_PCH,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SPI,
+ PCI_FUNCTION_NUMBER_PCH_SPI,
+ 0
+ );
+ ///
+ /// Clear BIOSWE bit (SPI PCI Offset DCh [0]) = 0b
+ /// Disable the access to the BIOS space for write cycles
+ ///
+ PciSegmentAnd8 (
+ SpiBaseAddress + R_SPI_CFG_BC,
+ (UINT8) (~B_SPI_CFG_BC_WPD)
+ );
+
+ ///
+ /// Check if EISS bit is set
+ ///
+ if (((PciSegmentRead8 (SpiBaseAddress + R_SPI_CFG_BC)) & B_SPI_CFG_BC_EISS) == B_SPI_CFG_BC_EISS) {
+ PchClearInSmmSts ();
+ }
+}
+
+/**
+ Check if it's granted to do flash write.
+
+ @retval TRUE It's secure to do flash write.
+ @retval FALSE It's not secure to do flash write.
+**/
+BOOLEAN
+IsSpiFlashWriteGranted (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 CpuIndex;
+ UINT64 ProcessorId;
+
+ if (mSmmCpuProtocol == NULL) {
+ Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **)&mSmmCpuProtocol);
+ ASSERT_EFI_ERROR (Status);
+ if (mSmmCpuProtocol == NULL) {
+ return TRUE;
+ }
+ }
+
+ for (CpuIndex = 0; CpuIndex < gSmst->NumberOfCpus; CpuIndex++) {
+ Status = mSmmCpuProtocol->ReadSaveState (
+ mSmmCpuProtocol,
+ sizeof (ProcessorId),
+ EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID,
+ CpuIndex,
+ &ProcessorId
+ );
+ //
+ // If the processor is in SMM at the time the SMI occurred,
+ // it will return success. Otherwise, EFI_NOT_FOUND is returned.
+ //
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
--
2.16.2.windows.1
next prev parent reply other threads:[~2019-08-17 0:17 UTC|newest]
Thread overview: 121+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-17 0:15 [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Kubacki, Michael A
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 01/37] CoffeelakeSiliconPkg: Add package and Include headers Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:08 ` Chiu, Chasel
2019-08-17 1:18 ` Chaganty, Rangasai V
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 02/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:08 ` Chiu, Chasel
2019-08-17 6:58 ` Chaganty, Rangasai V
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 03/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:08 ` Chiu, Chasel
2019-08-17 7:04 ` Chaganty, Rangasai V
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 04/37] CoffeelakeSiliconPkg/Pch: Add include headers Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:08 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 05/37] CoffeelakeSiliconPkg/Pch: Add ConfigBlock headers Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:09 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 06/37] CoffeelakeSiliconPkg/Pch: Add Library include headers Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:09 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 07/37] CoffeelakeSiliconPkg/Pch: Add PPI and Protocol " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:09 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 08/37] CoffeelakeSiliconPkg/Pch: Add Register " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:09 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 09/37] CoffeelakeSiliconPkg/Pch: Add Private " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:12 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 10/37] CoffeelakeSiliconPkg/Pch: Add Private/Library " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:09 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 11/37] CoffeelakeSiliconPkg/Pch: Add Private/Protocol " Kubacki, Michael A
2019-08-17 0:51 ` Nate DeSimone
2019-08-17 1:10 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 12/37] CoffeelakeSiliconPkg/SampleCode: Add Include headers Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:12 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 13/37] CoffeelakeSiliconPkg/SystemAgent: " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:12 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 14/37] CoffeelakeSiliconPkg: Add package common library instances Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:12 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:15 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 16/37] CoffeelakeSiliconPkg/Me: " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:12 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 17/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:13 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 18/37] CoffeelakeSiliconPkg/Pch: Add DXE " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:13 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 19/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:13 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 20/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 21/37] CoffeelakeSiliconPkg/Pch: Add Base " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:13 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 22/37] CoffeelakeSiliconPkg/Pch: Add DXE private " Kubacki, Michael A
2019-08-17 0:52 ` Nate DeSimone
2019-08-17 1:13 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 23/37] CoffeelakeSiliconPkg/Pch: Add PEI " Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 24/37] CoffeelakeSiliconPkg/Pch: Add SMM " Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 25/37] CoffeelakeSiliconPkg/SystemAgent: Add " Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` Kubacki, Michael A [this message]
2019-08-17 0:53 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 27/37] CoffeelakeSiliconPkg/Pch: Add PchSmiDispatcher Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:15 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 28/37] CoffeelakeSiliconPkg/SystemAgent: Add modules Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:15 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 29/37] CoffeelakeSiliconPkg: Add package DSC files Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:14 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 30/37] Maintainers.txt: Add CoffeelakeSiliconPkg maintainers Kubacki, Michael A
2019-08-17 0:53 ` Nate DeSimone
2019-08-17 1:15 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 31/37] WhiskeylakeOpenBoardPkg: Add package and headers Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-19 18:09 ` Sinha, Ankit
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 32/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add headers Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 0:15 ` [edk2-platforms][PATCH V1 33/37] WhiskeylakeOpenBoardPkg: Add library instances Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 34/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: " Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:17 ` Chiu, Chasel
2019-08-17 20:08 ` Chaganty, Rangasai V
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 35/37] WhiskeylakeOpenBoardPkg: Add modules Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:17 ` Chiu, Chasel
2019-08-17 7:50 ` Chaganty, Rangasai V
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 36/37] WhiskeylakeOpenBoardPkg/WhiskeylakeURvp: Add DSC and build files Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:16 ` Chiu, Chasel
2019-08-17 20:11 ` Chaganty, Rangasai V
2019-08-17 0:16 ` [edk2-platforms][PATCH V1 37/37] Add WhiskeylakeOpenBoardPkg to global build config and documentation Kubacki, Michael A
2019-08-17 0:54 ` Nate DeSimone
2019-08-17 1:17 ` Chiu, Chasel
2019-08-17 20:00 ` Chaganty, Rangasai V
2019-08-19 18:14 ` [edk2-platforms][PATCH V1 00/37] Coffee Lake and Whiskey Lake support Sinha, Ankit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190817001603.30632-27-michael.a.kubacki@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox