Commit c28e951fc797115eb7c79d31519215f5d79efea2

Authored by bellard
1 parent 07f4ddbf

x86_64 support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1371 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 77 additions and 9 deletions
@@ -45,6 +45,11 @@ @@ -45,6 +45,11 @@
45 #include <fcntl.h> 45 #include <fcntl.h>
46 #include "kqemu/kqemu.h" 46 #include "kqemu/kqemu.h"
47 47
  48 +/* compatibility stuff */
  49 +#ifndef KQEMU_RET_SYSCALL
  50 +#define KQEMU_RET_SYSCALL 0x0300 /* syscall insn */
  51 +#endif
  52 +
48 #ifdef _WIN32 53 #ifdef _WIN32
49 #define KQEMU_DEVICE "\\\\.\\kqemu" 54 #define KQEMU_DEVICE "\\\\.\\kqemu"
50 #else 55 #else
@@ -71,6 +76,12 @@ extern uint32_t **l1_phys_map; @@ -71,6 +76,12 @@ extern uint32_t **l1_phys_map;
71 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \ 76 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
72 : "0" (index)) 77 : "0" (index))
73 78
  79 +#ifdef __x86_64__
  80 +static int is_cpuid_supported(void)
  81 +{
  82 + return 1;
  83 +}
  84 +#else
74 static int is_cpuid_supported(void) 85 static int is_cpuid_supported(void)
75 { 86 {
76 int v0, v1; 87 int v0, v1;
@@ -87,6 +98,7 @@ static int is_cpuid_supported(void) @@ -87,6 +98,7 @@ static int is_cpuid_supported(void)
87 : "cc"); 98 : "cc");
88 return (v0 != v1); 99 return (v0 != v1);
89 } 100 }
  101 +#endif
90 102
91 static void kqemu_update_cpuid(CPUState *env) 103 static void kqemu_update_cpuid(CPUState *env)
92 { 104 {
@@ -231,8 +243,8 @@ struct fpxstate { @@ -231,8 +243,8 @@ struct fpxstate {
231 uint32_t mxcsr; 243 uint32_t mxcsr;
232 uint32_t mxcsr_mask; 244 uint32_t mxcsr_mask;
233 uint8_t fpregs1[8 * 16]; 245 uint8_t fpregs1[8 * 16];
234 - uint8_t xmm_regs[8 * 16];  
235 - uint8_t dummy2[224]; 246 + uint8_t xmm_regs[16 * 16];
  247 + uint8_t dummy2[96];
236 }; 248 };
237 249
238 static struct fpxstate fpx1 __attribute__((aligned(16))); 250 static struct fpxstate fpx1 __attribute__((aligned(16)));
@@ -308,7 +320,7 @@ static void restore_native_fp_fxrstor(CPUState *env) @@ -308,7 +320,7 @@ static void restore_native_fp_fxrstor(CPUState *env)
308 fp->mxcsr = env->mxcsr; 320 fp->mxcsr = env->mxcsr;
309 /* XXX: check if DAZ is not available */ 321 /* XXX: check if DAZ is not available */
310 fp->mxcsr_mask = 0xffff; 322 fp->mxcsr_mask = 0xffff;
311 - memcpy(fp->xmm_regs, env->xmm_regs, 8 * 16); 323 + memcpy(fp->xmm_regs, env->xmm_regs, CPU_NB_REGS * 16);
312 } 324 }
313 asm volatile ("fxrstor %0" : "=m" (*fp)); 325 asm volatile ("fxrstor %0" : "=m" (*fp));
314 } 326 }
@@ -334,7 +346,7 @@ static void save_native_fp_fxsave(CPUState *env) @@ -334,7 +346,7 @@ static void save_native_fp_fxsave(CPUState *env)
334 } 346 }
335 if (env->cpuid_features & CPUID_SSE) { 347 if (env->cpuid_features & CPUID_SSE) {
336 env->mxcsr = fp->mxcsr; 348 env->mxcsr = fp->mxcsr;
337 - memcpy(env->xmm_regs, fp->xmm_regs, 8 * 16); 349 + memcpy(env->xmm_regs, fp->xmm_regs, CPU_NB_REGS * 16);
338 } 350 }
339 351
340 /* we must restore the default rounding state */ 352 /* we must restore the default rounding state */
@@ -343,6 +355,55 @@ static void save_native_fp_fxsave(CPUState *env) @@ -343,6 +355,55 @@ static void save_native_fp_fxsave(CPUState *env)
343 asm volatile("fldcw %0" : : "m" (fpuc)); 355 asm volatile("fldcw %0" : : "m" (fpuc));
344 } 356 }
345 357
  358 +static int do_syscall(CPUState *env,
  359 + struct kqemu_cpu_state *kenv)
  360 +{
  361 + int selector;
  362 +
  363 + selector = (env->star >> 32) & 0xffff;
  364 +#ifdef __x86_64__
  365 + if (env->hflags & HF_LMA_MASK) {
  366 + env->regs[R_ECX] = kenv->next_eip;
  367 + env->regs[11] = env->eflags;
  368 +
  369 + cpu_x86_set_cpl(env, 0);
  370 + cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
  371 + 0, 0xffffffff,
  372 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  373 + DESC_S_MASK |
  374 + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
  375 + cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
  376 + 0, 0xffffffff,
  377 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  378 + DESC_S_MASK |
  379 + DESC_W_MASK | DESC_A_MASK);
  380 + env->eflags &= ~env->fmask;
  381 + if (env->hflags & HF_CS64_MASK)
  382 + env->eip = env->lstar;
  383 + else
  384 + env->eip = env->cstar;
  385 + } else
  386 +#endif
  387 + {
  388 + env->regs[R_ECX] = (uint32_t)kenv->next_eip;
  389 +
  390 + cpu_x86_set_cpl(env, 0);
  391 + cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
  392 + 0, 0xffffffff,
  393 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  394 + DESC_S_MASK |
  395 + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
  396 + cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
  397 + 0, 0xffffffff,
  398 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  399 + DESC_S_MASK |
  400 + DESC_W_MASK | DESC_A_MASK);
  401 + env->eflags &= ~(IF_MASK | RF_MASK | VM_MASK);
  402 + env->eip = (uint32_t)env->star;
  403 + }
  404 + return 2;
  405 +}
  406 +
