cpu/intel/common: Add/Use common function to set virtualization
Migrate duplicated enable_vmx() method from multiple CPUs to common
folder. Add common virtualization option for CPUs which support it.
Note that this changes the default to enable virtualization on CPUs
that support it.
Change-Id: Ib110bed6c9f5508e3f867dcdc6f341fc50e501d1
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-on: https://review.coreboot.org/17874
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins)
diff --git a/src/cpu/intel/Kconfig b/src/cpu/intel/Kconfig
index 5df8002..138da8c 100644
--- a/src/cpu/intel/Kconfig
+++ b/src/cpu/intel/Kconfig
@@ -45,3 +45,4 @@
# 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 0000000..739333e
--- /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 0000000..1e94ec9
--- /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 0000000..0d0b954
--- /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 0000000..da7b826
--- /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 030c863..8782448 100644
--- a/src/cpu/intel/fsp_model_206ax/Kconfig
+++ b/src/cpu/intel/fsp_model_206ax/Kconfig
@@ -37,6 +37,7 @@
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 @@
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 d2d61ef..65498f8 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 6789bae..1b3004c 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 @@
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 edf18f5..4c79b23 100644
--- a/src/cpu/intel/fsp_model_406dx/Kconfig
+++ b/src/cpu/intel/fsp_model_406dx/Kconfig
@@ -32,6 +32,7 @@
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 @@
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 3e29348..d82ddd6 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 ef48c03..11f5286 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 @@
/* 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 ec75391..d6df9c0 100644
--- a/src/cpu/intel/haswell/Kconfig
+++ b/src/cpu/intel/haswell/Kconfig
@@ -26,6 +26,7 @@
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 @@
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 d54a25c..bb0f376 100644
--- a/src/cpu/intel/haswell/Makefile.inc
+++ b/src/cpu/intel/haswell/Makefile.inc
@@ -23,6 +23,7 @@
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 2fac879..0b243ad 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 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 @@
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 12f04cc..2e154a3 100644
--- a/src/cpu/intel/model_1067x/Kconfig
+++ b/src/cpu/intel/model_1067x/Kconfig
@@ -9,3 +9,4 @@
# 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 3e0af86..3e6cb2c 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 e28a331..e0f74b2 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 @@
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 @@
/* 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 a005ba2..f365cf1 100644
--- a/src/cpu/intel/model_106cx/Kconfig
+++ b/src/cpu/intel/model_106cx/Kconfig
@@ -12,6 +12,7 @@
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 720052d..cd753db 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 7f4a9ab..3b9cbdb 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 @@
/* 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 f6d812f..59bb8d8 100644
--- a/src/cpu/intel/model_2065x/Kconfig
+++ b/src/cpu/intel/model_2065x/Kconfig
@@ -19,6 +19,7 @@
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 @@
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 cdf9fed..137d1c9 100644
--- a/src/cpu/intel/model_2065x/Makefile.inc
+++ b/src/cpu/intel/model_2065x/Makefile.inc
@@ -8,6 +8,7 @@
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 7987f8e..9bc9df1 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 @@
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 @@
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 b954b79..6c04fba 100644
--- a/src/cpu/intel/model_206ax/Kconfig
+++ b/src/cpu/intel/model_206ax/Kconfig
@@ -20,6 +20,7 @@
#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 @@
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 25f0742..b79ccd7 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 e7bfd9e..af712d0 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 @@
{ 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 @@
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 08a5775..10ebcc7 100644
--- a/src/cpu/intel/model_6ex/Kconfig
+++ b/src/cpu/intel/model_6ex/Kconfig
@@ -10,3 +10,4 @@
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 69d5c1b..4321f2a 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 d42ff69..cc1260e 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 @@
/* 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 baae196..8f05314 100644
--- a/src/cpu/intel/model_6fx/Kconfig
+++ b/src/cpu/intel/model_6fx/Kconfig
@@ -10,3 +10,4 @@
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 ba31c7e..de6fd8d 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 67a7408..91d8d01 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 @@
/* 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();