aboutsummaryrefslogtreecommitdiff
path: root/target-i386/op_helper.c
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-11-05 15:34:06 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-11-05 15:34:06 +0000
commit6fd805e1d45308d156469562bc6fd6d1e8d92360 (patch)
treebd6d43cb9e90707df4c021f997e5b1b14887d1ed /target-i386/op_helper.c
parent0650f1ab3042f05e9bf8ed9fe3d4dc130b38f162 (diff)
Split CPUID from op_helper
KVM needs to call CPUID from outside of the TCG code. This patch splits out the CPUID logic into a separate helper that both the op helper and KVM can call. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5626 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386/op_helper.c')
-rw-r--r--target-i386/op_helper.c168
1 files changed, 6 insertions, 162 deletions
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index d0919d95ff..c9c0936a70 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)