346 int kqemu_cpu_exec(CPUState *env) 407 int kqemu_cpu_exec(CPUState *env)
347 { 408 {
348 struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state; 409 struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
@@ -370,6 +431,9 @@ int kqemu_cpu_exec(CPUState *env) @@ -370,6 +431,9 @@ int kqemu_cpu_exec(CPUState *env)
370 kenv->cr3 = env->cr[3]; 431 kenv->cr3 = env->cr[3];
371 kenv->cr4 = env->cr[4]; 432 kenv->cr4 = env->cr[4];
372 kenv->a20_mask = env->a20_mask; 433 kenv->a20_mask = env->a20_mask;
  434 +#ifdef __x86_64__
  435 + kenv->efer = env->efer;
  436 +#endif
373 if (env->dr[7] & 0xff) { 437 if (env->dr[7] & 0xff) {
374 kenv->dr7 = env->dr[7]; 438 kenv->dr7 = env->dr[7];
375 kenv->dr0 = env->dr[0]; 439 kenv->dr0 = env->dr[0];
@@ -435,17 +499,21 @@ int kqemu_cpu_exec(CPUState *env) @@ -435,17 +499,21 @@ int kqemu_cpu_exec(CPUState *env)
435 fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret); 499 fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
436 } 500 }
437 #endif 501 #endif
  502 + if (ret == KQEMU_RET_SYSCALL) {
  503 + /* syscall instruction */
  504 + return do_syscall(env, kenv);
  505 + } else
438 if ((ret & 0xff00) == KQEMU_RET_INT) { 506 if ((ret & 0xff00) == KQEMU_RET_INT) {
439 env->exception_index = ret & 0xff; 507 env->exception_index = ret & 0xff;
440 env->error_code = 0; 508 env->error_code = 0;
441 env->exception_is_int = 1; 509 env->exception_is_int = 1;
442 env->exception_next_eip = kenv->next_eip; 510 env->exception_next_eip = kenv->next_eip;
443 #ifdef DEBUG 511 #ifdef DEBUG
444 - if (loglevel & CPU_LOG_INT) {  
445 - fprintf(logfile, "kqemu: interrupt v=%02x:\n",  
446 - env->exception_index);  
447 - cpu_dump_state(env, logfile, fprintf, 0);  
448 - } 512 + if (loglevel & CPU_LOG_INT) {
  513 + fprintf(logfile, "kqemu: interrupt v=%02x:\n",
  514 + env->exception_index);
  515 + cpu_dump_state(env, logfile, fprintf, 0);
  516 + }
449 #endif 517 #endif
450 return 1; 518 return 1;
451 } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) { 519 } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {