Commit 9df217a3 authored by bellard's avatar bellard

kqemu support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1283 c046a42c-6fe2-441c-8c8c-71466251a162
parent 92a31b1f
...@@ -209,7 +209,33 @@ int cpu_exec(CPUState *env1) ...@@ -209,7 +209,33 @@ int cpu_exec(CPUState *env1)
#endif #endif
} }
env->exception_index = -1; env->exception_index = -1;
}
#ifdef USE_KQEMU
if (kqemu_is_ok(env) && env->interrupt_request == 0) {
int ret;
env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
ret = kqemu_cpu_exec(env);
/* put eflags in CPU temporary format */
CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
DF = 1 - (2 * ((env->eflags >> 10) & 1));
CC_OP = CC_OP_EFLAGS;
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
if (ret == 1) {
/* exception */
longjmp(env->jmp_env, 1);
} else if (ret == 2) {
/* softmmu execution needed */
} else {
if (env->interrupt_request != 0) {
/* hardware interrupt will be executed just after */
} else {
/* otherwise, we restart */
longjmp(env->jmp_env, 1);
}
}
} }
#endif
T0 = 0; /* force lookup of first TB */ T0 = 0; /* force lookup of first TB */
for(;;) { for(;;) {
#ifdef __sparc__ #ifdef __sparc__
......
...@@ -586,3 +586,25 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) ...@@ -586,3 +586,25 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base; return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base;
} }
#endif #endif
#ifdef USE_KQEMU
extern int kqemu_fd;
extern int kqemu_flushed;
int kqemu_init(CPUState *env);
int kqemu_cpu_exec(CPUState *env);
void kqemu_flush_page(CPUState *env, target_ulong addr);
void kqemu_flush(CPUState *env, int global);
static inline int kqemu_is_ok(CPUState *env)
{
return(env->kqemu_enabled &&
(env->hflags & HF_CPL_MASK) == 3 &&
(env->eflags & IOPL_MASK) != IOPL_MASK &&
(env->cr[0] & CR0_PE_MASK) &&
(env->eflags & IF_MASK) &&
!(env->eflags & VM_MASK));
}
#endif
This diff is collapsed.
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
#if defined(__i386__) && !defined(CONFIG_SOFTMMU) #if defined(__i386__) && !defined(CONFIG_SOFTMMU)
#define USE_CODE_COPY #define USE_CODE_COPY
#endif #endif
#if defined(__linux__) && defined(CONFIG_SOFTMMU) && defined(__i386__) && !defined(TARGET_X86_64)
#define USE_KQEMU
#endif
#define R_EAX 0 #define R_EAX 0
#define R_ECX 1 #define R_ECX 1
...@@ -248,6 +251,14 @@ ...@@ -248,6 +251,14 @@
#define CPUID_SSE (1 << 25) #define CPUID_SSE (1 << 25)
#define CPUID_SSE2 (1 << 26) #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 EXCP00_DIVZ 0
#define EXCP01_SSTP 1 #define EXCP01_SSTP 1
#define EXCP02_NMI 2 #define EXCP02_NMI 2
...@@ -408,6 +419,16 @@ typedef struct CPUX86State { ...@@ -408,6 +419,16 @@ typedef struct CPUX86State {
int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */ int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
uint32_t hflags; /* hidden flags, see HF_xxx constants */ 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 */ /* FPU state */
unsigned int fpstt; /* top of stack index */ unsigned int fpstt; /* top of stack index */
unsigned int fpus; unsigned int fpus;
...@@ -431,13 +452,6 @@ typedef struct CPUX86State { ...@@ -431,13 +452,6 @@ typedef struct CPUX86State {
int64_t i64; int64_t i64;
} fp_convert; } 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; uint32_t mxcsr;
XMMReg xmm_regs[CPU_NB_REGS]; XMMReg xmm_regs[CPU_NB_REGS];
XMMReg xmm_t0; XMMReg xmm_t0;
...@@ -470,13 +484,10 @@ typedef struct CPUX86State { ...@@ -470,13 +484,10 @@ typedef struct CPUX86State {
int exception_is_int; int exception_is_int;
target_ulong exception_next_eip; target_ulong exception_next_eip;
struct TranslationBlock *current_tb; /* currently executing TB */ struct TranslationBlock *current_tb; /* currently executing TB */
target_ulong cr[5]; /* NOTE: cr1 is unused */
target_ulong dr[8]; /* debug registers */ target_ulong dr[8]; /* debug registers */
int interrupt_request; int interrupt_request;
int user_mode_only; /* user mode only simulation */ int user_mode_only; /* user mode only simulation */
uint32_t a20_mask;
/* soft mmu support */ /* soft mmu support */
/* in order to avoid passing too many arguments to the memory /* in order to avoid passing too many arguments to the memory
write helpers, we store some rarely used information in the CPU write helpers, we store some rarely used information in the CPU
...@@ -501,7 +512,11 @@ typedef struct CPUX86State { ...@@ -501,7 +512,11 @@ typedef struct CPUX86State {
uint32_t cpuid_vendor3; uint32_t cpuid_vendor3;
uint32_t cpuid_version; uint32_t cpuid_version;
uint32_t cpuid_features; 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 /* in order to simplify APIC support, we leave this pointer to the
user */ user */
struct APICState *apic_state; struct APICState *apic_state;
......
...@@ -1274,7 +1274,7 @@ void helper_cpuid(void) ...@@ -1274,7 +1274,7 @@ void helper_cpuid(void)
case 1: case 1:
EAX = env->cpuid_version; EAX = env->cpuid_version;
EBX = 0; EBX = 0;
ECX = 0; ECX = env->cpuid_ext_features;
EDX = env->cpuid_features; EDX = env->cpuid_features;
break; break;
default: default:
...@@ -1828,6 +1828,12 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) ...@@ -1828,6 +1828,12 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip)
ESP = (ESP & ~sp_mask) | (sp & sp_mask); ESP = (ESP & ~sp_mask) | (sp & sp_mask);
EIP = offset; EIP = offset;
} }
#ifdef USE_KQEMU
if (kqemu_is_ok(env)) {
env->exception_index = -1;
cpu_loop_exit();
}
#endif
} }
/* real and vm86 mode iret */ /* real and vm86 mode iret */
...@@ -2097,11 +2103,25 @@ void helper_iret_protected(int shift, int next_eip) ...@@ -2097,11 +2103,25 @@ void helper_iret_protected(int shift, int next_eip)
} else { } else {
helper_ret_protected(shift, 1, 0); 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) void helper_lret_protected(int shift, int addend)
{ {
helper_ret_protected(shift, 0, 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) void helper_sysenter(void)
...@@ -2146,6 +2166,12 @@ void helper_sysexit(void) ...@@ -2146,6 +2166,12 @@ void helper_sysexit(void)
DESC_W_MASK | DESC_A_MASK); DESC_W_MASK | DESC_A_MASK);
ESP = ECX; ESP = ECX;
EIP = EDX; 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) void helper_movl_crN_T0(int reg)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment