/** @file Pei CPU Specific Features. @copyright INTEL CONFIDENTIAL Copyright 2020 - 2021 Intel Corporation. The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material may contain trade secrets and proprietary and confidential information of Intel Corporation and its suppliers and licensors, and is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel's prior express written permission. No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing. Unless otherwise agreed by Intel in writing, you may not remove or alter this notice or any other notice embedded in Materials by Intel or Intel's suppliers or licensors in any way. This file contains an 'Intel Peripheral Driver' and is uniquely identified as "Intel Reference Module" and is licensed for Intel CPUs and chipsets under the terms of your license agreement with Intel or your vendor. This file may be modified by the user, subject to additional terms of the license agreement. @par Specification Reference: **/ #include "PeiCpuSpecificFeatures.h" #include #include #include #include #include #include /** Detects if HDC feature supported on current processor. @param[in] ProcessorNumber The index of the CPU executing this function. @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION structure for the CPU executing this function. @param[in] ConfigData A pointer to the configuration buffer returned by CPU_FEATURE_GET_CONFIG_DATA. NULL if CPU_FEATURE_GET_CONFIG_DATA was not provided in RegisterCpuFeature(). @retval TRUE HDC feature is supported. @retval FALSE HDC feature is not supported. @note This service could be called by BSP/APs. **/ BOOLEAN EFIAPI IsHdcSupport ( IN UINTN ProcessorNumber, IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, IN VOID *ConfigData OPTIONAL ) { MSR_MISC_PWR_MGMT_REGISTER MiscPwrMgmt; MiscPwrMgmt.Uint64 = AsmReadMsr64 (MSR_MISC_PWR_MGMT); if (MiscPwrMgmt.Bits.EnableSdc) { return TRUE; } return FALSE; } /** Initializes HDC feature to specific state. @param[in] ProcessorNumber The index of the CPU executing this function. @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION structure for the CPU executing this function. @param[in] ConfigData A pointer to the configuration buffer returned by CPU_FEATURE_GET_CONFIG_DATA. NULL if CPU_FEATURE_GET_CONFIG_DATA was not provided in RegisterCpuFeature(). @param[in] State If TRUE, then the HDC feature must be enabled. If FALSE, then the HDC feature must be disabled. @retval RETURN_SUCCESS HDC feature is initialized. @note This service could be called by BSP only. **/ RETURN_STATUS EFIAPI HdcInitialize ( IN UINTN ProcessorNumber, IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, IN VOID *ConfigData, OPTIONAL IN BOOLEAN State ) { // // The scope of the MSR_MISC_PWR_MGMT is package level, only program MSR_MISC_PWR_MGMT once for each package // if ((CpuInfo->First.Thread == 0) || (CpuInfo->First.Core == 0)) { return RETURN_SUCCESS; } // // Enabled by policy do nothing. // if (State) { // // Policy is Disabled, clear MSR_MISC_PWR_MGMT (1AAh) [10] // CPU_REGISTER_TABLE_WRITE_FIELD ( ProcessorNumber, Msr, MSR_MISC_PWR_MGMT, MSR_MISC_PWR_MGMT_REGISTER, Bits.EnableSdc, 0 ); } return RETURN_SUCCESS; } /** Initializes ApicTprUpdateMessage feature to specific state. @param[in] ProcessorNumber The index of the CPU executing this function. @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION structure for the CPU executing this function. @param[in] ConfigData A pointer to the configuration buffer returned by CPU_FEATURE_GET_CONFIG_DATA. NULL if CPU_FEATURE_GET_CONFIG_DATA was not provided in RegisterCpuFeature(). @param[in] State If TRUE, then the ApicTprUpdateMessage feature must be enabled. If FALSE, then the ApicTprUpdateMessage feature must be disabled. @retval RETURN_SUCCESS ApicTprUpdateMessage feature is initialized. @note This service could be called by BSP only. **/ RETURN_STATUS EFIAPI ApicTprUpdateMessageInitialize ( IN UINTN ProcessorNumber, IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, IN VOID *ConfigData, OPTIONAL IN BOOLEAN State ) { CPU_REGISTER_TABLE_WRITE_FIELD ( ProcessorNumber, Msr, MSR_PIC_MSG_CONTROL, MSR_PIC_MSG_CONTROL_REGISTER, Bits.TprMsgOff, (State) ? 0 : 1 ); return RETURN_SUCCESS; } /** Initializes Mlc Streamer Prefetcher feature to specific state. @param[in] ProcessorNumber The index of the CPU executing this function. @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION structure for the CPU executing this function. @param[in] ConfigData A pointer to the configuration buffer returned by CPU_FEATURE_GET_CONFIG_DATA. NULL if CPU_FEATURE_GET_CONFIG_DATA was not provided in RegisterCpuFeature(). @param[in] State If TRUE, then the Mlc Streamer Prefetcher feature must be enabled. If FALSE, then the Mlc Streamer Prefetcher feature must be disabled. @retval RETURN_SUCCESS Mlc Streamer Prefetcher feature is initialized. @note This service could be called by BSP only. **/ RETURN_STATUS EFIAPI MlcStreamerPrefetcherInitialize ( IN UINTN ProcessorNumber, IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, IN VOID *ConfigData, OPTIONAL IN BOOLEAN State ) { CPU_REGISTER_TABLE_WRITE_FIELD ( ProcessorNumber, Msr, MSR_MISC_FEATURE_CONTROL, MSR_MISC_FEATURE_CONTROL_REGISTER, Bits.MlcStreamerPrefetchDisable, (State) ? 0 : 1 ); return RETURN_SUCCESS; } /** Initializes Mlc Spatial Prefetcher feature to specific state. @param[in] ProcessorNumber The index of the CPU executing this function. @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION structure for the CPU executing this function. @param[in] ConfigData A pointer to the configuration buffer returned by CPU_FEATURE_GET_CONFIG_DATA. NULL if CPU_FEATURE_GET_CONFIG_DATA was not provided in RegisterCpuFeature(). @param[in] State If TRUE, then the Mlc Spatial Prefetcher feature must be enabled. If FALSE, then the Mlc Spatial Prefetcher feature must be disabled. @retval RETURN_SUCCESS Mlc Spatial Prefetcher feature is initialized. @note This service could be called by BSP only. **/ RETURN_STATUS EFIAPI MlcSpatialPrefetcherInitialize ( IN UINTN ProcessorNumber, IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, IN VOID *ConfigData, OPTIONAL IN BOOLEAN State ) { CPU_REGISTER_TABLE_WRITE_FIELD ( ProcessorNumber, Msr, MSR_MISC_FEATURE_CONTROL, MSR_MISC_FEATURE_CONTROL_REGISTER, Bits.MlcSpatialPrefetchDisable, (State) ? 0 : 1 ); return RETURN_SUCCESS; } /** Initializes three Strike Counter feature to specific state. @param[in] ProcessorNumber The index of the CPU executing this function. @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION structure for the CPU executing this function. @param[in] ConfigData A pointer to the configuration buffer returned by CPU_FEATURE_GET_CONFIG_DATA. NULL if CPU_FEATURE_GET_CONFIG_DATA was not provided in RegisterCpuFeature(). @param[in] State If TRUE, then the three Strike Counter feature must be enabled. If FALSE, then the three Strike Counter feature must be disabled. @retval RETURN_SUCCESS Three Strike Counter feature is initialized. @note This service could be called by BSP only. **/ RETURN_STATUS EFIAPI ThreeStrikeCounterInitialize ( IN UINTN ProcessorNumber, IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, IN VOID *ConfigData, OPTIONAL IN BOOLEAN State ) { CPU_REGISTER_TABLE_WRITE_FIELD ( ProcessorNumber, Msr, MSR_MISC_FEATURE_CONTROL, MSR_MISC_FEATURE_CONTROL_REGISTER, Bits.DisableThreeStrikeCnt, (State) ? 0 : 1 ); return RETURN_SUCCESS; } /** Prepares for the data used by CPU feature detection and initialization. @param[in] NumberOfProcessors The number of CPUs in the platform. @return Pointer to a buffer of CPU related configuration data. @note This service could be called by BSP only. **/ VOID * EFIAPI SpecificPpinGetConfigData ( IN UINTN NumberOfProcessors ) { VOID *ConfigData; ConfigData = AllocateZeroPool (sizeof (MSR_PPIN_CTL_REGISTER) * NumberOfProcessors); ASSERT (ConfigData != NULL); return ConfigData; } /** Detects if Protected Processor Inventory Number feature supported on current processor. @param[in] ProcessorNumber The index of the CPU executing this function. @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION structure for the CPU executing this function. @param[in] ConfigData A pointer to the configuration buffer returned by CPU_FEATURE_GET_CONFIG_DATA. NULL if CPU_FEATURE_GET_CONFIG_DATA was not provided in RegisterCpuFeature(). @retval TRUE Protected Processor Inventory Number feature is supported. @retval FALSE Protected Processor Inventory Number feature is not supported. @note This service could be called by BSP/APs. **/ BOOLEAN EFIAPI IsSpecificPpinSupport ( IN UINTN ProcessorNumber, IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, IN VOID *ConfigData OPTIONAL ) { if (MsrIsPpinCap ()) { return TRUE; } return FALSE; } /** Initializes Protected Processor Inventory Number feature to specific state. @param[in] ProcessorNumber The index of the CPU executing this function. @param[in] CpuInfo A pointer to the REGISTER_CPU_FEATURE_INFORMATION structure for the CPU executing this function. @param[in] ConfigData A pointer to the configuration buffer returned by CPU_FEATURE_GET_CONFIG_DATA. NULL if CPU_FEATURE_GET_CONFIG_DATA was not provided in RegisterCpuFeature(). @param[in] State If TRUE, then the Protected Processor Inventory Number feature must be enabled. If FALSE, then the Protected Processor Inventory Number feature must be disabled. @retval RETURN_SUCCESS Protected Processor Inventory Number feature is initialized. @retval RETURN_DEVICE_ERROR Device can't change state because it has been locked. @note This service could be called by BSP only. **/ RETURN_STATUS EFIAPI SpecificPpinInitialize ( IN UINTN ProcessorNumber, IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, IN VOID *ConfigData, OPTIONAL IN BOOLEAN State ) { MSR_PPIN_CTL_REGISTER *MsrPpinCtrl; ASSERT (ConfigData != NULL); MsrPpinCtrl = (MSR_PPIN_CTL_REGISTER *) ConfigData; // // If already locked, just based on the request state and // the current state to return the status. // if (MsrPpinCtrl[ProcessorNumber].Bits.Lock != 0) { return MsrPpinCtrl[ProcessorNumber].Bits.Enable == State ? RETURN_SUCCESS : RETURN_DEVICE_ERROR; } // // The scope of the MSR_PPIN_CTL_REGISTER is package level, only program MSR_PPIN_CTL_REGISTER once for each package. // if ((CpuInfo->First.Thread == 0) || (CpuInfo->First.Core == 0)) { return RETURN_SUCCESS; } if (State) { // // Enable and Unlock. // MsrPpinCtrl[ProcessorNumber].Bits.Enable = 1; MsrPpinCtrl[ProcessorNumber].Bits.Lock = 0; } else { // // Disable and Lock. // MsrPpinCtrl[ProcessorNumber].Bits.Enable = 0; MsrPpinCtrl[ProcessorNumber].Bits.Lock = 1; } CPU_REGISTER_TABLE_WRITE64 ( ProcessorNumber, Msr, MSR_PPIN_CTL, MsrPpinCtrl[ProcessorNumber].Uint64 ); return RETURN_SUCCESS; }