[coreboot-gerrit] Patch set updated for coreboot: cpu/intel/common: Add/Use common function to set virtualization

Martin Roth (martinroth@google.com) gerrit at coreboot.org
Mon Dec 26 17:42:24 CET 2016


Martin Roth (martinroth at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17874

-gerrit

commit 067a4a58d6e7bc7aafe2bf81c9a22dd632ed09b3
Author: Matt DeVillier <matt.devillier at gmail.com>
Date:   Wed Dec 14 16:12:43 2016 -0600

    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 at gmail.com>
---
 src/cpu/intel/Kconfig                            |  1 +
 src/cpu/intel/common/Kconfig                     | 23 ++++++++
 src/cpu/intel/common/Makefile.inc                |  1 +
 src/cpu/intel/common/common.h                    | 20 +++++++
 src/cpu/intel/common/common_init.c               | 71 ++++++++++++++++++++++++
 src/cpu/intel/fsp_model_206ax/Kconfig            |  5 +-
 src/cpu/intel/fsp_model_206ax/Makefile.inc       |  1 +
 src/cpu/intel/fsp_model_206ax/model_206ax_init.c | 42 +-------------
 src/cpu/intel/fsp_model_406dx/Kconfig            |  5 +-
 src/cpu/intel/fsp_model_406dx/Makefile.inc       |  1 +
 src/cpu/intel/fsp_model_406dx/model_406dx_init.c | 42 +-------------
 src/cpu/intel/haswell/Kconfig                    |  5 +-
 src/cpu/intel/haswell/Makefile.inc               |  1 +
 src/cpu/intel/haswell/haswell_init.c             | 46 +--------------
 src/cpu/intel/model_1067x/Kconfig                |  1 +
 src/cpu/intel/model_1067x/Makefile.inc           |  1 +
 src/cpu/intel/model_1067x/model_1067x_init.c     | 38 +------------
 src/cpu/intel/model_106cx/Kconfig                |  1 +
 src/cpu/intel/model_106cx/Makefile.inc           |  1 +
 src/cpu/intel/model_106cx/model_106cx_init.c     | 37 +-----------
 src/cpu/intel/model_2065x/Kconfig                |  5 +-
 src/cpu/intel/model_2065x/Makefile.inc           |  1 +
 src/cpu/intel/model_2065x/model_2065x_init.c     | 55 +-----------------
 src/cpu/intel/model_206ax/Kconfig                |  5 +-
 src/cpu/intel/model_206ax/Makefile.inc           |  1 +
 src/cpu/intel/model_206ax/model_206ax_init.c     | 55 +-----------------
 src/cpu/intel/model_6ex/Kconfig                  |  1 +
 src/cpu/intel/model_6ex/Makefile.inc             |  1 +
 src/cpu/intel/model_6ex/model_6ex_init.c         | 38 +------------
 src/cpu/intel/model_6fx/Kconfig                  |  1 +
 src/cpu/intel/model_6fx/Makefile.inc             |  1 +
 src/cpu/intel/model_6fx/model_6fx_init.c         | 37 +-----------
 src/soc/intel/broadwell/Kconfig                  |  2 +-
 src/soc/intel/broadwell/Makefile.inc             |  1 +
 src/soc/intel/broadwell/cpu.c                    |  4 ++
 35 files changed, 167 insertions(+), 384 deletions(-)

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 @@ 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 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 @@ 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 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 @@ 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 edf18f5..4c79b23 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 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 @@ 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 ec75391..d6df9c0 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 d54a25c..bb0f376 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 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 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 12f04cc..2e154a3 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 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 @@ 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 a005ba2..f365cf1 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 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 @@ 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 f6d812f..59bb8d8 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 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/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 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 @@ 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 b954b79..6c04fba 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 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 @@ 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 08a5775..10ebcc7 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 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 @@ 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 baae196..8f05314 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 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 @@ 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();
diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig
index 75cd831..01bcaf1 100644
--- a/src/soc/intel/broadwell/Kconfig
+++ b/src/soc/intel/broadwell/Kconfig
@@ -44,6 +44,7 @@ config CPU_SPECIFIC_OPTIONS
 	select HAVE_INTEL_FIRMWARE
 	select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE
 	select HAVE_SPI_CONSOLE_SUPPORT
+	select CPU_INTEL_COMMON
 
 config BOOTBLOCK_CPU_INIT
 	string
@@ -57,7 +58,6 @@ config BOOTBLOCK_SOUTHBRIDGE_INIT
 	string
 	default "soc/intel/broadwell/bootblock/pch.c"
 
-
 config MMCONF_BASE_ADDRESS
 	hex
 	default 0xf0000000
diff --git a/src/soc/intel/broadwell/Makefile.inc b/src/soc/intel/broadwell/Makefile.inc
index 4da8c20..c4f4538 100644
--- a/src/soc/intel/broadwell/Makefile.inc
+++ b/src/soc/intel/broadwell/Makefile.inc
@@ -7,6 +7,7 @@ subdirs-y += ../../../cpu/x86/smm
 subdirs-y += ../../../cpu/x86/tsc
 subdirs-y += ../../../cpu/intel/microcode
 subdirs-y += ../../../cpu/intel/turbo
+subdirs-y += ../../../cpu/intel/common
 
 ramstage-y += acpi.c
 ramstage-y += adsp.c
diff --git a/src/soc/intel/broadwell/cpu.c b/src/soc/intel/broadwell/cpu.c
index 16f350c..09fe5ac 100644
--- a/src/soc/intel/broadwell/cpu.c
+++ b/src/soc/intel/broadwell/cpu.c
@@ -40,6 +40,7 @@
 #include <soc/smm.h>
 #include <soc/systemagent.h>
 #include <soc/intel/broadwell/chip.h>
+#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[] = {
@@ -580,6 +581,9 @@ static void cpu_core_init(device_t cpu)
 	enable_lapic_tpr();
 	setup_lapic();
 
+	/* Set virtualization based on Kconfig option */
+	set_vmx();
+
 	/* Configure C States */
 	configure_c_states();
 



More information about the coreboot-gerrit mailing list