Supply real VMX capabilities together with the CPU MODEL .bochsrc option.

So now the same single option will choose not only the CPUID flags but also VMX capabilities matching real HW machine.

Removed cpuid of core2_extreme_x9770 from the cpudb. I don't remember its VMX capabilities anyway.
There is another Penryn model in the cpudb - core2_penryn_t9600.
This commit is contained in:
Stanislav Shwartsman 2011-09-26 12:31:40 +00:00
parent f7f06aebdf
commit c28c7f6a06
21 changed files with 449 additions and 1068 deletions

@ -4,10 +4,10 @@ Changes in 2.5 release (coming soon):
Brief summary :
! Fully configure CPU to emulate with a single .bochsrc option !
! Fully configurable CPU to emulate with a single .bochsrc option !
- 10% (ST) to 50% (SMP) CPU emulation speedup !
- Implemented support for x86 ISA extensions, Bochs is aligned with latest
published Intel Archicture Manual (rev 039, AVX rev 011):
- Implemented support for new x86 ISA extensions, Bochs is aligned with
latest published Intel Archicture Manual (rev 039, AVX rev 011):
- XSAVEOPT, AVX/AVX2/F16C, BMI1/BMI2, SMEP, SSE4A (AMD), INVPCID
- VMX: VMX Preemption Timer and Pause Loop Exiting VMEXIT controls
- TODO: FMA, XOP (AMD), SVM (AMD)
@ -59,7 +59,7 @@ Detailed change log :
- Implemented VMX preemption timer VMEXIT control (patch by Jianan Hao)
- Implemented Pause-Loop Exiting Secondary VMEXIT control.
- Added INVPCID instruction emulation support.
- Now you could disable x86-64 from .bochsrc so it becomes possible to
- Now you could disable x86-64 from .bochsrc so it become possible to
emulate 32-bit CPUs using Bochs binary compiled with x86-64 support.
- Updated/fixed instrumentation callbacks.
- Bugfixes for CPU emulation correctness and stability.

