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 15/37] CoffeelakeSiliconPkg/Cpu: Add library instances
Date: Fri, 16 Aug 2019 17:15:41 -0700 [thread overview]
Message-ID: <20190817001603.30632-16-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
Adds CPU library class instances.
* BaseCpuMailboxLibNull - Generic CPU mailbox interaction services.
* PeiCpuPolicyLib - CPU policy configuration services.
* PeiCpuPolicyLibPreMem - CPU policy pre-memory configuration services.
* PeiDxeSmmCpuPlatformLib - CPU platform services.
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/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf | 22 +
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf | 65 +++
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf | 43 ++
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf | 39 ++
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h | 30 ++
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h | 28 ++
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c | 90 ++++
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c | 293 +++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c | 108 +++++
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c | 434 ++++++++++++++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c | 160 ++++++++
Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c | 415 +++++++++++++++++++
12 files changed, 1727 insertions(+)
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf
new file mode 100644
index 0000000000..4fcfca4670
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.inf
@@ -0,0 +1,22 @@
+## @file
+# Component description file for Cpu Mailbox Null Lib
+#
+# Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = BaseCpuMailboxLibNull
+FILE_GUID = 74F470BC-1769-4732-B9C0-EE9AB0B12411
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = CpuMailboxLib
+
+[Packages]
+MdePkg/MdePkg.dec
+
+[Sources]
+BaseCpuMailboxLibNull.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
new file mode 100644
index 0000000000..c986e35360
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.inf
@@ -0,0 +1,65 @@
+## @file
+# Component description file for the PeiCpuPolicyLib library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiCpuPolicyLib
+FILE_GUID = 5baafc8f-25c6-4d19-b141-585757509372
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = CpuPolicyLib
+
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+PciSegmentLib
+SaPlatformLib
+SiConfigBlockLib
+PostCodeLib
+PcdLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PeiCpuPolicyLib.c
+PeiCpuPolicyLibrary.h
+CpuPrintPolicy.c
+PeiCpuPolicyLibPreMem.c
+CpuPrintPolicyPreMem.c
+
+[Ppis]
+gSiPolicyPpiGuid ## CONSUMES
+gSiPreMemPolicyPpiGuid ## CONSUMES
+
+[FixedPcd]
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase
+gSiPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize
+
+[Pcd]
+gUefiCpuPkgTokenSpaceGuid.PcdCpuApLoopMode ## Produces
+
+[Guids]
+gCpuConfigGuid ## PRODUCES
+gCpuSgxConfigGuid ## PRODUCES
+gCpuPowerMgmtBasicConfigGuid ## PRODUCES
+gCpuPowerMgmtCustomConfigGuid ## PRODUCES
+gCpuTestConfigGuid ## PRODUCES
+gCpuPidTestConfigGuid ## PRODUCES
+gCpuPowerMgmtTestConfigGuid ## PRODUCES
+gCpuConfigLibPreMemConfigGuid ## PRODUCES
+gCpuSecurityPreMemConfigGuid ## PRODUCES
+gCpuOverclockingPreMemConfigGuid ## CONSUMES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf
new file mode 100644
index 0000000000..52dc989f74
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.inf
@@ -0,0 +1,43 @@
+## @file
+# Component description file for the PeiCpuPolicyLibPreMem library.
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiCpuPolicyLibPreMem
+FILE_GUID = 5F4C2CF1-9DFE-4D99-9318-98FD31C8517D
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = CpuPolicyLibPreMem
+
+[LibraryClasses]
+DebugLib
+IoLib
+PeiServicesLib
+BaseMemoryLib
+MemoryAllocationLib
+CpuPlatformLib
+SiConfigBlockLib
+PostCodeLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+PeiCpuPolicyLib.c
+PeiCpuPolicyLibrary.h
+CpuPrintPolicy.c
+
+[Ppis]
+gSiPreMemPolicyPpiGuid ## CONSUMES
+
+[Guids]
+gCpuSecurityPreMemConfigGuid ## PRODUCES
+gCpuOverclockingPreMemConfigGuid ## PRODUCES
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
new file mode 100644
index 0000000000..0a56e42817
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/PeiDxeSmmCpuPlatformLib.inf
@@ -0,0 +1,39 @@
+## @file
+# Component description file for CPU Platform Lib
+#
+# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmCpuPlatformLib
+FILE_GUID = 11647130-6AA4-41A4-A3A8-5FA296ABD977
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = CpuPlatformLib
+
+[LibraryClasses]
+BaseLib
+BaseMemoryLib
+DebugLib
+IoLib
+PcdLib
+CpuLib
+TimerLib
+SynchronizationLib
+PciSegmentLib
+
+[Packages]
+MdePkg/MdePkg.dec
+UefiCpuPkg/UefiCpuPkg.dec
+CoffeelakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Sources]
+CpuPlatformLibrary.h
+CpuPlatformLibrary.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h
new file mode 100644
index 0000000000..6e993053fc
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibrary.h
@@ -0,0 +1,30 @@
+/** @file
+ Header file for the PeiCpuPolicyLib library.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _PEI_CPU_POLICY_LIBRARY_H_
+#define _PEI_CPU_POLICY_LIBRARY_H_
+
+#include <PiPei.h>
+#include <CpuAccess.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/SiPolicy.h>
+#include <Library/CpuPolicyLib.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/SiConfigBlockLib.h>
+#include <Library/CpuPlatformLib.h>
+#include <Register/Cpuid.h>
+#include <Library/PcdLib.h>
+
+#define MAX_MICROCODE_PATCH_SIZE 0x20000
+
+#endif // _PEI_CPU_POLICY_LIBRARY_H_
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h
new file mode 100644
index 0000000000..0b780acd22
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.h
@@ -0,0 +1,28 @@
+/** @file
+ Header file for Cpu Platform Lib implementation.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _CPU_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+#define _CPU_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/CpuLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Library/SynchronizationLib.h>
+
+#include <Register/Cpuid.h>
+#include <Register/Msr.h>
+#include <CpuAccess.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/PciSegmentLib.h>
+
+#endif
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c
new file mode 100644
index 0000000000..2af11ce8d0
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/BaseCpuMailboxLibNull/BaseCpuMailboxLibNull.c
@@ -0,0 +1,90 @@
+/** @file
+ Mailbox Library.
+
+ Copyright (c) 2017 - 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+
+/**
+ Generic Mailbox function for mailbox write commands. This function will
+ poll the mailbox interface for control, issue the write request, poll
+ for completion, and verify the write was successful.
+
+ @param[in] MailboxType The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+ @param[in] MailboxCommand Overclocking mailbox command data
+ @param[in] MailboxData Overclocking mailbox interface data
+ @param[out] *MailboxStatus Pointer to the mailbox status returned from pcode. Possible mailbox status values are:
+ - SUCCESS (0) Command succeeded.
+ - OC_LOCKED (1) Overclocking is locked. Service is read-only.
+ - INVALID_DOMAIN (2) Invalid Domain ID provided in command data.
+ - MAX_RATIO_EXCEEDED (3) Ratio exceeds maximum overclocking limits.
+ - MAX_VOLTAGE_EXCEEDED (4) Voltage exceeds input VR's max voltage.
+ - OC_NOT_SUPPORTED (5) Domain does not support overclocking.
+
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+ @retval EFI_UNSUPPORTED Unsupported MailboxType parameter.
+**/
+EFI_STATUS
+EFIAPI
+MailboxWrite (
+ IN UINT32 MailboxType,
+ IN UINT32 MailboxCommand,
+ IN UINT32 MailboxData,
+ OUT UINT32 *MailboxStatus
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Generic Mailbox function for mailbox read commands. This function will write
+ the read request from MailboxType, and populate the read results in the MailboxDataPtr.
+
+ @param[in] MailboxType The type of mailbox interface to read. The Overclocking mailbox is defined as MAILBOX_TYPE_OC = 2.
+ @param[in] MailboxCommand Overclocking mailbox command data
+ @param[out] *MailboxDataPtr Pointer to the overclocking mailbox interface data
+ @param[out] *MailboxStatus Pointer to the mailbox status returned from pcode. Possible mailbox status are
+ - SUCCESS (0) Command succeeded.
+ - OC_LOCKED (1) Overclocking is locked. Service is read-only.
+ - INVALID_DOMAIN (2) Invalid Domain ID provided in command data.
+ - MAX_RATIO_EXCEEDED (3) Ratio exceeds maximum overclocking limits.
+ - MAX_VOLTAGE_EXCEEDED (4) Voltage exceeds input VR's max voltage.
+ - OC_NOT_SUPPORTED (5) Domain does not support overclocking.
+
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_INVALID_PARAMETER Invalid read data detected from pcode.
+ @retval EFI_UNSUPPORTED Unsupported MailboxType parameter.
+**/
+EFI_STATUS
+EFIAPI
+MailboxRead (
+ IN UINT32 MailboxType,
+ IN UINT32 MailboxCommand,
+ OUT UINT32 *MailboxDataPtr,
+ OUT UINT32 *MailboxStatus
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Poll the run/busy bit of the mailbox until available or timeout expires.
+
+ @param[in] MailboxType
+
+ @retval EFI_SUCCESS Command succeeded.
+ @retval EFI_TIMEOUT Command timeout.
+**/
+EFI_STATUS
+EFIAPI
+PollMailboxReady (
+ IN UINT32 MailboxType
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c
new file mode 100644
index 0000000000..38cf383e8d
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicy.c
@@ -0,0 +1,293 @@
+/** @file
+ This file is PeiCpuPolicy library.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <Library/ConfigBlockLib.h>
+#include <Library/PcdLib.h>
+
+/**
+ Print CPU_CONFIG and serial out.
+
+ @param[in] CpuConfig Pointer to a CPU_CONFIG
+**/
+VOID
+CpuConfigPrint (
+ IN CONST CPU_CONFIG *CpuConfig
+ )
+{
+ DEBUG ((DEBUG_INFO, "------------------ CPU Config ------------------\n"));
+ DEBUG ((DEBUG_INFO, " CPU_CONFIG : AesEnable : 0x%x\n", CpuConfig->AesEnable));
+ DEBUG ((DEBUG_INFO, " CPU_CONFIG : MicrocodePatchAddress : 0x%x\n", CpuConfig->MicrocodePatchAddress));
+ DEBUG ((DEBUG_INFO, " CPU_CONFIG : DebugInterfaceEnable : 0x%X\n", CpuConfig->DebugInterfaceEnable));
+}
+
+/**
+ Print CPU_POWER_MGMT_BASIC_CONFIG and serial out.
+
+ @param[in] CpuPowerMgmtBasicConfig Pointer to a CPU_POWER_MGMT_BASIC_CONFIG
+**/
+VOID
+CpuPowerMgmtBasicConfigPrint (
+ IN CONST CPU_POWER_MGMT_BASIC_CONFIG *CpuPowerMgmtBasicConfig
+ )
+{
+ DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Basic Config ------------------\n"));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG : OneCoreRatioLimit : 0x%X , TwoCoreRatioLimit = 0x%X , ThreeCoreRatioLimit = 0x%X , FourCoreRatioLimit = 0x%X, FiveCoreRatioLimit = 0x%X, SixCoreRatioLimit = 0x%X, SevenCoreRatioLimit = 0x%X, EightCoreRatioLimit = 0x%X \n", CpuPowerMgmtBasicConfig->OneCoreRatioLimit, \
+ CpuPowerMgmtBasicConfig->TwoCoreRatioLimit, \
+ CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit, \
+ CpuPowerMgmtBasicConfig->FourCoreRatioLimit, \
+ CpuPowerMgmtBasicConfig->FiveCoreRatioLimit, \
+ CpuPowerMgmtBasicConfig->SixCoreRatioLimit, \
+ CpuPowerMgmtBasicConfig->SevenCoreRatioLimit, \
+ CpuPowerMgmtBasicConfig->EightCoreRatioLimit));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: Hwp : 0x%x\n", CpuPowerMgmtBasicConfig->Hwp));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: SkipSetBootPState : 0x%x\n", CpuPowerMgmtBasicConfig->SkipSetBootPState));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: HdcControl : 0x%X\n", CpuPowerMgmtBasicConfig->HdcControl));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: (Intel Turbo Boost Max Technology 3.0)EnableItbm : 0x%X\n", CpuPowerMgmtBasicConfig->EnableItbm));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: EnableItbmDriver : 0x%X\n", CpuPowerMgmtBasicConfig->EnableItbmDriver));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit2 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit2));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TurboPowerLimitLock : 0x%x\n", CpuPowerMgmtBasicConfig->TurboPowerLimitLock));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3DutyCycle : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3DutyCycle));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3Lock : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3Lock));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit4Lock : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit4Lock));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccOffsetClamp : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetClamp));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccOffsetLock : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetLock));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TurboMode : 0x%x\n", CpuPowerMgmtBasicConfig->TurboMode));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccActivationOffset : 0x%X\n", CpuPowerMgmtBasicConfig->TccActivationOffset));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit1 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit1));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit2Power : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit2Power));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit4 : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit4));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit1Time : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit1Time));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: PowerLimit3Time : 0x%x\n", CpuPowerMgmtBasicConfig->PowerLimit3Time));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: TccOffsetTimeWindowForRatl : 0x%X\n", CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: HwpInterruptControl : 0x%x\n", CpuPowerMgmtBasicConfig->HwpInterruptControl));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: MinRingRatioLimit : 0x%x\n", CpuPowerMgmtBasicConfig->MinRingRatioLimit));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_BASIC_CONFIG: MaxRingRatioLimit : 0x%x\n", CpuPowerMgmtBasicConfig->MaxRingRatioLimit));
+}
+
+/**
+ Print CPU_POWER_MGMT_CUSTOM_CONFIG and serial out.
+
+ @param[in] CpuPowerMgmtCustomConfig Pointer to a CPU_POWER_MGMT_CUSTOM_CONFIG
+**/
+VOID
+CpuPowerMgmtCustomConfigPrint (
+ IN CONST CPU_POWER_MGMT_CUSTOM_CONFIG *CpuPowerMgmtCustomConfig
+ )
+{
+ UINT32 Index = 0;
+ DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Custom Config ------------------\n"));
+ DEBUG ((DEBUG_INFO, "\n CustomRatioTable... \n"));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: VidNumber : 0x%x\n", CpuPowerMgmtCustomConfig->CustomRatioTable.NumberOfEntries));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: VidCpuid : 0x%x\n", CpuPowerMgmtCustomConfig->CustomRatioTable.Cpuid));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: VidMaxRatio : 0x%x\n", CpuPowerMgmtCustomConfig->CustomRatioTable.MaxRatio));
+ for (Index = 0; Index < MAX_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: StateRatio[%d] : 0x%x\n", Index, CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatio[Index]));
+ }
+ for (Index = 0; Index < MAX_16_CUSTOM_RATIO_TABLE_ENTRIES; Index++) {
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: StateRatioMax16[%d] : 0x%x\n", Index, CpuPowerMgmtCustomConfig->CustomRatioTable.StateRatioMax16[Index]));
+ }
+ for (Index = 0; Index < MAX_CUSTOM_CTDP_ENTRIES; Index++) {
+ DEBUG (
+ (DEBUG_INFO,
+ " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomPowerLimit1 : 0x%x\n",
+ Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomPowerLimit1)
+ );
+ DEBUG (
+ (DEBUG_INFO,
+ " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomPowerLimit2 : 0x%x\n",
+ Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomPowerLimit2)
+ );
+ DEBUG (
+ (DEBUG_INFO,
+ " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomPowerLimit1Time : 0x%x\n",
+ Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomPowerLimit1Time)
+ );
+ DEBUG (
+ (DEBUG_INFO,
+ " CPU_POWER_MGMT_CUSTOM_CONFIG: CustomConfigTdpTable[%d] CustomTurboActivationRatio : 0x%x\n",
+ Index,CpuPowerMgmtCustomConfig->CustomConfigTdpTable[Index].CustomTurboActivationRatio)
+ );
+ }
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: ConfigTdpLock : 0x%x\n", CpuPowerMgmtCustomConfig->ConfigTdpLock));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_CUSTOM_CONFIG: ConfigTdpBios : 0x%x\n", CpuPowerMgmtCustomConfig->ConfigTdpBios));
+}
+
+/**
+ Print CPU_TEST_CONFIG and serial out.
+
+ @param[in] CpuTestConfig Pointer to a CPU_TEST_CONFIG
+**/
+VOID
+CpuTestConfigPrint (
+ IN CONST CPU_TEST_CONFIG *CpuTestConfig
+ )
+{
+ UINT8 PcdCpuApLoopMode;
+
+ PcdCpuApLoopMode = PcdGet8 (PcdCpuApLoopMode);
+
+ DEBUG ((DEBUG_INFO, "------------------ CPU Test Config ------------------\n"));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MlcStreamerPrefetcher : 0x%X\n", CpuTestConfig->MlcStreamerPrefetcher));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MlcSpatialPrefetcher : 0x%X\n", CpuTestConfig->MlcSpatialPrefetcher));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MonitorMwaitEnable : 0x%X\n", CpuTestConfig->MonitorMwaitEnable));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: MachineCheckEnable : 0x%X\n", CpuTestConfig->MachineCheckEnable));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: DebugInterfaceLockEnable : 0x%X\n", CpuTestConfig->DebugInterfaceLockEnable));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceOutputScheme : 0x%X\n", CpuTestConfig->ProcessorTraceOutputScheme));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceEnable : 0x%X\n", CpuTestConfig->ProcessorTraceEnable));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceMemBase : 0x%llX\n", CpuTestConfig->ProcessorTraceMemBase));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ProcessorTraceMemLength : 0x%X\n", CpuTestConfig->ProcessorTraceMemLength));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: ThreeStrikeCounterDisable : 0x%X\n", CpuTestConfig->ThreeStrikeCounterDisable));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: VoltageOptimization : 0x%X\n", CpuTestConfig->VoltageOptimization));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: CpuWakeUpTimer : 0x%X\n", CpuTestConfig->CpuWakeUpTimer));
+ DEBUG ((DEBUG_INFO, " CPU_TEST_CONFIG: PcdCpuApLoopMode: 0x%X\n", PcdCpuApLoopMode));
+}
+
+/**
+ Print CPU_PID_TEST_CONFIG and serial out.
+
+ @param[in] CpuPidTestConfig Pointer to a CPU_PID_TEST_CONFIG
+**/
+VOID
+CpuPidTestConfigPrint (
+ IN CONST CPU_PID_TEST_CONFIG *CpuPidTestConfig
+ )
+{
+ UINT32 Index = 0;
+ DEBUG ((DEBUG_INFO, "------------------ CPU PID Test Config ------------------\n"));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PidTuning : 0x%X\n", Index, CpuPidTestConfig->PidTuning));
+ if ( CpuPidTestConfig->PidTuning == 1) {
+ for (Index = PID_DOMAIN_KP; Index <= PID_DOMAIN_KD; Index++) {
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : Ratl[%X] : 0x%X\n", Index, CpuPidTestConfig->Ratl[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr0[%X] : 0x%X\n", Index, CpuPidTestConfig->VrTdcVr0[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr1[%X] : 0x%X\n", Index, CpuPidTestConfig->VrTdcVr1[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr2[%X] : 0x%X\n", Index, CpuPidTestConfig->VrTdcVr2[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : VrTdcVr3[%X] : 0x%X\n", Index, CpuPidTestConfig->VrTdcVr3[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl1Msr[%X] : 0x%X\n", Index, CpuPidTestConfig->PbmPsysPl1Msr[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl1MmioPcs[%X] : 0x%X\n", Index, CpuPidTestConfig->PbmPsysPl1MmioPcs[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl2Msr[%X] : 0x%X\n", Index, CpuPidTestConfig->PbmPsysPl2Msr[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPsysPl2MmioPcs[%X] : 0x%X\n", Index, CpuPidTestConfig->PbmPsysPl2MmioPcs[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl1Msr[%X] : 0x%X\n", Index, CpuPidTestConfig->PbmPkgPl1Msr[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl1MmioPcs[%X] : 0x%X\n", Index, CpuPidTestConfig->PbmPkgPl1MmioPcs[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl2Msr[%X] : 0x%X\n", Index, CpuPidTestConfig->PbmPkgPl2Msr[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : PbmPkgPl2MmioPcs[%X] : 0x%X\n", Index, CpuPidTestConfig->PbmPkgPl2MmioPcs[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl1Msr[%X] : 0x%X\n", Index, CpuPidTestConfig->DdrPl1Msr[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl1MmioPcs[%X] : 0x%X\n", Index, CpuPidTestConfig->DdrPl1MmioPcs[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl2Msr[%X] : 0x%X\n", Index, CpuPidTestConfig->DdrPl2Msr[Index]));
+ DEBUG ((DEBUG_INFO, " CPU_PID_TEST_CONFIG : DdrPl2MmioPcs[%X] : 0x%X\n", Index, CpuPidTestConfig->DdrPl2MmioPcs[Index]));
+ }
+ }
+}
+
+/**
+ Print CPU_POWER_MGMT_TEST_CONFIG and serial out.
+
+ @param[in] CpuPowerMgmtTestConfig Pointer to a CPU_POWER_MGMT_TEST_CONFIG
+**/
+VOID
+CpuPowerMgmtTestConfigPrint (
+ IN CONST CPU_POWER_MGMT_TEST_CONFIG *CpuPowerMgmtTestConfig
+ )
+{
+ CPU_GENERATION CpuGeneration;
+ CpuGeneration = GetCpuGeneration();
+ DEBUG ((DEBUG_INFO, "------------------ CPU Power Mgmt Test Config ------------------\n"));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: Eist : 0x%x\n", CpuPowerMgmtTestConfig->Eist));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: EnergyEfficientPState : 0x%x\n", CpuPowerMgmtTestConfig->EnergyEfficientPState));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: EnergyEfficientTurbo : 0x%x\n", CpuPowerMgmtTestConfig->EnergyEfficientTurbo));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: TStates : 0x%x\n", CpuPowerMgmtTestConfig->TStates));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: BiProcHot : 0x%x\n", CpuPowerMgmtTestConfig->BiProcHot));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: DisableProcHotOut : 0x%x\n", CpuPowerMgmtTestConfig->DisableProcHotOut));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ProcHotResponse : 0x%x\n", CpuPowerMgmtTestConfig->ProcHotResponse));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: DisableVrThermalAlert : 0x%x\n", CpuPowerMgmtTestConfig->DisableVrThermalAlert));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: AutoThermalReporting : 0x%x\n", CpuPowerMgmtTestConfig->AutoThermalReporting));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ThermalMonitor : 0x%x\n", CpuPowerMgmtTestConfig->ThermalMonitor));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: Cx : 0x%x\n", CpuPowerMgmtTestConfig->Cx));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PmgCstCfgCtrlLock : 0x%x\n", CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C1e : 0x%x\n", CpuPowerMgmtTestConfig->C1e));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C1Autodemotion : 0x%x\n", CpuPowerMgmtTestConfig->C1AutoDemotion));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C1Undemotion : 0x%x\n", CpuPowerMgmtTestConfig->C1UnDemotion));
+ if(CpuGeneration == EnumCflCpu){
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C3AutoDemotion : 0x%x\n", CpuPowerMgmtTestConfig->C3AutoDemotion));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: C3UnDemotion : 0x%x\n", CpuPowerMgmtTestConfig->C3UnDemotion));
+ }
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PkgCState Demotion : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateDemotion));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PkgCstateUndemotion : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateUnDemotion));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CStatePreWake : 0x%x\n", CpuPowerMgmtTestConfig->CStatePreWake));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: TimedMwait : 0x%x\n", CpuPowerMgmtTestConfig->TimedMwait));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstCfgCtrIoMwaitRedirection : 0x%x\n", CpuPowerMgmtTestConfig->CstCfgCtrIoMwaitRedirection));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ProcHotLock : 0x%x\n", CpuPowerMgmtTestConfig->ProcHotLock));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: ConfigTdpLevel : 0x%x\n", CpuPowerMgmtTestConfig->ConfigTdpLevel));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: RaceToHalt : 0x%x\n", CpuPowerMgmtTestConfig->RaceToHalt));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl0Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl0TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl1Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl2Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl3Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl4Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl5Irtl : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: PkgCStateLimit : 0x%x\n", CpuPowerMgmtTestConfig->PkgCStateLimit));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl1TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl2TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl3TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl4TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CstateLatencyControl5TimeUnit : 0x%x\n", CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit));
+ DEBUG ((DEBUG_INFO, " CPU_POWER_MGMT_TEST_CONFIG: CustomPowerUnit : 0x%x\n", CpuPowerMgmtTestConfig->CustomPowerUnit));
+ DEBUG ((DEBUG_INFO, " PpmIrmSetting : 0x%x\n", CpuPowerMgmtTestConfig->PpmIrmSetting));
+}
+/**
+ Print whole CPU config blocks of SI_POLICY_PPI and serial out in PostMem.
+
+ @param[in] SiPolicyPpi The SI Policy PPI instance
+**/
+VOID
+CpuPrintPolicy (
+ IN SI_POLICY_PPI *SiPolicyPpi
+ )
+{
+DEBUG_CODE_BEGIN();
+ EFI_STATUS Status;
+ CPU_CONFIG *CpuConfig;
+ CPU_POWER_MGMT_BASIC_CONFIG *CpuPowerMgmtBasicConfig;
+ CPU_POWER_MGMT_CUSTOM_CONFIG *CpuPowerMgmtCustomConfig;
+ CPU_TEST_CONFIG *CpuTestConfig;
+ CPU_PID_TEST_CONFIG *CpuPidTestConfig;
+ CPU_POWER_MGMT_TEST_CONFIG *CpuPowerMgmtTestConfig;
+
+ Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuConfigGuid, (VOID *) &CpuConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtBasicConfigGuid, (VOID *) &CpuPowerMgmtBasicConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtCustomConfigGuid, (VOID *) &CpuPowerMgmtCustomConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuTestConfigGuid, (VOID *) &CpuTestConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPidTestConfigGuid, (VOID *) &CpuPidTestConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gCpuPowerMgmtTestConfigGuid, (VOID *) &CpuPowerMgmtTestConfig);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((DEBUG_INFO, "\n ------------------------ SiCpuPolicy Print Begin in PostMem----------------- \n"));
+ DEBUG ((DEBUG_INFO, " Revision= %x\n", SiPolicyPpi->TableHeader.Header.Revision));
+
+ CpuConfigPrint(CpuConfig);
+ CpuPowerMgmtBasicConfigPrint(CpuPowerMgmtBasicConfig);
+ CpuPowerMgmtCustomConfigPrint(CpuPowerMgmtCustomConfig);
+ CpuTestConfigPrint(CpuTestConfig);
+ CpuPidTestConfigPrint(CpuPidTestConfig);
+ CpuPowerMgmtTestConfigPrint(CpuPowerMgmtTestConfig);
+ DEBUG ((DEBUG_INFO, "\n ------------------------ SiCpuPolicy Print End in PostMem ----------------- \n\n"));
+DEBUG_CODE_END();
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c
new file mode 100644
index 0000000000..0bcb34c99c
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/CpuPrintPolicyPreMem.c
@@ -0,0 +1,108 @@
+/** @file
+ This file is PeiCpuPolicy library.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <Library/ConfigBlockLib.h>
+
+/**
+ Print CPU_CONFIG_LIB_PREMEM_CONFIG and serial out.
+
+ @param[in] CpuConfigLibPreMemConfig Pointer to a CPU_CONFIG_LIB_PREMEM_CONFIG
+
+**/
+VOID
+CpuConfigLibPreMemConfigPrint (
+ IN CONST CPU_CONFIG_LIB_PREMEM_CONFIG *CpuConfigLibPreMemConfig
+ )
+{
+ CPU_GENERATION CpuGeneration;
+ CpuGeneration = GetCpuGeneration();
+ DEBUG ((DEBUG_INFO, "------------------ CPU Config Lib PreMem Config ------------------\n"));
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : HyperThreading = 0x%x\n", CpuConfigLibPreMemConfig->HyperThreading));
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : BootFrequency = 0x%x\n", CpuConfigLibPreMemConfig->BootFrequency));
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : ActiveCoreCount = 0x%x\n", CpuConfigLibPreMemConfig->ActiveCoreCount));
+ if(CpuGeneration == EnumCflCpu){
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : FClkFrequency = 0x%x\n", CpuConfigLibPreMemConfig->FClkFrequency));
+ }
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : JtagC10PowerGateDisable = 0x%x\n", CpuConfigLibPreMemConfig->JtagC10PowerGateDisable));
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : BistOnReset = 0x%x\n", CpuConfigLibPreMemConfig->BistOnReset));
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : VmxEnable = 0x%x\n", CpuConfigLibPreMemConfig->VmxEnable));
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : CpuRatio = 0x%x\n", CpuConfigLibPreMemConfig->CpuRatio));
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : PeciSxReset = 0x%x\n", CpuConfigLibPreMemConfig->PeciSxReset));
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : PeciC10Reset = 0x%x\n", CpuConfigLibPreMemConfig->PeciC10Reset));
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : SkipMpInit = 0x%x\n", CpuConfigLibPreMemConfig->SkipMpInit));
+ DEBUG ((DEBUG_INFO, "CPU_CONFIG_LIB_PREMEM_CONFIG : DpSscMarginEnable = 0x%x\n", CpuConfigLibPreMemConfig->DpSscMarginEnable));
+}
+
+/**
+ Print CPU_OVERCLOCKING_PREMEM_CONFIG and serial out.
+
+ @param[in] CpuOverClockingConfig Pointer to a CPU_OVERCLOCKING_CONFIG
+**/
+VOID
+CpuOverClockingPreMemConfigPrint (
+ IN CONST CPU_OVERCLOCKING_PREMEM_CONFIG *CpuOverClockingPreMemConfig
+ )
+{
+ DEBUG ((DEBUG_INFO, "------------------ CPU OverClocking Config ------------------\n"));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: OcSupport : 0x%X\n", CpuOverClockingPreMemConfig->OcSupport));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: OcLock : 0x%X\n", CpuOverClockingPreMemConfig->OcLock));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageMode : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageMode));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreMaxOcRatio : 0x%X\n", CpuOverClockingPreMemConfig->CoreMaxOcRatio));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageOverride : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageOverride));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageAdaptive : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageAdaptive));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CoreVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->CoreVoltageOffset));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageMode : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageMode));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageOverride : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageOverride));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageAdaptive : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageAdaptive));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->RingVoltageOffset));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingMaxOcRatio : 0x%X\n", CpuOverClockingPreMemConfig->RingMaxOcRatio));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingDownBin : 0x%X\n", CpuOverClockingPreMemConfig->RingDownBin));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: Avx2RatioOffset : 0x%X\n", CpuOverClockingPreMemConfig->Avx2RatioOffset));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: Avx3RatioOffset : 0x%X\n", CpuOverClockingPreMemConfig->Avx3RatioOffset));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: BclkAdaptiveVoltage : 0x%X\n", CpuOverClockingPreMemConfig->BclkAdaptiveVoltage));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: CorePllVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->CorePllVoltageOffset));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: GtPllVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->GtPllVoltageOffset));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: RingPllVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->RingPllVoltageOffset));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: SaPllVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->SaPllVoltageOffset));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: McPllVoltageOffset : 0x%X\n", CpuOverClockingPreMemConfig->McPllVoltageOffset));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: TjMaxOffset : 0x%X\n", CpuOverClockingPreMemConfig->TjMaxOffset));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: TvbRatioClipping : 0x%X\n", CpuOverClockingPreMemConfig->TvbRatioClipping));
+ DEBUG ((DEBUG_INFO, " CPU_OVERCLOCKING_PREMEM_CONFIG:: TvbVoltageOptimization : 0x%X\n", CpuOverClockingPreMemConfig->TvbVoltageOptimization));
+}
+
+
+/**
+ Print whole CPU Config blocks of SI_PREMEM_POLICY_PPI and serial out in PreMem.
+
+ @param[in] SiPreMemPolicyPpi The SI Pre-Mem Policy PPI instance
+**/
+VOID
+CpuPreMemPrintPolicy (
+ IN SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
+ )
+{
+DEBUG_CODE_BEGIN();
+ EFI_STATUS Status;
+ CPU_CONFIG_LIB_PREMEM_CONFIG *CpuConfigLibPreMemConfig;
+ CPU_OVERCLOCKING_PREMEM_CONFIG *CpuOverclockingPreMemConfig;
+
+ DEBUG ((DEBUG_INFO, "\n------------------------ CPU - SiPreMemPolicyPpi Print Begin in PreMem -----------------\n"));
+
+ DEBUG ((DEBUG_INFO, " Revision= %x\n", SiPreMemPolicyPpi->TableHeader.Header.Revision));
+
+ Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuOverclockingPreMemConfigGuid, (VOID *) &CpuOverclockingPreMemConfig);
+ ASSERT_EFI_ERROR (Status);
+ CpuConfigLibPreMemConfigPrint(CpuConfigLibPreMemConfig);
+ CpuOverClockingPreMemConfigPrint(CpuOverclockingPreMemConfig);
+
+ DEBUG ((DEBUG_INFO, "\n------------------------ CPU - SiPreMemPolicyPpi Print End -----------------\n\n"));
+DEBUG_CODE_END();
+}
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c
new file mode 100644
index 0000000000..181b72fec5
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLib.c
@@ -0,0 +1,434 @@
+/** @file
+ This file is PeiCpuPolicy library.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <SaAccess.h>
+#include <CpuAccess.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/SaPlatformLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/PcdLib.h>
+
+#ifndef FSP_FLAG
+/**
+ Get the next microcode patch pointer.
+
+ @param[in, out] MicrocodeData - Input is a pointer to the last microcode patch address found,
+ and output points to the next patch address found.
+
+ @retval EFI_SUCCESS - Patch found.
+ @retval EFI_NOT_FOUND - Patch not found.
+**/
+EFI_STATUS
+EFIAPI
+RetrieveMicrocode (
+ IN OUT CPU_MICROCODE_HEADER **MicrocodeData
+ )
+{
+ UINTN MicrocodeStart;
+ UINTN MicrocodeEnd;
+ UINTN TotalSize;
+
+ if ((FixedPcdGet32 (PcdFlashMicrocodeFvBase) == 0) || (FixedPcdGet32 (PcdFlashMicrocodeFvSize) == 0)) {
+ return EFI_NOT_FOUND;
+ }
+
+ ///
+ /// Microcode binary in SEC
+ ///
+ MicrocodeStart = (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase) +
+ ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase))->HeaderLength +
+ sizeof (EFI_FFS_FILE_HEADER);
+
+ MicrocodeEnd = (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvBase) + (UINTN) FixedPcdGet32 (PcdFlashMicrocodeFvSize);
+
+ if (*MicrocodeData == NULL) {
+ *MicrocodeData = (CPU_MICROCODE_HEADER *) (UINTN) MicrocodeStart;
+ } else {
+ if (*MicrocodeData < (CPU_MICROCODE_HEADER *) (UINTN) MicrocodeStart) {
+ DEBUG ((DEBUG_INFO, "[CpuPolicy]*MicrocodeData < MicrocodeStart \n"));
+ return EFI_NOT_FOUND;
+ }
+
+ TotalSize = (UINTN) ((*MicrocodeData)->TotalSize);
+ if (TotalSize == 0) {
+ TotalSize = 2048;
+ }
+
+ *MicrocodeData = (CPU_MICROCODE_HEADER *) ((UINTN)*MicrocodeData + TotalSize);
+ if (*MicrocodeData >= (CPU_MICROCODE_HEADER *) (UINTN) (MicrocodeEnd) || (*MicrocodeData)->TotalSize == (UINT32) -1) {
+ DEBUG ((DEBUG_INFO, "[CpuPolicy]*MicrocodeData >= MicrocodeEnd \n"));
+ return EFI_NOT_FOUND;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Get the microcode patch pointer.
+
+ @retval EFI_PHYSICAL_ADDRESS - Address of the microcode patch, or NULL if not found.
+**/
+EFI_PHYSICAL_ADDRESS
+PlatformCpuLocateMicrocodePatch (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ CPU_MICROCODE_HEADER *MicrocodeData;
+ EFI_CPUID_REGISTER Cpuid;
+ UINT32 UcodeRevision;
+ UINTN MicrocodeBufferSize;
+ VOID *MicrocodeBuffer = NULL;
+
+ AsmCpuid (
+ CPUID_VERSION_INFO,
+ &Cpuid.RegEax,
+ &Cpuid.RegEbx,
+ &Cpuid.RegEcx,
+ &Cpuid.RegEdx
+ );
+
+ UcodeRevision = GetCpuUcodeRevision ();
+ MicrocodeData = NULL;
+ while (TRUE) {
+ ///
+ /// Find the next patch address
+ ///
+ Status = RetrieveMicrocode (&MicrocodeData);
+ DEBUG ((DEBUG_INFO, "MicrocodeData = %x\n", MicrocodeData));
+
+ if (Status != EFI_SUCCESS) {
+ break;
+ } else if (CheckMicrocode (Cpuid.RegEax, MicrocodeData, &UcodeRevision)) {
+ break;
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ return (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
+ }
+
+ ///
+ /// Check that microcode patch size is <= 128K max size,
+ /// then copy the patch from FV to temp buffer for faster access.
+ ///
+ MicrocodeBufferSize = (UINTN) MicrocodeData->TotalSize;
+
+ if (MicrocodeBufferSize <= MAX_MICROCODE_PATCH_SIZE) {
+ MicrocodeBuffer = AllocatePages (EFI_SIZE_TO_PAGES (MicrocodeBufferSize));
+ if (MicrocodeBuffer != NULL) {
+ DEBUG(( DEBUG_INFO, "Copying Microcode to temp buffer.\n"));
+ CopyMem (MicrocodeBuffer, MicrocodeData, MicrocodeBufferSize);
+
+ return (EFI_PHYSICAL_ADDRESS) (UINTN) MicrocodeBuffer;
+ } else {
+ DEBUG(( DEBUG_ERROR, "Failed to allocate enough memory for Microcode Patch.\n"));
+ }
+ } else {
+ DEBUG(( DEBUG_ERROR, "Microcode patch size is greater than max allowed size of 128K.\n"));
+ }
+ return (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
+}
+#endif
+
+/**
+ Load Config block default
+
+ @param[in] ConfigBlockPointer Pointer to config block
+**/
+VOID
+LoadCpuConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_CONFIG *CpuConfig;
+ CpuConfig = ConfigBlockPointer;
+
+ DEBUG ((DEBUG_INFO, "CpuConfig->Header.GuidHob.Name = %g\n", &CpuConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "CpuConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuConfig->Header.GuidHob.Header.HobLength));
+
+ /********************************
+ CPU configuration
+ ********************************/
+ CpuConfig->AesEnable = CPU_FEATURE_ENABLE;
+#ifndef FSP_FLAG
+ CpuConfig->MicrocodePatchAddress = PlatformCpuLocateMicrocodePatch ();
+#endif //FSP_FLAG
+}
+
+/**
+ Load Config block default
+
+ @param[in] ConfigBlockPointer Pointer to config block
+**/
+VOID
+LoadCpuSgxConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+
+ /********************************
+ CPU SGX configuration
+ ********************************/
+}
+
+/**
+ Load Config block default
+
+ @param[in] ConfigBlockPointer Pointer to config block
+**/
+VOID
+LoadCpuPowerMgmtBasicConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_POWER_MGMT_BASIC_CONFIG *CpuPowerMgmtBasicConfig;
+ CPU_SKU CpuSku;
+ MSR_REGISTER TempMsr;
+
+ CpuPowerMgmtBasicConfig = ConfigBlockPointer;
+ CpuSku = GetCpuSku();
+
+ DEBUG ((DEBUG_INFO, "CpuPowerMgmtBasicConfig->Header.GuidHob.Name = %g\n", &CpuPowerMgmtBasicConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "CpuPowerMgmtBasicConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPowerMgmtBasicConfig->Header.GuidHob.Header.HobLength));
+
+ /********************************
+ CPU Power Management Basic configuration
+ ********************************/
+ CpuPowerMgmtBasicConfig->Hwp = TRUE;
+ CpuPowerMgmtBasicConfig->HdcControl = TRUE;
+ CpuPowerMgmtBasicConfig->PowerLimit2 = TRUE;
+ CpuPowerMgmtBasicConfig->PowerLimit3Lock = TRUE;
+ CpuPowerMgmtBasicConfig->TccOffsetLock = FALSE;
+ CpuPowerMgmtBasicConfig->EnableItbm = TRUE;
+ CpuPowerMgmtBasicConfig->EnableItbmDriver = FALSE;
+
+ ///
+ /// Initialize RATL (Runtime Average Temperature Limit) Config for ULX.
+ ///
+ if (CpuSku == EnumCpuUlx) {
+ CpuPowerMgmtBasicConfig->TccActivationOffset = 15;
+ CpuPowerMgmtBasicConfig->TccOffsetTimeWindowForRatl = 5000; // 5 sec
+ CpuPowerMgmtBasicConfig->TccOffsetClamp = CPU_FEATURE_ENABLE;
+ }
+ CpuPowerMgmtBasicConfig->TurboMode = TRUE;
+
+ TempMsr.Qword = AsmReadMsr64 (MSR_TURBO_RATIO_LIMIT);
+ CpuPowerMgmtBasicConfig->OneCoreRatioLimit = TempMsr.Bytes.FirstByte;
+ CpuPowerMgmtBasicConfig->TwoCoreRatioLimit = TempMsr.Bytes.SecondByte;
+ CpuPowerMgmtBasicConfig->ThreeCoreRatioLimit = TempMsr.Bytes.ThirdByte;
+ CpuPowerMgmtBasicConfig->FourCoreRatioLimit = TempMsr.Bytes.FouthByte;
+ CpuPowerMgmtBasicConfig->FiveCoreRatioLimit = TempMsr.Bytes.FifthByte;
+ CpuPowerMgmtBasicConfig->SixCoreRatioLimit = TempMsr.Bytes.SixthByte;
+ CpuPowerMgmtBasicConfig->SevenCoreRatioLimit = TempMsr.Bytes.SeventhByte;
+ CpuPowerMgmtBasicConfig->EightCoreRatioLimit = TempMsr.Bytes.EighthByte;
+}
+
+/**
+ Load Config block default
+
+ @param[in] ConfigBlockPointer Pointer to config block
+**/
+VOID
+LoadCpuPowerMgmtCustomConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_POWER_MGMT_CUSTOM_CONFIG *CpuPowerMgmtCustomConfig;
+ CpuPowerMgmtCustomConfig = ConfigBlockPointer;
+
+ DEBUG ((DEBUG_INFO, "CpuPowerMgmtCustomConfig->Header.GuidHob.Name = %g\n", &CpuPowerMgmtCustomConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "CpuPowerMgmtCustomConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPowerMgmtCustomConfig->Header.GuidHob.Header.HobLength));
+
+ /********************************
+ CPU Power Management Custom configuration
+ ********************************/
+ CpuPowerMgmtCustomConfig->CustomRatioTable.Cpuid = (UINT16) ((GetCpuFamily() | GetCpuStepping()) & (0x0FFF));
+}
+
+/**
+ Load Config block default
+
+ @param[in] ConfigBlockPointer Pointer to config block
+**/
+VOID
+LoadCpuTestConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_TEST_CONFIG *CpuTestConfig;
+ CPU_SKU CpuSku;
+ CpuTestConfig = ConfigBlockPointer;
+
+ DEBUG ((DEBUG_INFO, "CpuTestConfig->Header.GuidHob.Name = %g\n", &CpuTestConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "CpuTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuTestConfig->Header.GuidHob.Header.HobLength));
+
+ CpuSku = GetCpuSku();
+ /********************************
+ CPU Test configuration
+ ********************************/
+
+ CpuTestConfig->MlcStreamerPrefetcher = CPU_FEATURE_ENABLE;
+ CpuTestConfig->MlcSpatialPrefetcher = CPU_FEATURE_ENABLE;
+ CpuTestConfig->MonitorMwaitEnable = CPU_FEATURE_ENABLE;
+ CpuTestConfig->MachineCheckEnable = CPU_FEATURE_ENABLE;
+ CpuTestConfig->DebugInterfaceLockEnable = CPU_FEATURE_ENABLE;
+
+ if ((CpuSku == EnumCpuUlx) || (CpuSku == EnumCpuUlt)){
+ /**
+ This policy should be used to enable or disable Voltage Optimization feature. Recommended defaults:
+ Enable - For Mobile SKUs(U/Y)
+ Disable - Rest of all SKUs other than Mobile.
+ **/
+ CpuTestConfig->VoltageOptimization = CPU_FEATURE_ENABLE;
+ }
+ else {
+ CpuTestConfig->VoltageOptimization = CPU_FEATURE_DISABLE;
+ }
+}
+
+/**
+ Load Config block default
+
+ @param[in] ConfigBlockPointer Pointer to config block
+**/
+VOID
+LoadCpuPidTestConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_PID_TEST_CONFIG *CpuPidTestConfig;
+ CpuPidTestConfig = ConfigBlockPointer;
+
+ DEBUG ((DEBUG_INFO, "CpuPidTestConfig->Header.GuidHob.Name = %g\n", &CpuPidTestConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "CpuPidTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPidTestConfig->Header.GuidHob.Header.HobLength));
+
+ /********************************
+ CPU PID Test configuration
+ ********************************/
+}
+
+/**
+ Load Config block default
+
+ @param[in] ConfigBlockPointer Pointer to config block
+**/
+VOID
+LoadCpuPowerMgmtTestConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_POWER_MGMT_TEST_CONFIG *CpuPowerMgmtTestConfig;
+ CPU_GENERATION CpuGeneration;
+ UINT16 CpuDid;
+
+ CpuPowerMgmtTestConfig = ConfigBlockPointer;
+ CpuDid = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MC_DEVICE_ID));
+
+ DEBUG ((DEBUG_INFO, "CpuPowerMgmtTestConfig->Header.GuidHob.Name = %g\n", &CpuPowerMgmtTestConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "CpuPowerMgmtTestConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuPowerMgmtTestConfig->Header.GuidHob.Header.HobLength));
+
+ /********************************
+ CPU Power Management Test configuration
+ ********************************/
+ CpuPowerMgmtTestConfig->Eist = TRUE;
+ CpuPowerMgmtTestConfig->EnergyEfficientPState = TRUE;
+ CpuPowerMgmtTestConfig->EnergyEfficientTurbo = TRUE;
+ if ((CpuDid == V_SA_DEVICE_ID_CFL_DT_1) || (CpuDid == V_SA_DEVICE_ID_CFL_DT_2)
+ || (CpuDid == V_SA_DEVICE_ID_CFL_DT_3) || (CpuDid == V_SA_DEVICE_ID_CFL_DT_4)) {
+ ///
+ /// CFL-S 6+2, CFL S 8+2, CFl S 4+2, CFL S 2+2
+ ///
+ CpuPowerMgmtTestConfig->EnergyEfficientTurbo = FALSE;
+ }
+ CpuPowerMgmtTestConfig->BiProcHot = TRUE;
+ CpuPowerMgmtTestConfig->DisableProcHotOut = TRUE;
+ CpuPowerMgmtTestConfig->AutoThermalReporting = TRUE;
+ CpuPowerMgmtTestConfig->ThermalMonitor = TRUE;
+ CpuPowerMgmtTestConfig->Cx = TRUE;
+ CpuPowerMgmtTestConfig->PmgCstCfgCtrlLock = TRUE;
+ CpuPowerMgmtTestConfig->C1e = TRUE;
+ CpuPowerMgmtTestConfig->C1AutoDemotion = TRUE;
+ CpuPowerMgmtTestConfig->C1UnDemotion = TRUE;
+ CpuGeneration = GetCpuGeneration();
+ if(CpuGeneration == EnumCflCpu){
+ CpuPowerMgmtTestConfig->C3AutoDemotion = TRUE;
+ CpuPowerMgmtTestConfig->C3UnDemotion = TRUE;
+ }
+
+ CpuPowerMgmtTestConfig->CStatePreWake = TRUE;
+ CpuPowerMgmtTestConfig->RaceToHalt = TRUE;
+ CpuPowerMgmtTestConfig->CstateLatencyControl0TimeUnit = TimeUnit1024ns;
+ CpuPowerMgmtTestConfig->CstateLatencyControl1TimeUnit = TimeUnit1024ns;
+ CpuPowerMgmtTestConfig->CstateLatencyControl2TimeUnit = TimeUnit1024ns;
+ CpuPowerMgmtTestConfig->CstateLatencyControl3TimeUnit = TimeUnit1024ns;
+ CpuPowerMgmtTestConfig->CstateLatencyControl4TimeUnit = TimeUnit1024ns;
+ CpuPowerMgmtTestConfig->CstateLatencyControl5TimeUnit = TimeUnit1024ns;
+ CpuPowerMgmtTestConfig->CstateLatencyControl0Irtl = C3_LATENCY;
+ CpuPowerMgmtTestConfig->CstateLatencyControl1Irtl = C6_C7_SHORT_LATENCY;
+ CpuPowerMgmtTestConfig->CstateLatencyControl2Irtl = C6_C7_LONG_LATENCY;
+ CpuPowerMgmtTestConfig->CstateLatencyControl3Irtl = C8_LATENCY;
+ CpuPowerMgmtTestConfig->CstateLatencyControl4Irtl = C9_LATENCY;
+ CpuPowerMgmtTestConfig->CstateLatencyControl5Irtl = C10_LATENCY;
+
+ CpuPowerMgmtTestConfig->PkgCStateLimit = PkgAuto;
+ CpuPowerMgmtTestConfig->CustomPowerUnit = PowerUnit125MilliWatts;
+ CpuPowerMgmtTestConfig->PpmIrmSetting = PpmIrmPairFixedPriority;
+}
+
+static COMPONENT_BLOCK_ENTRY mCpuIpBlocks [] = {
+ {&gCpuConfigGuid, sizeof (CPU_CONFIG), CPU_CONFIG_REVISION, LoadCpuConfigDefault},
+ {&gCpuPowerMgmtBasicConfigGuid, sizeof (CPU_POWER_MGMT_BASIC_CONFIG), CPU_POWER_MGMT_BASIC_CONFIG_REVISION, LoadCpuPowerMgmtBasicConfigDefault},
+ {&gCpuPowerMgmtCustomConfigGuid, sizeof (CPU_POWER_MGMT_CUSTOM_CONFIG), CPU_POWER_MGMT_CUSTOM_CONFIG_REVISION, LoadCpuPowerMgmtCustomConfigDefault},
+ {&gCpuTestConfigGuid, sizeof (CPU_TEST_CONFIG), CPU_TEST_CONFIG_REVISION, LoadCpuTestConfigDefault},
+ {&gCpuPidTestConfigGuid, sizeof (CPU_PID_TEST_CONFIG), CPU_PID_TEST_CONFIG_REVISION, LoadCpuPidTestConfigDefault},
+ {&gCpuPowerMgmtTestConfigGuid, sizeof (CPU_POWER_MGMT_TEST_CONFIG), CPU_POWER_MGMT_TEST_CONFIG_REVISION, LoadCpuPowerMgmtTestConfigDefault},
+};
+
+/**
+ Get CPU config block table total size.
+
+ @retval Size of CPU config block table
+**/
+UINT16
+EFIAPI
+CpuGetConfigBlockTotalSize (
+ VOID
+ )
+{
+ return GetComponentConfigBlockTotalSize (&mCpuIpBlocks[0], sizeof (mCpuIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+ CpuAddConfigBlocks add all Cpu config blocks.
+
+ @param[in] ConfigBlockTableAddress The pointer to add CPU config blocks
+
+ @retval EFI_SUCCESS The policy default is initialized.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddConfigBlocks (
+ IN VOID *ConfigBlockTableAddress
+ )
+{
+ EFI_STATUS Status;
+ DEBUG((DEBUG_INFO, "CPU Post-Mem Entry \n"));
+ PostCode (0xC00);
+
+ Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mCpuIpBlocks[0], sizeof (mCpuIpBlocks) / sizeof (COMPONENT_BLOCK_ENTRY));
+ DEBUG ((DEBUG_INFO, "CpuAddConfigBlocks Done \n"));
+ PostCode (0xC09);
+
+ return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c
new file mode 100644
index 0000000000..7d45e10236
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiCpuPolicyLib/PeiCpuPolicyLibPreMem.c
@@ -0,0 +1,160 @@
+/** @file
+ This file is PeiCpuPolicyLibPreMem library.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PeiCpuPolicyLibrary.h"
+#include <Library/PciSegmentLib.h>
+#include <Library/ConfigBlockLib.h>
+#include <Library/PostCodeLib.h>
+#include <Library/SaPlatformLib.h>
+
+/**
+ Load Config block default
+
+ @param[in] ConfigBlockPointer Pointer to config block
+**/
+VOID
+LoadCpuSecurityPreMemConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+
+}
+
+/**
+ Load Config block default
+
+ @param[in] ConfigBlockPointer Pointer to config block
+**/
+VOID
+LoadCpuConfigLibPreMemConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_GENERATION CpuGeneration;
+ CPU_CONFIG_LIB_PREMEM_CONFIG *CpuConfigLibPreMemConfig;
+ CPU_FAMILY CpuFamily;
+ CPU_SKU CpuSku;
+ BOOLEAN PegDisabled;
+ UINT64 MchBar;
+ UINT64 SaPciBase;
+
+ CpuConfigLibPreMemConfig = ConfigBlockPointer;
+ CpuFamily = GetCpuFamily();
+ CpuSku = GetCpuSku();
+
+ DEBUG ((DEBUG_INFO, "CpuConfigLibPreMemConfig->Header.GuidHob.Name = %g\n", &CpuConfigLibPreMemConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "CpuConfigLibPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuConfigLibPreMemConfig->Header.GuidHob.Header.HobLength));
+
+ /********************************
+ CPU Config Lib PreMem configuration
+ ********************************/
+ CpuConfigLibPreMemConfig->HyperThreading = CPU_FEATURE_ENABLE;
+ CpuConfigLibPreMemConfig->BootFrequency = 1; // Maximum non-turbo Performance
+ CpuConfigLibPreMemConfig->ActiveCoreCount = 0; // All cores active
+ CpuConfigLibPreMemConfig->JtagC10PowerGateDisable = CPU_FEATURE_DISABLE;
+ CpuConfigLibPreMemConfig->BistOnReset = CPU_FEATURE_DISABLE;
+ CpuConfigLibPreMemConfig->VmxEnable = CPU_FEATURE_ENABLE;
+ CpuConfigLibPreMemConfig->CpuRatio = (RShiftU64 (AsmReadMsr64 (MSR_PLATFORM_INFO), N_PLATFORM_INFO_MAX_RATIO) & B_PLATFORM_INFO_RATIO_MASK);
+
+ CpuGeneration = GetCpuGeneration();
+ if(CpuGeneration == EnumCflCpu){
+ ///
+ /// FCLK Frequency
+ ///
+
+ SaPciBase = PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, 0);
+ PciSegmentReadBuffer (SaPciBase + R_SA_MCHBAR, sizeof (MchBar), &MchBar);
+ MchBar &= ((UINT64) ~BIT0);
+ if (IsPchLinkDmi (CpuFamily) && (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_PEG_BUS_NUM, SA_PEG_DEV_NUM, SA_PEG0_FUN_NUM, PCI_VENDOR_ID_OFFSET)) != 0xFFFF)) {
+ PegDisabled = MmioRead32 ((UINTN) MchBar + R_SA_MCHBAR_BIOS_RESET_CPL_OFFSET) & BIT3;
+ } else {
+ PegDisabled = 1;
+ }
+
+ ///
+ /// DT/Halo FCLK = 1GHz
+ /// Ulx/Ult FCLK = 800MHz
+ ///
+ if (((CpuSku == EnumCpuHalo) && (!PegDisabled)) || (CpuSku == EnumCpuTrad)) {
+ CpuConfigLibPreMemConfig->FClkFrequency = 1; // 1Ghz
+ }
+ else {
+ CpuConfigLibPreMemConfig->FClkFrequency = 0; // 800MHz
+ }
+ ///
+ /// Disable Peci Reset on C10 exit on CFL based CPU's
+ /// Setting to 1 will activate the message that disables peci reset.
+ ///
+ CpuConfigLibPreMemConfig->PeciC10Reset = 1;
+ }
+}
+
+/**
+ Load Overclocking pre-mem Config block default
+
+ @param[in] ConfigBlockPointer Pointer to config block
+**/
+VOID
+LoadCpuOverclockingPreMemConfigDefault (
+ IN VOID *ConfigBlockPointer
+ )
+{
+ CPU_OVERCLOCKING_PREMEM_CONFIG *CpuOverclockingPreMemConfig;
+ CpuOverclockingPreMemConfig = ConfigBlockPointer;
+
+ /********************************
+ CPU Overclocking PreMem configuration
+ ********************************/
+ DEBUG ((DEBUG_INFO, "CpuOverclockingPreMemConfig->Header.GuidHob.Name = %g\n", &CpuOverclockingPreMemConfig->Header.GuidHob.Name));
+ DEBUG ((DEBUG_INFO, "CpuOverclockingPreMemConfig->Header.GuidHob.Header.HobLength = 0x%x\n", CpuOverclockingPreMemConfig->Header.GuidHob.Header.HobLength));
+}
+
+static COMPONENT_BLOCK_ENTRY mCpuIpBlocksPreMem [] = {
+ {&gCpuConfigLibPreMemConfigGuid, sizeof (CPU_CONFIG_LIB_PREMEM_CONFIG), CPU_CONFIG_LIB_PREMEM_CONFIG_REVISION, LoadCpuConfigLibPreMemConfigDefault},
+ {&gCpuOverclockingPreMemConfigGuid, sizeof (CPU_OVERCLOCKING_PREMEM_CONFIG), CPU_OVERCLOCKING_CONFIG_REVISION, LoadCpuOverclockingPreMemConfigDefault},
+};
+
+/**
+ Get CPU PREMEM config block table total size.
+
+ @retval Size of CPU PREMEM config block table
+**/
+UINT16
+EFIAPI
+CpuGetPreMemConfigBlockTotalSize (
+ VOID
+ )
+{
+ return GetComponentConfigBlockTotalSize (&mCpuIpBlocksPreMem[0], sizeof (mCpuIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+}
+
+/**
+ CpuAddPreMemConfigBlocks add all CPU PREMEM config blocks.
+
+ @param[in] ConfigBlockTableAddress The pointer to add CPU PREMEM config blocks
+
+ @retval EFI_SUCCESS The policy default is initialized.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+**/
+EFI_STATUS
+EFIAPI
+CpuAddPreMemConfigBlocks (
+ IN VOID *ConfigBlockTableAddress
+ )
+{
+ EFI_STATUS Status;
+ DEBUG((DEBUG_INFO, "CPU Pre-Mem Entry \n"));
+ PostCode (0xC00);
+
+ Status = AddComponentConfigBlocks (ConfigBlockTableAddress, &mCpuIpBlocksPreMem[0], sizeof (mCpuIpBlocksPreMem) / sizeof (COMPONENT_BLOCK_ENTRY));
+ DEBUG((DEBUG_INFO, "CpuAddPreMemConfigBlocks Done \n"));
+ PostCode (0xC0F);
+
+ return Status;
+}
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c
new file mode 100644
index 0000000000..18f2028fa9
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Cpu/Library/PeiDxeSmmCpuPlatformLib/CpuPlatformLibrary.c
@@ -0,0 +1,415 @@
+/** @file
+ CPU Platform Lib implementation.
+
+ Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "CpuPlatformLibrary.h"
+#include <SaAccess.h>
+#include <MeChipset.h>
+
+#define SKIP_MICROCODE_CHECKSUM_CHECK 1
+#define C6DRAM_ENABLE 1
+#define C6DRAM_DISABLE 0
+
+/**
+ Return CPU Family ID
+
+ @retval CPU_FAMILY CPU Family ID
+**/
+CPU_FAMILY
+EFIAPI
+GetCpuFamily (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER Cpuid;
+ ///
+ /// Read the CPUID information
+ ///
+ AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+ return ((CPU_FAMILY) (Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL));
+}
+
+/**
+ Return Cpu stepping type
+
+ @retval UINT8 Cpu stepping type
+**/
+CPU_STEPPING
+EFIAPI
+GetCpuStepping (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER Cpuid;
+ ///
+ /// Read the CPUID information
+ ///
+ AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+ return ((CPU_STEPPING) (Cpuid.RegEax & CPUID_FULL_STEPPING));
+}
+
+/**
+ Return CPU Sku
+
+ @retval UINT8 CPU Sku
+**/
+UINT8
+EFIAPI
+GetCpuSku (
+ VOID
+ )
+{
+ UINT8 CpuType;
+ UINT16 CpuDid;
+ UINT32 CpuFamilyModel;
+ EFI_CPUID_REGISTER Cpuid;
+ BOOLEAN SkuFound;
+
+ SkuFound = TRUE;
+ CpuType = EnumCpuUnknown;
+
+ ///
+ /// Read the CPUID & DID information
+ ///
+ AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+ CpuFamilyModel = Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL;
+ CpuDid = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MC_DEVICE_ID));
+
+ switch (CpuFamilyModel) {
+ case CPUID_FULL_FAMILY_MODEL_COFFEELAKE_ULT_ULX:
+ switch (CpuDid) {
+ case V_SA_DEVICE_ID_KBL_MB_ULT_1: // KBL ULT OPI
+ case V_SA_DEVICE_ID_CFL_ULT_1: // CFL ULT
+ case V_SA_DEVICE_ID_CFL_ULT_2: // CFL ULT
+ case V_SA_DEVICE_ID_CFL_ULT_3: // CFL ULT
+ case V_SA_DEVICE_ID_CFL_ULT_4: // CFL ULT
+ CpuType = EnumCpuUlt;
+ break;
+
+ default:
+ SkuFound = FALSE;
+ break;
+ }
+ break;
+
+ case CPUID_FULL_FAMILY_MODEL_COFFEELAKE_DT_HALO:
+ switch (CpuDid) {
+
+ case V_SA_DEVICE_ID_KBL_DT_2: // DT
+ case V_SA_DEVICE_ID_KBL_SVR_2: // Server
+ case V_SA_DEVICE_ID_CFL_DT_1: // DT
+ case V_SA_DEVICE_ID_CFL_DT_2: // DT
+ case V_SA_DEVICE_ID_CFL_DT_3: // DT
+ case V_SA_DEVICE_ID_CFL_DT_4: // DT
+ case V_SA_DEVICE_ID_CFL_WS_1: // WorkStation
+ case V_SA_DEVICE_ID_CFL_WS_2: // Workstation
+ case V_SA_DEVICE_ID_CFL_WS_3: // Workstation
+ case V_SA_DEVICE_ID_CFL_SVR_1: // Server
+ case V_SA_DEVICE_ID_CFL_SVR_2: // Server
+ case V_SA_DEVICE_ID_CFL_SVR_3: // Server
+ CpuType = EnumCpuTrad;
+ break;
+
+ case V_SA_DEVICE_ID_KBL_HALO_2: // Halo
+ case V_SA_DEVICE_ID_CFL_HALO_1: // Halo
+ case V_SA_DEVICE_ID_CFL_HALO_2: // Halo
+ case V_SA_DEVICE_ID_CFL_HALO_3: // Halo
+ CpuType = EnumCpuHalo;
+ break;
+
+ default:
+ SkuFound = FALSE;
+ break;
+ }
+ break;
+
+ default:
+ SkuFound = FALSE;
+ break;
+ }
+#ifdef CFL_SIMICS
+ CpuType = EnumCpuTrad;
+#else
+ if (!SkuFound) {
+ DEBUG ((DEBUG_ERROR, "Unsupported CPU SKU, Device ID: 0x%02X, CPUID: 0x%08X!\n", CpuDid, CpuFamilyModel));
+ ASSERT (FALSE);
+ }
+#endif
+
+ return CpuType;
+}
+
+/**
+ Returns the processor microcode revision of the processor installed in the system.
+
+ @retval Processor Microcode Revision
+**/
+UINT32
+GetCpuUcodeRevision (
+ VOID
+ )
+{
+ AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0);
+ AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
+ return (UINT32) RShiftU64 (AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID), 32);
+}
+
+/**
+ Verify the DWORD type checksum
+
+ @param[in] ChecksumAddr - The start address to be checkumed
+ @param[in] ChecksumLen - The length of data to be checksumed
+
+ @retval EFI_SUCCESS - Checksum correct
+ @retval EFI_CRC_ERROR - Checksum incorrect
+**/
+EFI_STATUS
+Checksum32Verify (
+ IN UINT32 *ChecksumAddr,
+ IN UINT32 ChecksumLen
+ )
+{
+#if SKIP_MICROCODE_CHECKSUM_CHECK
+ return EFI_SUCCESS;
+#else
+ UINT32 Checksum;
+ UINT32 Index;
+
+ Checksum = 0;
+
+ for (Index = 0; Index < ChecksumLen; Index++) {
+ Checksum += ChecksumAddr[Index];
+ }
+
+ return (Checksum == 0) ? EFI_SUCCESS : EFI_CRC_ERROR;
+#endif
+}
+
+/**
+ This function checks the MCU revision to decide if BIOS needs to load
+ microcode.
+
+ @param[in] MicrocodePointer - Microcode in memory
+ @param[in] Revision - Current CPU microcode revision
+
+ @retval EFI_SUCCESS - BIOS needs to load microcode
+ @retval EFI_ABORTED - Don't need to update microcode
+**/
+EFI_STATUS
+CheckMcuRevision (
+ IN CPU_MICROCODE_HEADER *MicrocodePointer,
+ IN UINT32 Revision
+ )
+{
+ EFI_STATUS Status;
+ Status = EFI_ABORTED;
+
+ if ((MicrocodePointer->UpdateRevision & 0x80000000) ||
+ (MicrocodePointer->UpdateRevision > Revision) ||
+ (Revision == 0)) {
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+/**
+ Check if this microcode is correct one for processor
+
+ @param[in] Cpuid - processor CPUID
+ @param[in] MicrocodeEntryPoint - entry point of microcode
+ @param[in] Revision - revision of microcode
+
+ @retval CorrectMicrocode if this microcode is correct
+**/
+BOOLEAN
+CheckMicrocode (
+ IN UINT32 Cpuid,
+ IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint,
+ IN UINT32 *Revision
+ )
+{
+ EFI_STATUS Status;
+ UINT8 ExtendedIndex;
+ MSR_IA32_PLATFORM_ID_REGISTER Msr;
+ UINT32 ExtendedTableLength;
+ UINT32 ExtendedTableCount;
+ BOOLEAN CorrectMicrocode;
+ CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
+ CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
+
+ Status = EFI_NOT_FOUND;
+ ExtendedTableLength = 0;
+ CorrectMicrocode = FALSE;
+
+ if (MicrocodeEntryPoint == NULL) {
+ return FALSE;
+ }
+
+ Msr.Uint64 = AsmReadMsr64 (MSR_IA32_PLATFORM_ID);
+
+ ///
+ /// Check if the microcode is for the Cpu and the version is newer
+ /// and the update can be processed on the platform
+ ///
+ if ((MicrocodeEntryPoint->HeaderVersion == 0x00000001) &&
+ !EFI_ERROR (CheckMcuRevision (MicrocodeEntryPoint, *Revision))
+ ) {
+ if ((MicrocodeEntryPoint->ProcessorId == Cpuid) && (MicrocodeEntryPoint->ProcessorFlags & (1 << (UINT8) Msr.Bits.PlatformId))) {
+ if (MicrocodeEntryPoint->DataSize == 0) {
+ Status = Checksum32Verify ((UINT32 *) MicrocodeEntryPoint, 2048 / sizeof (UINT32));
+ } else {
+ Status = Checksum32Verify (
+ (UINT32 *) MicrocodeEntryPoint,
+ (MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER)) / sizeof (UINT32)
+ );
+ }
+
+ if (!EFI_ERROR (Status)) {
+ CorrectMicrocode = TRUE;
+ }
+ } else if ((MicrocodeEntryPoint->DataSize != 0)) {
+ ///
+ /// Check the Extended Signature if the entended signature exist
+ /// Only the data size != 0 the extended signature may exist
+ ///
+ ExtendedTableLength = MicrocodeEntryPoint->TotalSize - (MicrocodeEntryPoint->DataSize + sizeof (CPU_MICROCODE_HEADER));
+ if (ExtendedTableLength != 0) {
+ ///
+ /// Extended Table exist, check if the CPU in support list
+ ///
+ ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINT8 *) (MicrocodeEntryPoint) + MicrocodeEntryPoint->DataSize + 48);
+ ///
+ /// Calulate Extended Checksum
+ ///
+ if ((ExtendedTableLength % 4) == 0) {
+ Status = Checksum32Verify ((UINT32 *) ExtendedTableHeader, ExtendedTableLength / sizeof (UINT32));
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Checksum correct
+ ///
+ ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount;
+ ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader + 1);
+ for (ExtendedIndex = 0; ExtendedIndex < ExtendedTableCount; ExtendedIndex++) {
+ ///
+ /// Verify Header
+ ///
+ if ((ExtendedTable->ProcessorSignature == Cpuid) && (ExtendedTable->ProcessorFlag & (1 << (UINT8) Msr.Bits.PlatformId))) {
+ Status = Checksum32Verify (
+ (UINT32 *) ExtendedTable,
+ sizeof (CPU_MICROCODE_EXTENDED_TABLE) / sizeof (UINT32)
+ );
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Find one
+ ///
+ CorrectMicrocode = TRUE;
+ break;
+ }
+ }
+
+ ExtendedTable++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return CorrectMicrocode;
+}
+
+/**
+ Check on the processor if SGX is supported.
+
+ @retval TRUE if SGX supported
+ @retval FALSE if SGX is not supported
+**/
+BOOLEAN
+IsSgxSupported (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER CpuidRegs;
+
+ //
+ // Processor support SGX feature by reading CPUID.(EAX=7,ECX=0):EBX[2]
+ //
+ AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, &CpuidRegs.RegEax,&CpuidRegs.RegEbx,&CpuidRegs.RegEcx,&CpuidRegs.RegEdx);
+
+ ///
+ /// SGX feature is supported with CPUID.(EAX=7,ECX=0):EBX[2]=1
+ /// PRMRR configuration enabled, MSR IA32_MTRRCAP (FEh) [12] == 1
+ ///
+ if (((CpuidRegs.RegEbx & BIT2)) && (AsmReadMsr64 (MSR_IA32_MTRRCAP) & BIT12)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ Get processor generation
+
+ @retval CPU_GENERATION Returns the executing thread's processor generation.
+**/
+CPU_GENERATION
+GetCpuGeneration (
+ VOID
+ )
+{
+ EFI_CPUID_REGISTER Cpuid;
+ CPU_FAMILY CpuFamilyModel;
+ CPU_GENERATION CpuGeneration;
+
+ CpuGeneration = EnumCflCpu;
+ ///
+ /// Read the CPUID information
+ ///
+ AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+ CpuFamilyModel = (CPU_FAMILY) (Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL);
+
+ switch (CpuFamilyModel) {
+ case EnumCpuCflUltUlx:
+ case EnumCpuCflDtHalo:
+ CpuGeneration = EnumCflCpu;
+ break;
+
+ default:
+ CpuGeneration = EnumCpuUnknownGeneration;
+ ASSERT (FALSE);
+ break;
+ }
+
+ return CpuGeneration;
+}
+
+/**
+ Is Whiskey Lake CPU.
+
+ @retval TRUE The CPUID corresponds with a Whiskey Lake CPU
+ @retval FALSE The CPUID does not correspond with a Whiskey Lake CPU
+**/
+BOOLEAN
+IsWhlCpu (
+ VOID
+ )
+{
+ CPU_FAMILY CpuFamily;
+ CPU_STEPPING CpuStepping;
+
+ CpuFamily = GetCpuFamily ();
+ CpuStepping = GetCpuStepping ();
+
+ //
+ // Check if it is Whiskey Lake CPU
+ //
+ if ((CpuFamily == EnumCpuCflUltUlx) && ((CpuStepping == EnumCflW0) || (CpuStepping == EnumCflV0))) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
--
2.16.2.windows.1
next prev parent reply other threads:[~2019-08-17 0:16 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 ` Kubacki, Michael A [this message]
2019-08-17 0:52 ` [edk2-platforms][PATCH V1 15/37] CoffeelakeSiliconPkg/Cpu: Add " 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 ` [edk2-platforms][PATCH V1 26/37] CoffeelakeSiliconPkg/Pch: Add modules 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 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-16-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