alder_lake_bios/Intel/AlderLake/AlderLakePlatSamplePkg/Setup/CpuSetup.c

3011 lines
95 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2012 - 2020, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
/** @file
CPU Setup Routines
@copyright
INTEL CONFIDENTIAL
Copyright 2009 - 2022 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 a 'Sample Driver' and is licensed as such under the terms
of your license agreement with Intel or your vendor. This file may be modified
by the user, subject to the additional terms of the license agreement.
@par Specification Reference:
**/
#include <PlatformNvRamHookLib.h>
#include <Library/CpuPlatformLib.h>
#include <Library/RngLib.h>
#include <Library/CpuMailboxLib.h>
#include <Protocol/DxeSmmReadyToLock.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Guid/MdeModuleHii.h>
#include <Library/BaseLib.h>
//[-start-020215-IB06462109-remove]//
//#include "Base.h"
//#include <SetupPrivate.h>
//#include "Platform.h"
//[-end-020215-IB06462109-remove]//
#include "PlatformBoardId.h"
#include <Register/Cpuid.h>
#include <Register/Msr.h>
#include <Protocol/CpuInfo.h>
#include <Library/PciSegmentLib.h>
#include <Library/BootGuardLibVer1.h>
#include <Library/MeFwStsLib.h>
#include <Register/PchRegs.h>
#include <Library/SpiAccessLib.h>
#include <Protocol/MpService.h>
#include <VoltageRegulatorCommands.h>
#include <CpuDataHob.h>
#include <Register/CommonMsr.h>
#include <Register/AdlMsr.h>
//[-start-020215-IB06462109-remove]//
//#include <CmosMap.h>
//#include <Library/CmosAccessLib.h>
//[-end-020215-IB06462109-remove]//
//[-start-020215-IB06462109-add]//
#include <ChipsetCmos.h>
#include <SetupUtility.h>
#include <OemSetup.h>
//[-end-020215-IB06462109-add]//
#include <Register/ArchMsr.h>
//[-start-211215-IB11790442-remove]//
//#include <CmosMap.h>
//#include <Library/CmosAccessLib.h>
//[-end-211215-IB11790442-remove]//
#include <Register/SaRegsHostBridge.h>
#include <Library/PreSiliconEnvDetectLib.h>
#include <Txt.h>
#include <CpuRegs.h>
#if FixedPcdGetBool(PcdITbtEnable) == 1
#include <TcssDataHob.h>
#endif
#define OC_LIB_CMD_GET_FAVORED_CORE 0x1C
#define CORE_RATIO_NON_EXT_MODE_LIMIT 85
//[-start-020215-IB06462109-add]//
CHIPSET_CONFIGURATION mSetupConfiguration;
CPU_SETUP mCpuSetup;
//[-end-020215-IB06462109-add]//
static EFI_HII_HANDLE gHiiHandle;
static UINT8 mCoreRatioFinal[TURBO_RATIO_LIMIT_ARRAY_SIZE] = {0};
EFI_MP_SERVICES_PROTOCOL *mMpService;
UINT32 mCoreIndex = 0;
STATIC SETUP_CPU_FEATURES mSetupCpuFeatures;
typedef struct _MAILBOX_READ {
UINT32 *MailboxDataPtr;
UINT32 *MailboxStatus;
} MAILBOX_READ;
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID FuseFreqString [] = {
STRING_TOKEN (STR_P0_FUSED_MAX_CORE_VALUE),
STRING_TOKEN (STR_P1_FUSED_MAX_CORE_VALUE),
STRING_TOKEN (STR_P2_FUSED_MAX_CORE_VALUE),
STRING_TOKEN (STR_P3_FUSED_MAX_CORE_VALUE),
STRING_TOKEN (STR_P4_FUSED_MAX_CORE_VALUE),
STRING_TOKEN (STR_P5_FUSED_MAX_CORE_VALUE),
STRING_TOKEN (STR_P6_FUSED_MAX_CORE_VALUE),
STRING_TOKEN (STR_P7_FUSED_MAX_CORE_VALUE)
};
extern UINT8 AdvancedBin[];
GLOBAL_REMOVE_IF_UNREFERENCED CPU_DATA_HOB *mCpuDataHob;
/**
This function update Bit 4 of CMOS index 0x2A (index reg: 0x70, Data : 0x71)
based on TXT setup option.
If TXT is Enabled Bit 4 will be 1, else bit 4 will be 0
@param[IN] EFI_FORM_CALLBACK_PROTOCOL *This
@param[IN] UINT16 KeyValue
@param[IN] EFI_IFR_DATA_ARRAY *Data,
@param[IN] EFI_HII_CALLBACK_PACKET **Packet
@retval EFI_SUCCESS
**/
EFI_STATUS
EFIAPI
TxtPolicyCallBackFunction (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID KeyValue,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
);
/**
Update the min, max, and default values for CpuRatio.
@param[in] CpuRatioDefault The CPU MNTR default.
@retval EFI_SUCCESS Values updated successfully.
@retval EFI_NOT_FOUND Failed to update it.
**/
EFI_STATUS
InitCpuMntrDefaultVfr (
UINT8 CpuRatioDefault
);
/**
This function to be used with StartUpAllAps for retrieving
the Max Core Frequency of all cores.
@param[in] VOID *Buffer
**/
VOID
EFIAPI
MailboxReadFavoredCore (
IN OUT VOID *Buffer
)
{
MAILBOX_READ *MailboxReadParameters;
UINT32 FuseCoreMax;
UINT32 MailboxStatus;
PCODE_MAILBOX_INTERFACE MailboxCommand;
MailboxReadParameters = (MAILBOX_READ *) Buffer;
MailboxCommand.InterfaceData = 0;
MailboxCommand.Fields.Command = OC_LIB_CMD_GET_FAVORED_CORE;
MailboxRead (MAILBOX_TYPE_OC, MailboxCommand.InterfaceData, &FuseCoreMax, &MailboxStatus);
MailboxReadParameters->MailboxDataPtr [mCoreIndex] = FuseCoreMax;
MailboxReadParameters->MailboxStatus [mCoreIndex] = MailboxStatus;
}
/**
Check if this is Big/Small -core processor
@param[out] CoreType Output pointer that get CPUID_HYBRID_INFORMATION data
**/
VOID
EFIAPI
GetCoreType (
OUT UINT8 *CoreType
)
{
UINT32 Eax;
UINT32 CpuidExtendCpuFlagEdx;
AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, NULL, NULL, NULL, &CpuidExtendCpuFlagEdx);
if ((CpuidExtendCpuFlagEdx & BIT15) == BIT15) {
//
// Check which is the running core by reading CPUID.(EAX=1AH, ECX=00H):EAX
//
AsmCpuid (CPUID_HYBRID_INFORMATION, &Eax, NULL, NULL, NULL);
*CoreType = (UINT8)((Eax & 0xFF000000) >> 24);
} else if (GetCpuFamily () == CPUID_FULL_FAMILY_MODEL_ALDERLAKE_ATOM) {
*CoreType = CPUID_CORE_TYPE_INTEL_ATOM;
} else {
*CoreType = CPUID_CORE_TYPE_INTEL_CORE;
}
return;
}
/**
Initialize Turbo Core Ratio defaults.
@param[in] EFI_EVENT Event
@param[in] VOID *Context
**/
VOID
InitTurboRatioDefault (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINT8 Index;
ADL_MSR_BIGCORE_TURBO_RATIO_LIMIT_REGISTER MsrTurboRatioLimitRatio;
ADL_MSR_BIGCORE_TURBO_RATIO_LIMIT_CORES_REGISTER MsrTurboRatioLimitNumCore;
ADL_MSR_ATOM_TURBO_RATIO_LIMIT_REGISTER AtomMsrTurboRatioLimitRatio;
ADL_MSR_ATOM_TURBO_RATIO_LIMIT_CORES_REGISTER AtomMsrTurboRatioLimitNumCore;
UINTN VariableSize;
UINT32 Attributes;
UINT8 MaxBusRatio;
UINT8 MinBusRatio;
MaxBusRatio = 0;
MinBusRatio = 0;
VariableSize = sizeof (CPU_SETUP);
Status = gRT->GetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
&Attributes,
&VariableSize,
&mCpuSetup
);
ASSERT_EFI_ERROR (Status);
if (mCpuSetup.IsTurboRatioDefaultsInitialized == 0) {
///
/// Get Maximum Non-Turbo bus ratio (HFM) from Platform Info MSR Bits[15:8]
///
GetBusRatio (&MaxBusRatio, &MinBusRatio);
mCpuSetup.IsTurboRatioDefaultsInitialized = 1;
mCpuSetup.FlexRatioOverrideDefault = MaxBusRatio;
MsrTurboRatioLimitRatio.Uint64 = AsmReadMsr64 (ADL_MSR_BIGCORE_TURBO_RATIO_LIMIT);
mCpuSetup.RatioLimitRatioDefault[0] = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup0;
mCpuSetup.RatioLimitRatioDefault[1] = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup1;
mCpuSetup.RatioLimitRatioDefault[2] = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup2;
mCpuSetup.RatioLimitRatioDefault[3] = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup3;
mCpuSetup.RatioLimitRatioDefault[4] = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup4;
mCpuSetup.RatioLimitRatioDefault[5] = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup5;
mCpuSetup.RatioLimitRatioDefault[6] = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup6;
mCpuSetup.RatioLimitRatioDefault[7] = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup7;
for (Index = 0; Index < TURBO_RATIO_LIMIT_ARRAY_SIZE; Index++) {
mCpuSetup.RatioLimitRatio[Index] = mCpuSetup.RatioLimitRatioDefault[Index];
}
MsrTurboRatioLimitNumCore.Uint64 = AsmReadMsr64 (ADL_MSR_BIGCORE_TURBO_RATIO_LIMIT_CORES);
mCpuSetup.RatioLimitNumCoreDefault[0] = (UINT8) MsrTurboRatioLimitNumCore.Bits.Numcore0;
mCpuSetup.RatioLimitNumCoreDefault[1] = (UINT8) MsrTurboRatioLimitNumCore.Bits.Numcore1;
mCpuSetup.RatioLimitNumCoreDefault[2] = (UINT8) MsrTurboRatioLimitNumCore.Bits.Numcore2;
mCpuSetup.RatioLimitNumCoreDefault[3] = (UINT8) MsrTurboRatioLimitNumCore.Bits.Numcore3;
mCpuSetup.RatioLimitNumCoreDefault[4] = (UINT8) MsrTurboRatioLimitNumCore.Bits.Numcore4;
mCpuSetup.RatioLimitNumCoreDefault[5] = (UINT8) MsrTurboRatioLimitNumCore.Bits.Numcore5;
mCpuSetup.RatioLimitNumCoreDefault[6] = (UINT8) MsrTurboRatioLimitNumCore.Bits.Numcore6;
mCpuSetup.RatioLimitNumCoreDefault[7] = (UINT8) MsrTurboRatioLimitNumCore.Bits.Numcore7;
for (Index = 0; Index < TURBO_RATIO_LIMIT_ARRAY_SIZE; Index++) {
mCpuSetup.RatioLimitNumCore[Index] = mCpuSetup.RatioLimitNumCoreDefault[Index];
}
if ((mCpuSetup.ActiveSmallCoreCount != 0) && !IsSimicsEnvironment () && !IsHSLEEnvironment ()) {
AtomMsrTurboRatioLimitRatio.Uint64 = AsmReadMsr64 (ADL_MSR_ATOM_TURBO_RATIO_LIMIT);
mCpuSetup.AtomRatioLimitRatioDefault[0] = (UINT8) AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup0;
mCpuSetup.AtomRatioLimitRatioDefault[1] = (UINT8) AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup1;
mCpuSetup.AtomRatioLimitRatioDefault[2] = (UINT8) AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup2;
mCpuSetup.AtomRatioLimitRatioDefault[3] = (UINT8) AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup3;
mCpuSetup.AtomRatioLimitRatioDefault[4] = (UINT8) AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup4;
mCpuSetup.AtomRatioLimitRatioDefault[5] = (UINT8) AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup5;
mCpuSetup.AtomRatioLimitRatioDefault[6] = (UINT8) AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup6;
mCpuSetup.AtomRatioLimitRatioDefault[7] = (UINT8) AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup7;
for (Index = 0; Index < TURBO_RATIO_LIMIT_ARRAY_SIZE; Index++) {
mCpuSetup.AtomRatioLimitRatio[Index] = mCpuSetup.AtomRatioLimitRatioDefault[Index];
}
AtomMsrTurboRatioLimitNumCore.Uint64 = AsmReadMsr64 (ADL_MSR_ATOM_TURBO_RATIO_LIMIT_CORES);
mCpuSetup.AtomRatioLimitNumCoreDefault[0] = (UINT8) AtomMsrTurboRatioLimitNumCore.Bits.Numcore0;
mCpuSetup.AtomRatioLimitNumCoreDefault[1] = (UINT8) AtomMsrTurboRatioLimitNumCore.Bits.Numcore1;
mCpuSetup.AtomRatioLimitNumCoreDefault[2] = (UINT8) AtomMsrTurboRatioLimitNumCore.Bits.Numcore2;
mCpuSetup.AtomRatioLimitNumCoreDefault[3] = (UINT8) AtomMsrTurboRatioLimitNumCore.Bits.Numcore3;
mCpuSetup.AtomRatioLimitNumCoreDefault[4] = (UINT8) AtomMsrTurboRatioLimitNumCore.Bits.Numcore4;
mCpuSetup.AtomRatioLimitNumCoreDefault[5] = (UINT8) AtomMsrTurboRatioLimitNumCore.Bits.Numcore5;
mCpuSetup.AtomRatioLimitNumCoreDefault[6] = (UINT8) AtomMsrTurboRatioLimitNumCore.Bits.Numcore6;
mCpuSetup.AtomRatioLimitNumCoreDefault[7] = (UINT8) AtomMsrTurboRatioLimitNumCore.Bits.Numcore7;
for (Index = 0; Index < TURBO_RATIO_LIMIT_ARRAY_SIZE; Index++) {
mCpuSetup.AtomRatioLimitNumCore[Index] = mCpuSetup.AtomRatioLimitNumCoreDefault[Index];
}
}
Status = gRT->SetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
Attributes,
VariableSize,
&mCpuSetup
);
ASSERT_EFI_ERROR (Status);
}
}
/**
Initialize AcheckRequest defaults. Always reset to Disable
**/
VOID
InitTxtAcheckDefault (
VOID
)
{
EFI_STATUS Status;
UINT32 VariableAttr;
UINTN VariableSize;
VariableAttr = 0;
VariableSize = sizeof (CPU_SETUP);
Status = gRT->GetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
&VariableAttr,
&VariableSize,
&mCpuSetup
);
if (EFI_ERROR (Status)) {
VariableAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
}
ASSERT_EFI_ERROR (Status);
mCpuSetup.AcheckRequest = 0;
Status = gRT->SetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
VariableAttr,
VariableSize,
&mCpuSetup
);
ASSERT_EFI_ERROR (Status);
}
/**
This function update Bit 4 of CMOS index 0x2A (index reg: 0x70, Data : 0x71)
based on TXT setup option.
If TXT is Enabled Bit 4 will be 1, else bit 4 will be 0
@param[IN] EFI_FORM_CALLBACK_PROTOCOL *This
@param[IN] UINT16 KeyValue
@param[IN] EFI_IFR_DATA_ARRAY *Data,
@param[IN] EFI_HII_CALLBACK_PACKET **Packet
@retval EFI_SUCCESS
**/
EFI_STATUS
EFIAPI
TxtPolicyCallBackFunction (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID KeyValue,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
EFI_STATUS Status;
CPU_SETUP *CpuSetup;
UINTN VarSize;
UINT8 TxtStatus;
UINT8 NewTxtStatus;
EFI_STRING RequestString;
Status = EFI_SUCCESS;
RequestString = NULL;
//
// Only process KEY_TXT_POLICY_FIT callback
//
if (KeyValue != KEY_TXT_POLICY_FIT) {
return EFI_UNSUPPORTED;
}
switch (Action) {
case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
//
// Set Txt knob value to the default value (Disabled)
//
Value->u8 = 0;
break;
case EFI_BROWSER_ACTION_CHANGED:
case EFI_BROWSER_ACTION_CHANGING:
break;
default:
return EFI_UNSUPPORTED;
break;
}
VarSize = sizeof (CPU_SETUP);
CpuSetup = AllocatePool (VarSize);
ASSERT (CpuSetup != NULL);
if (CpuSetup == NULL) {
DEBUG ((DEBUG_ERROR, "TxtPolicyCallBackFunction: Out of resources allocating CpuSetup!\n"));
return EFI_OUT_OF_RESOURCES;
}
//
// GetBrowserData by VarStore Name (Setup)
//
if (!HiiGetBrowserData (&gCpuSetupVariableGuid, L"CpuSetup", VarSize, (UINT8 *) CpuSetup)) {
FreePool (CpuSetup);
DEBUG ((DEBUG_ERROR, "TxtPolicyCallBackFunction: CpuSetup not found!\n"));
return EFI_NOT_FOUND;
}
//
// Read current TXT status from CMOS
//
//[-start-200206-IB17040105-modify]//
// NewTxtStatus = TxtStatus = CmosRead8 (FIT_REC_TXT_POLICY_TYPE_A);
NewTxtStatus = TxtStatus = ReadCmos8 (FIT_REC_TXT_POLICY_TYPE_A);
//[-end-200206-IB17040105-modify]//
//
// Handle restoring TXT to default state (DISABLED)
//
if (Action == EFI_BROWSER_ACTION_DEFAULT_STANDARD) {
CpuSetup->Txt = FALSE;
}
if (CpuSetup->Txt == FALSE) {
DEBUG ((DEBUG_INFO, "TxtPolicyCallBackFunction: Setting TXT to disabled.\n"));
NewTxtStatus &= ~BIT4;
} else {
DEBUG ((DEBUG_INFO, "TxtPolicyCallBackFunction: Setting TXT to enabled.\n"));
NewTxtStatus |= BIT4;
}
//
// Sync CMOS with new Txt Status
//
if (NewTxtStatus != TxtStatus) {
//[-start-200206-IB17040105-modify]//
// CmosWrite8 (FIT_REC_TXT_POLICY_TYPE_A, NewTxtStatus);
WriteCmos8 (FIT_REC_TXT_POLICY_TYPE_A, NewTxtStatus);
//[-end-200206-IB17040105-modify]//
}
//
// Update menu string with new value
//
RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, Txt), sizeof (CpuSetup->Txt));
if (RequestString != NULL) {
if (!HiiSetBrowserData (&gCpuSetupVariableGuid, L"CpuSetup", VarSize, (UINT8 *) CpuSetup, RequestString)) {
DEBUG ((DEBUG_ERROR, "TxtPolicyCallBackFunction: Setting Hii string ERROR!\n"));
Status = EFI_NOT_FOUND;
}
ASSERT_EFI_ERROR (Status);
FreePool (RequestString);
}
FreePool (CpuSetup);
return Status;
}
/**
Initialize Debug CPU Disabled (DCD) Bit information
**/
VOID
InitDCDInfo (
VOID
)
{
EFI_STATUS Status;
UINT32 VariableAttr;
UINTN VariableSize;
VariableAttr = 0;
VariableSize = sizeof (CPU_SETUP);
Status = gRT->GetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
&VariableAttr,
&VariableSize,
&mCpuSetup
);
if (EFI_ERROR (Status)) {
VariableAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
}
ASSERT_EFI_ERROR (Status);
if (IsCpuDebugDisabled ()) {
mCpuSetup.DebugCpuDisabled = 1;
} else {
mCpuSetup.DebugCpuDisabled = 0;
}
Status = gRT->SetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
VariableAttr,
VariableSize,
&mCpuSetup
);
ASSERT_EFI_ERROR (Status);
}
#if FixedPcdGetBool(PcdITbtEnable) == 1
/**
Limit CPU Package Cx limit to C2 if TCSS IOM is not ready.
**/
VOID
OverrideCpuCxLimitForTcssIom (
VOID
)
{
EFI_STATUS Status;
UINT32 VariableAttr;
UINTN VariableSize;
TCSS_DATA_HOB *TcssHob;
TcssHob = NULL;
VariableAttr = 0;
///
/// Locate HOB for TCSS Data
///
TcssHob = (TCSS_DATA_HOB *) GetFirstGuidHob (&gTcssHobGuid);
if (TcssHob == NULL) {
DEBUG ((DEBUG_ERROR, "SA TSCC Data HOB not found\n"));
return;
}
///
/// Check IOM ready state
/// - Limit Package C state to PC2 when IOM is not ready
/// - Keep user setting when IOM is ready, and return
///
if (TcssHob->TcssData.IOMReady == 1) {
return;
}
VariableSize = sizeof (CPU_SETUP);
Status = gRT->GetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
&VariableAttr,
&VariableSize,
&mCpuSetup
);
if (EFI_ERROR (Status)) {
VariableAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
}
ASSERT_EFI_ERROR (Status);
DEBUG ((DEBUG_INFO, "CpuSetup warming: Limit Package C state to PC2 when IOM is not ready\n"));
mCpuSetup.PkgCStateLimit = 1; //Limit Package C state to PC2
Status = gRT->SetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
VariableAttr,
VariableSize,
&mCpuSetup
);
ASSERT_EFI_ERROR (Status);
}
#endif // FixedPcdGetBool(PcdITbtEnable) == 1
///
///
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mAcLoadlineInfoStr[] = {
STRING_TOKEN(STR_VR_AC_LOADLINE_INFO_VALUE0),
STRING_TOKEN(STR_VR_AC_LOADLINE_INFO_VALUE1),
STRING_TOKEN(STR_VR_AC_LOADLINE_INFO_VALUE2)
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mDcLoadlineInfoStr[] = {
STRING_TOKEN(STR_VR_DC_LOADLINE_INFO_VALUE0),
STRING_TOKEN(STR_VR_DC_LOADLINE_INFO_VALUE1),
STRING_TOKEN(STR_VR_DC_LOADLINE_INFO_VALUE2)
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mPsi1ThresholdInfoStr[] = {
STRING_TOKEN(STR_VR_PSI1_THRESHOLD_INFO_VALUE0),
STRING_TOKEN(STR_VR_PSI1_THRESHOLD_INFO_VALUE1),
STRING_TOKEN(STR_VR_PSI1_THRESHOLD_INFO_VALUE2)
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mPsi2ThresholdInfoStr[] = {
STRING_TOKEN(STR_VR_PSI2_THRESHOLD_INFO_VALUE0),
STRING_TOKEN(STR_VR_PSI2_THRESHOLD_INFO_VALUE1),
STRING_TOKEN(STR_VR_PSI2_THRESHOLD_INFO_VALUE2)
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mPsi3ThresholdInfoStr[] = {
STRING_TOKEN(STR_VR_PSI3_THRESHOLD_INFO_VALUE0),
STRING_TOKEN(STR_VR_PSI3_THRESHOLD_INFO_VALUE1),
STRING_TOKEN(STR_VR_PSI3_THRESHOLD_INFO_VALUE2)
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mImonOffsetInfoStr[] = {
STRING_TOKEN(STR_VR_IMON_OFFSET_INFO_VALUE0),
STRING_TOKEN(STR_VR_IMON_OFFSET_INFO_VALUE1),
STRING_TOKEN(STR_VR_IMON_OFFSET_INFO_VALUE2)
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mImonSlopeInfoStr[] = {
STRING_TOKEN(STR_VR_IMON_SLOPE_INFO_VALUE0),
STRING_TOKEN(STR_VR_IMON_SLOPE_INFO_VALUE1),
STRING_TOKEN(STR_VR_IMON_SLOPE_INFO_VALUE2)
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mIccMaxInfoStr[] = {
STRING_TOKEN(STR_VR_ICCMAX_INFO_VALUE0),
STRING_TOKEN(STR_VR_ICCMAX_INFO_VALUE1),
STRING_TOKEN(STR_VR_ICCMAX_INFO_VALUE2)
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mTdcCurrentLimitInfoStr[] = {
STRING_TOKEN(STR_VR_TDC_CURRENT_LIMIT_INFO_VALUE0),
STRING_TOKEN(STR_VR_TDC_CURRENT_LIMIT_INFO_VALUE1),
STRING_TOKEN(STR_VR_TDC_CURRENT_LIMIT_INFO_VALUE2)
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mVoltageLimitInfoStr[] = {
STRING_TOKEN(STR_VR_VOLTAGE_LIMIT_INFO_VALUE0),
STRING_TOKEN(STR_VR_VOLTAGE_LIMIT_INFO_VALUE1),
STRING_TOKEN(STR_VR_VOLTAGE_LIMIT_INFO_VALUE2)
};
/**
Display the CPU VR menu programmed defaults.
**/
VOID
InitCpuVrConfig (
VOID
)
{
EFI_STATUS Status;
UINT32 MailboxData;
UINT32 MailboxStatus;
UINT32 MailboxType;
UINT64 TempAcLoadline;
UINT64 TempDcLoadline;
UINT64 ConvertedImonOffset;
UINT64 ConvertedImonSlope;
UINT8 TempVrAddress;
UINTN VrIndex;
UINTN VariableSize;
UINT32 Attributes;
BOOLEAN SvidEnabled;
PCODE_MAILBOX_INTERFACE MailboxCommand;
VariableSize = sizeof (CPU_SETUP);
Status = gRT->GetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
&Attributes,
&VariableSize,
&mCpuSetup
);
ASSERT_EFI_ERROR (Status);
DEBUG ((DEBUG_INFO, "InitCpuVrConfig ()\n"));
if (mCpuDataHob == NULL) {
return;
}
DEBUG ((DEBUG_INFO, "MinVrIndex - %x\n", mCpuDataHob->MinVrIndex));
DEBUG ((DEBUG_INFO, "MaxVrIndex - %x\n", mCpuDataHob->MaxVrIndex));
///
/// CPU VR MSR mailbox
///
MailboxType = MAILBOX_TYPE_VR_MSR;
//
// Read the VCCINAUX ICCMAX
//
MailboxCommand.InterfaceData = 0;
MailboxCommand.Fields.Command = MAILBOX_VR_CMD_SVID_VR_HANDLER;
MailboxCommand.Fields.Param1 = MAILBOX_VR_SUBCMD_SVID_GET_VCCINAUX_IMON_IMAX;
MailboxCommand.Fields.Param2 = 0;
MailboxData = 0;
DEBUG ((DEBUG_INFO, "(MAILBOX) Mailbox Read Command = READ_VCCINAUX_IMON_IMAX_CMD\n"));
Status = MailboxRead (MailboxType, MailboxCommand.InterfaceData, &MailboxData, &MailboxStatus);
DEBUG ((DEBUG_INFO, "(MAILBOX) VccInAuxImonIccImax = %d (1/4 Amp)\n", MailboxData));
if (MailboxStatus != PCODE_MAILBOX_CC_SUCCESS) {
DEBUG ((DEBUG_ERROR, "VR: Error Reading VccIn AUX IccMax Current. EFI_STATUS = %r, Mailbox Status = %X\n", Status, MailboxStatus));
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_VR_VCCIN_AUX_IMON_ICC_IMAX_VALUE),
L"%d",
MailboxData
);
for (VrIndex = mCpuDataHob->MinVrIndex; VrIndex < mCpuDataHob->MaxVrIndex; VrIndex++) {
//
// If VrIndex is over the count of InfoStr array, end the loop to avoid overflow.
//
if (VrIndex >= (sizeof (mIccMaxInfoStr) / sizeof (mIccMaxInfoStr[0]))) {
ASSERT (FALSE);
break;
}
TempVrAddress = mCpuDataHob->VrAddress[VrIndex];
if (VrIndex == 0) {
SvidEnabled = (mCpuDataHob->SvidEnabled & BIT0) != 0;
} else if (VrIndex == 1) {
SvidEnabled = (mCpuDataHob->SvidEnabled & BIT1) != 0;
} else if (VrIndex == 2) {
SvidEnabled = (mCpuDataHob->SvidEnabled & BIT2) != 0;
} else {
SvidEnabled = FALSE;
}
if ((mCpuSetup.VrConfigEnable[VrIndex] == 1) && SvidEnabled) {
///
/// AC / DC Loadline
///
MailboxCommand.InterfaceData = 0;
MailboxCommand.Fields.Command = MAILBOX_VR_CMD_SVID_VR_HANDLER;
MailboxCommand.Fields.Param1 = MAILBOX_VR_SUBCMD_SVID_GET_ACDC_LOADLINE;
MailboxCommand.Fields.Param2 = (TempVrAddress & VR_ADDRESS_MASK);
MailboxData = 0;
Status = MailboxRead (MailboxType, MailboxCommand.InterfaceData, &MailboxData, &MailboxStatus);
if (MailboxStatus != PCODE_MAILBOX_CC_SUCCESS) {
DEBUG ((DEBUG_ERROR, "VR: Error Reading AC/DC Loadline. EFI_STATUS = %r, Mailbox Status = %X\n", Status, MailboxStatus));
}
TempAcLoadline = (MailboxData & AC_LOADLINE_MASK);
TempDcLoadline = RShiftU64 ((MailboxData & DC_LOADLINE_MASK), DC_LOADLINE_OFFSET);
///
/// Loadline is 1/100 mOhm units. Mailbox interface requires Loadline in U-4.20 Ohms format.
/// After multiplying by 2^20, we must divide the result by 100,000 to convert to Ohms.
/// Adding half of divisor to dividend to account for rounding errors in fixed point arithmetic.
///
TempAcLoadline = MultU64x32 (TempAcLoadline, 100000);
TempAcLoadline = (UINT16) ((TempAcLoadline + (1 << 19)) >> 20);
TempDcLoadline = MultU64x32 (TempDcLoadline, 100000);
TempDcLoadline = (UINT16) ((TempDcLoadline + (1 << 19)) >> 20);
InitString (
gHiiHandle,
mAcLoadlineInfoStr[VrIndex],
L"%d",
TempAcLoadline
);
InitString (
gHiiHandle,
mDcLoadlineInfoStr[VrIndex],
L"%d",
TempDcLoadline
);
///
/// PS Cutoff Current
///
MailboxCommand.InterfaceData = 0;
MailboxCommand.Fields.Command = MAILBOX_VR_CMD_SVID_VR_HANDLER;
MailboxCommand.Fields.Param1 = MAILBOX_VR_SUBCMD_SVID_GET_PS_CUTOFF;
MailboxCommand.Fields.Param2 = (TempVrAddress & VR_ADDRESS_MASK);
MailboxData = 0;
Status = MailboxRead (MailboxType, MailboxCommand.InterfaceData, &MailboxData, &MailboxStatus);
if (MailboxStatus != PCODE_MAILBOX_CC_SUCCESS) {
DEBUG ((DEBUG_ERROR, "VR: Error Reading PS Cutoff Current. EFI_STATUS = %r, Mailbox Status = %X\n", Status, MailboxStatus));
}
DEBUG ((DEBUG_INFO, "(MAILBOX) GET_PS_CUTOFF Data = %x\n", MailboxData));
InitString (
gHiiHandle,
mPsi1ThresholdInfoStr[VrIndex],
L"%d",
(UINT16) (MailboxData & PSI_THRESHOLD_MASK)
);
InitString (
gHiiHandle,
mPsi2ThresholdInfoStr[VrIndex],
L"%d",
(UINT16) ((MailboxData & PSI2_THRESHOLD_OFFSET_MASK) >> PSI2_THRESHOLD_OFFSET)
);
InitString (
gHiiHandle,
mPsi3ThresholdInfoStr[VrIndex],
L"%d",
(UINT16) ((MailboxData & PSI3_THRESHOLD_OFFSET_MASK) >> PSI3_THRESHOLD_OFFSET)
);
///
/// IMON Config
/// -Policy Imon offset is defined in 1/1000 increments
/// -Policy Imon slope is defined in 1/100 increments
/// -Mailbox ImonOffset = (PlatPolicyImonOffset * 2^8)/1000
/// -Mailbox ImonSlope = (PlatPolicyImonSlope * 2^15)/100
/// -Adding half of divisor to dividend to account for rounding errors in fixed point arithmetic.
///
MailboxCommand.InterfaceData = 0;
MailboxCommand.Fields.Command = MAILBOX_VR_CMD_SVID_VR_HANDLER;
MailboxCommand.Fields.Param1 = MAILBOX_VR_SUBCMD_SVID_GET_IMON_CONFIG;
MailboxCommand.Fields.Param2 = (TempVrAddress & VR_ADDRESS_MASK);
MailboxData = 0;
Status = MailboxRead (MailboxType, MailboxCommand.InterfaceData, &MailboxData, &MailboxStatus);
if (MailboxStatus != PCODE_MAILBOX_CC_SUCCESS) {
DEBUG ((DEBUG_ERROR, "VR: Error Reading IMON Config. EFI_STATUS = %r, Mailbox Status = %X\n", Status, MailboxStatus));
}
if (MailboxData & BIT15) {
///
/// Offset is negative, convert from 2's complement to absolute value for display
///
ConvertedImonOffset = (UINT16) (~((MailboxData & VR_IMON_OFFSET_MASK) - 1));
ConvertedImonOffset = (UINT16) (((ConvertedImonOffset * 1000) + 500) / (1 << 8));
} else {
ConvertedImonOffset = (UINT16) ((((MailboxData & VR_IMON_OFFSET_MASK) * 1000) + 500) / (1 << 8));
}
ConvertedImonSlope = (UINT16) (((((MailboxData & VR_IMON_SLOPE_MASK) >> VR_IMON_SLOPE_OFFSET) * 100) + 50) / (1 << 15));
InitString (
gHiiHandle,
mImonOffsetInfoStr[VrIndex],
L"%d",
ConvertedImonOffset
);
InitString (
gHiiHandle,
mImonSlopeInfoStr[VrIndex],
L"%d",
ConvertedImonSlope
);
///
/// Icc Max
///
MailboxCommand.InterfaceData = 0;
MailboxCommand.Fields.Command = MAILBOX_VR_CMD_SVID_VR_HANDLER;
MailboxCommand.Fields.Param1 = MAILBOX_VR_SUBCMD_SVID_GET_MAX_ICC;
MailboxCommand.Fields.Param2 = (TempVrAddress & VR_ADDRESS_MASK);
MailboxData = 0;
Status = MailboxRead (MailboxType, MailboxCommand.InterfaceData, &MailboxData, &MailboxStatus);
if (MailboxStatus != PCODE_MAILBOX_CC_SUCCESS) {
DEBUG ((DEBUG_ERROR, "VR: Error Reading ICC Max. EFI_STATUS = %r, Mailbox Status = %X\n", Status, MailboxStatus));
}
InitString (
gHiiHandle,
mIccMaxInfoStr[VrIndex],
L"%d",
(UINT16) (MailboxData & 0x07FF)
);
if (!IsSaVrSupport ()) {
///
/// VR TDC Settings
/// -Mailbox TDC Current Limit defined as U15.12.3, Range 0-4095A
/// -Policy defined in 1/8 A increments
///
MailboxCommand.InterfaceData = 0;
MailboxCommand.Fields.Command = MAILBOX_VR_CMD_READ_VR_TDC_CONFIG;
MailboxCommand.Fields.Param1 = (TempVrAddress & VR_ADDRESS_MASK);
MailboxData = 0;
Status = MailboxRead (MailboxType, MailboxCommand.InterfaceData, &MailboxData, &MailboxStatus);
if (MailboxStatus != PCODE_MAILBOX_CC_SUCCESS) {
DEBUG ((DEBUG_ERROR, "VR: Error Reading VR TDC Config. EFI_STATUS = %r, Mailbox Status = %X\n", Status, MailboxStatus));
}
InitString (
gHiiHandle,
mTdcCurrentLimitInfoStr[VrIndex],
L"%d",
(UINT16)((MailboxData & VR_TDC_CURRENT_LIMIT_MASK))
);
DEBUG ((DEBUG_INFO, "VR: TDC[%x] = %d\n", VrIndex, (UINT16)((MailboxData & VR_TDC_CURRENT_LIMIT_MASK))));
}
///
/// VR Voltage Limit
/// -Mailbox Voltage Limit defined as U16.3.13, Range 0-7.999V
/// -Policy defined in mV, Range 0-7999mV
/// -Adding half of divisor to dividend to account for rounding errors in fixed point arithmetic.
///
MailboxCommand.InterfaceData = 0;
MailboxCommand.Fields.Command = MAILBOX_VR_CMD_SVID_VR_HANDLER;
MailboxCommand.Fields.Param1 = MAILBOX_VR_SUBCMD_SVID_GET_VOLTAGE_LIMIT;
MailboxCommand.Fields.Param2 = (TempVrAddress & VR_ADDRESS_MASK);
MailboxData = 0;
Status = MailboxRead (MailboxType, MailboxCommand.InterfaceData, &MailboxData, &MailboxStatus);
if (MailboxStatus != PCODE_MAILBOX_CC_SUCCESS) {
DEBUG ((DEBUG_ERROR, "VR: Error Reading VR Voltage Config. EFI_STATUS = %r, Mailbox Status = %X\n", Status, MailboxStatus));
}
InitString (
gHiiHandle,
mVoltageLimitInfoStr[VrIndex],
L"%d",
(UINT16) ((((MailboxData & VR_VOLTAGE_LIMIT_MASK) * 1000) + 500) / (1 << 13))
);
DEBUG ((DEBUG_INFO, "VR: Voltage Limit[%x] = %d\n", VrIndex, (UINT16)((((MailboxData & VR_VOLTAGE_LIMIT_MASK) * 1000) + 500) / (1 << 13))));
}
}
}
/**
Initialize Turbo Ratio strings.
**/
VOID
InitTurboRatioInfo (
VOID
)
{
UINT8 TurboRatioLimitRatio;
ADL_MSR_BIGCORE_TURBO_RATIO_LIMIT_REGISTER MsrTurboRatioLimitRatio;
ADL_MSR_BIGCORE_TURBO_RATIO_LIMIT_CORES_REGISTER MsrTurboRatioLimitNumCore;
ADL_MSR_ATOM_TURBO_RATIO_LIMIT_REGISTER AtomMsrTurboRatioLimitRatio;
ADL_MSR_ATOM_TURBO_RATIO_LIMIT_CORES_REGISTER AtomMsrTurboRatioLimitNumCore;
//
// Turbo Ratio Limit Ratio
//
MsrTurboRatioLimitRatio.Uint64 = AsmReadMsr64 (ADL_MSR_BIGCORE_TURBO_RATIO_LIMIT);
TurboRatioLimitRatio = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup0;
if (mCoreRatioFinal[0] == 0) {
mCoreRatioFinal[0] = TurboRatioLimitRatio;
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_RATIO0_VALUE),
L"%d",
TurboRatioLimitRatio
);
TurboRatioLimitRatio = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup1;
if (mCoreRatioFinal[1] == 0) {
mCoreRatioFinal[1] = TurboRatioLimitRatio;
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_RATIO1_VALUE),
L"%d",
TurboRatioLimitRatio
);
TurboRatioLimitRatio = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup2;
if (mCoreRatioFinal[2] == 0) {
mCoreRatioFinal[2] = TurboRatioLimitRatio;
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_RATIO2_VALUE),
L"%d",
TurboRatioLimitRatio
);
TurboRatioLimitRatio = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup3;
if (mCoreRatioFinal[3] == 0) {
mCoreRatioFinal[3] = TurboRatioLimitRatio;
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_RATIO3_VALUE),
L"%d",
TurboRatioLimitRatio
);
TurboRatioLimitRatio = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup4;
if (mCoreRatioFinal[4] == 0) {
mCoreRatioFinal[4] = TurboRatioLimitRatio;
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_RATIO4_VALUE),
L"%d",
TurboRatioLimitRatio
);
TurboRatioLimitRatio = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup5;
if (mCoreRatioFinal[5] == 0) {
mCoreRatioFinal[5] = TurboRatioLimitRatio;
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_RATIO5_VALUE),
L"%d",
TurboRatioLimitRatio
);
TurboRatioLimitRatio = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup6;
if (mCoreRatioFinal[6] == 0) {
mCoreRatioFinal[6] = TurboRatioLimitRatio;
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_RATIO6_VALUE),
L"%d",
TurboRatioLimitRatio
);
TurboRatioLimitRatio = (UINT8) MsrTurboRatioLimitRatio.Bits.MaxTurboGroup7;
if (mCoreRatioFinal[7] == 0) {
mCoreRatioFinal[7] = TurboRatioLimitRatio;
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_RATIO7_VALUE),
L"%d",
TurboRatioLimitRatio
);
//
// Turbo Ratio Limit Num Core
//
MsrTurboRatioLimitNumCore.Uint64 = AsmReadMsr64 (ADL_MSR_BIGCORE_TURBO_RATIO_LIMIT_CORES);
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_NUMCORE0_VALUE),
L"%d",
MsrTurboRatioLimitNumCore.Bits.Numcore0
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_NUMCORE1_VALUE),
L"%d",
MsrTurboRatioLimitNumCore.Bits.Numcore1
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_NUMCORE2_VALUE),
L"%d",
MsrTurboRatioLimitNumCore.Bits.Numcore2
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_NUMCORE3_VALUE),
L"%d",
MsrTurboRatioLimitNumCore.Bits.Numcore3
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_NUMCORE4_VALUE),
L"%d",
MsrTurboRatioLimitNumCore.Bits.Numcore4
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_NUMCORE5_VALUE),
L"%d",
MsrTurboRatioLimitNumCore.Bits.Numcore5
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_NUMCORE6_VALUE),
L"%d",
MsrTurboRatioLimitNumCore.Bits.Numcore6
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_TURBO_RATIO_LIMIT_NUMCORE7_VALUE),
L"%d",
MsrTurboRatioLimitNumCore.Bits.Numcore7
);
//
// ATOM Turbo Ratio Limit Ratio
//
AtomMsrTurboRatioLimitRatio.Uint64 = AsmReadMsr64 (ADL_MSR_ATOM_TURBO_RATIO_LIMIT);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_RATIO0_VALUE),
L"%d",
AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup0
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_RATIO1_VALUE),
L"%d",
AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup1
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_RATIO2_VALUE),
L"%d",
AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup2
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_RATIO3_VALUE),
L"%d",
AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup3
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_RATIO4_VALUE),
L"%d",
AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup4
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_RATIO5_VALUE),
L"%d",
AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup5
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_RATIO6_VALUE),
L"%d",
AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup6
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_RATIO7_VALUE),
L"%d",
AtomMsrTurboRatioLimitRatio.Bits.MaxTurboGroup7
);
//
// ATOM Turbo Ratio Limit Num Core
//
AtomMsrTurboRatioLimitNumCore.Uint64 = AsmReadMsr64 (ADL_MSR_ATOM_TURBO_RATIO_LIMIT_CORES);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_NUMCORE0_VALUE),
L"%d",
AtomMsrTurboRatioLimitNumCore.Bits.Numcore0
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_NUMCORE1_VALUE),
L"%d",
AtomMsrTurboRatioLimitNumCore.Bits.Numcore1
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_NUMCORE2_VALUE),
L"%d",
AtomMsrTurboRatioLimitNumCore.Bits.Numcore2
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_NUMCORE3_VALUE),
L"%d",
AtomMsrTurboRatioLimitNumCore.Bits.Numcore3
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_NUMCORE4_VALUE),
L"%d",
AtomMsrTurboRatioLimitNumCore.Bits.Numcore4
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_NUMCORE5_VALUE),
L"%d",
AtomMsrTurboRatioLimitNumCore.Bits.Numcore5
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_NUMCORE6_VALUE),
L"%d",
AtomMsrTurboRatioLimitNumCore.Bits.Numcore6
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_TURBO_RATIO_LIMIT_NUMCORE7_VALUE),
L"%d",
AtomMsrTurboRatioLimitNumCore.Bits.Numcore7
);
}
/**
Initialize CPU strings and VR topology.
@param[in] EFI_EVENT Event
@param[in] VOID *Context
**/
VOID
InitCPUInfo (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINTN VariableSize;
UINT32 VariableAttributes;
UINT32 Index;
CHAR8 String[15];
MSR_BIOS_SIGN_ID_REGISTER MsrSignId;
UINT16 PowerLimitInteger;
UINT16 PowerLimitFraction;
UINT16 PowerLimitInteger2;
UINT16 PowerLimitFraction2;
UINT8 PowerUnit;
CPUID_VERSION_INFO_ECX Ecx;
UINT8 CtdpLevels;
UINT8 CtdpRatio;
UINT16 CtdpTdp;
UINT32 CtdpAddress;
CPU_INFO_PROTOCOL *DxeCpuInfo;
UINT32 CpuSetupVolVarAttr;
CPU_SETUP_VOLATILE_DATA CpuSetupVolData;
UINTN MchBar;
UINT64 MmioValue64;
UINT32 RegEcx;
UINT32 RfiNominalValue;
UINT32 RfiTotalFreqInKhz;
UINT16 RfiFreqMhz;
UINT16 RfiFreqKhz;
CONST CHAR8 *GenerationString = NULL;
CONST CHAR8 *SkuString = NULL;
MSR_CORE_THREAD_COUNT_REGISTER MsrCoreThreadCount;
MAILBOX_READ MailboxReadParameters;
UINTN NumberOfCores;
UINTN ProcNum;
UINTN LogProcNum;
UINTN BspIndex;
MSR_IA32_DEBUG_INTERFACE_REGISTER DebugInterfaceReg = {0};
VOID *Hob;
MSR_PACKAGE_POWER_SKU_REGISTER PackagePowerSkuMsr;
MSR_PACKAGE_POWER_SKU_UNIT_REGISTER PackagePowerSkuUnitMsr;
MSR_PACKAGE_RAPL_LIMIT_REGISTER PackageRaplLimitMsr;
MSR_CONFIG_TDP_NOMINAL_REGISTER ConfigTdpNominalMsr;
MSR_CONFIG_TDP_LEVEL1_REGISTER ConfigTdpLevel1Msr;
MSR_CONFIG_TDP_LEVEL2_REGISTER ConfigTdpLevel2Msr;
MSR_TURBO_ACTIVATION_RATIO_REGISTER TurboActivationRatioMsr;
MSR_TEMPERATURE_TARGET_REGISTER TemperatureTargetMsr;
UINT32 CpuFeatureVarAttr;
UINT8 FusedP0Ratio;
EFI_PROCESSOR_INFORMATION MpContext;
UINT32 BigCoreNumber;
UINT32 AtomCoreNumber;
UINT8 ApCoreType;
PowerLimitInteger = PowerLimitFraction = 0;
PowerUnit = 0;
RegEcx = 0;
BigCoreNumber = 0;
AtomCoreNumber = 0;
mCpuDataHob = NULL;
VariableSize = sizeof (SETUP_VOLATILE_DATA);
Status = gRT->GetVariable (
L"SetupVolatileData",
&gSetupVariableGuid,
NULL,
&VariableSize,
&mSetupVolatileData
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return ;
}
///
/// Locate DxeCpuInfo protocol instance and gather CPU information
///
Status = gBS->LocateProtocol (&gCpuInfoProtocolGuid, NULL, (VOID **) &DxeCpuInfo);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR,"Failed to locate DxeCpuInfo Protocol\n"));
return;
}
///
/// Update current Debug interface MSR enable/disable state
///
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &Ecx.Uint32, NULL);
if (Ecx.Bits.SDBG == 1) {
DebugInterfaceReg.Uint64 = AsmReadMsr64 (MSR_IA32_DEBUG_INTERFACE);
//[-start-200309-IB14630348-add]//
} else {
InitString (
gHiiHandle,
STRING_TOKEN (STR_DEBUG_MSR_INTERFACE_STATUS_VALUE),
L"%a",
"Disabled"
);
//[-end-200309-IB14630348-add]//
}
if (DebugInterfaceReg.Bits.DebugOccurred) {
InitString (
gHiiHandle,
STRING_TOKEN (STR_DEBUG_MSR_INTERFACE_STATUS_VALUE),
L"%a",
"Enabled"
);
} else {
InitString (
gHiiHandle,
STRING_TOKEN (STR_DEBUG_MSR_INTERFACE_STATUS_VALUE),
L"%a",
"Disabled"
);
}
if (DxeCpuInfo->CpuInfo[BIG_CORE].NumCores != 0){
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_VERSION_VALUE),
L"%a",
DxeCpuInfo->CpuInfo[BIG_CORE].BrandString
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_SPEED_VALUE),
L"%d MHz",
DxeCpuInfo->CpuInfo[BIG_CORE].IntendedFreq
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_ID_VALUE),
L"0x%X",
DxeCpuInfo->CpuInfo[BIG_CORE].CpuSignature
);
} else {
///
/// Update with small core data
///
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_VERSION_VALUE),
L"%a",
DxeCpuInfo->CpuInfo[SMALL_CORE].BrandString
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_SPEED_VALUE),
L"%d MHz",
DxeCpuInfo->CpuInfo[SMALL_CORE].IntendedFreq
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_ID_VALUE),
L"0x%X",
DxeCpuInfo->CpuInfo[SMALL_CORE].CpuSignature
);
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_PACKAGE_VALUE),
L"%a",
"Not Implemented Yet"
);
//
// Update the Microcode Revision
//
MsrSignId.Uint64 = AsmReadMsr64 (MSR_BIOS_SIGN_ID);
if (MsrSignId.Bits.PatchId != 0) {
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_MICROCODE_VALUE),
L"%x",
MsrSignId.Bits.PatchId
);
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_ATOM_COUNT_VALUE),
L"%dCore(s) / %dThread(s)",
DxeCpuInfo->CpuInfo[SMALL_CORE].NumCores,
DxeCpuInfo->CpuInfo[SMALL_CORE].NumCores * DxeCpuInfo->CpuInfo[SMALL_CORE].NumHts
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_CORE_COUNT_VALUE),
L"%dCore(s) / %dThread(s)",
DxeCpuInfo->CpuInfo[BIG_CORE].NumCores,
DxeCpuInfo->CpuInfo[BIG_CORE].NumCores * DxeCpuInfo->CpuInfo[BIG_CORE].NumHts
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_CORE_SPEED_VALUE),
L"%d MHz",
DxeCpuInfo->CpuInfo[SMALL_CORE].IntendedFreq
);
if (DxeCpuInfo->CpuInfo[BIG_CORE].NumCores != 0){
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_BRAND_VALUE),
L"%a",
DxeCpuInfo->CpuInfo[BIG_CORE].BrandString
);
} else {
//
// Update processor brand with small core data
//
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_BRAND_VALUE),
L"%a",
DxeCpuInfo->CpuInfo[SMALL_CORE].BrandString
);
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_CORE_SPEED_VALUE),
L"%d MHz",
DxeCpuInfo->CpuInfo[BIG_CORE].IntendedFreq
);
for (Index = 0; Index <= DxeCpuInfo->CpuInfo[SMALL_CORE].MaxCacheSupported; ++Index) {
switch (DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Level) {
case 1:
//
// L1 cache size is per core. Display the size per core times number of cores.
// If there's only 1 enabled core, simply display the size per core.
//
if (DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Type == 1) {
if (DxeCpuInfo->CpuInfo[SMALL_CORE].NumCores == 1) {
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_CORE_L1_DATA_CACHE_VALUE),
L"%d KB",
DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Size
);
} else {
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_CORE_L1_DATA_CACHE_VALUE),
L"%d KB x %d",
DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Size,
DxeCpuInfo->CpuInfo[SMALL_CORE].NumCores
);
}
} else if (DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Type == 2) {
if (DxeCpuInfo->CpuInfo[SMALL_CORE].NumCores == 1) {
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_CORE_L1_INSTR_CACHE_VALUE),
L"%d KB",
DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Size
);
} else {
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_CORE_L1_INSTR_CACHE_VALUE),
L"%d KB x %d",
DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Size,
DxeCpuInfo->CpuInfo[SMALL_CORE].NumCores
);
}
}
break;
case 2:
//
// L2 cache size is shared per 4 atom cores. Display the size per core times number of cores.
// If there's less than 4 enabled core, simply display the size per core.
//
if (DxeCpuInfo->CpuInfo[SMALL_CORE].NumCores <= 4) {
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_CORE_L2_CACHE_VALUE),
L"%d KB",
DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Size
);
} else {
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_CORE_L2_CACHE_VALUE),
L"%d KB x %d",
DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Size,
DxeCpuInfo->CpuInfo[SMALL_CORE].NumCores / 4 //L2 is shared per 4 Atom Cores
);
}
break;
case 3:
//
// L3 cache size is not per core. It is shared between cores.
//
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_CORE_L3_CACHE_VALUE),
L"%d MB",
DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Size / 1024
);
break;
case 4:
InitString (
gHiiHandle,
STRING_TOKEN (STR_ATOM_CORE_L4_CACHE_VALUE),
L"%d MB",
DxeCpuInfo->CpuInfo[SMALL_CORE].CacheInfo[Index].Size / 1024
);
break;
}
}
for (Index = 0; Index <= DxeCpuInfo->CpuInfo[BIG_CORE].MaxCacheSupported; ++Index) {
switch (DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Level) {
case 1:
//
// L1 cache size is per core. Display the size per core times number of cores.
// If there's only 1 enabled core, simply display the size per core.
//
if (DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Type == 1) {
if (DxeCpuInfo->CpuInfo[BIG_CORE].NumCores == 1) {
InitString (
gHiiHandle,
STRING_TOKEN (STR_CORE_L1_DATA_CACHE_VALUE),
L"%d KB",
DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Size
);
} else {
InitString (
gHiiHandle,
STRING_TOKEN (STR_CORE_L1_DATA_CACHE_VALUE),
L"%d KB x %d",
DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Size,
DxeCpuInfo->CpuInfo[BIG_CORE].NumCores
);
}
} else if (DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Type == 2) {
if (DxeCpuInfo->CpuInfo[BIG_CORE].NumCores == 1) {
InitString (
gHiiHandle,
STRING_TOKEN (STR_CORE_L1_INSTR_CACHE_VALUE),
L"%d KB",
DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Size
);
} else {
InitString (
gHiiHandle,
STRING_TOKEN (STR_CORE_L1_INSTR_CACHE_VALUE),
L"%d KB x %d",
DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Size,
DxeCpuInfo->CpuInfo[BIG_CORE].NumCores
);
}
}
break;
case 2:
//
// L2 cache size is per core. Display the size per core times number of cores.
// If there's only 1 enabled core, simply display the size per core.
//
if (DxeCpuInfo->CpuInfo[BIG_CORE].NumCores == 1) {
InitString (
gHiiHandle,
STRING_TOKEN (STR_CORE_L2_CACHE_VALUE),
L"%d KB",
DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Size
);
} else {
InitString (
gHiiHandle,
STRING_TOKEN (STR_CORE_L2_CACHE_VALUE),
L"%d KB x %d",
DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Size,
DxeCpuInfo->CpuInfo[BIG_CORE].NumCores
);
}
break;
case 3:
//
// L3 cache size is not per core. It is shared between cores.
//
InitString (
gHiiHandle,
STRING_TOKEN (STR_CORE_L3_CACHE_VALUE),
L"%d MB",
DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Size / 1024
);
break;
case 4:
InitString (
gHiiHandle,
STRING_TOKEN (STR_CORE_L4_CACHE_VALUE),
L"%d MB",
DxeCpuInfo->CpuInfo[BIG_CORE].CacheInfo[Index].Size / 1024
);
break;
}
}
GenerationString = GetGenerationString ();
SkuString = GetSkuString ();
if ((GenerationString != NULL) && (SkuString != NULL)) {
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_VALUE),
L"%a %a",
GenerationString,
SkuString
);
} else {
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_VALUE),
L"%a",
"Unknown"
);
}
VariableSize = sizeof (SETUP_CPU_FEATURES);
Status = gRT->GetVariable (
L"SetupCpuFeatures",
&gSetupVariableGuid,
&CpuFeatureVarAttr,
&VariableSize,
&mSetupCpuFeatures
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return ;
}
VariableSize = sizeof (CPU_SETUP);
gRT->GetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
&VariableAttributes,
&VariableSize,
&mCpuSetup
);
//
// Init CPU the number of all cores including enabled & disabled.
//
if (mCpuSetup.AllSmallCoreCount == 0) {
mCpuSetup.AllSmallCoreCount = mSetupCpuFeatures.NumSmallCores;
}
if (mCpuSetup.AllBigCoreCount == 0) {
mCpuSetup.AllBigCoreCount = mSetupCpuFeatures.NumCores;
}
gRT->SetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
VariableAttributes,
sizeof (mCpuSetup),
&mCpuSetup
);
if (mSetupCpuFeatures.VTAvailable) {
AsciiSPrint (String, 15, "Supported");
} else {
AsciiSPrint (String, 15, "Not Supported");
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_VMX_VALUE),
L"%a",
String
);
if (mSetupCpuFeatures.TXTAvailable) {
AsciiSPrint (String, 15, "Supported");
} else {
AsciiSPrint (String, 15, "Not Supported");
}
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_SMX_VALUE),
L"%a",
String
);
//
// TXT/BTG related infromation
//
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_CRASH_REGISTER_VALUE),
L"0x%08x",
MmioRead32(TXT_PUBLIC_BASE + TXT_CRASHCODE_REG_OFF)
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_SPAD_REGISTER_VALUE),
L"0x%016lx",
MmioRead64(TXT_PUBLIC_BASE + R_CPU_BOOT_GUARD_BOOTSTATUS)
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_BTG_STATUS_VALUE),
L"0x%08x",
MmioRead32(TXT_PUBLIC_BASE + R_CPU_BOOT_GUARD_ACM_STATUS)
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_BTG_ACM_POL_STS_VALUE),
L"0x%016lx",
MmioRead64(TXT_PUBLIC_BASE + R_CPU_ACM_POLICY_STATUS)
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_PROCESSOR_BTG_SACM_INFO_VALUE),
L"0x%016lx",
AsmReadMsr64(MSR_BOOT_GUARD_SACM_INFO)
);
//
// Package Power SKU Unit
//
PackagePowerSkuUnitMsr.Uint64 = AsmReadMsr64 (MSR_PACKAGE_POWER_SKU_UNIT);
PowerUnit = (UINT8) PackagePowerSkuUnitMsr.Bits.PwrUnit;
PowerUnit = (UINT8) LShiftU64 (2, (PowerUnit - 1));
if (PowerUnit == 0 ) {
ASSERT (FALSE);
return;
}
//
// Min and Max Turbo Power Limit
//
PackagePowerSkuMsr.Uint64 = AsmReadMsr64 (MSR_PACKAGE_POWER_SKU);
PowerLimitFraction = PowerLimitInteger = (UINT16) PackagePowerSkuMsr.Bits.PkgMaxPwr;
//
// 0 for Max Power Limit means no limit, so set the value to 0x7FFF (max value possible)
//
if (PowerLimitInteger == 0 ) {
PowerLimitFraction = PowerLimitInteger= 0x7FFF;
}
PowerLimitInteger = PowerLimitInteger / PowerUnit;
PowerLimitFraction = PowerLimitFraction % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction = (PowerLimitFraction * 1000 ) / PowerUnit;
InitString (
gHiiHandle,
STRING_TOKEN (STR_MAX_TURBO_POWER_LIMIT_VALUE),
L"%d.%d",
PowerLimitInteger,PowerLimitFraction
);
PowerLimitFraction = PowerLimitInteger = (UINT16) PackagePowerSkuMsr.Bits.PkgMinPwr;
PowerLimitInteger = PowerLimitInteger / PowerUnit;
PowerLimitFraction = PowerLimitFraction % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction = (PowerLimitFraction * 1000 ) / PowerUnit;
InitString (
gHiiHandle,
STRING_TOKEN (STR_MIN_TURBO_POWER_LIMIT_VALUE),
L"%d.%d",
PowerLimitInteger,PowerLimitFraction
);
//
// Package TDP Limit
//
PowerLimitFraction = PowerLimitInteger = (UINT16) PackagePowerSkuMsr.Bits.PkgTdp;
PowerLimitInteger = PowerLimitInteger / PowerUnit;
PowerLimitFraction = PowerLimitFraction % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction = (PowerLimitFraction * 1000 ) / PowerUnit;
InitString (
gHiiHandle,
STRING_TOKEN (STR_TDP_LIMIT_VALUE),
L"%d.%d",
PowerLimitInteger,PowerLimitFraction
);
//
// Turbo Power Limit
//
PackageRaplLimitMsr.Uint64 = AsmReadMsr64 (MSR_PACKAGE_RAPL_LIMIT);
//
// Long duration power limit
//
PowerLimitFraction = PowerLimitInteger = (UINT16) PackageRaplLimitMsr.Bits.PkgPwrLim1;
PowerLimitInteger = PowerLimitInteger / PowerUnit;
PowerLimitFraction = PowerLimitFraction % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction = (PowerLimitFraction * 1000 ) / PowerUnit;
InitString (
gHiiHandle,
STRING_TOKEN (STR_LONG_DUR_PWR_LIMIT_VALUE),
L"%d.%d",
PowerLimitInteger,
PowerLimitFraction
);
//
// Short duration power limit
// Notice, we are using TempMsr.Dwords.High, so reusing Power Limit 1 Mask
//
PowerLimitFraction = PowerLimitInteger = (UINT16) PackageRaplLimitMsr.Bits.PkgPwrLim2;
PowerLimitInteger = PowerLimitInteger / PowerUnit;
PowerLimitFraction = PowerLimitFraction % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction = (PowerLimitFraction * 1000 ) / PowerUnit;
InitString (
gHiiHandle,
STRING_TOKEN (STR_SHORT_DUR_PWR_LIMIT_VALUE),
L"%d.%d",
PowerLimitInteger,
PowerLimitFraction
);
//
// Initialize Turbo Ratio strings
//
InitTurboRatioInfo ();
//
// Get the number of configurable TDP Levels supported
//
CtdpLevels = GetConfigTdpLevels ();
InitString (
gHiiHandle,
STRING_TOKEN (STR_CTDP_LEVELS_VALUE),
L"%d",
CtdpLevels + 1
);
if (CtdpLevels != 0) {
//
// Get Nominal Ratio
//
ConfigTdpNominalMsr.Uint64 = AsmReadMsr64 (MSR_CONFIG_TDP_NOMINAL);
CtdpRatio = (UINT8) ConfigTdpNominalMsr.Bits.TdpRatio;
// Package TDP Limit
PowerLimitFraction = PowerLimitInteger = (UINT8) PackagePowerSkuMsr.Bits.PkgTdp;
PowerLimitInteger = PowerLimitInteger / PowerUnit;
PowerLimitFraction = PowerLimitFraction % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction = (PowerLimitFraction * 1000) / PowerUnit;
InitString (
gHiiHandle,
STRING_TOKEN (STR_CTDP_NOMINAL_VALUE),
L"Ratio:%d TAR:%d PL1:%d.%dW",
CtdpRatio,
CtdpRatio - 1,
PowerLimitInteger,
PowerLimitFraction
);
//
// Get Level1 Ratio and TDP
//
ConfigTdpLevel1Msr.Uint64 = AsmReadMsr64 (MSR_CONFIG_TDP_LEVEL1);
CtdpRatio = (UINT8) ConfigTdpLevel1Msr.Bits.TdpRatio;
PowerLimitFraction = PowerLimitInteger = (UINT8) ConfigTdpLevel1Msr.Bits.PkgTdp;
PowerLimitInteger = PowerLimitInteger / PowerUnit;
PowerLimitFraction = PowerLimitFraction % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction = (PowerLimitFraction * 1000) / PowerUnit;
InitString (
gHiiHandle,
STRING_TOKEN (STR_CTDP_LEVEL1_VALUE),
L"Ratio:%d TAR:%d PL1:%d.%dW",
CtdpRatio,
CtdpRatio - 1,
PowerLimitInteger,
PowerLimitFraction
);
//
// Get Level2 Ratio and TDP
//
ConfigTdpLevel2Msr.Uint64 = AsmReadMsr64 (MSR_CONFIG_TDP_LEVEL2);
CtdpRatio = (UINT8) ConfigTdpLevel2Msr.Bits.TdpRatio;
PowerLimitFraction = PowerLimitInteger = (UINT8) ConfigTdpLevel2Msr.Bits.PkgTdp;
PowerLimitInteger = PowerLimitInteger / PowerUnit;
PowerLimitFraction = PowerLimitFraction % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction = (PowerLimitFraction * 1000) / PowerUnit;
InitString (
gHiiHandle,
STRING_TOKEN (STR_CTDP_LEVEL2_VALUE),
L"Ratio:%d TAR:%d PL1:%d.%dW",
CtdpRatio,
CtdpRatio - 1,
PowerLimitInteger,
PowerLimitFraction
);
//
// Get MMIO Power Limit 1
//
CtdpAddress = (UINT32) ((UINTN) PcdGet64 (PcdMchBaseAddress) + 0x59A0);
CtdpTdp = (UINT16) ((*((UINT32*) ((UINTN) CtdpAddress))) & 0x7FFF);
PowerLimitFraction = PowerLimitInteger = CtdpTdp;
PowerLimitInteger = PowerLimitInteger / PowerUnit;
PowerLimitFraction = PowerLimitFraction % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction = (PowerLimitFraction * 1000) / PowerUnit;
//
// Get MSR Power Limit 1
//
PackageRaplLimitMsr.Uint64 = AsmReadMsr64 (MSR_PACKAGE_RAPL_LIMIT);
PowerLimitFraction2 = PowerLimitInteger2 = (UINT16) PackageRaplLimitMsr.Bits.PkgPwrLim1;
PowerLimitInteger2 = PowerLimitInteger2 / PowerUnit;
PowerLimitFraction2 = PowerLimitFraction2 % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction2 = (PowerLimitFraction2 * 1000) / PowerUnit;
InitString (
gHiiHandle,
STRING_TOKEN (STR_CTDP_PWR_LIMIT1_VALUE),
L"%d.%dW (MSR:%d.%d)",
PowerLimitInteger,
PowerLimitFraction,
PowerLimitInteger2,
PowerLimitFraction2
);
//
// Get MMIO Power Limit 2
//
CtdpAddress = (UINT32) ((UINTN) PcdGet64 (PcdMchBaseAddress) + 0x59A4);
CtdpTdp = (UINT16) ((*((UINT32*) ((UINTN) CtdpAddress))) & 0x7FFF);
PowerLimitFraction = PowerLimitInteger = CtdpTdp;
PowerLimitInteger = PowerLimitInteger / PowerUnit;
PowerLimitFraction = PowerLimitFraction % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction = (PowerLimitFraction * 1000) / PowerUnit;
//
// Get MSR Power Limit 2
//
PowerLimitFraction2 = PowerLimitInteger2 = (UINT16) PackageRaplLimitMsr.Bits.PkgPwrLim2;
PowerLimitInteger2 = PowerLimitInteger2 / PowerUnit;
PowerLimitFraction2 = PowerLimitFraction2 % PowerUnit;
// Now convert fractional part into 3 decimal place
PowerLimitFraction2 = (PowerLimitFraction2 * 1000) / PowerUnit;
InitString (
gHiiHandle,
STRING_TOKEN (STR_CTDP_PWR_LIMIT2_VALUE),
L"%d.%dW (MSR:%d.%d)",
PowerLimitInteger,
PowerLimitFraction,
PowerLimitInteger2,
PowerLimitFraction2
);
//
// Get TAR value
//
TurboActivationRatioMsr.Uint64 = AsmReadMsr64 (MSR_TURBO_ACTIVATION_RATIO);
if (TurboActivationRatioMsr.Bits.TurboActivationRatioLock) {
InitString (
gHiiHandle,
STRING_TOKEN (STR_CTDP_TAR_VALUE),
L"%d (Locked)",
TurboActivationRatioMsr.Bits.MaxNonTurboRatio
);
} else {
InitString (
gHiiHandle,
STRING_TOKEN (STR_CTDP_TAR_VALUE),
L"%d (Unlocked)",
TurboActivationRatioMsr.Bits.MaxNonTurboRatio
);
}
}
VariableSize = sizeof (CPU_SETUP_VOLATILE_DATA);
Status = gRT->GetVariable (
L"CpuSetupVolatileData",
&gCpuSetupVariableGuid,
&CpuSetupVolVarAttr,
&VariableSize,
&CpuSetupVolData
);
if (EFI_ERROR (Status)) {
CpuSetupVolVarAttr = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
}
ASSERT_EFI_ERROR (Status);
///
/// Get CPU VR topology
///
Hob = (CPU_DATA_HOB *) GetFirstGuidHob (&gCpuDataHobGuid);
mCpuDataHob = (CPU_DATA_HOB *)((UINTN)Hob + sizeof (EFI_HOB_GUID_TYPE));
if (mCpuDataHob == NULL) {
DEBUG((DEBUG_ERROR, "CPU Data HOB not available\n"));
ASSERT (mCpuDataHob != NULL);
}
//
// Lock the VR submenu if it does not use SVID.
// VR Type. 1 - No SVID VR, 0 - SVID VR
//
if (mCpuDataHob == NULL) {
CpuSetupVolData.CoreVrLocked = 0;
CpuSetupVolData.GtVrLocked = 0;
CpuSetupVolData.SaVrLocked = 0;
} else {
CpuSetupVolData.CoreVrLocked = (mCpuDataHob->SvidEnabled & BIT0) == 0;
CpuSetupVolData.GtVrLocked = (mCpuDataHob->SvidEnabled & BIT1) == 0;
CpuSetupVolData.SaVrLocked = (mCpuDataHob->SvidEnabled & BIT2) == 0;
}
Status = gRT->SetVariable (
L"CpuSetupVolatileData",
&gCpuSetupVariableGuid,
CpuSetupVolVarAttr,
sizeof (CpuSetupVolData),
&CpuSetupVolData
);
ASSERT_EFI_ERROR (Status);
///
/// Calculate RFI nominal frequency.
///
RfiNominalValue = 0;
MchBar = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MCHBAR)) & ~BIT0;
MmioValue64 = ((UINT64) MmioRead32 (MchBar + R_RFI_CONTROL2_0_0_0_MCHBAR_PCU) & ~BIT0) + LShiftU64 ((UINT64) MmioRead32 (MchBar + R_RFI_CONTROL2_0_0_0_MCHBAR_PCU + 4), 32);
///
/// Get XTAL clock frequency
///
AsmCpuid(CPUID_TIME_STAMP_COUNTER, NULL, NULL, &RegEcx, NULL);
///
/// RFI_CONTROL MMIO has High and Low byte. High byte is needed for freq calculation.
/// So shift by PF3_OFFSET for 38Mhz and PF2_OFFSET for 24Mhz.
/// Final RFI freq would be the High Byte << 3 for 38MHz and High Byte << 2 for 24MHz
/// Convert value to frequency in KHz by multiplying by ClockFreq / 128.
/// So multiply by either 38400 / 128 = 300, or 24000 / 128 = 375 / 2.
///
///
if (RegEcx == CLOCK_FREQUENCY_38MHz) {
RfiNominalValue = (UINT32) (MmioValue64 >> N_RFI_FREQ_HI_PF3_OFFSET);
RfiTotalFreqInKhz = (UINT32) ((RfiNominalValue << 3) * 300);
} else if (RegEcx == CLOCK_FREQUENCY_24MHz) {
RfiNominalValue = (UINT32) (MmioValue64 >> N_RFI_FREQ_HI_PF2_OFFSET);
RfiTotalFreqInKhz = (UINT32) (((RfiNominalValue << 2) * 375) / 2);
} else {
DEBUG ((DEBUG_ERROR, "Unexpected Clock Frequency! RegEcx: %d\n", RegEcx));
RfiTotalFreqInKhz = 0;
}
DEBUG ((DEBUG_INFO, "Rfi Freq : %d Khz\n", RfiTotalFreqInKhz));
RfiFreqMhz = (UINT16) (RfiTotalFreqInKhz / 1000);
RfiFreqKhz = (UINT16) (RfiTotalFreqInKhz % 1000);
InitString (
gHiiHandle,
STRING_TOKEN (STR_CPU_RFI_NOM_FREQ_VALUE),
L"%d.%dMHz",
RfiFreqMhz,
RfiFreqKhz
);
TemperatureTargetMsr.Uint64 = AsmReadMsr64 (MSR_TEMPERATURE_TARGET);
mCpuSetup.TCCActivationOffset = (UINT8) TemperatureTargetMsr.Bits.TjMaxTccOffset;
InitString (
gHiiHandle,
STRING_TOKEN (STR_TCC_ACTIVATION_VALUE),
L"%d ",
mCpuSetup.TCCActivationOffset
);
///
/// Client S/H is able to support the OCMB commmand 0x1C
///
if (IsItbmSupported ()) {
//
// Locate the MP services protocol
// Find the MP Protocol. This is an MP platform, so MP protocol must be there.
//
Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &mMpService);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return;
}
ZeroMem (&MpContext, sizeof (EFI_PROCESSOR_INFORMATION));
MsrCoreThreadCount.Uint64 = AsmReadMsr64 (MSR_CORE_THREAD_COUNT);
NumberOfCores = (UINTN) MsrCoreThreadCount.Bits.Corecount;
LogProcNum = (UINTN) MsrCoreThreadCount.Bits.Threadcount;
MailboxReadParameters.MailboxDataPtr = AllocateZeroPool (sizeof (UINT32) * NumberOfCores);
MailboxReadParameters.MailboxStatus = AllocateZeroPool (sizeof (EFI_STATUS) * NumberOfCores);
if ((MailboxReadParameters.MailboxDataPtr == NULL) || (MailboxReadParameters.MailboxStatus == NULL)) {
return;
}
Status = mMpService->WhoAmI (mMpService, &BspIndex);
//
// Read Favored Core Information from each core index
//
mCoreIndex = 0;
for (Index = 0; Index < LogProcNum; Index++) {
Status = mMpService->GetProcessorInfo (
mMpService,
(UINTN)Index,
&MpContext
);
if (EFI_ERROR (Status)) {
return;
}
if (MpContext.Location.Thread != 0) {
// Continue when the processor is not 1st thread of Core, i.e. the 2nd, 3rd or 4th thread of Core.
continue;
}
if (Index == BspIndex) {
MailboxReadFavoredCore ((VOID*) &MailboxReadParameters);
mCoreIndex++;
ApCoreType = 0;
GetCoreType (&ApCoreType);
if (ApCoreType == CPUID_CORE_TYPE_INTEL_CORE) {
BigCoreNumber++;
} else if (ApCoreType == CPUID_CORE_TYPE_INTEL_ATOM) {
AtomCoreNumber++;
}
} else {
mMpService->StartupThisAP (
mMpService,
(EFI_AP_PROCEDURE) MailboxReadFavoredCore,
Index,
NULL,
0,
(VOID*) &MailboxReadParameters,
NULL
);
mCoreIndex++;
ApCoreType = 0;
mMpService->StartupThisAP (
mMpService,
(EFI_AP_PROCEDURE) GetCoreType,
Index,
NULL,
0,
(UINT8 *) &ApCoreType,
NULL
);
if (ApCoreType == CPUID_CORE_TYPE_INTEL_CORE) {
BigCoreNumber++;
} else if (ApCoreType == CPUID_CORE_TYPE_INTEL_ATOM) {
AtomCoreNumber++;
}
}
}
for (ProcNum = 0; ProcNum < BigCoreNumber; ProcNum++) {
InitString (
gHiiHandle,
STRING_TOKEN (FuseFreqString [ProcNum]),
L"%d",
((UINT32) MailboxReadParameters.MailboxDataPtr [ProcNum] & 0xFF)
);
}
///
/// We check OCMB 0x1C[15:8] FusedP0 max ratio to identify ITBMT supported
/// non-ITBMT: All cores are the same value
/// ITBMT: Difference value among all cores
///
mSetupCpuFeatures.ItbmAvailable = 0;
FusedP0Ratio = (UINT8) (RShiftU64 (MailboxReadParameters.MailboxDataPtr [0], 8) & 0xFF);
for (ProcNum = 1; ProcNum < BigCoreNumber; ProcNum++) {
if (FusedP0Ratio != ((UINT8) RShiftU64 (MailboxReadParameters.MailboxDataPtr [ProcNum], 8) & 0xFF)) {
mSetupCpuFeatures.ItbmAvailable = 1;
break;
}
}
Status = gRT->SetVariable (
L"SetupCpuFeatures",
&gSetupVariableGuid,
CpuFeatureVarAttr,
sizeof (SETUP_CPU_FEATURES),
&mSetupCpuFeatures
);
ASSERT_EFI_ERROR (Status);
FreePool (MailboxReadParameters.MailboxDataPtr);
FreePool (MailboxReadParameters.MailboxStatus);
}
}
/**
Cpu setup callback
@param[in] EFI_EVENT Event
@param[in] VOID *Context
**/
VOID
EFIAPI
CpuSetupCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINTN VariableSize;
VariableSize = sizeof (CPU_SETUP);
Status = gRT->GetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
NULL,
&VariableSize,
&mCpuSetup
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return ;
}
//[-start-020215-IB06462109-modify]//
// SaveCpuRatio (mCpuSetup.CpuRatio);
WriteExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, CMOS_CPU_RATIO_OFFSET, mCpuSetup.CpuRatio);
//[-end-020215-IB06462109-modify]//
///
/// Save the Alias Check request to use in early PEI phase
///
//[-start-020215-IB06462109-modify]//
// SaveTxtAliasCheck (mCpuSetup.AcheckRequest);
WriteExtCmos8 (R_XCMOS_INDEX, R_XCMOS_DATA, CMOS_TXT_REG, mCpuSetup.AcheckRequest);
//[-end-020215-IB06462109-modify]//
}
/**
Initialize CPU strings.
@param[in] EFI_HII_HANDLE HiiHandle
@param[in] UINT16 Class
**/
VOID
InitCPUStrings (
EFI_HII_HANDLE HiiHandle,
UINT16 Class
)
{
//[-start-020215-IB06462109-remove]//
// EFI_EVENT SetupNvramCallbackEvt;
// VOID *SetupNvramCallbackReg;
//[-end-020215-IB06462109-remove]//
CONST CHAR8 *RevisionTableString = NULL;
//[-start-020215-IB06462109-add]//
CHIPSET_CONFIGURATION *MyIfrNVData;
MyIfrNVData = (CHIPSET_CONFIGURATION *)gSUBrowser->SCBuffer;
CopyMem (&mSetupConfiguration, MyIfrNVData, PcdGet32 (PcdSetupConfigSize));
//[-end-020215-IB06462109-add]//
if ((Class == MAIN_FORM_SET_CLASS) || (Class == ADVANCED_FORM_SET_CLASS)) {
DEBUG ((DEBUG_INFO, "<InitCPUStrings>"));
gHiiHandle = HiiHandle;
InitTurboRatioDefault (NULL, NULL);
InitTxtAcheckDefault ();
InitDCDInfo ();
InitCPUInfo (NULL, NULL);
///
///
//[-start-020215-IB06462109-modify]//
// SetupNvramCallbackEvt = EfiCreateProtocolNotifyEvent (
// &gSetupNvramUpdateGuid,
// TPL_CALLBACK,
// CpuSetupCallback,
// NULL,
// &SetupNvramCallbackReg
// );
// ASSERT (SetupNvramCallbackEvt != NULL);
CpuSetupCallback(NULL, NULL);
//[-end-020215-IB06462109-modify]//
}
//[-start-020215-IB06462109-modify]//
// if (Class == MAIN_FORM_SET_CLASS) {
if (Class == ADVANCED_FORM_SET_CLASS) {
//[-end-020215-IB06462109-modify]//
RevisionTableString = GetRevisionTable ();
InitString (
HiiHandle,
STRING_TOKEN (STR_PROCESSOR_STEPPING_VALUE),
L"%a",
RevisionTableString
);
}
InitCpuVrConfig (); ///< Display CPU VR config default programmed values.
#if FixedPcdGetBool(PcdITbtEnable) == 1
OverrideCpuCxLimitForTcssIom ();
#endif // FixedPcdGetBool(PcdITbtEnable) == 1
//[-start-020215-IB06462109-add]//
//
// Copy local Setup buffer data to Global Setup buffer
//
CopyMem (MyIfrNVData, &mSetupConfiguration, PcdGet32 (PcdSetupConfigSize));
//[-end-020215-IB06462109-add]//
}
/**
This function validates the Flex Ratio setup value
@param[in] EFI_FORM_CALLBACK_PROTOCOL *This
@param[in] UINT16 KeyValue
@param[in] EFI_IFR_DATA_ARRAY *Data,
@param[in] EFI_HII_CALLBACK_PACKET **Packet
@retval EFI_SUCCESS Call Back Function executed successfully
**/
EFI_STATUS
EFIAPI
CpuFormCallBackFunction (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID KeyValue,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
CPU_SETUP *CpuSetup;
UINT8 RatioLimitMin;
UINTN VarSize;
UINTN VariableSize;
EFI_STATUS Status;
//[-start-020215-IB06462109-modify]//
// EFI_STRING RequestString = NULL;
CPU_SETUP *MyCpuIfrNVData;
BOOLEAN ActionStatus = FALSE;
//[-end-020215-IB06462109-modify]//
UINT8 MaxBusRatio;
UINT8 MinBusRatio;
MaxBusRatio = 0;
MinBusRatio = 0;
Status = EFI_UNSUPPORTED;
if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
if (Action == EFI_BROWSER_ACTION_DEFAULT_STANDARD) {
Status = EFI_SUCCESS;
switch (KeyValue) {
case KEY_CpuRatioLimit:
break;
case KEY_RatioLimitRatio0:
Value->u8 = mCpuSetup.RatioLimitRatioDefault[0];
break;
case KEY_RatioLimitRatio1:
Value->u8 = mCpuSetup.RatioLimitRatioDefault[1];
break;
case KEY_RatioLimitRatio2:
Value->u8 = mCpuSetup.RatioLimitRatioDefault[2];
break;
case KEY_RatioLimitRatio3:
Value->u8 = mCpuSetup.RatioLimitRatioDefault[3];
break;
case KEY_RatioLimitRatio4:
Value->u8 = mCpuSetup.RatioLimitRatioDefault[4];
break;
case KEY_RatioLimitRatio5:
Value->u8 = mCpuSetup.RatioLimitRatioDefault[5];
break;
case KEY_RatioLimitRatio6:
Value->u8 = mCpuSetup.RatioLimitRatioDefault[6];
break;
case KEY_RatioLimitRatio7:
Value->u8 = mCpuSetup.RatioLimitRatioDefault[7];
break;
case KEY_RatioLimitNumCore0:
Value->u8 = mCpuSetup.RatioLimitNumCoreDefault[0];
break;
case KEY_RatioLimitNumCore1:
Value->u8 = mCpuSetup.RatioLimitNumCoreDefault[1];
break;
case KEY_RatioLimitNumCore2:
Value->u8 = mCpuSetup.RatioLimitNumCoreDefault[2];
break;
case KEY_RatioLimitNumCore3:
Value->u8 = mCpuSetup.RatioLimitNumCoreDefault[3];
break;
case KEY_RatioLimitNumCore4:
Value->u8 = mCpuSetup.RatioLimitNumCoreDefault[4];
break;
case KEY_RatioLimitNumCore5:
Value->u8 = mCpuSetup.RatioLimitNumCoreDefault[5];
break;
case KEY_RatioLimitNumCore6:
Value->u8 = mCpuSetup.RatioLimitNumCoreDefault[6];
break;
case KEY_RatioLimitNumCore7:
Value->u8 = mCpuSetup.RatioLimitNumCoreDefault[7];
break;
case KEY_AtomRatioLimitRatio0:
Value->u8 = mCpuSetup.AtomRatioLimitRatioDefault[0];
break;
case KEY_AtomRatioLimitRatio1:
Value->u8 = mCpuSetup.AtomRatioLimitRatioDefault[1];
break;
case KEY_AtomRatioLimitRatio2:
Value->u8 = mCpuSetup.AtomRatioLimitRatioDefault[2];
break;
case KEY_AtomRatioLimitRatio3:
Value->u8 = mCpuSetup.AtomRatioLimitRatioDefault[3];
break;
case KEY_AtomRatioLimitRatio4:
Value->u8 = mCpuSetup.AtomRatioLimitRatioDefault[4];
break;
case KEY_AtomRatioLimitRatio5:
Value->u8 = mCpuSetup.AtomRatioLimitRatioDefault[5];
break;
case KEY_AtomRatioLimitRatio6:
Value->u8 = mCpuSetup.AtomRatioLimitRatioDefault[6];
break;
case KEY_AtomRatioLimitRatio7:
Value->u8 = mCpuSetup.AtomRatioLimitRatioDefault[7];
break;
case KEY_AtomRatioLimitNumCore0:
Value->u8 = mCpuSetup.AtomRatioLimitNumCoreDefault[0];
break;
case KEY_AtomRatioLimitNumCore1:
Value->u8 = mCpuSetup.AtomRatioLimitNumCoreDefault[1];
break;
case KEY_AtomRatioLimitNumCore2:
Value->u8 = mCpuSetup.AtomRatioLimitNumCoreDefault[2];
break;
case KEY_AtomRatioLimitNumCore3:
Value->u8 = mCpuSetup.AtomRatioLimitNumCoreDefault[3];
break;
case KEY_AtomRatioLimitNumCore4:
Value->u8 = mCpuSetup.AtomRatioLimitNumCoreDefault[4];
break;
case KEY_AtomRatioLimitNumCore5:
Value->u8 = mCpuSetup.AtomRatioLimitNumCoreDefault[5];
break;
case KEY_AtomRatioLimitNumCore6:
Value->u8 = mCpuSetup.AtomRatioLimitNumCoreDefault[6];
break;
case KEY_AtomRatioLimitNumCore7:
Value->u8 = mCpuSetup.AtomRatioLimitNumCoreDefault[7];
break;
default:
Status = EFI_UNSUPPORTED;
}
}
return Status;
}
//[-start-020215-IB06462109-remove]//
//RequestString = NULL;
//[-end-020215-IB06462109-modify]//
Status = EFI_SUCCESS;
VarSize = sizeof (CPU_SETUP);
CpuSetup = AllocatePool (VarSize);
ASSERT (CpuSetup != NULL);
if (CpuSetup == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//[-start-200215-IB06462109-add]//
// Init local variable "CpuSetup"
MyCpuIfrNVData = (CPU_SETUP *)gRcSUBrowser->CpuSUBrowserData;
CopyMem (CpuSetup, MyCpuIfrNVData, VarSize);
//[-end-200215-IB06462109-add]//
//[-start-200215-IB06462109-modify]//
// GetBrowserData by VarStore Name (Setup)
ActionStatus = HiiGetBrowserData(&gCpuSetupVariableGuid, L"CpuSetup", VarSize, (UINT8 *) CpuSetup);
if (ActionStatus == FALSE) {
Status = EFI_NOT_FOUND;
}
ASSERT_EFI_ERROR (Status);
//[-end-200215-IB06462109-modify]//
//
// Get Maximum Non-Turbo bus ratio (HFM) from Platform Info MSR Bits[15:8]
//
GetBusRatio (&MaxBusRatio, &MinBusRatio);
//
// Save the Max Non Turbo Ratio
//
if (MaxBusRatio > CpuSetup->MaxNonTurboRatio) {
CpuSetup->MaxNonTurboRatio = MaxBusRatio;
} else {
MaxBusRatio = CpuSetup->MaxNonTurboRatio;
}
VariableSize = sizeof (CPU_SETUP);
Status = gRT->GetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
NULL,
&VariableSize,
&mCpuSetup
);
ASSERT_EFI_ERROR (Status);
//
// If Flex Ratio Override is disabled, use the original fused value.
// Otherwise, use the current Flex Ratio value.
//
if (mCpuSetup.CpuRatioOverride == 0) {
RatioLimitMin = mCpuSetup.FlexRatioOverrideDefault;
} else {
RatioLimitMin = mCpuSetup.CpuRatio;
}
switch (KeyValue) {
case KEY_CpuRatioLimit:
break;
case KEY_RatioLimitRatio0:
if (CpuSetup->RatioLimitRatio[0] < RatioLimitMin) {
CpuSetup->RatioLimitRatio[0] = mCoreRatioFinal[0];
}
if ((CpuSetup->RatioLimitRatio[0] > CORE_RATIO_NON_EXT_MODE_LIMIT) &&
((CpuSetup->CoreRatioExtensionMode != 1) || (CpuSetup->OverclockingSupport != 1))){
CpuSetup->RatioLimitRatio[0] = CORE_RATIO_NON_EXT_MODE_LIMIT;
}
mCoreRatioFinal[0] = CpuSetup->RatioLimitRatio[0];
//[-start-200215-IB06462109-remove]//
// RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, RatioLimitRatio[0]), sizeof (CpuSetup->RatioLimitRatio[0]));
//[-end-200215-IB06462109-remove]//
break;
case KEY_RatioLimitRatio1:
if (CpuSetup->RatioLimitRatio[1] < RatioLimitMin) {
CpuSetup->RatioLimitRatio[1] = mCoreRatioFinal[1];
}
if ((CpuSetup->RatioLimitRatio[1] > CORE_RATIO_NON_EXT_MODE_LIMIT) &&
((CpuSetup->CoreRatioExtensionMode != 1) || (CpuSetup->OverclockingSupport != 1))){
CpuSetup->RatioLimitRatio[1] = CORE_RATIO_NON_EXT_MODE_LIMIT;
}
mCoreRatioFinal[1] = CpuSetup->RatioLimitRatio[1];
//[-start-200215-IB06462109-remove]//
// RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, RatioLimitRatio[1]), sizeof (CpuSetup->RatioLimitRatio[1]));
//[-end-200215-IB06462109-remove]//
break;
case KEY_RatioLimitRatio2:
if (CpuSetup->RatioLimitRatio[2] < RatioLimitMin) {
CpuSetup->RatioLimitRatio[2] = mCoreRatioFinal[2];
}
if ((CpuSetup->RatioLimitRatio[2] > CORE_RATIO_NON_EXT_MODE_LIMIT) &&
((CpuSetup->CoreRatioExtensionMode != 1) || (CpuSetup->OverclockingSupport != 1))){
CpuSetup->RatioLimitRatio[2] = CORE_RATIO_NON_EXT_MODE_LIMIT;
}
mCoreRatioFinal[2] = CpuSetup->RatioLimitRatio[2];
//[-start-200215-IB06462109-remove]//
// RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, RatioLimitRatio[2]), sizeof (CpuSetup->RatioLimitRatio[2]));
//[-end-200215-IB06462109-remove]//
break;
case KEY_RatioLimitRatio3:
if (CpuSetup->RatioLimitRatio[3] < RatioLimitMin) {
CpuSetup->RatioLimitRatio[3] = mCoreRatioFinal[3];
}
if ((CpuSetup->RatioLimitRatio[3] > CORE_RATIO_NON_EXT_MODE_LIMIT) &&
((CpuSetup->CoreRatioExtensionMode != 1) || (CpuSetup->OverclockingSupport != 1))){
CpuSetup->RatioLimitRatio[3] = CORE_RATIO_NON_EXT_MODE_LIMIT;
}
mCoreRatioFinal[3] = CpuSetup->RatioLimitRatio[3];
//[-start-200215-IB06462109-remove]//
// RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, RatioLimitRatio[3]), sizeof (CpuSetup->RatioLimitRatio[3]));
//[-end-200215-IB06462109-remove]//
break;
case KEY_RatioLimitRatio4:
if (CpuSetup->RatioLimitRatio[4] < RatioLimitMin) {
CpuSetup->RatioLimitRatio[4] = mCoreRatioFinal[4];
}
if ((CpuSetup->RatioLimitRatio[4] > CORE_RATIO_NON_EXT_MODE_LIMIT) &&
((CpuSetup->CoreRatioExtensionMode != 1) || (CpuSetup->OverclockingSupport != 1))){
CpuSetup->RatioLimitRatio[4] = CORE_RATIO_NON_EXT_MODE_LIMIT;
}
mCoreRatioFinal[4] = CpuSetup->RatioLimitRatio[4];
//[-start-200215-IB06462109-remove]//
// RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, RatioLimitRatio[4]), sizeof (CpuSetup->RatioLimitRatio[4]));
//[-end-200215-IB06462109-remove]//
break;
case KEY_RatioLimitRatio5:
if (CpuSetup->RatioLimitRatio[5] < RatioLimitMin) {
CpuSetup->RatioLimitRatio[5] = mCoreRatioFinal[5];
}
if ((CpuSetup->RatioLimitRatio[5] > CORE_RATIO_NON_EXT_MODE_LIMIT) &&
((CpuSetup->CoreRatioExtensionMode != 1) || (CpuSetup->OverclockingSupport != 1))){
CpuSetup->RatioLimitRatio[5] = CORE_RATIO_NON_EXT_MODE_LIMIT;
}
mCoreRatioFinal[5] = CpuSetup->RatioLimitRatio[5];
//[-start-200215-IB06462109-remove]//
// RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, RatioLimitRatio[5]), sizeof (CpuSetup->RatioLimitRatio[5]));
//[-end-200215-IB06462109-remove]//
break;
case KEY_RatioLimitRatio6:
if (CpuSetup->RatioLimitRatio[6] < RatioLimitMin) {
CpuSetup->RatioLimitRatio[6] = mCoreRatioFinal[6];
}
if ((CpuSetup->RatioLimitRatio[6] > CORE_RATIO_NON_EXT_MODE_LIMIT) &&
((CpuSetup->CoreRatioExtensionMode != 1) || (CpuSetup->OverclockingSupport != 1))){
CpuSetup->RatioLimitRatio[6] = CORE_RATIO_NON_EXT_MODE_LIMIT;
}
mCoreRatioFinal[6] = CpuSetup->RatioLimitRatio[6];
//[-start-200215-IB06462109-remove]//
// RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, RatioLimitRatio[6]), sizeof (CpuSetup->RatioLimitRatio[6]));
//[-end-200215-IB06462109-remove]//
break;
case KEY_RatioLimitRatio7:
if (CpuSetup->RatioLimitRatio[7] < RatioLimitMin) {
CpuSetup->RatioLimitRatio[7] = mCoreRatioFinal[7];
}
if ((CpuSetup->RatioLimitRatio[7] > CORE_RATIO_NON_EXT_MODE_LIMIT) &&
((CpuSetup->CoreRatioExtensionMode != 1) || (CpuSetup->OverclockingSupport != 1))){
CpuSetup->RatioLimitRatio[7] = CORE_RATIO_NON_EXT_MODE_LIMIT;
}
mCoreRatioFinal[7] = CpuSetup->RatioLimitRatio[7];
//[-start-200215-IB06462109-remove]//
// RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, RatioLimitRatio[7]), sizeof (CpuSetup->RatioLimitRatio[7]));
//[-end-200215-IB06462109-remove]//
break;
default:
break;
}
//[-start-200215-IB06462109-add]//
#if 0
//[-end-200215-IB06462109-add]//
if (RequestString != NULL) {
VarSize = sizeof (CPU_SETUP);
if (!HiiSetBrowserData (&gCpuSetupVariableGuid, L"CpuSetup", VarSize, (UINT8 *) CpuSetup, RequestString)) {
Status = EFI_NOT_FOUND;
}
ASSERT_EFI_ERROR (Status);
FreePool (RequestString);
}
//[-start-200215-IB06462109-add]//
#else
CopyMem (MyCpuIfrNVData, CpuSetup, VarSize);
#endif
//[-end-200215-IB06462109-add]//
FreePool (CpuSetup);
return EFI_SUCCESS;
}
/**
Initial CPU MNTR default in SETUP variable and VFR.
@retval EFI_SUCCESS The initialization is done.
@retval EFI_NOT_FOUND Failed to initial CPU MNTR.
**/
EFI_STATUS
EFIAPI
InitCpuMntrDefault (
VOID
)
{
EFI_STATUS Status;
UINTN VariableSize;
UINT32 Attributes;
UINT8 MaxBusRatio;
UINT8 MinBusRatio;
MaxBusRatio = 0;
MinBusRatio = 0;
VariableSize = sizeof (CPU_SETUP);
Status = gRT->GetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
&Attributes,
&VariableSize,
&mCpuSetup
);
if (EFI_ERROR (Status)) {
return Status;
}
GetBusRatio (&MaxBusRatio, &MinBusRatio);
if (mCpuSetup.CpuRatioOverride == 0) {
mCpuSetup.CpuDefaultRatio = MaxBusRatio;
}
mCpuSetup.CpuRatio = MaxBusRatio;
Status = gRT->SetVariable (
L"CpuSetup",
&gCpuSetupVariableGuid,
Attributes,
VariableSize,
&mCpuSetup
);
Status = InitCpuMntrDefaultVfr (mCpuSetup.CpuDefaultRatio);
return EFI_SUCCESS;
}
/**
Update the min, max, and default values for CpuRatio.
@param[in] CpuRatioDefault The CPU MNTR default.
@retval EFI_SUCCESS Values updated successfully.
@retval EFI_NOT_FOUND Failed to update it.
**/
EFI_STATUS
InitCpuMntrDefaultVfr (
UINT8 CpuRatioDefault
)
{
EFI_HII_PACKAGE_HEADER *PackageHdr;
CHAR8 *BytePtr;
EFI_IFR_OP_HEADER *ParentIfr;
EFI_IFR_GUID_LABEL *LabelPtr;
EFI_IFR_DEFAULT *DefaultPtr;
UINTN PackageSize;
EFI_IFR_NUMERIC *NumericPtr;
//
// add Array Length (UINT32) to point to package header.
//
PackageHdr = (EFI_HII_PACKAGE_HEADER *) (AdvancedBin + sizeof (UINT32));
PackageSize = PackageHdr->Length;
PackageSize = PackageSize & 0x00ffffff;
BytePtr = (CHAR8 *) (PackageHdr + 1);
//
// loop to find CPU RATIO label.
//
while (TRUE) {
if (BytePtr >= (CHAR8 *) PackageHdr + PackageSize) {
DEBUG ((DEBUG_ERROR, "Couldn't find the target node to patch.\n"));
return EFI_NOT_FOUND;
}
ParentIfr = (EFI_IFR_OP_HEADER *) BytePtr;
if (ParentIfr->OpCode == EFI_IFR_GUID_OP) {
LabelPtr = (EFI_IFR_GUID_LABEL *) ParentIfr;
if (CompareGuid ((EFI_GUID *) (VOID *) &LabelPtr->Guid, &gEfiIfrTianoGuid) && (LabelPtr->Number == LABEL_CPU_RATIO)) {
BytePtr += sizeof (EFI_IFR_GUID_LABEL);
break;
}
}
BytePtr += ParentIfr->Length;
}
//
// loop to find CPU ratio numeric OP code.
//
while (TRUE) {
if (BytePtr >= (CHAR8 *) PackageHdr + PackageSize) {
DEBUG ((DEBUG_ERROR, "Couldn't find the target node to patch.\n"));
return EFI_NOT_FOUND;
}
ParentIfr = (EFI_IFR_OP_HEADER *) BytePtr;
if (ParentIfr->OpCode == EFI_IFR_NUMERIC_OP) {
NumericPtr = (EFI_IFR_NUMERIC *) ParentIfr;
NumericPtr->data.u8.MinValue = GetMaxEfficiencyRatio ();
NumericPtr->data.u8.MaxValue = CpuRatioDefault;
break;
}
BytePtr += ParentIfr->Length;
}
//
// advance to numeric default OP code.
//
while (TRUE) {
if (BytePtr >= (CHAR8 *) PackageHdr + PackageSize) {
DEBUG ((DEBUG_ERROR, "Couldn't find the target node to patch.\n"));
return EFI_NOT_FOUND;
}
ParentIfr = (EFI_IFR_OP_HEADER *) BytePtr;
if (ParentIfr->OpCode == EFI_IFR_DEFAULT_OP) {
DefaultPtr = (EFI_IFR_DEFAULT *) ParentIfr;
break;
}
BytePtr += ParentIfr->Length;
}
//
// Now the Default value is found. Patch it!
//
DefaultPtr->Value.u8 = CpuRatioDefault;
return EFI_SUCCESS;
}
/**
This function resets the dynamic VR data when the VrPowerDelivery is updated
@param[in] EFI_FORM_CALLBACK_PROTOCOL *This
@param[in] UINT16 KeyValue
@param[in] EFI_IFR_DATA_ARRAY *Data,
@param[in] EFI_HII_CALLBACK_PACKET **Packet
@retval EFI_SUCCESS Call Back Function executed successfully
**/
EFI_STATUS
EFIAPI
CpuVrConfigCallBackFunction (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID KeyValue,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
CPU_SETUP CpuSetup;
UINTN VarSize;
UINT32 Index;
EFI_STATUS Status;
EFI_STRING RequestString;
Status = EFI_SUCCESS;
RequestString = NULL;
if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
return EFI_UNSUPPORTED;
}
VarSize = sizeof (CPU_SETUP);
// GetBrowserData by VarStore Name (Setup)
if (!HiiGetBrowserData (&gCpuSetupVariableGuid, L"CpuSetup", VarSize, (UINT8 *) &CpuSetup)) {
Status = EFI_NOT_FOUND;
}
ASSERT_EFI_ERROR (Status);
switch (KeyValue) {
case KEY_VrPowerDeliveryChange:
//
// If VrPowerDeliveryDesign Changed, we must revert any dynamic VR initialization
// Dynamic settings are VR settings which are part of the VR override table
//
for (Index = 0; Index < MAX_VR_NUM; Index++) {
//
// Set loadline to AUTO
//
CpuSetup.AcLoadline[Index] = 0;
RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, AcLoadline[Index]), sizeof (CpuSetup.AcLoadline[Index]));
VarSize = sizeof (CPU_SETUP);
if (!HiiSetBrowserData (&gCpuSetupVariableGuid, L"CpuSetup", VarSize, (UINT8 *) &CpuSetup, RequestString)) {
Status = EFI_NOT_FOUND;
}
ASSERT_EFI_ERROR (Status);
CpuSetup.DcLoadline[Index] = 0;
RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, DcLoadline[Index]), sizeof (CpuSetup.DcLoadline[Index]));
if (!HiiSetBrowserData (&gCpuSetupVariableGuid, L"CpuSetup", VarSize, (UINT8 *) &CpuSetup, RequestString)) {
Status = EFI_NOT_FOUND;
}
ASSERT_EFI_ERROR (Status);
//
// Set IccMax to AUTO
//
CpuSetup.IccMax[Index] = 0;
RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, IccMax[Index]), sizeof (CpuSetup.IccMax[Index]));
if (!HiiSetBrowserData (&gCpuSetupVariableGuid, L"CpuSetup", VarSize, (UINT8 *) &CpuSetup, RequestString)) {
Status = EFI_NOT_FOUND;
}
ASSERT_EFI_ERROR (Status);
//
// Set VR TDC to AUTO
//
CpuSetup.TdcCurrentLimit[Index] = 0;
RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, TdcCurrentLimit[Index]), sizeof (CpuSetup.TdcCurrentLimit[Index]));
if (!HiiSetBrowserData (&gCpuSetupVariableGuid, L"CpuSetup", VarSize, (UINT8 *) &CpuSetup, RequestString)) {
Status = EFI_NOT_FOUND;
}
ASSERT_EFI_ERROR (Status);
//
// Set VR Voltage Limit to AUTO
//
CpuSetup.VrVoltageLimit[Index] = 0;
RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (CPU_SETUP, VrVoltageLimit[Index]), sizeof (CpuSetup.VrVoltageLimit[Index]));
if (!HiiSetBrowserData (&gCpuSetupVariableGuid, L"CpuSetup", VarSize, (UINT8 *) &CpuSetup, RequestString)) {
Status = EFI_NOT_FOUND;
}
ASSERT_EFI_ERROR (Status);
}
break;
default:
ASSERT(FALSE);
}
if (RequestString != NULL) {
FreePool (RequestString);
}
return EFI_SUCCESS;
}