@ -851,6 +851,9 @@ public: // for now...
Bit64u isa_extensions_bitmask;
Bit32u cpu_extensions_bitmask;
#if BX_SUPPORT_VMX
Bit32u vmx_extensions_bitmask;
#endif
#define BX_CPUID_SUPPORT_ISA_EXTENSION(feature) \
(BX_CPU_THIS_PTR isa_extensions_bitmask & (feature))
@ -858,6 +861,9 @@ public: // for now...
#define BX_CPUID_SUPPORT_CPU_EXTENSION(feature) \
(BX_CPU_THIS_PTR cpu_extensions_bitmask & (feature))
#define BX_SUPPORT_VMX_EXTENSION(feature) \
(BX_CPU_THIS_PTR vmx_extensions_bitmask & (feature))
// General register set
// rax: accumulator
// rbx: base
@ -995,6 +1001,7 @@ public: // for now...
Bit64u vmxonptr;
VMCS_CACHE vmcs;
VMX_CAP vmx_cap;
#endif
bx_bool EXT; /* 1 if processing external interrupt or exception
@ -3985,6 +3992,7 @@ public: // for now...
BX_SMF void VMexitSaveGuestMSRs(void);
BX_SMF void VMexitLoadHostState(void);
BX_SMF void set_VMCSPTR(Bit64u vmxptr);
BX_SMF void init_vmx_capabilities();
BX_SMF void init_VMCS(void);
BX_SMF bx_bool vmcs_field_supported(Bit32u encoding);
BX_SMF void register_vmx_state(bx_param_c *parent);

@ -44,7 +44,6 @@ CPUDB_OBJS = pentium_mmx.o \
athlon64_clawhammer.o \
core_duo_t2400_yonah.o \
core2_penryn_t9600.o \
core2_extreme_x9770.o \
corei7_sandy_bridge_2600K.o \
atom_n270.o
@ -93,15 +92,6 @@ atom_n270.o: atom_n270.@CPP_SUFFIX@ ../../bochs.h ../../config.h ../../osdep.h \
../apic.h ../i387.h ../../fpu/softfloat.h ../../fpu/tag_w.h \
../../fpu/status_w.h ../../fpu/control_w.h ../xmm.h ../vmx.h \
../../param_names.h atom_n270.h
core2_extreme_x9770.o: core2_extreme_x9770.@CPP_SUFFIX@ ../../bochs.h \
../../config.h ../../osdep.h ../../bx_debug/debug.h ../../config.h \
../../osdep.h ../../gui/siminterface.h ../../cpudb.h \
../../gui/paramtree.h ../../memory/memory.h ../../pc_system.h \
../../gui/gui.h ../../instrument/stubs/instrument.h ../cpu.h ../cpuid.h \
../crregs.h ../descriptor.h ../instr.h ../ia_opcodes.h ../lazy_flags.h \
../icache.h ../apic.h ../i387.h ../../fpu/softfloat.h ../../fpu/tag_w.h \
../../fpu/status_w.h ../../fpu/control_w.h ../xmm.h ../vmx.h \
../../param_names.h core2_extreme_x9770.h ../../cpu/cpuid.h
core2_penryn_t9600.o: core2_penryn_t9600.@CPP_SUFFIX@ ../../bochs.h ../../config.h \
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \

@ -78,7 +78,7 @@ Bit64u amd_k6_2_chomper_t::get_isa_extensions_bitmask(void) const
BX_ISA_486 |
BX_ISA_PENTIUM |
BX_ISA_MMX |
BX_ISA_SYSCALL_SYSRET |
BX_ISA_SYSCALL_SYSRET_LEGACY |
BX_ISA_3DNOW;
}

@ -86,7 +86,7 @@ Bit64u athlon64_clawhammer_t::get_isa_extensions_bitmask(void) const
BX_ISA_P6 |
BX_ISA_MMX |
BX_ISA_3DNOW |
BX_ISA_SYSCALL_SYSRET |
BX_ISA_SYSCALL_SYSRET_LEGACY |
BX_ISA_SYSENTER_SYSEXIT |
BX_ISA_CLFLUSH |
BX_ISA_SSE |

@ -1,622 +0,0 @@
/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2011 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
//
/////////////////////////////////////////////////////////////////////////
#include "bochs.h"
#include "cpu.h"
#include "param_names.h"
#include "core2_extreme_x9770.h"
#define LOG_THIS cpu->
#if BX_SUPPORT_X86_64
core2_extreme_x9770_t::core2_extreme_x9770_t(BX_CPU_C *cpu): bx_cpuid_t(cpu)
{
#if BX_SUPPORT_SMP
nthreads = SIM->get_param_num(BXPN_CPU_NTHREADS)->get();
ncores = SIM->get_param_num(BXPN_CPU_NCORES)->get();
nprocessors = SIM->get_param_num(BXPN_CPU_NPROCESSORS)->get();
#endif
if (! BX_SUPPORT_X86_64)
BX_PANIC(("You must enable x86-64 for Intel Core2 X9770 configuration"));
}
void core2_extreme_x9770_t::get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpuid_function_t *leaf) const
{
static bx_bool cpuid_limit_winnt = SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->get();
if (cpuid_limit_winnt)
if (function > 2 && function < 0x80000000) function = 2;
switch(function) {
case 0x80000000:
get_ext_cpuid_leaf_0(leaf);
return;
case 0x80000001:
get_ext_cpuid_leaf_1(leaf);
return;
case 0x80000002:
case 0x80000003:
case 0x80000004:
get_ext_cpuid_brand_string_leaf(function, leaf);
return;
case 0x80000005:
get_ext_cpuid_leaf_5(leaf);
return;
case 0x80000006:
get_ext_cpuid_leaf_6(leaf);
return;
case 0x80000007:
get_ext_cpuid_leaf_7(leaf);
return;
case 0x80000008:
get_ext_cpuid_leaf_8(leaf);
return;
case 0x00000000:
get_std_cpuid_leaf_0(leaf);
return;
case 0x00000001:
get_std_cpuid_leaf_1(leaf);
return;
case 0x00000002:
get_std_cpuid_leaf_2(leaf);
return;
case 0x00000003:
get_std_cpuid_leaf_3(leaf);
return;
case 0x00000004:
get_std_cpuid_leaf_4(subfunction, leaf);
return;
case 0x00000005:
get_std_cpuid_leaf_5(leaf);
return;
case 0x00000006:
get_std_cpuid_leaf_6(leaf);
return;
case 0x00000007:
case 0x00000008:
get_reserved_leaf(leaf);
return;
case 0x00000009:
get_std_cpuid_leaf_9(leaf);
return;
case 0x0000000A:
default:
get_std_cpuid_leaf_A(leaf);
return;
}
}
Bit64u core2_extreme_x9770_t::get_isa_extensions_bitmask(void) const
{
return BX_ISA_X87 |
BX_ISA_486 |
BX_ISA_PENTIUM |
BX_ISA_P6 |
BX_ISA_MMX |
BX_ISA_SYSENTER_SYSEXIT |
BX_ISA_CLFLUSH |
BX_ISA_SSE |
BX_ISA_SSE2 |
BX_ISA_SSE3 |
BX_ISA_SSSE3 |
BX_ISA_SSE4_1 |
#if BX_SUPPORT_MONITOR_MWAIT
BX_ISA_MONITOR_MWAIT |
#endif
#if BX_SUPPORT_VMX
BX_ISA_VMX |
#endif
/* BX_ISA_SMX | */
BX_ISA_LM_LAHF_SAHF;
}
Bit32u core2_extreme_x9770_t::get_cpu_extensions_bitmask(void) const
{
return BX_CPU_DEBUG_EXTENSIONS |
BX_CPU_VME |
BX_CPU_PSE |
BX_CPU_PAE |
BX_CPU_PGE |
BX_CPU_PSE36 |
BX_CPU_MTRR |
BX_CPU_PAT |
BX_CPU_XAPIC |
BX_CPU_LONG_MODE |
BX_CPU_NX;
}
// leaf 0x00000000 //
void core2_extreme_x9770_t::get_std_cpuid_leaf_0(cpuid_function_t *leaf) const
{
static const char* vendor_string = "GenuineIntel";
// EAX: highest std function understood by CPUID
// EBX: vendor ID string
// EDX: vendor ID string
// ECX: vendor ID string
static bx_bool cpuid_limit_winnt = SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->get();
if (cpuid_limit_winnt)
leaf->eax = 0x2;
else
leaf->eax = 0xA;
// CPUID vendor string (e.g. GenuineIntel, AuthenticAMD, CentaurHauls, ...)
memcpy(&(leaf->ebx), vendor_string, 4);
memcpy(&(leaf->edx), vendor_string + 4, 4);
memcpy(&(leaf->ecx), vendor_string + 8, 4);
#ifdef BX_BIG_ENDIAN
leaf->ebx = bx_bswap32(leaf->ebx);
leaf->ecx = bx_bswap32(leaf->ecx);
leaf->edx = bx_bswap32(leaf->edx);
#endif
}
// leaf 0x00000001 //
void core2_extreme_x9770_t::get_std_cpuid_leaf_1(cpuid_function_t *leaf) const
{
// EAX: CPU Version Information
// [3:0] Stepping ID
// [7:4] Model: starts at 1
// [11:8] Family: 4=486, 5=Pentium, 6=PPro, ...
// [13:12] Type: 0=OEM, 1=overdrive, 2=dual cpu, 3=reserved
// [19:16] Extended Model
// [27:20] Extended Family
leaf->eax = 0x00010676;
// EBX:
// [7:0] Brand ID
// [15:8] CLFLUSH cache line size (value*8 = cache line size in bytes)
// [23:16] Number of logical processors in one physical processor
// [31:24] Local Apic ID
#if BX_SUPPORT_SMP
unsigned n_logical_processors = ncores*nthreads;
#else
unsigned n_logical_processors = 1;
#endif
leaf->ebx = ((CACHE_LINE_SIZE / 8) << 8) |
(n_logical_processors << 16);
#if BX_SUPPORT_APIC
leaf->ebx |= ((cpu->get_apic_id() & 0xff) << 24);
#endif
// ECX: Extended Feature Flags
// * [0:0] SSE3: SSE3 Instructions
// [1:1] PCLMULQDQ Instruction support
// * [2:2] DTES64: 64-bit DS area
// * [3:3] MONITOR/MWAIT support
// * [4:4] DS-CPL: CPL qualified debug store
// * [5:5] VMX: Virtual Machine Technology
// [6:6] SMX: Secure Virtual Machine Technology
// * [7:7] EST: Enhanced Intel SpeedStep Technology
// * [8:8] TM2: Thermal Monitor 2
// * [9:9] SSSE3: SSSE3 Instructions
// [10:10] CNXT-ID: L1 context ID
// [11:11] reserved
// [12:12] FMA Instructions support
// * [13:13] CMPXCHG16B: CMPXCHG16B instruction support
// * [14:14] xTPR update control
// * [15:15] PDCM - Perfon and Debug Capability MSR
// [16:16] reserved
// [17:17] PCID: Process Context Identifiers
// [18:18] DCA - Direct Cache Access
// * [19:19] SSE4.1 Instructions
// [20:20] SSE4.2 Instructions
// [21:21] X2APIC
// [22:22] MOVBE instruction
// [23:23] POPCNT instruction
// [24:24] TSC Deadline
// [25:25] AES Instructions
// [26:26] XSAVE extensions support
// [27:27] OSXSAVE support
// [28:28] AVX extensions support
// [29:29] AVX F16C - Float16 conversion support
// [30:30] RDRAND instruction
// [31:31] reserved
leaf->ecx = BX_CPUID_EXT_SSE3 |
BX_CPUID_EXT_DTES64 |
#if BX_SUPPORT_MONITOR_MWAIT
BX_CPUID_EXT_MONITOR_MWAIT |
#endif
BX_CPUID_EXT_DS_CPL |
#if BX_SUPPORT_VMX
BX_CPUID_EXT_VMX |
#endif
/* BX_CPUID_EXT_SMX | */
BX_CPUID_EXT_EST |
BX_CPUID_EXT_THERMAL_MONITOR2 |
BX_CPUID_EXT_SSSE3 |
BX_CPUID_EXT_CMPXCHG16B |
BX_CPUID_EXT_xTPR |
BX_CPUID_EXT_PDCM |
BX_CPUID_EXT_SSE4_1;
// EDX: Standard Feature Flags
// * [0:0] FPU on chip
// * [1:1] VME: Virtual-8086 Mode enhancements
// * [2:2] DE: Debug Extensions (I/O breakpoints)
// * [3:3] PSE: Page Size Extensions
// * [4:4] TSC: Time Stamp Counter
// * [5:5] MSR: RDMSR and WRMSR support
// * [6:6] PAE: Physical Address Extensions
// * [7:7] MCE: Machine Check Exception
// * [8:8] CXS: CMPXCHG8B instruction
// * [9:9] APIC: APIC on Chip
// [10:10] Reserved
// * [11:11] SYSENTER/SYSEXIT support
// * [12:12] MTRR: Memory Type Range Reg
// * [13:13] PGE/PTE Global Bit
// * [14:14] MCA: Machine Check Architecture
// * [15:15] CMOV: Cond Mov/Cmp Instructions
// * [16:16] PAT: Page Attribute Table
// * [17:17] PSE-36: Physical Address Extensions
// [18:18] PSN: Processor Serial Number
// * [19:19] CLFLUSH: CLFLUSH Instruction support
// [20:20] Reserved
// * [21:21] DS: Debug Store
// * [22:22] ACPI: Thermal Monitor and Software Controlled Clock Facilities
// * [23:23] MMX Technology
// * [24:24] FXSR: FXSAVE/FXRSTOR (also indicates CR4.OSFXSR is available)
// * [25:25] SSE: SSE Extensions
// * [26:26] SSE2: SSE2 Extensions
// * [27:27] Self Snoop
// * [28:28] Hyper Threading Technology
// * [29:29] TM: Thermal Monitor
// [30:30] Reserved
// * [31:31] PBE: Pending Break Enable
leaf->edx = BX_CPUID_STD_X87 |
BX_CPUID_STD_VME |
BX_CPUID_STD_DEBUG_EXTENSIONS |
BX_CPUID_STD_PSE |
BX_CPUID_STD_TSC |
BX_CPUID_STD_MSR |
BX_CPUID_STD_PAE |
BX_CPUID_STD_MCE |
BX_CPUID_STD_CMPXCHG8B |
BX_CPUID_STD_SYSENTER_SYSEXIT |
BX_CPUID_STD_MTRR |
BX_CPUID_STD_GLOBAL_PAGES |
BX_CPUID_STD_MCA |
BX_CPUID_STD_CMOV |
BX_CPUID_STD_PAT |
BX_CPUID_STD_PSE36 |
BX_CPUID_STD_CLFLUSH |
BX_CPUID_STD_DEBUG_STORE |
BX_CPUID_STD_ACPI |
BX_CPUID_STD_MMX |
BX_CPUID_STD_FXSAVE_FXRSTOR |
BX_CPUID_STD_SSE |
BX_CPUID_STD_SSE2 |
BX_CPUID_STD_SELF_SNOOP |
BX_CPUID_STD_HT |
BX_CPUID_STD_THERMAL_MONITOR |
BX_CPUID_STD_PBE;
#if BX_SUPPORT_APIC
// if MSR_APICBASE APIC Global Enable bit has been cleared,
// the CPUID feature flag for the APIC is set to 0.
if (cpu->msr.apicbase & 0x800)
leaf->edx |= BX_CPUID_STD_APIC; // APIC on chip
#endif
}
// leaf 0x00000002 //
void core2_extreme_x9770_t::get_std_cpuid_leaf_2(cpuid_function_t *leaf) const
{
// CPUID function 0x00000002 - Cache and TLB Descriptors
leaf->eax = 0x05B0B101;
leaf->ebx = 0x005657F0;
leaf->ecx = 0x00000000;
leaf->edx = 0x2CB4304E;
}
// leaf 0x00000003 //
void core2_extreme_x9770_t::get_std_cpuid_leaf_3(cpuid_function_t *leaf) const
{
// CPUID function 0x00000003 - Processor Serial Number
leaf->eax = 0;
leaf->ebx = 0;
leaf->ecx = 0;
leaf->edx = 0;
}
// leaf 0x00000004 //
void core2_extreme_x9770_t::get_std_cpuid_leaf_4(Bit32u subfunction, cpuid_function_t *leaf) const
{
// CPUID function 0x00000004 - Deterministic Cache Parameters
// EAX:
// [04-00] - Cache Type Field
// 0 = No more caches
// 1 = Data Cache
// 2 = Instruction Cache
// 3 = Unified Cache
// [07-05] - Cache Level (starts at 1)]
// [08] - Self Initializing cache level (doesn't need software initialization)
// [09] - Fully Associative cache
// [13-10] - Reserved
// [25-14] - Maximum number of addressable IDs for logical processors sharing this cache
// [31-26] - Maximum number of addressable IDs for processor cores in the physical package - 1
// EBX:
// [11-00] - L = System Coherency Line Size
// [21-12] - P = Physical Line partitions
// [31-22] - W = Ways of associativity
// ECX: Number of Sets
// EDX:
// [00] - Writeback invalidate
// [01] - Cache Inclusiveness
// [02] - Complex Cache Indexing
// [31-03] - Reserved
switch(subfunction) {
case 0:
leaf->eax = 0x0C000121;
leaf->ebx = 0x01C0003F;
leaf->ecx = 0x0000003F;
leaf->edx = 0x00000001;
break;
case 1:
leaf->eax = 0x0C000122;
leaf->ebx = 0x01C0003F;
leaf->ecx = 0x0000003F;
leaf->edx = 0x00000001;
break;
case 2:
leaf->eax = 0x0C004143;
leaf->ebx = 0x05C0003F;
leaf->ecx = 0x00000FFF;
leaf->edx = 0x00000001;
break;
default:
leaf->eax = 0;
leaf->ebx = 0;
leaf->ecx = 0;
leaf->edx = 0;
return;
}
}
// leaf 0x00000005 //
void core2_extreme_x9770_t::get_std_cpuid_leaf_5(cpuid_function_t *leaf) const
{
// CPUID function 0x00000005 - MONITOR/MWAIT Leaf
#if BX_SUPPORT_MONITOR_MWAIT
// EAX - Smallest monitor-line size in bytes
// EBX - Largest monitor-line size in bytes
// ECX -
// [31:2] - reserved
// [1:1] - exit MWAIT even with EFLAGS.IF = 0
// [0:0] - MONITOR/MWAIT extensions are supported
// EDX -
// [03-00] - number of C0 sub C-states supported using MWAIT
// [07-04] - number of C1 sub C-states supported using MWAIT
// [11-08] - number of C2 sub C-states supported using MWAIT
// [15-12] - number of C3 sub C-states supported using MWAIT
// [19-16] - number of C4 sub C-states supported using MWAIT
// [31-20] - reserved (MBZ)
leaf->eax = CACHE_LINE_SIZE;
leaf->ebx = CACHE_LINE_SIZE;
leaf->ecx = 3;
leaf->edx = 0x00000020;
#else
leaf->eax = 0;
leaf->ebx = 0;
leaf->ecx = 0;
leaf->edx = 0;
#endif
}
// leaf 0x00000006 //
void core2_extreme_x9770_t::get_std_cpuid_leaf_6(cpuid_function_t *leaf) const
{
// CPUID function 0x00000006 - Thermal and Power Management Leaf
leaf->eax = 0x00000001;
leaf->ebx = 0x00000002;
leaf->ecx = 0x00000001;
leaf->edx = 0x00000000;
}
// leaf 0x00000007 not supported //
// leaf 0x00000008 reserved //
// leaf 0x00000009 //
void core2_extreme_x9770_t::get_std_cpuid_leaf_9(cpuid_function_t *leaf) const
{
// CPUID function 0x00000009 - Direct Cache Access Information
leaf->eax = 0;
leaf->ebx = 0;
leaf->ecx = 0;
leaf->edx = 0;
}
// leaf 0x0000000A //
void core2_extreme_x9770_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf) const
{
// CPUID function 0x0000000A - Architectural Performance Monitoring Leaf
leaf->eax = 0x07280202;
leaf->ebx = 0x00000000;
leaf->ecx = 0x00000000;
leaf->edx = 0x00000503;
BX_INFO(("WARNING: Architectural Performance Monitoring is not implemented"));
}
// leaf 0x80000000 //
void core2_extreme_x9770_t::get_ext_cpuid_leaf_0(cpuid_function_t *leaf) const
{
// EAX: highest extended function understood by CPUID
// EBX: reserved
// EDX: reserved
// ECX: reserved
leaf->eax = 0x80000008;
leaf->ebx = 0;
leaf->edx = 0; // Reserved for Intel
leaf->ecx = 0;
}
// leaf 0x80000001 //
void core2_extreme_x9770_t::get_ext_cpuid_leaf_1(cpuid_function_t *leaf) const
{
// EAX: CPU Version Information (reserved for Intel)
leaf->eax = 0;
// EBX: Brand ID (reserved for Intel)
leaf->ebx = 0;
// ECX:
// * [0:0] LAHF/SAHF instructions support in 64-bit mode
// [1:1] CMP_Legacy: Core multi-processing legacy mode (AMD)
// [2:2] SVM: Secure Virtual Machine (AMD)
// [3:3] Extended APIC Space
// [4:4] AltMovCR8: LOCK MOV CR0 means MOV CR8
// [5:5] LZCNT: LZCNT instruction support
// [6:6] SSE4A: SSE4A Instructions support (deprecated?)
// [7:7] Misaligned SSE support
// [8:8] PREFETCHW: PREFETCHW instruction support
// [9:9] OSVW: OS visible workarounds (AMD)
// [11:10] reserved
// [12:12] SKINIT support
// [13:13] WDT: Watchdog timer support
// [31:14] reserved
leaf->ecx = BX_CPUID_EXT2_LAHF_SAHF;
// EDX:
// Many of the bits in EDX are the same as FN 0x00000001 [*] for AMD
// [10:0] Reserved for Intel
// ? [11:11] SYSCALL/SYSRET support
// [19:12] Reserved for Intel
// * [20:20] No-Execute page protection
// [25:21] Reserved
// [26:26] 1G paging support
// [27:27] Support RDTSCP Instruction
// [28:28] Reserved
// * [29:29] Long Mode
// [30:30] AMD 3DNow! Extensions
// [31:31] AMD 3DNow! Instructions
leaf->edx = BX_CPUID_STD2_NX |
BX_CPUID_STD2_LONG_MODE;
if (cpu->long64_mode())
leaf->edx |= BX_CPUID_STD2_SYSCALL_SYSRET;
}
// leaf 0x80000002 //
// leaf 0x80000003 //
// leaf 0x80000004 //
void core2_extreme_x9770_t::get_ext_cpuid_brand_string_leaf(Bit32u function, cpuid_function_t *leaf) const
{
// CPUID function 0x80000002-0x80000004 - Processor Name String Identifier
static const char* brand_string = "Intel(R) Core(TM)2 Extreme CPU X9770 @ 3.20GHz";
switch(function) {
case 0x80000002:
memcpy(&(leaf->eax), brand_string , 4);
memcpy(&(leaf->ebx), brand_string + 4, 4);
memcpy(&(leaf->ecx), brand_string + 8, 4);
memcpy(&(leaf->edx), brand_string + 12, 4);
break;
case 0x80000003:
memcpy(&(leaf->eax), brand_string + 16, 4);
memcpy(&(leaf->ebx), brand_string + 20, 4);
memcpy(&(leaf->ecx), brand_string + 24, 4);
memcpy(&(leaf->edx), brand_string + 28, 4);
break;
case 0x80000004:
memcpy(&(leaf->eax), brand_string + 32, 4);
memcpy(&(leaf->ebx), brand_string + 36, 4);
memcpy(&(leaf->ecx), brand_string + 40, 4);
memcpy(&(leaf->edx), brand_string + 44, 4);
break;
default:
break;
}
#ifdef BX_BIG_ENDIAN
leaf->eax = bx_bswap32(leaf->eax);
leaf->ebx = bx_bswap32(leaf->ebx);
leaf->ecx = bx_bswap32(leaf->ecx);
leaf->edx = bx_bswap32(leaf->edx);
#endif
}
// leaf 0x80000005 //
void core2_extreme_x9770_t::get_ext_cpuid_leaf_5(cpuid_function_t *leaf) const
{
// CPUID function 0x800000005 - L1 Cache and TLB Identifiers
leaf->eax = 0;
leaf->ebx = 0;
leaf->ecx = 0; // reserved for Intel
leaf->edx = 0;
}
// leaf 0x80000006 //
void core2_extreme_x9770_t::get_ext_cpuid_leaf_6(cpuid_function_t *leaf) const
{
// CPUID function 0x800000006 - L2 Cache and TLB Identifiers
leaf->eax = 0x00000000;
leaf->ebx = 0x00000000;
leaf->ecx = 0x18008040;
leaf->edx = 0x00000000;
}
// leaf 0x80000007 //
void core2_extreme_x9770_t::get_ext_cpuid_leaf_7(cpuid_function_t *leaf) const
{
// CPUID function 0x800000007 - Advanced Power Management
leaf->eax = 0;
leaf->ebx = 0;
leaf->ecx = 0;
leaf->edx = 0;
}
// leaf 0x80000008 //
void core2_extreme_x9770_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) const
{
// virtual & phys address size in low 2 bytes.
leaf->eax = BX_PHY_ADDRESS_WIDTH | (BX_LIN_ADDRESS_WIDTH << 8);
leaf->ebx = 0;
leaf->ecx = 0; // Reserved, undefined
leaf->edx = 0;
}
void core2_extreme_x9770_t::dump_cpuid(void) const
{
struct cpuid_function_t leaf;
unsigned n;
for (n=0; n<=0xa; n++) {
get_cpuid_leaf(n, 0x00000000, &leaf);
BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx));
}
for (n=0x80000000; n<=0x80000008; n++) {
get_cpuid_leaf(n, 0x00000000, &leaf);
BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx));
}
}
bx_cpuid_t *create_core2_extreme_x9770_cpuid(BX_CPU_C *cpu) { return new core2_extreme_x9770_t(cpu); }
#endif

@ -1,76 +0,0 @@
/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2011 Stanislav Shwartsman
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
//
/////////////////////////////////////////////////////////////////////////
#ifndef BX_CORE2_X9770_CPUID_DEFINITIONS_H
#define BX_CORE2_X9770_CPUID_DEFINITIONS_H
#if BX_SUPPORT_X86_64
#include "cpu/cpuid.h"
class core2_extreme_x9770_t : public bx_cpuid_t {
public:
core2_extreme_x9770_t(BX_CPU_C *cpu);
virtual ~core2_extreme_x9770_t() {}
// return CPU name
virtual const char *get_name(void) const { return "core2_extreme_x9770"; }
virtual Bit64u get_isa_extensions_bitmask(void) const;
virtual Bit32u get_cpu_extensions_bitmask(void) const;
virtual void get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpuid_function_t *leaf) const;
virtual void dump_cpuid(void) const;
private:
#if BX_SUPPORT_SMP
unsigned nprocessors;
unsigned ncores;
unsigned nthreads;
#endif
void get_std_cpuid_leaf_0(cpuid_function_t *leaf) const;
void get_std_cpuid_leaf_1(cpuid_function_t *leaf) const;
void get_std_cpuid_leaf_2(cpuid_function_t *leaf) const;
void get_std_cpuid_leaf_3(cpuid_function_t *leaf) const;
void get_std_cpuid_leaf_4(Bit32u subfunction, cpuid_function_t *leaf) const;
void get_std_cpuid_leaf_5(cpuid_function_t *leaf) const;
void get_std_cpuid_leaf_6(cpuid_function_t *leaf) const;
void get_std_cpuid_leaf_9(cpuid_function_t *leaf) const;
void get_std_cpuid_leaf_A(cpuid_function_t *leaf) const;
void get_ext_cpuid_leaf_0(cpuid_function_t *leaf) const;
void get_ext_cpuid_leaf_1(cpuid_function_t *leaf) const;
void get_ext_cpuid_brand_string_leaf(Bit32u function, cpuid_function_t *leaf) const;
void get_ext_cpuid_leaf_5(cpuid_function_t *leaf) const;
void get_ext_cpuid_leaf_6(cpuid_function_t *leaf) const;
void get_ext_cpuid_leaf_7(cpuid_function_t *leaf) const;
void get_ext_cpuid_leaf_8(cpuid_function_t *leaf) const;
};
extern bx_cpuid_t *create_core2_extreme_x9770_cpuid(BX_CPU_C *cpu);
#endif // BX_SUPPORT_X86_64
#endif

