diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuCommonFeaturesLib/MachineCheck.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuCommonFeaturesLib/MachineCheck.c | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuCommonFeaturesLib/MachineCheck.c b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuCommonFeaturesLib/MachineCheck.c new file mode 100644 index 00000000..59e213ce --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuCommonFeaturesLib/MachineCheck.c @@ -0,0 +1,344 @@ +/** @file + Machine Check features. + + Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "CpuCommonFeatures.h" + +/** + Detects if Machine Check Exception 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 Machine Check Exception feature is supported. + @retval FALSE Machine Check Exception feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +MceSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + return (CpuInfo->CpuIdVersionInfoEdx.Bits.MCE == 1); +} + +/** + Initializes Machine Check Exception 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 Machine Check Exception feature must be enabled. + If FALSE, then the Machine Check Exception feature must be disabled. + + @retval RETURN_SUCCESS Machine Check Exception feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +MceInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // Set MCE bit in CR4 + // + CPU_REGISTER_TABLE_WRITE_FIELD ( + ProcessorNumber, + ControlRegister, + 4, + IA32_CR4, + Bits.MCE, + (State) ? 1 : 0 + ); + return RETURN_SUCCESS; +} + +/** + Detects if Machine Check Architecture 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 Machine Check Architecture feature is supported. + @retval FALSE Machine Check Architecture feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +McaSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + if (!MceSupport (ProcessorNumber, CpuInfo, ConfigData)) { + return FALSE; + } + return (CpuInfo->CpuIdVersionInfoEdx.Bits.MCA == 1); +} + +/** + Initializes Machine Check Architecture 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 Machine Check Architecture feature must be enabled. + If FALSE, then the Machine Check Architecture feature must be disabled. + + @retval RETURN_SUCCESS Machine Check Architecture feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +McaInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + MSR_IA32_MCG_CAP_REGISTER McgCap; + UINT32 BankIndex; + + // + // The scope of MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS is core for below processor type, only program + // MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS for thread 0 in each core. + // + if (IS_ATOM_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_SANDY_BRIDGE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_SKYLAKE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_XEON_PHI_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_PENTIUM_4_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_CORE_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + // + // The scope of MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS is package for below processor type, only program + // MSR_IA32_MC*_CTL/MSR_IA32_MC*_STATUS for thread 0 core 0 in each package. + // + if (IS_NEHALEM_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if ((CpuInfo->ProcessorInfo.Location.Thread != 0) || (CpuInfo->ProcessorInfo.Location.Core != 0)) { + return RETURN_SUCCESS; + } + } + + if (State) { + McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP); + for (BankIndex = 0; BankIndex < (UINT32) McgCap.Bits.Count; BankIndex++) { + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_MC0_CTL + BankIndex * 4, + MAX_UINT64 + ); + } + + if (PcdGetBool (PcdIsPowerOnReset)) { + for (BankIndex = 0; BankIndex < (UINTN) McgCap.Bits.Count; BankIndex++) { + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_MC0_STATUS + BankIndex * 4, + 0 + ); + } + } + } + + return RETURN_SUCCESS; +} + +/** + Detects if IA32_MCG_CTL 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 IA32_MCG_CTL feature is supported. + @retval FALSE IA32_MCG_CTL feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +McgCtlSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + MSR_IA32_MCG_CAP_REGISTER McgCap; + + if (!McaSupport (ProcessorNumber, CpuInfo, ConfigData)) { + return FALSE; + } + McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP); + return (McgCap.Bits.MCG_CTL_P == 1); +} + +/** + Initializes IA32_MCG_CTL 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 IA32_MCG_CTL feature must be enabled. + If FALSE, then the IA32_MCG_CTL feature must be disabled. + + @retval RETURN_SUCCESS IA32_MCG_CTL feature is initialized. + + @note This service could be called by BSP only. +**/ +RETURN_STATUS +EFIAPI +McgCtlInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + CPU_REGISTER_TABLE_WRITE64 ( + ProcessorNumber, + Msr, + MSR_IA32_MCG_CTL, + (State)? MAX_UINT64 : 0 + ); + return RETURN_SUCCESS; +} + +/** + Detects if Local machine check exception 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 Local machine check exception feature is supported. + @retval FALSE Local machine check exception feature is not supported. + + @note This service could be called by BSP/APs. +**/ +BOOLEAN +EFIAPI +LmceSupport ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData OPTIONAL + ) +{ + MSR_IA32_MCG_CAP_REGISTER McgCap; + + if (!McaSupport (ProcessorNumber, CpuInfo, ConfigData)) { + return FALSE; + } + + McgCap.Uint64 = AsmReadMsr64 (MSR_IA32_MCG_CAP); + if (ProcessorNumber == 0) { + DEBUG ((DEBUG_INFO, "LMCE enable = %x\n", (BOOLEAN) (McgCap.Bits.MCG_LMCE_P != 0))); + } + return (BOOLEAN) (McgCap.Bits.MCG_LMCE_P != 0); +} + +/** + Initializes Local machine check exception 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 Local machine check exception + feature must be enabled. + If FALSE, then the Local machine check exception + feature must be disabled. + + @retval RETURN_SUCCESS Local machine check exception feature is initialized. + +**/ +RETURN_STATUS +EFIAPI +LmceInitialize ( + IN UINTN ProcessorNumber, + IN REGISTER_CPU_FEATURE_INFORMATION *CpuInfo, + IN VOID *ConfigData, OPTIONAL + IN BOOLEAN State + ) +{ + // + // The scope of LcmeOn bit in the MSR_IA32_MISC_ENABLE is core for below processor type, only program + // MSR_IA32_MISC_ENABLE for thread 0 in each core. + // + if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) || + IS_PENTIUM_4_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) { + if (CpuInfo->ProcessorInfo.Location.Thread != 0) { + return RETURN_SUCCESS; + } + } + + CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD ( + ProcessorNumber, + Msr, + MSR_IA32_FEATURE_CONTROL, + MSR_IA32_FEATURE_CONTROL_REGISTER, + Bits.LmceOn, + (State) ? 1 : 0 + ); + + return RETURN_SUCCESS; +} |