summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-06-25 16:18:05 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-06-25 16:18:05 +0000
commita363e34cc51220a31691d54e576fb0e29ec02646 (patch)
tree529a6c74433e28079cc24084b781477e62f42e8d
parentea041c0e3375801694610250a8cc3e1240e2ad87 (diff)
downloadqemu-a363e34cc51220a31691d54e576fb0e29ec02646.tar.gz
fixed VM86 support in Virtual Linux - fixed compilation issues with gcc 2.96 - cpuid returns now pentium pro in order to avoid F00F bug workaround in Linux kernel
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@277 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--helper-i386.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/helper-i386.c b/helper-i386.c
index 9fc40181ae..f47252ac12 100644
--- a/helper-i386.c
+++ b/helper-i386.c
@@ -216,7 +216,10 @@ static void do_interrupt_protected(int intno, int is_int, int error_code,
break;
}
dpl = (e2 >> DESC_DPL_SHIFT) & 3;
- cpl = env->segs[R_CS].selector & 3;
+ if (env->eflags & VM_MASK)
+ cpl = 3;
+ else
+ cpl = env->segs[R_CS].selector & 3;
/* check privledge if software int */
if (is_int && dpl < cpl)
raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
@@ -572,13 +575,25 @@ void helper_cpuid(void)
ECX = 0x6c65746e;
EDX = 0x49656e69;
} else if (EAX == 1) {
+ int family, model, stepping;
/* EAX = 1 info */
- EAX = 0x52b;
+#if 0
+ /* pentium 75-200 */
+ family = 5;
+ model = 2;
+ stepping = 11;
+#else
+ /* pentium pro */
+ family = 6;
+ model = 1;
+ stepping = 3;
+#endif
+ EAX = (family << 8) | (model << 4) | stepping;
EBX = 0;
ECX = 0;
EDX = CPUID_FP87 | CPUID_DE | CPUID_PSE |
CPUID_TSC | CPUID_MSR | CPUID_MCE |
- CPUID_CX8;
+ CPUID_CX8 | CPUID_PGE | CPUID_CMOV;
}
}
@@ -751,7 +766,9 @@ void jmp_seg(int selector, unsigned int new_eip)
load_seg_cache(&sc1, e1, e2);
if (new_eip > sc1.limit)
raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
- env->segs[R_CS] = sc1;
+ env->segs[R_CS].base = sc1.base;
+ env->segs[R_CS].limit = sc1.limit;
+ env->segs[R_CS].flags = sc1.flags;
env->segs[R_CS].selector = (selector & 0xfffc) | cpl;
EIP = new_eip;
} else {