@ -1,245 +0,0 @@
CPU-Z TXT Report
-------------------------------------------------------------------------
Binaries
-------------------------------------------------------------------------
CPU-Z version 1.53
Processors
-------------------------------------------------------------------------
Number of processors 1
Number of threads 4
APICs
-------------------------------------------------------------------------
Processor 0
-- Core 0
-- Thread 0 0
-- Core 1
-- Thread 0 1
-- Core 3
-- Thread 0 3
-- Core 2
-- Thread 0 2
Processors Information
-------------------------------------------------------------------------
Processor 1 ID = 0
Number of cores 4 (max 4)
Number of threads 4 (max 4)
Name Intel Core 2 Extreme QX9770
Codename Yorkfield
Specification Intel(R) Core(TM)2 Extreme CPU X9770 @ 3.20GHz
Package (platform ID) Socket 775 LGA (0x4)
CPUID 6.7.6
Extended CPUID 6.17
Core Stepping C0
Technology 45 nm
Core Speed 2397.7 MHz
Multiplier x FSB 6.0 x 399.6 MHz
Rated Bus speed 1598.5 MHz
Stock frequency 3200 MHz
Instructions sets MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, EM64T, VT-x
L1 Data cache 4 x 32 KBytes, 8-way set associative, 64-byte line size
L1 Instruction cache 4 x 32 KBytes, 8-way set associative, 64-byte line size
L2 cache 2 x 6144 KBytes, 24-way set associative, 64-byte line size
FID/VID Control yes
FID range 6.0x - 8.0x
Max VID 1.288 V
Thread dumps
-------------------------------------------------------------------------
CPU Thread 0
APIC ID 0
Topology Processor ID 0, Core ID 0, Thread ID 0
Type 01008002h
Max CPUID level 0000000Ah
Max CPUID ext. level 80000008h
Cache descriptor Level 1, D, 32 KB, 1 thread(s)
Cache descriptor Level 1, I, 32 KB, 1 thread(s)
Cache descriptor Level 2, U, 6 MB, 2 thread(s)
CPUID
0x00000000 0x0000000A 0x756E6547 0x6C65746E 0x49656E69
0x00000001 0x00010676 0x00040800 0x0008E3BD 0xBFEBFBFF
0x00000002 0x05B0B101 0x005657F0 0x00000000 0x2CB4304E
0x00000003 0x00000000 0x00000000 0x00000000 0x00000000
0x00000004 0x0C000121 0x01C0003F 0x0000003F 0x00000001
0x00000004 0x0C000122 0x01C0003F 0x0000003F 0x00000001
0x00000004 0x0C004143 0x05C0003F 0x00000FFF 0x00000001
0x00000005 0x00000040 0x00000040 0x00000003 0x00000020
0x00000006 0x00000001 0x00000002 0x00000001 0x00000000
0x00000007 0x00000000 0x00000000 0x00000000 0x00000000
0x00000008 0x00000400 0x00000000 0x00000000 0x00000000
0x00000009 0x00000000 0x00000000 0x00000000 0x00000000
0x0000000A 0x07280202 0x00000000 0x00000000 0x00000503
0x80000000 0x80000008 0x00000000 0x00000000 0x00000000
0x80000001 0x00000000 0x00000000 0x00000001 0x20100000
0x80000002 0x65746E49 0x2952286C 0x726F4320 0x4D542865
0x80000003 0x45203229 0x65727478 0x4320656D 0x58205550
0x80000004 0x30373739 0x20402020 0x30322E33 0x007A4847
0x80000005 0x00000000 0x00000000 0x00000000 0x00000000
0x80000006 0x00000000 0x00000000 0x18008040 0x00000000
0x80000007 0x00000000 0x00000000 0x00000000 0x00000000
0x80000008 0x00003024 0x00000000 0x00000000 0x00000000
MSR 0x0000001B 0x00000000 0xFEE00900
MSR 0x00000017 0x0C100000 0x88C40825
MSR 0x000000CD 0x00000000 0x00000806
MSR 0x0000003F 0x00000000 0x00000000
MSR 0x000000CE 0x001A0825 0x7F7F0716
MSR 0x000001A0 0x00000040 0x62872489
MSR 0x000000EE 0x00000000 0x877D4B00
MSR 0x0000011E 0x00000000 0xBE702111
MSR 0x00000194 0x00000000 0x00010825
MSR 0x0000019C 0x00000000 0x882E0000
MSR 0x00000198 0x061A0825 0x86000825
MSR 0x00000199 0x00000000 0x00000825
CPU Thread 1
APIC ID 1
Topology Processor ID 0, Core ID 1, Thread ID 0
Type 01008002h
Max CPUID level 0000000Ah
Max CPUID ext. level 80000008h
Cache descriptor Level 1, D, 32 KB, 1 thread(s)
Cache descriptor Level 1, I, 32 KB, 1 thread(s)
Cache descriptor Level 2, U, 6 MB, 2 thread(s)
CPUID
0x00000000 0x0000000A 0x756E6547 0x6C65746E 0x49656E69
0x00000001 0x00010676 0x01040800 0x0008E3BD 0xBFEBFBFF
0x00000002 0x05B0B101 0x005657F0 0x00000000 0x2CB4304E
0x00000003 0x00000000 0x00000000 0x00000000 0x00000000
0x00000004 0x0C000121 0x01C0003F 0x0000003F 0x00000001
0x00000004 0x0C000122 0x01C0003F 0x0000003F 0x00000001
0x00000004 0x0C004143 0x05C0003F 0x00000FFF 0x00000001
0x00000005 0x00000040 0x00000040 0x00000003 0x00000020
0x00000006 0x00000001 0x00000002 0x00000001 0x00000000
0x00000007 0x00000000 0x00000000 0x00000000 0x00000000
0x00000008 0x00000400 0x00000000 0x00000000 0x00000000
0x00000009 0x00000000 0x00000000 0x00000000 0x00000000
0x0000000A 0x07280202 0x00000000 0x00000000 0x00000503
0x80000000 0x80000008 0x00000000 0x00000000 0x00000000
0x80000001 0x00000000 0x00000000 0x00000001 0x20100000
0x80000002 0x65746E49 0x2952286C 0x726F4320 0x4D542865
0x80000003 0x45203229 0x65727478 0x4320656D 0x58205550
0x80000004 0x30373739 0x20402020 0x30322E33 0x007A4847
0x80000005 0x00000000 0x00000000 0x00000000 0x00000000
0x80000006 0x00000000 0x00000000 0x18008040 0x00000000
0x80000007 0x00000000 0x00000000 0x00000000 0x00000000
0x80000008 0x00003024 0x00000000 0x00000000 0x00000000
MSR 0x0000001B 0x00000000 0xFEE00800
MSR 0x00000017 0x0C100000 0x88C40825
MSR 0x000000CD 0x00000000 0x00000806
MSR 0x0000003F 0x00000000 0x00000000
MSR 0x000000CE 0x001A0825 0x7F7F0716
MSR 0x000001A0 0x00000040 0x62872489
MSR 0x000000EE 0x00000000 0x877D4B00
MSR 0x0000011E 0x00000000 0xBE702111
MSR 0x00000194 0x00000000 0x00010825
MSR 0x0000019C 0x00000000 0x882E0000
MSR 0x00000198 0x061A0825 0x8600061A
MSR 0x00000199 0x00000000 0x0000061A
CPU Thread 2
APIC ID 3
Topology Processor ID 0, Core ID 3, Thread ID 0
Type 01008002h
Max CPUID level 0000000Ah
Max CPUID ext. level 80000008h
Cache descriptor Level 1, D, 32 KB, 1 thread(s)
Cache descriptor Level 1, I, 32 KB, 1 thread(s)
Cache descriptor Level 2, U, 6 MB, 2 thread(s)
CPUID
0x00000000 0x0000000A 0x756E6547 0x6C65746E 0x49656E69
0x00000001 0x00010676 0x03040800 0x0008E3BD 0xBFEBFBFF
0x00000002 0x05B0B101 0x005657F0 0x00000000 0x2CB4304E
0x00000003 0x00000000 0x00000000 0x00000000 0x00000000
0x00000004 0x0C000121 0x01C0003F 0x0000003F 0x00000001
0x00000004 0x0C000122 0x01C0003F 0x0000003F 0x00000001
0x00000004 0x0C004143 0x05C0003F 0x00000FFF 0x00000001
0x00000005 0x00000040 0x00000040 0x00000003 0x00000020
0x00000006 0x00000001 0x00000002 0x00000001 0x00000000
0x00000007 0x00000000 0x00000000 0x00000000 0x00000000
0x00000008 0x00000400 0x00000000 0x00000000 0x00000000
0x00000009 0x00000000 0x00000000 0x00000000 0x00000000
0x0000000A 0x07280202 0x00000000 0x00000000 0x00000503
0x80000000 0x80000008 0x00000000 0x00000000 0x00000000
0x80000001 0x00000000 0x00000000 0x00000001 0x20100000
0x80000002 0x65746E49 0x2952286C 0x726F4320 0x4D542865
0x80000003 0x45203229 0x65727478 0x4320656D 0x58205550
0x80000004 0x30373739 0x20402020 0x30322E33 0x007A4847
0x80000005 0x00000000 0x00000000 0x00000000 0x00000000
0x80000006 0x00000000 0x00000000 0x18008040 0x00000000
0x80000007 0x00000000 0x00000000 0x00000000 0x00000000
0x80000008 0x00003024 0x00000000 0x00000000 0x00000000
MSR 0x0000001B 0x00000000 0xFEE00800
MSR 0x00000017 0x0C100000 0x88C40825
MSR 0x000000CD 0x00000000 0x00000806
MSR 0x0000003F 0x00000000 0x00000000
MSR 0x000000CE 0x001A0825 0x7F7F0716
MSR 0x000001A0 0x00000040 0x62852489
MSR 0x000000EE 0x00000000 0x877D4B00
MSR 0x0000011E 0x00000000 0xBE702111
MSR 0x00000194 0x00000000 0x00010825
MSR 0x0000019C 0x00000000 0x88500000
MSR 0x00000198 0x061A0825 0x86000825
MSR 0x00000199 0x00000000 0x00000825
CPU Thread 3
APIC ID 2
Topology Processor ID 0, Core ID 2, Thread ID 0
Type 01008002h
Max CPUID level 0000000Ah
Max CPUID ext. level 80000008h
Cache descriptor Level 1, D, 32 KB, 1 thread(s)
Cache descriptor Level 1, I, 32 KB, 1 thread(s)
Cache descriptor Level 2, U, 6 MB, 2 thread(s)
CPUID
0x00000000 0x0000000A 0x756E6547 0x6C65746E 0x49656E69
0x00000001 0x00010676 0x02040800 0x0008E3BD 0xBFEBFBFF
0x00000002 0x05B0B101 0x005657F0 0x00000000 0x2CB4304E
0x00000003 0x00000000 0x00000000 0x00000000 0x00000000
0x00000004 0x0C000121 0x01C0003F 0x0000003F 0x00000001
0x00000004 0x0C000122 0x01C0003F 0x0000003F 0x00000001
0x00000004 0x0C004143 0x05C0003F 0x00000FFF 0x00000001
0x00000005 0x00000040 0x00000040 0x00000003 0x00000020
0x00000006 0x00000001 0x00000002 0x00000001 0x00000000
0x00000007 0x00000000 0x00000000 0x00000000 0x00000000
0x00000008 0x00000400 0x00000000 0x00000000 0x00000000
0x00000009 0x00000000 0x00000000 0x00000000 0x00000000
0x0000000A 0x07280202 0x00000000 0x00000000 0x00000503
0x80000000 0x80000008 0x00000000 0x00000000 0x00000000
0x80000001 0x00000000 0x00000000 0x00000001 0x20100000
0x80000002 0x65746E49 0x2952286C 0x726F4320 0x4D542865
0x80000003 0x45203229 0x65727478 0x4320656D 0x58205550
0x80000004 0x30373739 0x20402020 0x30322E33 0x007A4847
0x80000005 0x00000000 0x00000000 0x00000000 0x00000000
0x80000006 0x00000000 0x00000000 0x18008040 0x00000000
0x80000007 0x00000000 0x00000000 0x00000000 0x00000000
0x80000008 0x00003024 0x00000000 0x00000000 0x00000000
MSR 0x0000001B 0x00000000 0xFEE00800
MSR 0x00000017 0x0C100000 0x88C40825
MSR 0x000000CD 0x00000000 0x00000806
MSR 0x0000003F 0x00000000 0x00000000
MSR 0x000000CE 0x001A0825 0x7F7F0716
MSR 0x000001A0 0x00000040 0x62852489
MSR 0x000000EE 0x00000000 0x877D4B00
MSR 0x0000011E 0x00000000 0xBE702111
MSR 0x00000194 0x00000000 0x00010825
MSR 0x0000019C 0x00000000 0x88500000
MSR 0x00000198 0x061A0825 0x86000825
MSR 0x00000199 0x00000000 0x00000825

