added basic (very basic) SVM CPUID into generic_cpuid module

This commit is contained in:
Stanislav Shwartsman 2011-12-28 21:54:51 +00:00
parent 0a14f08f16
commit 2b854cb101
6 changed files with 101 additions and 40 deletions

View File

@ -343,6 +343,9 @@ void amd_k6_2_chomper_t::dump_cpuid(void) const
get_cpuid_leaf(n, 0x00000000, &leaf);
BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx));
}
get_cpuid_leaf(0x8fffffff, 0x00000000, &leaf);
BX_INFO(("CPUID[0x8fffffff]: %08x %08x %08x %08x", leaf.eax, leaf.ebx, leaf.ecx, leaf.edx));
}
bx_cpuid_t *create_amd_k6_2_chomper_cpuid(BX_CPU_C *cpu) { return new amd_k6_2_chomper_t(cpu); }

View File

@ -431,6 +431,9 @@ void athlon64_clawhammer_t::dump_cpuid(void) const
get_cpuid_leaf(n, 0x00000000, &leaf);
BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx));
}
get_cpuid_leaf(0x8fffffff, 0x00000000, &leaf);
BX_INFO(("CPUID[0x8fffffff]: %08x %08x %08x %08x", leaf.eax, leaf.ebx, leaf.ecx, leaf.edx));
}
bx_cpuid_t *create_athlon64_clawhammer_cpuid(BX_CPU_C *cpu) { return new athlon64_clawhammer_t(cpu); }

View File

