diff options
Diffstat (limited to 'target-i386/op_helper.c')
-rw-r--r-- | target-i386/op_helper.c | 168 |
1 files changed, 6 insertions, 162 deletions
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index d0919d9..c9c0936 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -1885,171 +1885,15 @@ void helper_single_step(void) void helper_cpuid(void) { - uint32_t index; + uint32_t eax, ebx, ecx, edx; helper_svm_check_intercept_param(SVM_EXIT_CPUID, 0); - - index = (uint32_t)EAX; - /* test if maximum index reached */ - if (index & 0x80000000) { - if (index > env->cpuid_xlevel) - index = env->cpuid_level; - } else { - if (index > env->cpuid_level) - index = env->cpuid_level; - } - switch(index) { - case 0: - EAX = env->cpuid_level; - EBX = env->cpuid_vendor1; - EDX = env->cpuid_vendor2; - ECX = env->cpuid_vendor3; - break; - case 1: - EAX = env->cpuid_version; - EBX = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */ - ECX = env->cpuid_ext_features; - EDX = env->cpuid_features; - break; - case 2: - /* cache info: needed for Pentium Pro compatibility */ - EAX = 1; - EBX = 0; - ECX = 0; - EDX = 0x2c307d; - break; - case 4: - /* cache info: needed for Core compatibility */ - switch (ECX) { - case 0: /* L1 dcache info */ - EAX = 0x0000121; - EBX = 0x1c0003f; - ECX = 0x000003f; - EDX = 0x0000001; - break; - case 1: /* L1 icache info */ - EAX = 0x0000122; - EBX = 0x1c0003f; - ECX = 0x000003f; - EDX = 0x0000001; - break; - case 2: /* L2 cache info */ - EAX = 0x0000143; - EBX = 0x3c0003f; - ECX = 0x0000fff; - EDX = 0x0000001; - break; - default: /* end of info */ - EAX = 0; - EBX = 0; - ECX = 0; - EDX = 0; - break; - } - - break; - case 5: - /* mwait info: needed for Core compatibility */ - EAX = 0; /* Smallest monitor-line size in bytes */ - EBX = 0; /* Largest monitor-line size in bytes */ - ECX = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE; - EDX = 0; - break; - case 6: - /* Thermal and Power Leaf */ - EAX = 0; - EBX = 0; - ECX = 0; - EDX = 0; - break; - case 9: - /* Direct Cache Access Information Leaf */ - EAX = 0; /* Bits 0-31 in DCA_CAP MSR */ - EBX = 0; - ECX = 0; - EDX = 0; - break; - case 0xA: - /* Architectural Performance Monitoring Leaf */ - EAX = 0; - EBX = 0; - ECX = 0; - EDX = 0; - break; - case 0x80000000: - EAX = env->cpuid_xlevel; - EBX = env->cpuid_vendor1; - EDX = env->cpuid_vendor2; - ECX = env->cpuid_vendor3; - break; - case 0x80000001: - EAX = env->cpuid_features; - EBX = 0; - ECX = env->cpuid_ext3_features; - EDX = env->cpuid_ext2_features; - break; - case 0x80000002: - case 0x80000003: - case 0x80000004: - EAX = env->cpuid_model[(index - 0x80000002) * 4 + 0]; - EBX = env->cpuid_model[(index - 0x80000002) * 4 + 1]; - ECX = env->cpuid_model[(index - 0x80000002) * 4 + 2]; - EDX = env->cpuid_model[(index - 0x80000002) * 4 + 3]; - break; - case 0x80000005: - /* cache info (L1 cache) */ - EAX = 0x01ff01ff; - EBX = 0x01ff01ff; - ECX = 0x40020140; - EDX = 0x40020140; - break; - case 0x80000006: - /* cache info (L2 cache) */ - EAX = 0; - EBX = 0x42004200; - ECX = 0x02008140; - EDX = 0; - break; - case 0x80000008: - /* virtual & phys address size in low 2 bytes. */ -/* XXX: This value must match the one used in the MMU code. */ - if (env->cpuid_ext2_features & CPUID_EXT2_LM) { - /* 64 bit processor */ -#if defined(USE_KQEMU) - EAX = 0x00003020; /* 48 bits virtual, 32 bits physical */ -#else -/* XXX: The physical address space is limited to 42 bits in exec.c. */ - EAX = 0x00003028; /* 48 bits virtual, 40 bits physical */ -#endif - } else { -#if defined(USE_KQEMU) - EAX = 0x00000020; /* 32 bits physical */ -#else - if (env->cpuid_features & CPUID_PSE36) - EAX = 0x00000024; /* 36 bits physical */ - else - EAX = 0x00000020; /* 32 bits physical */ -#endif - } - EBX = 0; - ECX = 0; - EDX = 0; - break; - case 0x8000000A: - EAX = 0x00000001; /* SVM Revision */ - EBX = 0x00000010; /* nr of ASIDs */ - ECX = 0; - EDX = 0; /* optional features */ - break; - default: - /* reserved values: zero */ - EAX = 0; - EBX = 0; - ECX = 0; - EDX = 0; - break; - } + cpu_x86_cpuid(env, (uint32_t)EAX, &eax, &ebx, &ecx, &edx); + EAX = eax; + EBX = ebx; + ECX = ecx; + EDX = edx; } void helper_enter_level(int level, int data32, target_ulong t1) |