From: Anthony Liguori <aliguori@us.ibm.com>
To: qemu-devel@nongnu.org
Cc: Glauber Costa <glommer@redhat.com>, Avi Kivity <avi@redhat.com>,
kvm-devel <kvm@vger.kernel.org>,
Anthony Liguori <aliguori@us.ibm.com>
Subject: [Qemu-devel] [PATCH 2/3] Split CPUID from op_helper
Date: Tue, 28 Oct 2008 15:13:33 -0500 [thread overview]
Message-ID: <1225224814-9875-2-git-send-email-aliguori@us.ibm.com> (raw)
In-Reply-To: <1225224814-9875-1-git-send-email-aliguori@us.ibm.com>
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>
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index b1678ef..263a477 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -730,6 +730,10 @@ void cpu_smm_update(CPUX86State *env);
/* will be suppressed */
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
+void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx);
+
/* used to debug */
#define X86_DUMP_FPU 0x0001 /* dump FPU state too */
#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
diff --git a/target-i386/helper.c b/target-i386/helper.c
index c2e1a88..905ae9b 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1287,3 +1287,169 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
return paddr;
}
#endif /* !CONFIG_USER_ONLY */
+
+void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ /* 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;
+ }
+}
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index ebb5824..e424c61 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)
next prev parent reply other threads:[~2008-10-28 20:14 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-28 20:13 [Qemu-devel] [PATCH 1/3] Add additional CPU flag definitions Anthony Liguori
2008-10-28 20:13 ` Anthony Liguori [this message]
2008-10-28 20:13 ` [Qemu-devel] [PATCH 3/3] Add KVM support to QEMU Anthony Liguori
2008-10-28 20:49 ` Hollis Blanchard
2008-10-28 21:10 ` Anthony Liguori
2008-10-28 20:57 ` Andreas Färber
2008-10-28 21:04 ` Glauber Costa
2008-10-28 21:16 ` Anthony Liguori
2008-10-28 21:05 ` Anthony Liguori
2008-11-04 13:25 ` Avi Kivity
2008-10-28 21:41 ` [Qemu-devel] " Gerd Hoffmann
2008-10-28 21:51 ` Anthony Liguori
2008-10-28 23:04 ` Glauber Costa
2008-10-28 23:36 ` Anthony Liguori
2008-10-29 9:54 ` Avi Kivity
2008-10-29 12:35 ` Glauber Costa
2008-10-29 12:39 ` Avi Kivity
2008-10-29 12:56 ` Glauber Costa
2008-10-29 13:07 ` Anthony Liguori
2008-10-29 13:23 ` Avi Kivity
2008-10-29 13:32 ` Anthony Liguori
2008-10-29 13:51 ` Hollis Blanchard
2008-10-29 14:09 ` Avi Kivity
2008-10-29 14:16 ` Fabrice Bellard
2008-10-29 14:23 ` Anthony Liguori
2008-10-29 19:13 ` Blue Swirl
2008-11-01 16:25 ` Blue Swirl
2008-10-29 14:58 ` Glauber Costa
2008-10-29 17:41 ` Glauber Costa
2008-10-29 19:01 ` Anthony Liguori
2008-11-04 13:24 ` Avi Kivity
2008-11-04 14:02 ` Anthony Liguori
2008-11-04 14:46 ` Avi Kivity
2008-11-04 14:50 ` Anthony Liguori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1225224814-9875-2-git-send-email-aliguori@us.ibm.com \
--to=aliguori@us.ibm.com \
--cc=avi@redhat.com \
--cc=glommer@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).