aboutsummaryrefslogtreecommitdiff
path: root/target-i386
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-02-10 22:05:51 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-02-10 22:05:51 +0000
commit9df217a31741e21eb63a5e3ee8529391ba3762e3 (patch)
tree53332ef1b810f1093cbf300381457fc6cdde97b5 /target-i386
parent92a31b1fff09bed823865262d4b3c8e7b246c812 (diff)
kqemu support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1283 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386')
-rw-r--r--target-i386/cpu.h35
-rw-r--r--target-i386/helper.c28
2 files changed, 52 insertions, 11 deletions
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 781be2838e..74c882b867 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -39,6 +39,9 @@
#if defined(__i386__) && !defined(CONFIG_SOFTMMU)
#define USE_CODE_COPY
#endif
+#if defined(__linux__) && defined(CONFIG_SOFTMMU) && defined(__i386__) && !defined(TARGET_X86_64)
+#define USE_KQEMU
+#endif
#define R_EAX 0
#define R_ECX 1
@@ -248,6 +251,14 @@
#define CPUID_SSE (1 << 25)
#define CPUID_SSE2 (1 << 26)
+#define CPUID_EXT_SS3 (1 << 0)
+#define CPUID_EXT_MONITOR (1 << 3)
+#define CPUID_EXT_CX16 (1 << 13)
+
+#define CPUID_EXT2_SYSCALL (1 << 11)
+#define CPUID_EXT2_NX (1 << 20)
+#define CPUID_EXT2_LM (1 << 29)
+
#define EXCP00_DIVZ 0
#define EXCP01_SSTP 1
#define EXCP02_NMI 2
@@ -408,6 +419,16 @@ typedef struct CPUX86State {
int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
uint32_t hflags; /* hidden flags, see HF_xxx constants */
+ /* segments */
+ SegmentCache segs[6]; /* selector values */
+ SegmentCache ldt;
+ SegmentCache tr;
+ SegmentCache gdt; /* only base and limit are used */
+ SegmentCache idt; /* only base and limit are used */
+
+ target_ulong cr[5]; /* NOTE: cr1 is unused */
+ uint32_t a20_mask;
+
/* FPU state */
unsigned int fpstt; /* top of stack index */
unsigned int fpus;
@@ -431,13 +452,6 @@ typedef struct CPUX86State {
int64_t i64;
} fp_convert;
- /* segments */
- SegmentCache segs[6]; /* selector values */
- SegmentCache ldt;
- SegmentCache tr;
- SegmentCache gdt; /* only base and limit are used */
- SegmentCache idt; /* only base and limit are used */
-
uint32_t mxcsr;
XMMReg xmm_regs[CPU_NB_REGS];
XMMReg xmm_t0;
@@ -470,13 +484,10 @@ typedef struct CPUX86State {
int exception_is_int;
target_ulong exception_next_eip;
struct TranslationBlock *current_tb; /* currently executing TB */
- target_ulong cr[5]; /* NOTE: cr1 is unused */
target_ulong dr[8]; /* debug registers */
int interrupt_request;
int user_mode_only; /* user mode only simulation */
- uint32_t a20_mask;
-
/* soft mmu support */
/* in order to avoid passing too many arguments to the memory
write helpers, we store some rarely used information in the CPU
@@ -501,7 +512,11 @@ typedef struct CPUX86State {
uint32_t cpuid_vendor3;
uint32_t cpuid_version;
uint32_t cpuid_features;
+ uint32_t cpuid_ext_features;
+#ifdef USE_KQEMU
+ int kqemu_enabled;
+#endif
/* in order to simplify APIC support, we leave this pointer to the
user */
struct APICState *apic_state;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index ea2ef5e027..b727e93d66 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1274,7 +1274,7 @@ void helper_cpuid(void)
case 1:
EAX = env->cpuid_version;
EBX = 0;
- ECX = 0;
+ ECX = env->cpuid_ext_features;
EDX = env->cpuid_features;
break;
default:
@@ -1828,6 +1828,12 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
ESP = (ESP & ~sp_mask) | (sp & sp_mask);
EIP = offset;
}
+#ifdef USE_KQEMU
+ if (kqemu_is_ok(env)) {
+ env->exception_index = -1;
+ cpu_loop_exit();
+ }
+#endif
}
/* real and vm86 mode iret */
@@ -2097,11 +2103,25 @@ void helper_iret_protected(int shift, int next_eip)
} else {
helper_ret_protected(shift, 1, 0);
}
+#ifdef USE_KQEMU
+ if (kqemu_is_ok(env)) {
+ CC_OP = CC_OP_EFLAGS;
+ env->exception_index = -1;
+ cpu_loop_exit();
+ }
+#endif
}
void helper_lret_protected(int shift, int addend)
{
helper_ret_protected(shift, 0, addend);
+#ifdef USE_KQEMU
+ if (kqemu_is_ok(env)) {
+ CC_OP = CC_OP_EFLAGS;
+ env->exception_index = -1;
+ cpu_loop_exit();
+ }
+#endif
}
void helper_sysenter(void)
@@ -2146,6 +2166,12 @@ void helper_sysexit(void)
DESC_W_MASK | DESC_A_MASK);
ESP = ECX;
EIP = EDX;
+#ifdef USE_KQEMU
+ if (kqemu_is_ok(env)) {
+ env->exception_index = -1;
+ cpu_loop_exit();
+ }
+#endif
}
void helper_movl_crN_T0(int reg)