@ -154,6 +154,17 @@ Bit32u core2_penryn_t9600_t::get_cpu_extensions_bitmask(void) const
BX_CPU_NX;
}
#if BX_SUPPORT_VMX
Bit32u core2_penryn_t9600_t::get_vmx_extensions_bitmask(void) const
{
return BX_VMX_TPR_SHADOW |
BX_VMX_VIRTUAL_NMI |
BX_VMX_APIC_VIRTUALIZATION |
BX_VMX_WBINVD_VMEXIT |
BX_VMX_PERF_GLOBAL_CTRL;
}
#endif
// leaf 0x00000000 //
void core2_penryn_t9600_t::get_std_cpuid_leaf_0(cpuid_function_t *leaf) const
{

@ -38,6 +38,9 @@ public:
virtual Bit64u get_isa_extensions_bitmask(void) const;
virtual Bit32u get_cpu_extensions_bitmask(void) const;
#if BX_SUPPORT_VMX
virtual Bit32u get_vmx_extensions_bitmask(void) const;
#endif
virtual void get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpuid_function_t *leaf) const;

@ -38,6 +38,9 @@ public:
virtual Bit64u get_isa_extensions_bitmask(void) const;
virtual Bit32u get_cpu_extensions_bitmask(void) const;
#if BX_SUPPORT_VMX
virtual Bit32u get_vmx_extensions_bitmask(void) const { return 0; } // only basic support
#endif
virtual void get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpuid_function_t *leaf) const;

@ -168,6 +168,29 @@ Bit32u corei7_sandy_bridge_2600k_t::get_cpu_extensions_bitmask(void) const
BX_CPU_PCID;
}
#if BX_SUPPORT_VMX
Bit32u corei7_sandy_bridge_2600k_t::get_vmx_extensions_bitmask(void) const
{
return BX_VMX_TPR_SHADOW |
BX_VMX_APIC_VIRTUALIZATION |
BX_VMX_VIRTUAL_NMI |
BX_VMX_CR3_VMEXIT_DISABLE |
/* BX_VMX_MONITOR_TRAP_FLAG | */ // not implemented yet
BX_VMX_VPID |
BX_VMX_EPT |
BX_VMX_UNRESTRICTED_GUEST |
BX_VMX_PAUSE_LOOP_EXITING |
BX_VMX_PREEMPTION_TIMER |
BX_VMX_SAVE_DEBUGCTL_DISABLE |
BX_VMX_PERF_GLOBAL_CTRL |
BX_VMX_PAT |
BX_VMX_EFER |
BX_VMX_DESCRIPTOR_TABLE_EXIT |
BX_VMX_X2APIC_VIRTUALIZATION |
BX_VMX_WBINVD_VMEXIT;
}
#endif
// leaf 0x00000000 //
void corei7_sandy_bridge_2600k_t::get_std_cpuid_leaf_0(cpuid_function_t *leaf) const
{

@ -38,6 +38,9 @@ public:
virtual Bit64u get_isa_extensions_bitmask(void) const;
virtual Bit32u get_cpu_extensions_bitmask(void) const;
#if BX_SUPPORT_VMX
virtual Bit32u get_vmx_extensions_bitmask(void) const;
#endif
virtual void get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpuid_function_t *leaf) const;

@ -41,6 +41,9 @@ public:
virtual Bit64u get_isa_extensions_bitmask(void) const = 0;
virtual Bit32u get_cpu_extensions_bitmask(void) const = 0;
#if BX_SUPPORT_VMX
virtual Bit32u get_vmx_extensions_bitmask(void) const { return 0; }
#endif
virtual void get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpuid_function_t *leaf) const = 0;
@ -66,59 +69,78 @@ protected:
typedef bx_cpuid_t* (*bx_create_cpuid_method)(BX_CPU_C *cpu);
// cpuid ISA (duplicated in disasm.h)
#define BX_ISA_X87 (BX_CONST64(1) << 0) /* FPU (X87) instruction */
#define BX_ISA_486 (BX_CONST64(1) << 1) /* 486 new instruction */
#define BX_ISA_PENTIUM (BX_CONST64(1) << 2) /* Pentium new instruction */
#define BX_ISA_P6 (BX_CONST64(1) << 3) /* P6 new instruction */
#define BX_ISA_MMX (BX_CONST64(1) << 4) /* MMX instruction */
#define BX_ISA_3DNOW (BX_CONST64(1) << 5) /* 3DNow! instruction (AMD) */
#define BX_ISA_SYSCALL_SYSRET (BX_CONST64(1) << 6) /* SYSCALL/SYSRET in legacy mode (AMD) */
#define BX_ISA_SYSENTER_SYSEXIT (BX_CONST64(1) << 7) /* SYSENTER/SYSEXIT instruction */
#define BX_ISA_CLFLUSH (BX_CONST64(1) << 8) /* CLFLUSH instruction */
#define BX_ISA_SSE (BX_CONST64(1) << 9) /* SSE instruction */
#define BX_ISA_SSE2 (BX_CONST64(1) << 10) /* SSE2 instruction */
#define BX_ISA_SSE3 (BX_CONST64(1) << 11) /* SSE3 instruction */
#define BX_ISA_SSSE3 (BX_CONST64(1) << 12) /* SSSE3 instruction */
#define BX_ISA_SSE4_1 (BX_CONST64(1) << 13) /* SSE4_1 instruction */
#define BX_ISA_SSE4_2 (BX_CONST64(1) << 14) /* SSE4_2 instruction */
#define BX_ISA_MONITOR_MWAIT (BX_CONST64(1) << 15) /* MONITOR/MWAIT instruction */
#define BX_ISA_VMX (BX_CONST64(1) << 16) /* VMX instruction */
#define BX_ISA_SMX (BX_CONST64(1) << 17) /* SMX instruction */
#define BX_ISA_LM_LAHF_SAHF (BX_CONST64(1) << 18) /* Long Mode LAHF/SAHF instruction */
#define BX_ISA_RDTSCP (BX_CONST64(1) << 19) /* RDTSCP instruction */
#define BX_ISA_XSAVE (BX_CONST64(1) << 20) /* XSAVE/XRSTOR extensions instruction */
#define BX_ISA_XSAVEOPT (BX_CONST64(1) << 21) /* XSAVEOPT instruction */
#define BX_ISA_AES_PCLMULQDQ (BX_CONST64(1) << 22) /* AES+PCLMULQDQ instruction */
#define BX_ISA_MOVBE (BX_CONST64(1) << 23) /* MOVBE Intel Atom(R) instruction */
#define BX_ISA_FSGSBASE (BX_CONST64(1) << 24) /* FS/GS BASE access instruction */
#define BX_ISA_INVPCID (BX_CONST64(1) << 25) /* INVPCID instruction */
#define BX_ISA_AVX (BX_CONST64(1) << 26) /* AVX instruction */
#define BX_ISA_AVX2 (BX_CONST64(1) << 27) /* AVX2 instruction */
#define BX_ISA_AVX_F16C (BX_CONST64(1) << 28) /* AVX F16 convert instruction */
#define BX_ISA_AVX_FMA (BX_CONST64(1) << 29) /* AVX FMA instruction */
#define BX_ISA_SSE4A (BX_CONST64(1) << 30) /* SSE4A instruction (AMD) */
#define BX_ISA_LZCNT (BX_CONST64(1) << 31) /* LZCNT instruction */
#define BX_ISA_BMI1 (BX_CONST64(1) << 32) /* BMI1 instruction */
#define BX_ISA_BMI2 (BX_CONST64(1) << 33) /* BMI2 instruction */
#define BX_ISA_X87 (BX_CONST64(1) << 0) /* FPU (X87) instruction */
#define BX_ISA_486 (BX_CONST64(1) << 1) /* 486 new instruction */
#define BX_ISA_PENTIUM (BX_CONST64(1) << 2) /* Pentium new instruction */
#define BX_ISA_P6 (BX_CONST64(1) << 3) /* P6 new instruction */
#define BX_ISA_MMX (BX_CONST64(1) << 4) /* MMX instruction */
#define BX_ISA_3DNOW (BX_CONST64(1) << 5) /* 3DNow! instruction (AMD) */
#define BX_ISA_SYSCALL_SYSRET_LEGACY (BX_CONST64(1) << 6) /* SYSCALL/SYSRET in legacy mode (AMD) */
#define BX_ISA_SYSENTER_SYSEXIT (BX_CONST64(1) << 7) /* SYSENTER/SYSEXIT instruction */
#define BX_ISA_CLFLUSH (BX_CONST64(1) << 8) /* CLFLUSH instruction */
#define BX_ISA_SSE (BX_CONST64(1) << 9) /* SSE instruction */
#define BX_ISA_SSE2 (BX_CONST64(1) << 10) /* SSE2 instruction */
#define BX_ISA_SSE3 (BX_CONST64(1) << 11) /* SSE3 instruction */
#define BX_ISA_SSSE3 (BX_CONST64(1) << 12) /* SSSE3 instruction */
#define BX_ISA_SSE4_1 (BX_CONST64(1) << 13) /* SSE4_1 instruction */
#define BX_ISA_SSE4_2 (BX_CONST64(1) << 14) /* SSE4_2 instruction */
#define BX_ISA_MONITOR_MWAIT (BX_CONST64(1) << 15) /* MONITOR/MWAIT instruction */
#define BX_ISA_VMX (BX_CONST64(1) << 16) /* VMX instruction */
#define BX_ISA_SMX (BX_CONST64(1) << 17) /* SMX instruction */
#define BX_ISA_LM_LAHF_SAHF (BX_CONST64(1) << 18) /* Long Mode LAHF/SAHF instruction */
#define BX_ISA_RDTSCP (BX_CONST64(1) << 19) /* RDTSCP instruction */
#define BX_ISA_XSAVE (BX_CONST64(1) << 20) /* XSAVE/XRSTOR extensions instruction */
#define BX_ISA_XSAVEOPT (BX_CONST64(1) << 21) /* XSAVEOPT instruction */
#define BX_ISA_AES_PCLMULQDQ (BX_CONST64(1) << 22) /* AES+PCLMULQDQ instruction */
#define BX_ISA_MOVBE (BX_CONST64(1) << 23) /* MOVBE Intel Atom(R) instruction */
#define BX_ISA_FSGSBASE (BX_CONST64(1) << 24) /* FS/GS BASE access instruction */
#define BX_ISA_INVPCID (BX_CONST64(1) << 25) /* INVPCID instruction */
#define BX_ISA_AVX (BX_CONST64(1) << 26) /* AVX instruction */
#define BX_ISA_AVX2 (BX_CONST64(1) << 27) /* AVX2 instruction */
#define BX_ISA_AVX_F16C (BX_CONST64(1) << 28) /* AVX F16 convert instruction */
#define BX_ISA_AVX_FMA (BX_CONST64(1) << 29) /* AVX FMA instruction */
#define BX_ISA_SSE4A (BX_CONST64(1) << 30) /* SSE4A instruction (AMD) */
#define BX_ISA_LZCNT (BX_CONST64(1) << 31) /* LZCNT instruction */
#define BX_ISA_BMI1 (BX_CONST64(1) << 32) /* BMI1 instruction */
#define BX_ISA_BMI2 (BX_CONST64(1) << 33) /* BMI2 instruction */
// cpuid non-ISA features
#define BX_CPU_DEBUG_EXTENSIONS (1 << 0) /* Debug Extensions support */
#define BX_CPU_VME (1 << 1) /* VME support */
#define BX_CPU_PSE (1 << 2) /* PSE support */
#define BX_CPU_PAE (1 << 3) /* PAE support */
#define BX_CPU_PGE (1 << 4) /* Global Pages support */
#define BX_CPU_PSE36 (1 << 5) /* PSE-36 support */
#define BX_CPU_MTRR (1 << 6) /* MTRR support */
#define BX_CPU_PAT (1 << 7) /* PAT support */
#define BX_CPU_XAPIC (1 << 8) /* XAPIC support */
#define BX_CPU_X2APIC (1 << 9) /* X2APIC support */
#define BX_CPU_NX (1 << 10) /* No-Execute support */
#define BX_CPU_LONG_MODE (1 << 11) /* Long Mode (x86-64) support */
#define BX_CPU_1G_PAGES (1 << 12) /* 1Gb pages support */
#define BX_CPU_PCID (1 << 13) /* PCID pages support */
#define BX_CPU_SMEP (1 << 14) /* SMEP support */
#define BX_CPU_FFXSR (1 << 15) /* EFER.FFXSR support */
#define BX_CPU_ALT_MOV_CR8 (1 << 16) /* LOCK CR0 access CR8 */
#define BX_CPU_DEBUG_EXTENSIONS (1 << 0) /* Debug Extensions support */
#define BX_CPU_VME (1 << 1) /* VME support */
#define BX_CPU_PSE (1 << 2) /* PSE support */
#define BX_CPU_PAE (1 << 3) /* PAE support */
#define BX_CPU_PGE (1 << 4) /* Global Pages support */
#define BX_CPU_PSE36 (1 << 5) /* PSE-36 support */
#define BX_CPU_MTRR (1 << 6) /* MTRR support */
#define BX_CPU_PAT (1 << 7) /* PAT support */
#define BX_CPU_XAPIC (1 << 8) /* XAPIC support */
#define BX_CPU_X2APIC (1 << 9) /* X2APIC support */
#define BX_CPU_NX (1 << 10) /* No-Execute support */
#define BX_CPU_LONG_MODE (1 << 11) /* Long Mode (x86-64) support */
#define BX_CPU_1G_PAGES (1 << 12) /* 1Gb pages support */
#define BX_CPU_PCID (1 << 13) /* PCID pages support */
#define BX_CPU_SMEP (1 << 14) /* SMEP support */
#define BX_CPU_FFXSR (1 << 15) /* EFER.FFXSR support */
#define BX_CPU_ALT_MOV_CR8 (1 << 16) /* LOCK CR0 access CR8 */
// cpuid VMX features
#define BX_VMX_TPR_SHADOW (1 << 0) /* TPR shadow */
#define BX_VMX_VIRTUAL_NMI (1 << 1) /* Virtual NMI */
#define BX_VMX_APIC_VIRTUALIZATION (1 << 2) /* APIC Virtualization */
#define BX_VMX_WBINVD_VMEXIT (1 << 3) /* WBINVD VMEXIT */
#define BX_VMX_PERF_GLOBAL_CTRL (1 << 4) /* Save/Restore MSR_PERF_GLOBAL_CTRL */
#define BX_VMX_MONITOR_TRAP_FLAG (1 << 5) /* Monitor trap Flag (MTF) */
#define BX_VMX_VPID (1 << 6) /* VPID */
#define BX_VMX_EPT (1 << 7) /* Extended Page Tables (EPT) */
#define BX_VMX_CR3_VMEXIT_DISABLE (1 << 8) /* Disable CR3 Read/Write VMEXIT */
#define BX_VMX_UNRESTRICTED_GUEST (1 << 9) /* Unrestricted Guest */
#define BX_VMX_PAUSE_LOOP_EXITING (1 << 10) /* Pause Loop Exiting */
#define BX_VMX_PREEMPTION_TIMER (1 << 11) /* VMX preemption timer */
#define BX_VMX_SAVE_DEBUGCTL_DISABLE (1 << 12) /* Disable Save/Restore of MSR_DEBUGCTL */
#define BX_VMX_PAT (1 << 13) /* Save/Restore MSR_PAT */
#define BX_VMX_EFER (1 << 14) /* Save/Restore MSR_EFER */
#define BX_VMX_DESCRIPTOR_TABLE_EXIT (1 << 15) /* Descriptor Table VMEXIT */
#define BX_VMX_X2APIC_VIRTUALIZATION (1 << 16) /* Virtualize X2APIC */
// CPUID defines - STD features CPUID[0x00000001].EDX
// ----------------------------

