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)
This commit is contained in:
parent
2a58975264
commit
ed6fe2f64b
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
ramstage-y += common_init.c
|
|
@ -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
|
|
@ -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");
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
ramstage-y += model_406dx_init.c
|
||||
subdirs-y += ../../x86/name
|
||||
subdirs-y += ../common
|
||||
|
||||
ramstage-y += acpi.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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue