/** @file
This file is SampleCode of the library for Intel CPU PEI Policy initialization.
Copyright (c) 2020, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PeiCpuPolicyUpdate.h"
#include
#include
#include
#include
#include
/**
Check on the processor if SGX is supported.
@retval True if SGX supported or FALSE if not
**/
BOOLEAN
IsSgxCapSupported (
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 only on WHL and later,
/// 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;
}
/**
This function performs CPU PEI Policy initialization in Pre-memory.
@param[in] SiPreMemPolicyPpi The SI Pre-Mem Policy PPI instance
@retval EFI_SUCCESS The PPI is installed and initialized.
@retval EFI ERRORS The PPI is not successfully installed.
@retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
**/
EFI_STATUS
EFIAPI
UpdatePeiCpuPolicyPreMem (
IN OUT SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi
)
{
EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
CPU_CONFIG_LIB_PREMEM_CONFIG *CpuConfigLibPreMemConfig;
CPU_OVERCLOCKING_PREMEM_CONFIG *CpuOverClockingPreMemConfig;
UINT32 PchSpiBar0;
UINT32 MaxLogicProcessors;
Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuConfigLibPreMemConfigGuid, (VOID *) &CpuConfigLibPreMemConfig);
ASSERT_EFI_ERROR (Status);
Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gCpuOverclockingPreMemConfigGuid, (VOID *) &CpuOverClockingPreMemConfig);
ASSERT_EFI_ERROR (Status);
DEBUG ((DEBUG_INFO, "UpdatePeiCpuPolicyPreMem Start\n"));
//
// Get current boot mode
//
Status = PeiServicesGetBootMode (&BootMode);
ASSERT_EFI_ERROR (Status);
SpiServiceInit ();
PchSpiBar0 = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (
DEFAULT_PCI_SEGMENT_NUMBER_PCH,
DEFAULT_PCI_BUS_NUMBER_PCH,
PCI_DEVICE_NUMBER_PCH_SPI,
PCI_FUNCTION_NUMBER_PCH_SPI,
R_SPI_CFG_BAR0
));
PchSpiBar0 &= ~(B_SPI_CFG_BAR0_MASK);
if (PchSpiBar0 == 0) {
DEBUG ((DEBUG_ERROR, "ERROR : PchSpiBar0 is invalid!\n"));
ASSERT (FALSE);
}
CpuConfigLibPreMemConfig->PeciC10Reset = 0;
CpuConfigLibPreMemConfig->CpuRatio = 0;
///
/// Set PcdCpuMaxLogicalProcessorNumber to max number of logical processors enabled
/// Read MSR_CORE_THREAD_COUNT (0x35) to check the total active Threads
///
MaxLogicProcessors = (UINT32) (AsmReadMsr64 (MSR_CORE_THREAD_COUNT) & B_THREAD_COUNT_MASK);
DEBUG ((DEBUG_INFO, "MaxLogicProcessors = %d\n", MaxLogicProcessors));
PcdSet32S (PcdCpuMaxLogicalProcessorNumber, MaxLogicProcessors);
return EFI_SUCCESS;
}