@ -888,6 +888,39 @@ void bx_generic_cpuid_t::init_cpu_extensions_bitmask(void)
this->cpu_extensions_bitmask = features_bitmask;
}
#if BX_SUPPORT_VMX
void bx_generic_cpuid_t::init_vmx_extensions_bitmask(void)
{
Bit32u features_bitmask = BX_VMX_VIRTUAL_NMI;
static bx_bool x86_64_enabled = SIM->get_param_bool(BXPN_CPUID_X86_64)->get();
if (x86_64_enabled) {
features_bitmask |= BX_VMX_TPR_SHADOW;
#if BX_SUPPORT_VMX >= 2
features_bitmask |= BX_VMX_APIC_VIRTUALIZATION |
BX_VMX_PREEMPTION_TIMER |
BX_VMX_PAT |
BX_VMX_EFER |
BX_VMX_EPT |
BX_VMX_VPID |
BX_VMX_UNRESTRICTED_GUEST |
BX_VMX_DESCRIPTOR_TABLE_EXIT |
BX_VMX_X2APIC_VIRTUALIZATION |
BX_VMX_WBINVD_VMEXIT |
BX_VMX_PAUSE_LOOP_EXITING;
features_bitmask |= BX_VMX_CR3_VMEXIT_DISABLE |
BX_VMX_MONITOR_TRAP_FLAG |
BX_VMX_SAVE_DEBUGCTL_DISABLE |
BX_VMX_PERF_GLOBAL_CTRL;
#endif
}
this->vmx_extensions_bitmask = features_bitmask;
}
#endif
/*
* Get CPU version information:
*

@ -38,6 +38,9 @@ public:
virtual Bit64u get_isa_extensions_bitmask(void) const { return isa_extensions_bitmask; }
virtual Bit32u get_cpu_extensions_bitmask(void) const { return cpu_extensions_bitmask; }
#if BX_SUPPORT_VMX
virtual Bit32u get_vmx_extensions_bitmask(void) const { return vmx_extensions_bitmask; }
#endif
virtual void get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpuid_function_t *leaf) const;
@ -46,9 +49,15 @@ public:
private:
void init_isa_extensions_bitmask(void);
void init_cpu_extensions_bitmask(void);
#if BX_SUPPORT_VMX
void init_vmx_extensions_bitmask(void);
#endif
Bit64u isa_extensions_bitmask;
Bit32u cpu_extensions_bitmask;
#if BX_SUPPORT_VMX
Bit32u vmx_extensions_bitmask;
#endif
#if BX_SUPPORT_SMP
unsigned nprocessors;

@ -725,8 +725,8 @@ bx_define_opcode(BX_IA_PSWAPD_PqQq, &BX_CPU_C::PSWAPD_PqQq, &BX_CPU_C::PSWAPD_Pq
#endif
bx_define_opcode(BX_IA_PREFETCHW, &BX_CPU_C::NOP, &BX_CPU_C::NOP, 0, 0) // NOP even when no 3DNow!
bx_define_opcode(BX_IA_SYSCALL_LEGACY, NULL, &BX_CPU_C::SYSCALL, BX_ISA_SYSCALL_SYSRET, 0)
bx_define_opcode(BX_IA_SYSRET_LEGACY, NULL, &BX_CPU_C::SYSRET, BX_ISA_SYSCALL_SYSRET, 0)
bx_define_opcode(BX_IA_SYSCALL_LEGACY, NULL, &BX_CPU_C::SYSCALL, BX_ISA_SYSCALL_SYSRET_LEGACY, 0)
bx_define_opcode(BX_IA_SYSRET_LEGACY, NULL, &BX_CPU_C::SYSRET, BX_ISA_SYSCALL_SYSRET_LEGACY, 0)
// P6 new instructions
bx_define_opcode(BX_IA_CMOVB_GdEd, &BX_CPU_C::LOAD_Ed, &BX_CPU_C::CMOVB_GdEdR, BX_ISA_P6, 0)

@ -44,6 +44,9 @@ BX_CPU_C::BX_CPU_C(unsigned id): bx_cpuid(id)
isa_extensions_bitmask = BX_SUPPORT_FPU ? BX_ISA_X87 : 0;
cpu_extensions_bitmask = 0;
#if BX_SUPPORT_VMX
vmx_extensions_bitmask = 0;
#endif
}
#if BX_WITH_WX
@ -189,6 +192,9 @@ void BX_CPU_C::initialize(void)
BX_CPU_THIS_PTR isa_extensions_bitmask = cpuid->get_isa_extensions_bitmask();
BX_CPU_THIS_PTR cpu_extensions_bitmask = cpuid->get_cpu_extensions_bitmask();
#if BX_SUPPORT_VMX
BX_CPU_THIS_PTR vmx_extensions_bitmask = cpuid->get_vmx_extensions_bitmask();
#endif
#endif
init_FetchDecodeTables(); // must be called after init_isa_features_bitmask()
@ -354,6 +360,9 @@ void BX_CPU_C::register_state(void)
BXRS_HEX_PARAM_SIMPLE(cpu, isa_extensions_bitmask);
BXRS_HEX_PARAM_SIMPLE(cpu, cpu_extensions_bitmask);
#if BX_SUPPORT_VMX
BXRS_HEX_PARAM_SIMPLE(cpu, vmx_extensions_bitmask);
#endif
BXRS_DEC_PARAM_SIMPLE(cpu, cpu_mode);
BXRS_HEX_PARAM_SIMPLE(cpu, activity_state);
BXRS_HEX_PARAM_SIMPLE(cpu, inhibit_mask);
@ -965,7 +974,7 @@ void BX_CPU_C::reset(unsigned source)
BX_CPU_THIS_PTR efer_suppmask = 0;
if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_NX))
BX_CPU_THIS_PTR efer_suppmask |= BX_EFER_NXE_MASK;
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_SYSCALL_SYSRET))
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_SYSCALL_SYSRET_LEGACY))
BX_CPU_THIS_PTR efer_suppmask |= BX_EFER_SCE_MASK;
#if BX_SUPPORT_X86_64
if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_LONG_MODE)) {

@ -35,6 +35,8 @@ void BX_CPU_C::init_VMCS(void)
static bx_bool vmcs_map_ready = 0;
unsigned type, field;
init_vmx_capabilities();
if (vmcs_map_ready) return;
vmcs_map_ready = 1;
@ -89,7 +91,10 @@ bx_bool BX_CPU_C::vmcs_field_supported(Bit32u encoding)
/* VMCS 16-bit control fields */
/* binary 0000_00xx_xxxx_xxx0 */
case VMCS_16BIT_CONTROL_VPID:
return 1;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_VPID))
return 1;
else
return 0;
#endif
/* VMCS 16-bit guest-state fields */
@ -131,15 +136,22 @@ bx_bool BX_CPU_C::vmcs_field_supported(Bit32u encoding)
case VMCS_32BIT_CONTROL_VMENTRY_INTERRUPTION_INFO:
case VMCS_32BIT_CONTROL_VMENTRY_EXCEPTION_ERR_CODE:
case VMCS_32BIT_CONTROL_VMENTRY_INSTRUCTION_LENGTH:
return 1;
#if BX_SUPPORT_X86_64
case VMCS_32BIT_CONTROL_TPR_THRESHOLD:
if (bx_cpuid_support_x86_64())
return 1;
else
return 0;
#endif
#if BX_SUPPORT_VMX >= 2
case VMCS_32BIT_CONTROL_SECONDARY_VMEXEC_CONTROLS:
case VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_GAP:
case VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_WINDOW:
#endif
return 1;
#endif
/* VMCS 32-bit read only data fields */
/* binary 0100_01xx_xxxx_xxx0 */
@ -177,10 +189,15 @@ bx_bool BX_CPU_C::vmcs_field_supported(Bit32u encoding)
case VMCS_32BIT_GUEST_ACTIVITY_STATE:
case VMCS_32BIT_GUEST_SMBASE:
case VMCS_32BIT_GUEST_IA32_SYSENTER_CS_MSR:
return 1;
#if BX_SUPPORT_VMX >= 2
case VMCS_32BIT_GUEST_PREEMPTION_TIMER_VALUE:
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PREEMPTION_TIMER))
return 1;
else
return 0;
#endif
return 1;
/* VMCS 32-bit host-state fields */
/* binary 0100_11xx_xxxx_xxx0 */
@ -205,24 +222,38 @@ bx_bool BX_CPU_C::vmcs_field_supported(Bit32u encoding)
case VMCS_64BIT_CONTROL_EXECUTIVE_VMCS_PTR_HI:
case VMCS_64BIT_CONTROL_TSC_OFFSET:
case VMCS_64BIT_CONTROL_TSC_OFFSET_HI:
return 1;
#if BX_SUPPORT_X86_64
case VMCS_64BIT_CONTROL_VIRTUAL_APIC_PAGE_ADDR:
case VMCS_64BIT_CONTROL_VIRTUAL_APIC_PAGE_ADDR_HI:
if (bx_cpuid_support_x86_64())
return 1;
else
return 0;
#endif
#if BX_SUPPORT_VMX >= 2
case VMCS_64BIT_CONTROL_APIC_ACCESS_ADDR:
case VMCS_64BIT_CONTROL_APIC_ACCESS_ADDR_HI:
return 1;
case VMCS_64BIT_CONTROL_EPTPTR:
case VMCS_64BIT_CONTROL_EPTPTR_HI:
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPT))
return 1;
else
return 0;
#endif
return 1;
#if BX_SUPPORT_VMX >= 2
/* VMCS 64-bit read only data fields */
/* binary 0010_01xx_xxxx_xxx0 */
case VMCS_64BIT_GUEST_PHYSICAL_ADDR:
case VMCS_64BIT_GUEST_PHYSICAL_ADDR_HI:
return 1;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPT))
return 1;
else
return 0;
#endif
/* VMCS 64-bit guest state fields */
@ -231,11 +262,23 @@ bx_bool BX_CPU_C::vmcs_field_supported(Bit32u encoding)
case VMCS_64BIT_GUEST_LINK_POINTER_HI:
case VMCS_64BIT_GUEST_IA32_DEBUGCTL:
case VMCS_64BIT_GUEST_IA32_DEBUGCTL_HI:
return 1;
#if BX_SUPPORT_VMX >= 2
case VMCS_64BIT_GUEST_IA32_PAT:
case VMCS_64BIT_GUEST_IA32_PAT_HI:
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PAT))
return 1;
else
return 0;
case VMCS_64BIT_GUEST_IA32_EFER:
case VMCS_64BIT_GUEST_IA32_EFER_HI:
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EFER))
return 1;
else
return 0;
case VMCS_64BIT_GUEST_IA32_PDPTE0:
case VMCS_64BIT_GUEST_IA32_PDPTE0_HI:
case VMCS_64BIT_GUEST_IA32_PDPTE1:
@ -244,17 +287,28 @@ bx_bool BX_CPU_C::vmcs_field_supported(Bit32u encoding)
case VMCS_64BIT_GUEST_IA32_PDPTE2_HI:
case VMCS_64BIT_GUEST_IA32_PDPTE3:
case VMCS_64BIT_GUEST_IA32_PDPTE3_HI:
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPT))
return 1;
else
return 0;
#endif
return 1;
#if BX_SUPPORT_VMX >= 2
/* VMCS 64-bit host state fields */
/* binary 0010_11xx_xxxx_xxx0 */
case VMCS_64BIT_HOST_IA32_PAT:
case VMCS_64BIT_HOST_IA32_PAT_HI:
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PAT))
return 1;
else
return 0;
case VMCS_64BIT_HOST_IA32_EFER:
case VMCS_64BIT_HOST_IA32_EFER_HI:
return 1;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EFER))
return 1;
else
return 0;
#endif
/* VMCS natural width control fields */
@ -326,4 +380,189 @@ bx_bool BX_CPU_C::vmcs_field_supported(Bit32u encoding)
return 0;
}
void BX_CPU_C::init_vmx_capabilities(void)
{
struct bx_VMX_Cap *cap = &BX_CPU_THIS_PTR vmx_cap;
// pin based vm exec controls
// -----------------------------------------------------------
// [00] External Interrupt Exiting
// 1 [01] Reserved (must be '1)
// 1 [02] Reserved (must be '1)
// [03] NMI Exiting
// 1 [04] Reserved (must be '1)
// [05] Virtual NMI (require Virtual NMI support)
// [06] Activate VMX Preemption Timer (require VMX Preemption Timer support)
cap->vmx_pin_vmexec_ctrl_supported_bits =
VMX_VM_EXEC_CTRL1_EXTERNAL_INTERRUPT_VMEXIT |
VMX_VM_EXEC_CTRL1_NMI_VMEXIT;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_VIRTUAL_NMI))
cap->vmx_pin_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL1_VIRTUAL_NMI;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PREEMPTION_TIMER))
cap->vmx_pin_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL1_VMX_PREEMPTION_TIMER_VMEXIT;
// proc based vm exec controls
// -----------------------------------------------------------
// 0 [00] Reserved (must be '0)
// 1 [01] Reserved (must be '1)
// [02] Interrupt Window Exiting
// [03] TSC Offset Enable
// 1 [06-04] Reserved (must be '1)
// [07] HLT Exiting
// 1 [08] Reserved (must be '1)
// [09] INVLPG Exiting
// [10] MWAIT Exiting (require MONITOR/MWAIT support)
// [11] RDPMC Exiting
// [12] RDTSC Exiting
// 1 [14-13] Reserved (must be '1)
// 1 [15] CR3 Write Exiting (legacy must be '1, introduced with EPT support)
// 1 [16] CR3 Read Exiting (legacy must be '1, introduced with EPT support)
// 0 [18-17] Reserved (must be '0)
// [19] CR8 Write Exiting (require TPR Shadow support, require x86-64 support)
// [20] CR8 Read Exiting (require TPR Shadow support, require x86-64 support)
// [21] TPR Shadow Enable (require TPR Shadow support, require x86-64 support)
// [22] NMI Window Exiting (require Virtual NMI support)
// [23] DRx Access Exiting
// [24] I/O Access Exiting
// [25] I/O Bitmaps
// 1 [26] Reserved (must be '1)
// [27] Monitor Trap Flag Enable (require Monitor Trap Flag support)
// [28] MSR Bitmaps
// [29] MONITOR Exiting (require MONITOR/MWAIT support)
// [30] PAUSE Exiting
// [31] Secondary proc-based vmexec controls
cap->vmx_proc_vmexec_ctrl_supported_bits =
VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT |
VMX_VM_EXEC_CTRL2_TSC_OFFSET |
VMX_VM_EXEC_CTRL2_HLT_VMEXIT |
VMX_VM_EXEC_CTRL2_INVLPG_VMEXIT |
VMX_VM_EXEC_CTRL2_RDPMC_VMEXIT |
VMX_VM_EXEC_CTRL2_RDTSC_VMEXIT |
VMX_VM_EXEC_CTRL2_CR3_WRITE_VMEXIT |
VMX_VM_EXEC_CTRL2_CR3_READ_VMEXIT |
VMX_VM_EXEC_CTRL2_DRx_ACCESS_VMEXIT |
VMX_VM_EXEC_CTRL2_IO_VMEXIT |
VMX_VM_EXEC_CTRL2_IO_BITMAPS |
VMX_VM_EXEC_CTRL2_MSR_BITMAPS |
VMX_VM_EXEC_CTRL2_PAUSE_VMEXIT;
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_MONITOR_MWAIT)) {
cap->vmx_proc_vmexec_ctrl_supported_bits |=
VMX_VM_EXEC_CTRL2_MWAIT_VMEXIT | VMX_VM_EXEC_CTRL2_MONITOR_VMEXIT;
}
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_TPR_SHADOW)) {
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL2_TPR_SHADOW;
if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_LONG_MODE))
cap->vmx_proc_vmexec_ctrl_supported_bits |=
VMX_VM_EXEC_CTRL2_CR8_WRITE_VMEXIT | VMX_VM_EXEC_CTRL2_CR8_READ_VMEXIT;
}
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_VIRTUAL_NMI))
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL2_NMI_WINDOW_VMEXIT;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_MONITOR_TRAP_FLAG))
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL2_MONITOR_TRAP_FLAG;
// secondary proc based vm exec controls
// -----------------------------------------------------------
// [00] Apic Virtualization
// [01] EPT Enable
// [02] Descriptor Table Exiting
// [03] RDTSCP Exiting (require RDTSCP instruction support)
// [04] Virtualize X2APIC Mode (doesn't require actual X2APIC to be enabled)
// [05] VPID Enable
// [06] WBINVD Exiting
// [07] Unrestricted Guest
// [08] Reserved
// [09] Reserved
// [10] PAUSE Loop Exiting
// [11] RDRAND Exiting (require RDRAND instruction support)
cap->vmx_vmexec_ctrl2_supported_bits = 0;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_APIC_VIRTUALIZATION))
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EPT))
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_EPT_ENABLE;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_DESCRIPTOR_TABLE_EXIT))
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT;
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_RDTSCP))
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_RDTSCP;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_X2APIC_VIRTUALIZATION))
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_VPID))
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_VPID_ENABLE;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_WBINVD_VMEXIT))
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_WBINVD_VMEXIT;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_UNRESTRICTED_GUEST))
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PAUSE_LOOP_EXITING))
cap->vmx_vmexec_ctrl2_supported_bits |= VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT;
// enable secondary vm exec controls if needed
if (cap->vmx_vmexec_ctrl2_supported_bits != 0)
cap->vmx_proc_vmexec_ctrl_supported_bits |= VMX_VM_EXEC_CTRL2_SECONDARY_CONTROLS;
// vmexit controls
// -----------------------------------------------------------
// 1 [01-00] Reserved (must be '1)
// 1 [02] Save guest MSR_DEBUGCTL on VMEXIT (legacy must be '1)
// 1 [08-03] Reserved (must be '1)
// [09] Host Address Space Size (x86-64 host, x86-64 support required)
// 1 [11-10] Reserved (must be '1)
// [12] Load host MSR_PERF_GLOBAL_CTRL on VMEXIT
// 1 [14-13] Reserved (must be '1)
// [15] Acknowledge interrupts on VMEXIT
// 1 [17-16] Reserved (must be '1)
// [18] Save guest MSR_PAT on VMEXIT
// [19] Load host MSR_PAT on VMEXIT
// [20] Save guest MSR_EFER on VMEXIT
// [21] Load host MSR_EFER on VMEXIT
// [22] Save VMX preemption timer counter on VMEXIT
cap->vmx_vmexit_ctrl_supported_bits =
VMX_VMEXIT_CTRL1_INTA_ON_VMEXIT | VMX_VMEXIT_CTRL1_SAVE_DBG_CTRLS;
if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_LONG_MODE))
cap->vmx_vmexit_ctrl_supported_bits |= VMX_VMEXIT_CTRL1_HOST_ADDR_SPACE_SIZE;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PERF_GLOBAL_CTRL))
cap->vmx_vmexit_ctrl_supported_bits |= VMX_VMEXIT_CTRL1_LOAD_PERF_GLOBAL_CTRL_MSR;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PAT)) {
cap->vmx_vmexit_ctrl_supported_bits |=
VMX_VMEXIT_CTRL1_STORE_PAT_MSR | VMX_VMEXIT_CTRL1_LOAD_PAT_MSR;
}
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EFER)) {
cap->vmx_vmexit_ctrl_supported_bits |=
VMX_VMEXIT_CTRL1_STORE_EFER_MSR | VMX_VMEXIT_CTRL1_LOAD_EFER_MSR;
}
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PREEMPTION_TIMER))
cap->vmx_vmexit_ctrl_supported_bits |= VMX_VMEXIT_CTRL1_STORE_VMX_PREEMPTION_TIMER;
// vmentry controls
// -----------------------------------------------------------
// 1 [01-00] Reserved (must be '1)
// 1 [02] Load MSR_DEBUGCTL on VMEXIT (legacy must be '1)
// 1 [08-03] Reserved (must be '1)
// [09] x86-64 guest (x86-64 support required)
// [10] Enter to SMM mode
// [11] Deactivate Dual SMM Monitor treatment
// 1 [12] Reserved (must be '1)
// [13] Load guest MSR_PERF_GLOBAL_CTRL
// [14] Load guest MSR_PAT
// [15] Load guest MSR_EFER
cap->vmx_vmentry_ctrl_supported_bits = VMX_VMENTRY_CTRL1_LOAD_DBG_CTRLS |
VMX_VMENTRY_CTRL1_SMM_ENTER |
VMX_VMENTRY_CTRL1_DEACTIVATE_DUAL_MONITOR_TREATMENT;
if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_LONG_MODE))
cap->vmx_vmentry_ctrl_supported_bits |= VMX_VMENTRY_CTRL1_X86_64_GUEST;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PERF_GLOBAL_CTRL))
cap->vmx_vmentry_ctrl_supported_bits |= VMX_VMENTRY_CTRL1_LOAD_PERF_GLOBAL_CTRL_MSR;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_PAT))
cap->vmx_vmentry_ctrl_supported_bits |= VMX_VMENTRY_CTRL1_LOAD_PAT_MSR;
if (BX_SUPPORT_VMX_EXTENSION(BX_VMX_EFER))
cap->vmx_vmentry_ctrl_supported_bits |= VMX_VMENTRY_CTRL1_LOAD_EFER_MSR;
}
#endif