@ -40,6 +40,35 @@ bx_generic_cpuid_t::bx_generic_cpuid_t(BX_CPU_C *cpu): bx_cpuid_t(cpu)
init_isa_extensions_bitmask();
init_cpu_extensions_bitmask();
#if BX_CPU_LEVEL <= 5
// 486 and Pentium processors
max_std_leaf = 1;
#else
// for Pentium Pro, Pentium II, Pentium 4 processors
max_std_leaf = 2;
// do not report CPUID functions above 0x3 if cpuid_limit_winnt is set
// to workaround WinNT issue.
static bx_bool cpuid_limit_winnt = SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->get();
if (! cpuid_limit_winnt) {
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_MONITOR_MWAIT))
max_std_leaf = 0x5;
if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_X2APIC))
max_std_leaf = 0xB;
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_XSAVE))
max_std_leaf = 0xD;
}
#endif
#if BX_CPU_LEVEL <= 5
max_ext_leaf = 0;
#else
max_ext_leaf = 0x80000008;
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_SVM))
max_ext_leaf = 0x8000000A;
#endif
}
void bx_generic_cpuid_t::get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpuid_function_t *leaf) const
@ -48,6 +77,13 @@ void bx_generic_cpuid_t::get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpu
if (cpuid_limit_winnt)
if (function > 2 && function < 0x80000000) function = 2;
#if BX_CPU_LEVEL >= 6
if (function >= 0x80000000 && function > max_ext_leaf)
function = max_ext_leaf;
#endif
if (function < 0x80000000 && function > max_std_leaf)
function = max_std_leaf;
switch(function) {
#if BX_CPU_LEVEL >= 6
case 0x80000000:
@ -61,7 +97,6 @@ void bx_generic_cpuid_t::get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpu
case 0x80000004:
get_ext_cpuid_brand_string_leaf(function, leaf);
return;
#if BX_SUPPORT_X86_64
case 0x80000005:
get_ext_cpuid_leaf_5(leaf);
return;
@ -74,6 +109,10 @@ void bx_generic_cpuid_t::get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpu
case 0x80000008:
get_ext_cpuid_leaf_8(leaf);
return;
#if BX_SUPPORT_SVM
case 0x8000000A:
get_ext_cpuid_leaf_A(leaf);
return;
#endif
#endif
case 0x00000000:
@ -133,26 +172,7 @@ void bx_generic_cpuid_t::get_std_cpuid_leaf_0(cpuid_function_t *leaf) const
// EBX: vendor ID string
// EDX: vendor ID string
// ECX: vendor ID string
#if BX_CPU_LEVEL <= 5
// 486 and Pentium processors
leaf->eax = 1;
#else
// for Pentium Pro, Pentium II, Pentium 4 processors
leaf->eax = 2;
// do not report CPUID functions above 0x3 if cpuid_limit_winnt is set
// to workaround WinNT issue.
static bx_bool cpuid_limit_winnt = SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->get();
if (! cpuid_limit_winnt) {
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_MONITOR_MWAIT))
leaf->eax = 0x5;
if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_X2APIC))
leaf->eax = 0xb;
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_XSAVE))
leaf->eax = 0xd;
}
#endif
leaf->eax = max_std_leaf;
// CPUID vendor string (e.g. GenuineIntel, AuthenticAMD, CentaurHauls, ...)
memcpy(&(leaf->ebx), vendor_string, 4);
@ -459,7 +479,7 @@ void bx_generic_cpuid_t::get_ext_cpuid_leaf_0(cpuid_function_t *leaf) const
// EBX: vendor ID string
// EDX: vendor ID string
// ECX: vendor ID string
leaf->eax = BX_SUPPORT_X86_64 ? 0x80000008 : 0x80000004;
leaf->eax = max_ext_leaf;
#if BX_CPU_VENDOR_INTEL
leaf->ebx = 0;
leaf->edx = 0; // Reserved for Intel
@ -566,8 +586,6 @@ void bx_generic_cpuid_t::get_ext_cpuid_brand_string_leaf(Bit32u function, cpuid_
#endif
}
#if BX_SUPPORT_X86_64
// leaf 0x80000005 //
void bx_generic_cpuid_t::get_ext_cpuid_leaf_5(cpuid_function_t *leaf) const
{
@ -608,6 +626,40 @@ void bx_generic_cpuid_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) const
leaf->edx = 0;
}
#if BX_SUPPORT_SVM
// leaf 0x8000000A //
void bx_generic_cpuid_t::get_ext_cpuid_leaf_A(cpuid_function_t *leaf) const
{
if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_SVM))
{
leaf->eax = BX_SVM_REVISION;
leaf->ebx = 0x40; /* number of ASIDs */
leaf->ecx = 0;
// [0:0] NP - Nested paging support
// [1:1] LBR virtualization
// [2:2] SVM Lock
// [3:3] NRIPS - Next RIP save on VMEXIT
// [4:4] TscRate - MSR based TSC ratio control
// [5:5] VMCB Clean bits support
// [6:6] Flush by ASID support
// [7:7] Decode assists support
// [9:8] Reserved
// [10:10] Pause filter support
// [11:11] Reserved
// [12:12] Pause filter threshold support
// [31:13] Reserved
leaf->edx = 0;
}
else {
leaf->eax = 0;
leaf->ebx = 0;
leaf->ecx = 0; // Reserved, undefined
leaf->edx = 0;
}
}
#endif
#endif
@ -1432,25 +1484,16 @@ Bit32u bx_generic_cpuid_t::get_ext3_cpuid_features(void) const
void bx_generic_cpuid_t::dump_cpuid(void) const
{
struct cpuid_function_t leaf;
unsigned n;
get_cpuid_leaf(0x00000000, 0x00000000, &leaf);
BX_INFO(("CPUID[0x00000000]: %08x %08x %08x %08x", leaf.eax, leaf.ebx, leaf.ecx, leaf.edx));
Bit32u max_std_function = leaf.eax, n;
if (max_std_function > 0) {
for (n=1; n<=max_std_function;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=0; n <= max_std_leaf; 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));
}
#if BX_CPU_LEVEL >= 6
get_cpuid_leaf(0x80000000, 0x00000000, &leaf);
BX_INFO(("CPUID[0x80000000]: %08x %08x %08x %08x", leaf.eax, leaf.ebx, leaf.ecx, leaf.edx));
Bit32u max_ext_function = leaf.eax;
if (max_ext_function > 0) {
for (n=0x80000001; n<=max_ext_function;n++) {
if (max_ext_leaf > 0) {
for (n=0x80000000; n <= max_ext_leaf; 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));
}

View File

@ -74,6 +74,9 @@ private:
unsigned nthreads;
#endif
unsigned max_std_leaf;
unsigned max_ext_leaf;
void get_std_cpuid_leaf_0(cpuid_function_t *leaf) const;
void get_std_cpuid_leaf_1(cpuid_function_t *leaf) const;
#if BX_CPU_LEVEL >= 6
@ -91,11 +94,12 @@ private:
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;
#if BX_SUPPORT_X86_64
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;
#if BX_SUPPORT_SVM
void get_ext_cpuid_leaf_A(cpuid_function_t *leaf) const;
#endif
Bit32u get_std2_cpuid_features(void) const;

View File

@ -341,6 +341,12 @@ bx_bool BX_CPU_C::SvmEnterLoadCheckControls(SVM_CONTROLS *ctrls)
return 0;
}
Bit32u guest_asid = vmcb_read32(SVM_CONTROL_GUEST_ASID);
if (guest_asid == 0) {
BX_ERROR(("VMRUN: attempt to run guest with host ASID !"));
return 0;
}
ctrls->v_tpr = vmcb_read8(SVM_CONTROL_VTPR);
ctrls->v_irq = vmcb_read8(SVM_CONTROL_VIRQ) & 0x1;
ctrls->v_intr_masking = vmcb_read8(SVM_CONTROL_VINTR_MASKING) & 0x1;

View File

@ -26,6 +26,8 @@
#if BX_SUPPORT_SVM
#define BX_SVM_REVISION 0x01 /* FIXME: check what is real SVM revision */
enum SVM_intercept_codes {
SVM_VMEXIT_CR0_READ = 0,
SVM_VMEXIT_CR2_READ = 2,