diff options
Diffstat (limited to 'src/cpu/intel')
32 files changed, 161 insertions, 383 deletions
diff --git a/src/cpu/intel/Kconfig b/src/cpu/intel/Kconfig index 5df8002715..138da8c1dd 100644 --- a/src/cpu/intel/Kconfig +++ b/src/cpu/intel/Kconfig @@ -45,3 +45,4 @@ source src/cpu/intel/socket_rPGA989/Kconfig # Architecture specific features source src/cpu/intel/fit/Kconfig source src/cpu/intel/turbo/Kconfig +source src/cpu/intel/common/Kconfig diff --git a/src/cpu/intel/common/Kconfig b/src/cpu/intel/common/Kconfig new file mode 100644 index 0000000000..739333e4aa --- /dev/null +++ b/src/cpu/intel/common/Kconfig @@ -0,0 +1,23 @@ +config CPU_INTEL_COMMON + bool + +if CPU_INTEL_COMMON + +config ENABLE_VMX + bool "Enable VMX for virtualization" + default y + +config SET_VMX_LOCK_BIT + bool "Set lock bit after configuring VMX" + depends on ENABLE_VMX + default y + help + Although the Intel manual says you must set the lock bit in addition + to the VMX bit in order for VMX to work, this isn't strictly true, so + we have the option to leave it unlocked and allow the OS (e.g. Linux) + to manage things itself. This is beneficial for testing purposes as + there is no need to reflash the firmware just to toggle the lock bit. + However, leaving the lock bit unset will break Windows' detection of + VMX support and built-in virtualization features like Hyper-V. + +endif diff --git a/src/cpu/intel/common/Makefile.inc b/src/cpu/intel/common/Makefile.inc new file mode 100644 index 0000000000..1e94ec92e4 --- /dev/null +++ b/src/cpu/intel/common/Makefile.inc @@ -0,0 +1 @@ +ramstage-y += common_init.c diff --git a/src/cpu/intel/common/common.h b/src/cpu/intel/common/common.h new file mode 100644 index 0000000000..0d0b954886 --- /dev/null +++ b/src/cpu/intel/common/common.h @@ -0,0 +1,20 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CPU_INTEL_COMMON_H +#define _CPU_INTEL_COMMON_H + +void set_vmx(void); + +#endif diff --git a/src/cpu/intel/common/common_init.c b/src/cpu/intel/common/common_init.c new file mode 100644 index 0000000000..da7b82651f --- /dev/null +++ b/src/cpu/intel/common/common_init.c @@ -0,0 +1,71 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <cpu/x86/msr.h> +#include "common.h" + +#define IA32_FEATURE_CONTROL 0x3a +#define CPUID_VMX (1 << 5) +#define CPUID_SMX (1 << 6) + +void set_vmx(void) +{ + struct cpuid_result regs; + msr_t msr; + int enable = IS_ENABLED(CONFIG_ENABLE_VMX); + int lock = IS_ENABLED(CONFIG_SET_VMX_LOCK_BIT); + + regs = cpuid(1); + /* Check that the VMX is supported before reading or writing the MSR. */ + if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX))) { + printk(BIOS_DEBUG, "CPU doesn't support VMX; exiting\n"); + return; + } + + msr = rdmsr(IA32_FEATURE_CONTROL); + + if (msr.lo & (1 << 0)) { + printk(BIOS_ERR, "VMX is locked, so %s will do nothing\n", __func__); + /* VMX locked. If we set it again we get an illegal + * instruction + */ + return; + } + + /* The IA32_FEATURE_CONTROL MSR may initialize with random values. + * It must be cleared regardless of VMX config setting. + */ + msr.hi = msr.lo = 0; + + if (enable) { + msr.lo |= (1 << 2); + if (regs.ecx & CPUID_SMX) + msr.lo |= (1 << 1); + } + + wrmsr(IA32_FEATURE_CONTROL, msr); + + if (lock) { + /* Set lock bit */ + msr.lo |= (1 << 0); + wrmsr(IA32_FEATURE_CONTROL, msr); + } + + printk(BIOS_DEBUG, "VMX status: %s, %s\n", enable ? "enabled" : "disabled", + lock ? "locked" : "unlocked"); +} diff --git a/src/cpu/intel/fsp_model_206ax/Kconfig b/src/cpu/intel/fsp_model_206ax/Kconfig index 030c863e4b..878244861c 100644 --- a/src/cpu/intel/fsp_model_206ax/Kconfig +++ b/src/cpu/intel/fsp_model_206ax/Kconfig @@ -37,6 +37,7 @@ config CPU_SPECIFIC_OPTIONS select PARALLEL_CPU_INIT select TSC_SYNC_MFENCE select LAPIC_MONOTONIC_TIMER + select CPU_INTEL_COMMON config BOOTBLOCK_CPU_INIT string @@ -46,8 +47,4 @@ config SMM_TSEG_SIZE hex default 0x800000 -config ENABLE_VMX - bool "Enable VMX for virtualization" - default n - endif diff --git a/src/cpu/intel/fsp_model_206ax/Makefile.inc b/src/cpu/intel/fsp_model_206ax/Makefile.inc index d2d61ef883..65498f8652 100644 --- a/src/cpu/intel/fsp_model_206ax/Makefile.inc +++ b/src/cpu/intel/fsp_model_206ax/Makefile.inc @@ -1,6 +1,7 @@ ramstage-y += model_206ax_init.c subdirs-y += ../../x86/name subdirs-y += ../smm/gen1 +subdirs-y += ../common ramstage-y += acpi.c diff --git a/src/cpu/intel/fsp_model_206ax/model_206ax_init.c b/src/cpu/intel/fsp_model_206ax/model_206ax_init.c index 6789baedcf..1b3004c135 100644 --- a/src/cpu/intel/fsp_model_206ax/model_206ax_init.c +++ b/src/cpu/intel/fsp_model_206ax/model_206ax_init.c @@ -32,43 +32,7 @@ #include "model_206ax.h" #include "chip.h" #include <cpu/intel/smm/gen1/smi.h> - -static void enable_vmx(void) -{ - struct cpuid_result regs; - msr_t msr; - int enable = IS_ENABLED(CONFIG_ENABLE_VMX); - - regs = cpuid(1); - /* Check that the VMX is supported before reading or writing the MSR. */ - if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX))) - return; - - msr = rdmsr(IA32_FEATURE_CONTROL); - - if (msr.lo & (1 << 0)) { - printk(BIOS_ERR, "VMX is locked, so %s will do nothing\n", __func__); - /* VMX locked. If we set it again we get an illegal - * instruction - */ - return; - } - - /* The IA32_FEATURE_CONTROL MSR may initialize with random values. - * It must be cleared regardless of VMX config setting. - */ - msr.hi = msr.lo = 0; - - printk(BIOS_DEBUG, "%s VMX\n", enable ? "Enabling" : "Disabling"); - - if (enable) { - msr.lo |= (1 << 2); - if (regs.ecx & CPUID_SMX) - msr.lo |= (1 << 1); - } - - wrmsr(IA32_FEATURE_CONTROL, msr); -} +#include <cpu/intel/common/common.h> /* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */ static const u8 power_limit_time_sec_to_msr[] = { @@ -390,8 +354,8 @@ static void model_206ax_init(struct device *cpu) enable_lapic_tpr(); setup_lapic(); - /* Enable virtualization if Kconfig option is set */ - enable_vmx(); + /* Set virtualization based on Kconfig option */ + set_vmx(); /* Configure Enhanced SpeedStep and Thermal Sensors */ configure_misc(); diff --git a/src/cpu/intel/fsp_model_406dx/Kconfig b/src/cpu/intel/fsp_model_406dx/Kconfig index edf18f5d3e..4c79b239b6 100644 --- a/src/cpu/intel/fsp_model_406dx/Kconfig +++ b/src/cpu/intel/fsp_model_406dx/Kconfig @@ -32,6 +32,7 @@ config CPU_SPECIFIC_OPTIONS select PARALLEL_CPU_INIT select TSC_SYNC_MFENCE select LAPIC_MONOTONIC_TIMER + select CPU_INTEL_COMMON # Microcode header files are delivered in FSP package select USES_MICROCODE_HEADER_FILES if HAVE_FSP_BIN @@ -52,10 +53,6 @@ config BOOTBLOCK_CPU_INIT string default "cpu/intel/fsp_model_406dx/bootblock.c" -config ENABLE_VMX - bool "Enable VMX for virtualization" - default n - #set up microcode for rangeley POSTGOLD4 release config CPU_MICROCODE_HEADER_FILES string diff --git a/src/cpu/intel/fsp_model_406dx/Makefile.inc b/src/cpu/intel/fsp_model_406dx/Makefile.inc index 3e293480c2..d82ddd6d45 100644 --- a/src/cpu/intel/fsp_model_406dx/Makefile.inc +++ b/src/cpu/intel/fsp_model_406dx/Makefile.inc @@ -15,6 +15,7 @@ ramstage-y += model_406dx_init.c subdirs-y += ../../x86/name +subdirs-y += ../common ramstage-y += acpi.c diff --git a/src/cpu/intel/fsp_model_406dx/model_406dx_init.c b/src/cpu/intel/fsp_model_406dx/model_406dx_init.c index ef48c032f4..11f5286bb0 100644 --- a/src/cpu/intel/fsp_model_406dx/model_406dx_init.c +++ b/src/cpu/intel/fsp_model_406dx/model_406dx_init.c @@ -25,46 +25,10 @@ #include <cpu/intel/microcode.h> #include <cpu/x86/cache.h> #include <cpu/x86/name.h> +#include <cpu/intel/common/common.h> #include "model_406dx.h" #include "chip.h" -static void enable_vmx(void) -{ - struct cpuid_result regs; - msr_t msr; - int enable = IS_ENABLED(CONFIG_ENABLE_VMX); - - regs = cpuid(1); - /* Check that the VMX is supported before reading or writing the MSR. */ - if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX))) - return; - - msr = rdmsr(IA32_FEATURE_CONTROL); - - if (msr.lo & (1 << 0)) { - printk(BIOS_ERR, "VMX is locked, so %s will do nothing\n", __func__); - /* VMX locked. If we set it again we get an illegal - * instruction - */ - return; - } - - /* The IA32_FEATURE_CONTROL MSR may initialize with random values. - * It must be cleared regardless of VMX config setting. - */ - msr.hi = msr.lo = 0; - - printk(BIOS_DEBUG, "%s VMX\n", enable ? "Enabling" : "Disabling"); - - if (enable) { - msr.lo |= (1 << 2); - if (regs.ecx & CPUID_SMX) - msr.lo |= (1 << 1); - } - - wrmsr(IA32_FEATURE_CONTROL, msr); -} - int cpu_config_tdp_levels(void) { msr_t platform_info; @@ -185,8 +149,8 @@ static void model_406dx_init(struct device *cpu) /* Enable the local CPU APICs */ setup_lapic(); - /* Enable virtualization */ - enable_vmx(); + /* Set virtualization based on Kconfig option */ + set_vmx(); /* Configure Enhanced SpeedStep and Thermal Sensors */ configure_misc(); diff --git a/src/cpu/intel/haswell/Kconfig b/src/cpu/intel/haswell/Kconfig index ec75391eae..d6df9c0aa8 100644 --- a/src/cpu/intel/haswell/Kconfig +++ b/src/cpu/intel/haswell/Kconfig @@ -26,6 +26,7 @@ config CPU_SPECIFIC_OPTIONS select CPU_INTEL_FIRMWARE_INTERFACE_TABLE select PARALLEL_CPU_INIT select PARALLEL_MP + select CPU_INTEL_COMMON config BOOTBLOCK_CPU_INIT string @@ -35,10 +36,6 @@ config SMM_TSEG_SIZE hex default 0x800000 -config ENABLE_VMX - bool "Enable VMX for virtualization" - default n - config IED_REGION_SIZE hex default 0x400000 diff --git a/src/cpu/intel/haswell/Makefile.inc b/src/cpu/intel/haswell/Makefile.inc index d54a25c249..bb0f376b92 100644 --- a/src/cpu/intel/haswell/Makefile.inc +++ b/src/cpu/intel/haswell/Makefile.inc @@ -23,6 +23,7 @@ subdirs-y += ../../x86/cache subdirs-y += ../../x86/smm subdirs-y += ../microcode subdirs-y += ../turbo +subdirs-y += ../common cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_306cx/microcode.bin cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_4065x/microcode.bin diff --git a/src/cpu/intel/haswell/haswell_init.c b/src/cpu/intel/haswell/haswell_init.c index 2fac8791d3..0b243ade9a 100644 --- a/src/cpu/intel/haswell/haswell_init.c +++ b/src/cpu/intel/haswell/haswell_init.c @@ -34,6 +34,7 @@ #include <pc80/mc146818rtc.h> #include <northbridge/intel/haswell/haswell.h> #include <southbridge/intel/lynxpoint/pch.h> +#include <cpu/intel/common/common.h> #include "haswell.h" #include "chip.h" @@ -145,47 +146,6 @@ static acpi_cstate_t cstate_map[NUM_C_STATES] = { }, }; -static void enable_vmx(void) -{ - struct cpuid_result regs; - msr_t msr; - int enable = IS_ENABLED(CONFIG_ENABLE_VMX); - - regs = cpuid(1); - /* Check that the VMX is supported before reading or writing the MSR. */ - if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX))) - return; - - msr = rdmsr(IA32_FEATURE_CONTROL); - - if (msr.lo & (1 << 0)) { - printk(BIOS_ERR, "VMX is locked, so %s will do nothing\n", __func__); - /* VMX locked. If we set it again we get an illegal - * instruction - */ - return; - } - - /* The IA32_FEATURE_CONTROL MSR may initialize with random values. - * It must be cleared regardless of VMX config setting. - */ - msr.hi = msr.lo = 0; - - printk(BIOS_DEBUG, "%s VMX\n", enable ? "Enabling" : "Disabling"); - - if (enable) { - msr.lo |= (1 << 2); - if (regs.ecx & CPUID_SMX) - msr.lo |= (1 << 1); - } - - wrmsr(IA32_FEATURE_CONTROL, msr); - - msr.lo |= (1 << 0); /* Set lock bit */ - - wrmsr(IA32_FEATURE_CONTROL, msr); -} - /* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */ static const u8 power_limit_time_sec_to_msr[] = { [0] = 0x00, @@ -724,8 +684,8 @@ static void haswell_init(struct device *cpu) enable_lapic_tpr(); setup_lapic(); - /* Enable virtualization if Kconfig option is set */ - enable_vmx(); + /* Set virtualization based on Kconfig option */ + set_vmx(); /* Configure C States */ configure_c_states(); diff --git a/src/cpu/intel/model_1067x/Kconfig b/src/cpu/intel/model_1067x/Kconfig index 12f04cc2a1..2e154a3b66 100644 --- a/src/cpu/intel/model_1067x/Kconfig +++ b/src/cpu/intel/model_1067x/Kconfig @@ -9,3 +9,4 @@ config CPU_INTEL_MODEL_1067X # select UDELAY_LAPIC select TSC_SYNC_MFENCE select SUPPORT_CPU_UCODE_IN_CBFS + select CPU_INTEL_COMMON diff --git a/src/cpu/intel/model_1067x/Makefile.inc b/src/cpu/intel/model_1067x/Makefile.inc index 3e0af86338..3e6cb2c24b 100644 --- a/src/cpu/intel/model_1067x/Makefile.inc +++ b/src/cpu/intel/model_1067x/Makefile.inc @@ -1,4 +1,5 @@ ramstage-y += model_1067x_init.c subdirs-y += ../../x86/name +subdirs-y += ../common cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_1067x/microcode.bin diff --git a/src/cpu/intel/model_1067x/model_1067x_init.c b/src/cpu/intel/model_1067x/model_1067x_init.c index e28a331225..e0f74b25c1 100644 --- a/src/cpu/intel/model_1067x/model_1067x_init.c +++ b/src/cpu/intel/model_1067x/model_1067x_init.c @@ -27,7 +27,7 @@ #include <cpu/intel/hyperthreading.h> #include <cpu/x86/cache.h> #include <cpu/x86/name.h> - +#include <cpu/intel/common/common.h> #include "chip.h" static void init_timer(void) @@ -42,38 +42,6 @@ static void init_timer(void) lapic_write(LAPIC_TMICT, 0xffffffff); } -#define IA32_FEATURE_CONTROL 0x003a - -#define CPUID_VMX (1 << 5) -#define CPUID_SMX (1 << 6) -static void enable_vmx(void) -{ - struct cpuid_result regs; - msr_t msr; - - msr = rdmsr(IA32_FEATURE_CONTROL); - - if (msr.lo & (1 << 0)) { - /* VMX locked. If we set it again we get an illegal - * instruction - */ - return; - } - - regs = cpuid(1); - if (regs.ecx & CPUID_VMX) { - msr.lo |= (1 << 2); - if (regs.ecx & CPUID_SMX) - msr.lo |= (1 << 1); - } - - wrmsr(IA32_FEATURE_CONTROL, msr); - - msr.lo |= (1 << 0); /* Set lock bit */ - - wrmsr(IA32_FEATURE_CONTROL, msr); -} - #define MSR_BBL_CR_CTL3 0x11e static void configure_c_states(const int quad) @@ -328,8 +296,8 @@ static void model_1067x_init(struct device *cpu) /* Initialize the APIC timer */ init_timer(); - /* Enable virtualization */ - enable_vmx(); + /* Set virtualization based on Kconfig option */ + set_vmx(); /* Configure C States */ configure_c_states(quad); diff --git a/src/cpu/intel/model_106cx/Kconfig b/src/cpu/intel/model_106cx/Kconfig index a005ba21da..f365cf179e 100644 --- a/src/cpu/intel/model_106cx/Kconfig +++ b/src/cpu/intel/model_106cx/Kconfig @@ -12,6 +12,7 @@ config CPU_INTEL_MODEL_106CX select TSC_SYNC_MFENCE select SUPPORT_CPU_UCODE_IN_CBFS select SERIALIZED_SMM_INITIALIZATION + select CPU_INTEL_COMMON if CPU_INTEL_MODEL_106CX diff --git a/src/cpu/intel/model_106cx/Makefile.inc b/src/cpu/intel/model_106cx/Makefile.inc index 720052d2b5..cd753db0e4 100644 --- a/src/cpu/intel/model_106cx/Makefile.inc +++ b/src/cpu/intel/model_106cx/Makefile.inc @@ -1,4 +1,5 @@ ramstage-y += model_106cx_init.c subdirs-y += ../../x86/name +subdirs-y += ../common cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_106cx/microcode.bin diff --git a/src/cpu/intel/model_106cx/model_106cx_init.c b/src/cpu/intel/model_106cx/model_106cx_init.c index 7f4a9abda5..3b9cbdb622 100644 --- a/src/cpu/intel/model_106cx/model_106cx_init.c +++ b/src/cpu/intel/model_106cx/model_106cx_init.c @@ -25,38 +25,7 @@ #include <cpu/intel/hyperthreading.h> #include <cpu/x86/cache.h> #include <cpu/x86/name.h> - -#define IA32_FEATURE_CONTROL 0x003a - -#define CPUID_VMX (1 << 5) -#define CPUID_SMX (1 << 6) -static void enable_vmx(void) -{ - struct cpuid_result regs; - msr_t msr; - - msr = rdmsr(IA32_FEATURE_CONTROL); - - if (msr.lo & (1 << 0)) { - /* VMX locked. If we set it again we get an illegal - * instruction - */ - return; - } - - regs = cpuid(1); - if (regs.ecx & CPUID_VMX) { - msr.lo |= (1 << 2); - if (regs.ecx & CPUID_SMX) - msr.lo |= (1 << 1); - } - - wrmsr(IA32_FEATURE_CONTROL, msr); - - msr.lo |= (1 << 0); /* Set lock bit */ - - wrmsr(IA32_FEATURE_CONTROL, msr); -} +#include <cpu/intel/common/common.h> #define HIGHEST_CLEVEL 3 static void configure_c_states(void) @@ -127,8 +96,8 @@ static void model_106cx_init(struct device *cpu) /* Enable the local CPU APICs */ setup_lapic(); - /* Enable virtualization */ - enable_vmx(); + /* Set virtualization based on Kconfig option */ + set_vmx(); /* Configure C States */ configure_c_states(); diff --git a/src/cpu/intel/model_2065x/Kconfig b/src/cpu/intel/model_2065x/Kconfig index f6d812fad8..59bb8d8b86 100644 --- a/src/cpu/intel/model_2065x/Kconfig +++ b/src/cpu/intel/model_2065x/Kconfig @@ -19,6 +19,7 @@ config CPU_SPECIFIC_OPTIONS select PARALLEL_CPU_INIT #select AP_IN_SIPI_WAIT select TSC_SYNC_MFENCE + select CPU_INTEL_COMMON config BOOTBLOCK_CPU_INIT string @@ -28,10 +29,6 @@ config SMM_TSEG_SIZE hex default 0x800000 -config ENABLE_VMX - bool "Enable VMX for virtualization" - default n - config XIP_ROM_SIZE hex default 0x20000 diff --git a/src/cpu/intel/model_2065x/Makefile.inc b/src/cpu/intel/model_2065x/Makefile.inc index cdf9fed3e2..137d1c94d0 100644 --- a/src/cpu/intel/model_2065x/Makefile.inc +++ b/src/cpu/intel/model_2065x/Makefile.inc @@ -8,6 +8,7 @@ subdirs-y += ../../intel/turbo subdirs-y += ../../intel/microcode subdirs-y += ../../x86/smm subdirs-y += ../smm/gen1 +subdirs-y += ../common ramstage-y += tsc_freq.c romstage-y += tsc_freq.c diff --git a/src/cpu/intel/model_2065x/model_2065x_init.c b/src/cpu/intel/model_2065x/model_2065x_init.c index 7987f8e36a..9bc9df1e99 100644 --- a/src/cpu/intel/model_2065x/model_2065x_init.c +++ b/src/cpu/intel/model_2065x/model_2065x_init.c @@ -32,6 +32,7 @@ #include "model_2065x.h" #include "chip.h" #include <cpu/intel/smm/gen1/smi.h> +#include <cpu/intel/common/common.h> /* * List of supported C-states in this processor @@ -132,56 +133,6 @@ int cpu_get_apic_id_map(int *apic_id_map) return threads_per_package; } -static void enable_vmx(void) -{ - struct cpuid_result regs; - msr_t msr; - int enable = CONFIG_ENABLE_VMX; - - regs = cpuid(1); - /* Check that the VMX is supported before reading or writing the MSR. */ - if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX))) - return; - - msr = rdmsr(IA32_FEATURE_CONTROL); - - if (msr.lo & (1 << 0)) { - printk(BIOS_ERR, "VMX is locked, so %s will do nothing\n", __func__); - /* VMX locked. If we set it again we get an illegal - * instruction - */ - return; - } - - /* The IA32_FEATURE_CONTROL MSR may initialize with random values. - * It must be cleared regardless of VMX config setting. - */ - msr.hi = msr.lo = 0; - - printk(BIOS_DEBUG, "%s VMX\n", enable ? "Enabling" : "Disabling"); - - /* Even though the Intel manual says you must set the lock bit in addition - * to the VMX bit in order for VMX to work, it is incorrect. Thus we leave - * it unlocked for the OS to manage things itself. This is good for a few - * reasons: - * - No need to reflash the bios just to toggle the lock bit. - * - The VMX bits really really should match each other across cores, so - * hard locking it on one while another has the opposite setting can - * easily lead to crashes as code using VMX migrates between them. - * - Vendors that want to "upsell" from a bios that disables+locks to - * one that doesn't is sleazy. - * By leaving this to the OS (e.g. Linux), people can do exactly what they - * want on the fly, and do it correctly (e.g. across multiple cores). - */ - if (enable) { - msr.lo |= (1 << 2); - if (regs.ecx & CPUID_SMX) - msr.lo |= (1 << 1); - } - - wrmsr(IA32_FEATURE_CONTROL, msr); -} - int cpu_config_tdp_levels(void) { @@ -383,8 +334,8 @@ static void model_2065x_init(struct device *cpu) enable_lapic_tpr(); setup_lapic(); - /* Enable virtualization if enabled in CMOS */ - enable_vmx(); + /* Set virtualization based on Kconfig option */ + set_vmx(); /* Configure Enhanced SpeedStep and Thermal Sensors */ configure_misc(); diff --git a/src/cpu/intel/model_206ax/Kconfig b/src/cpu/intel/model_206ax/Kconfig index b954b79c61..6c04fba829 100644 --- a/src/cpu/intel/model_206ax/Kconfig +++ b/src/cpu/intel/model_206ax/Kconfig @@ -20,6 +20,7 @@ config CPU_SPECIFIC_OPTIONS #select AP_IN_SIPI_WAIT select TSC_SYNC_MFENCE select LAPIC_MONOTONIC_TIMER + select CPU_INTEL_COMMON config BOOTBLOCK_CPU_INIT string @@ -33,8 +34,4 @@ config SMM_TSEG_SIZE hex default 0x800000 -config ENABLE_VMX - bool "Enable VMX for virtualization" - default n - endif diff --git a/src/cpu/intel/model_206ax/Makefile.inc b/src/cpu/intel/model_206ax/Makefile.inc index 25f07425dd..b79ccd71ff 100644 --- a/src/cpu/intel/model_206ax/Makefile.inc +++ b/src/cpu/intel/model_206ax/Makefile.inc @@ -1,6 +1,7 @@ ramstage-y += model_206ax_init.c subdirs-y += ../../x86/name subdirs-y += ../smm/gen1 +subdirs-y += ../common ramstage-y += acpi.c diff --git a/src/cpu/intel/model_206ax/model_206ax_init.c b/src/cpu/intel/model_206ax/model_206ax_init.c index e7bfd9e298..af712d0db5 100644 --- a/src/cpu/intel/model_206ax/model_206ax_init.c +++ b/src/cpu/intel/model_206ax/model_206ax_init.c @@ -32,6 +32,7 @@ #include "model_206ax.h" #include "chip.h" #include <cpu/intel/smm/gen1/smi.h> +#include <cpu/intel/common/common.h> /* * List of supported C-states in this processor @@ -110,56 +111,6 @@ static acpi_cstate_t cstate_map[] = { { 0 } }; -static void enable_vmx(void) -{ - struct cpuid_result regs; - msr_t msr; - int enable = CONFIG_ENABLE_VMX; - - regs = cpuid(1); - /* Check that the VMX is supported before reading or writing the MSR. */ - if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX))) - return; - - msr = rdmsr(IA32_FEATURE_CONTROL); - - if (msr.lo & (1 << 0)) { - printk(BIOS_ERR, "VMX is locked, so %s will do nothing\n", __func__); - /* VMX locked. If we set it again we get an illegal - * instruction - */ - return; - } - - /* The IA32_FEATURE_CONTROL MSR may initialize with random values. - * It must be cleared regardless of VMX config setting. - */ - msr.hi = msr.lo = 0; - - printk(BIOS_DEBUG, "%s VMX\n", enable ? "Enabling" : "Disabling"); - - /* Even though the Intel manual says you must set the lock bit in addition - * to the VMX bit in order for VMX to work, it is incorrect. Thus we leave - * it unlocked for the OS to manage things itself. This is good for a few - * reasons: - * - No need to reflash the bios just to toggle the lock bit. - * - The VMX bits really really should match each other across cores, so - * hard locking it on one while another has the opposite setting can - * easily lead to crashes as code using VMX migrates between them. - * - Vendors that want to "upsell" from a bios that disables+locks to - * one that doesn't is sleazy. - * By leaving this to the OS (e.g. Linux), people can do exactly what they - * want on the fly, and do it correctly (e.g. across multiple cores). - */ - if (enable) { - msr.lo |= (1 << 2); - if (regs.ecx & CPUID_SMX) - msr.lo |= (1 << 1); - } - - wrmsr(IA32_FEATURE_CONTROL, msr); -} - /* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */ static const u8 power_limit_time_sec_to_msr[] = { [0] = 0x00, @@ -576,8 +527,8 @@ static void model_206ax_init(struct device *cpu) enable_lapic_tpr(); setup_lapic(); - /* Enable virtualization if enabled in CMOS */ - enable_vmx(); + /* Set virtualization based on Kconfig option */ + set_vmx(); /* Configure C States */ configure_c_states(); diff --git a/src/cpu/intel/model_6ex/Kconfig b/src/cpu/intel/model_6ex/Kconfig index 08a5775737..10ebcc7044 100644 --- a/src/cpu/intel/model_6ex/Kconfig +++ b/src/cpu/intel/model_6ex/Kconfig @@ -10,3 +10,4 @@ config CPU_INTEL_MODEL_6EX select AP_IN_SIPI_WAIT select TSC_SYNC_MFENCE select SUPPORT_CPU_UCODE_IN_CBFS + select CPU_INTEL_COMMON diff --git a/src/cpu/intel/model_6ex/Makefile.inc b/src/cpu/intel/model_6ex/Makefile.inc index 69d5c1b83f..4321f2a5f5 100644 --- a/src/cpu/intel/model_6ex/Makefile.inc +++ b/src/cpu/intel/model_6ex/Makefile.inc @@ -1,4 +1,5 @@ ramstage-y += model_6ex_init.c subdirs-y += ../../x86/name +subdirs-y += ../common cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6ex/microcode.bin diff --git a/src/cpu/intel/model_6ex/model_6ex_init.c b/src/cpu/intel/model_6ex/model_6ex_init.c index d42ff694ee..cc1260ea81 100644 --- a/src/cpu/intel/model_6ex/model_6ex_init.c +++ b/src/cpu/intel/model_6ex/model_6ex_init.c @@ -26,39 +26,7 @@ #include <cpu/intel/speedstep.h> #include <cpu/x86/cache.h> #include <cpu/x86/name.h> - - -#define IA32_FEATURE_CONTROL 0x003a - -#define CPUID_VMX (1 << 5) -#define CPUID_SMX (1 << 6) -static void enable_vmx(void) -{ - struct cpuid_result regs; - msr_t msr; - - msr = rdmsr(IA32_FEATURE_CONTROL); - - if (msr.lo & (1 << 0)) { - /* VMX locked. If we set it again we get an illegal - * instruction - */ - return; - } - - regs = cpuid(1); - if (regs.ecx & CPUID_VMX) { - msr.lo |= (1 << 2); - if (regs.ecx & CPUID_SMX) - msr.lo |= (1 << 1); - } - - wrmsr(IA32_FEATURE_CONTROL, msr); - - msr.lo |= (1 << 0); /* Set lock bit */ - - wrmsr(IA32_FEATURE_CONTROL, msr); -} +#include <cpu/intel/common/common.h> #define HIGHEST_CLEVEL 3 static void configure_c_states(void) @@ -163,8 +131,8 @@ static void model_6ex_init(struct device *cpu) /* Enable the local CPU APICs */ setup_lapic(); - /* Enable virtualization */ - enable_vmx(); + /* Set virtualization based on Kconfig option */ + set_vmx(); /* Configure C States */ configure_c_states(); diff --git a/src/cpu/intel/model_6fx/Kconfig b/src/cpu/intel/model_6fx/Kconfig index baae196253..8f053142d4 100644 --- a/src/cpu/intel/model_6fx/Kconfig +++ b/src/cpu/intel/model_6fx/Kconfig @@ -10,3 +10,4 @@ config CPU_INTEL_MODEL_6FX select AP_IN_SIPI_WAIT select TSC_SYNC_MFENCE select SUPPORT_CPU_UCODE_IN_CBFS + select CPU_INTEL_COMMON diff --git a/src/cpu/intel/model_6fx/Makefile.inc b/src/cpu/intel/model_6fx/Makefile.inc index ba31c7ed39..de6fd8d93d 100644 --- a/src/cpu/intel/model_6fx/Makefile.inc +++ b/src/cpu/intel/model_6fx/Makefile.inc @@ -1,4 +1,5 @@ ramstage-y += model_6fx_init.c subdirs-y += ../../x86/name +subdirs-y += ../common cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_6fx/microcode.bin diff --git a/src/cpu/intel/model_6fx/model_6fx_init.c b/src/cpu/intel/model_6fx/model_6fx_init.c index 67a7408814..91d8d0192d 100644 --- a/src/cpu/intel/model_6fx/model_6fx_init.c +++ b/src/cpu/intel/model_6fx/model_6fx_init.c @@ -26,38 +26,7 @@ #include <cpu/intel/hyperthreading.h> #include <cpu/x86/cache.h> #include <cpu/x86/name.h> - -#define IA32_FEATURE_CONTROL 0x003a - -#define CPUID_VMX (1 << 5) -#define CPUID_SMX (1 << 6) -static void enable_vmx(void) -{ - struct cpuid_result regs; - msr_t msr; - - msr = rdmsr(IA32_FEATURE_CONTROL); - - if (msr.lo & (1 << 0)) { - /* VMX locked. If we set it again we get an illegal - * instruction - */ - return; - } - - regs = cpuid(1); - if (regs.ecx & CPUID_VMX) { - msr.lo |= (1 << 2); - if (regs.ecx & CPUID_SMX) - msr.lo |= (1 << 1); - } - - wrmsr(IA32_FEATURE_CONTROL, msr); - - msr.lo |= (1 << 0); /* Set lock bit */ - - wrmsr(IA32_FEATURE_CONTROL, msr); -} +#include <cpu/intel/common/common.h> #define HIGHEST_CLEVEL 3 static void configure_c_states(void) @@ -180,8 +149,8 @@ static void model_6fx_init(struct device *cpu) /* Enable the local CPU APICs */ setup_lapic(); - /* Enable virtualization */ - enable_vmx(); + /* Set virtualization based on Kconfig option */ + set_vmx(); /* Configure C States */ configure_c_states(); |