@ -501,6 +501,19 @@ typedef struct bx_VMCS_HOST_STATE
#endif
} VMCS_HOST_STATE;
typedef struct bx_VMX_Cap
{
//
// VMX Capabilities
//
Bit32u vmx_pin_vmexec_ctrl_supported_bits;
Bit32u vmx_proc_vmexec_ctrl_supported_bits;
Bit32u vmx_vmexec_ctrl2_supported_bits;
Bit32u vmx_vmexit_ctrl_supported_bits;
Bit32u vmx_vmentry_ctrl_supported_bits;
} VMX_CAP;
typedef struct bx_VMCS
{
//
@ -519,9 +532,7 @@ typedef struct bx_VMCS
#else // only really supported features
#define VMX_VM_EXEC_CTRL1_SUPPORTED_BITS \
(VMX_VM_EXEC_CTRL1_EXTERNAL_INTERRUPT_VMEXIT | \
VMX_VM_EXEC_CTRL1_NMI_VMEXIT | \
((BX_SUPPORT_VMX >= 2) ? VMX_VM_EXEC_CTRL1_VMX_PREEMPTION_TIMER_VMEXIT : 0))
(BX_CPU_THIS_PTR vmx_cap.vmx_pin_vmexec_ctrl_supported_bits)
#endif
@ -556,26 +567,7 @@ typedef struct bx_VMCS
#else // only really supported features
#define VMX_VM_EXEC_CTRL2_SUPPORTED_BITS \
(VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT | \
VMX_VM_EXEC_CTRL2_TSC_OFFSET | \
VMX_VM_EXEC_CTRL2_HLT_VMEXIT | \
VMX_VM_EXEC_CTRL2_INVLPG_VMEXIT | \
VMX_VM_EXEC_CTRL2_MWAIT_VMEXIT | \
VMX_VM_EXEC_CTRL2_RDPMC_VMEXIT | \
VMX_VM_EXEC_CTRL2_RDTSC_VMEXIT | \
VMX_VM_EXEC_CTRL2_CR3_WRITE_VMEXIT | \
VMX_VM_EXEC_CTRL2_CR3_READ_VMEXIT | \
(BX_SUPPORT_X86_64 ? VMX_VM_EXEC_CTRL2_CR8_WRITE_VMEXIT : 0) | \
(BX_SUPPORT_X86_64 ? VMX_VM_EXEC_CTRL2_CR8_READ_VMEXIT : 0) | \
(BX_SUPPORT_X86_64 ? VMX_VM_EXEC_CTRL2_TPR_SHADOW : 0) | \
VMX_VM_EXEC_CTRL2_NMI_WINDOW_VMEXIT | \
VMX_VM_EXEC_CTRL2_DRx_ACCESS_VMEXIT | \
VMX_VM_EXEC_CTRL2_IO_VMEXIT | \
VMX_VM_EXEC_CTRL2_IO_BITMAPS | \
VMX_VM_EXEC_CTRL2_MSR_BITMAPS | \
VMX_VM_EXEC_CTRL2_MONITOR_VMEXIT | \
VMX_VM_EXEC_CTRL2_PAUSE_VMEXIT | \
((BX_SUPPORT_VMX >= 2) ? VMX_VM_EXEC_CTRL2_SECONDARY_CONTROLS : 0))
(BX_CPU_THIS_PTR vmx_cap.vmx_proc_vmexec_ctrl_supported_bits)
#endif
@ -599,15 +591,7 @@ typedef struct bx_VMCS
#else // only really supported features
#define VMX_VM_EXEC_CTRL3_SUPPORTED_BITS \
(VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES | \
VMX_VM_EXEC_CTRL3_EPT_ENABLE | \
VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT | \
VMX_VM_EXEC_CTRL3_RDTSCP | \
VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE | \
VMX_VM_EXEC_CTRL3_VPID_ENABLE | \
VMX_VM_EXEC_CTRL3_WBINVD_VMEXIT | \
VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST | \
VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT)
(BX_CPU_THIS_PTR vmx_cap.vmx_vmexec_ctrl2_supported_bits)
#endif
@ -668,14 +652,7 @@ typedef struct bx_VMCS
#else // only really supported features
#define VMX_VMEXIT_CTRL1_SUPPORTED_BITS \
(VMX_VMEXIT_CTRL1_SAVE_DBG_CTRLS | \
(BX_SUPPORT_X86_64 ? VMX_VMEXIT_CTRL1_HOST_ADDR_SPACE_SIZE : 0) | \
VMX_VMEXIT_CTRL1_INTA_ON_VMEXIT | \
((BX_SUPPORT_VMX >= 2) ? VMX_VMEXIT_CTRL1_STORE_PAT_MSR : 0) | \
((BX_SUPPORT_VMX >= 2) ? VMX_VMEXIT_CTRL1_LOAD_PAT_MSR : 0) | \
((BX_SUPPORT_VMX >= 2) ? VMX_VMEXIT_CTRL1_STORE_EFER_MSR : 0) | \
((BX_SUPPORT_VMX >= 2) ? VMX_VMEXIT_CTRL1_LOAD_EFER_MSR : 0) | \
((BX_SUPPORT_VMX >= 2) ? VMX_VMEXIT_CTRL1_STORE_VMX_PREEMPTION_TIMER : 0))
(BX_CPU_THIS_PTR vmx_cap.vmx_vmexit_ctrl_supported_bits)
#endif
@ -705,12 +682,7 @@ typedef struct bx_VMCS
#else // only really supported features
#define VMX_VMENTRY_CTRL1_SUPPORTED_BITS \
(VMX_VMENTRY_CTRL1_LOAD_DBG_CTRLS | \
(BX_SUPPORT_X86_64 ? VMX_VMENTRY_CTRL1_X86_64_GUEST : 0) | \
VMX_VMENTRY_CTRL1_SMM_ENTER | \
VMX_VMENTRY_CTRL1_DEACTIVATE_DUAL_MONITOR_TREATMENT | \
((BX_SUPPORT_VMX >= 2) ? VMX_VMENTRY_CTRL1_LOAD_PAT_MSR : 0) | \
((BX_SUPPORT_VMX >= 2) ? VMX_VMENTRY_CTRL1_LOAD_EFER_MSR : 0))
(BX_CPU_THIS_PTR vmx_cap.vmx_vmentry_ctrl_supported_bits)
#endif
@ -801,7 +773,7 @@ enum VMX_Activity_State {
#define VMX_MSR_VMX_BASIC_LO (VMX_VMCS_REVISION_ID)
#define VMX_MSR_VMX_BASIC_HI \
(VMX_VMCS_AREA_SIZE | ((!BX_SUPPORT_X86_64) << 16) | \
(VMX_VMCS_AREA_SIZE | ((!bx_cpuid_support_x86_64()) << 16) | \
(BX_MEMTYPE_WB << 18) | (1<<22)) | ((BX_SUPPORT_VMX >= 2) ? (1<<23) : 0)
#define VMX_MSR_VMX_BASIC \

@ -34,7 +34,6 @@ bx_define_cpudb(atom_n270)
#if BX_SUPPORT_X86_64
bx_define_cpudb(p4_prescott_celeron_336)
bx_define_cpudb(athlon64_clawhammer)
bx_define_cpudb(core2_extreme_x9770)
bx_define_cpudb(core2_penryn_t9600)
#if BX_SUPPORT_AVX
bx_define_cpudb(corei7_sandy_bridge_2600k)