/[qemu]/qemu/kqemu.c
ViewVC logotype

Diff of /qemu/kqemu.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by bellard, Sun Apr 17 18:33:47 2005 UTC revision 1.3 by bellard, Sat Apr 23 17:45:43 2005 UTC
# Line 45  Line 45 
45  #include <fcntl.h>  #include <fcntl.h>
46  #include "kqemu/kqemu.h"  #include "kqemu/kqemu.h"
47    
48    /* compatibility stuff */
49    #ifndef KQEMU_RET_SYSCALL
50    #define KQEMU_RET_SYSCALL   0x0300 /* syscall insn */
51    #endif
52    
53  #ifdef _WIN32  #ifdef _WIN32
54  #define KQEMU_DEVICE "\\\\.\\kqemu"  #define KQEMU_DEVICE "\\\\.\\kqemu"
55  #else  #else
# Line 71  extern uint32_t **l1_phys_map; Line 76  extern uint32_t **l1_phys_map;
76                  : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \                  : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
77                  : "0" (index))                  : "0" (index))
78    
79    #ifdef __x86_64__
80    static int is_cpuid_supported(void)
81    {
82        return 1;
83    }
84    #else
85  static int is_cpuid_supported(void)  static int is_cpuid_supported(void)
86  {  {
87      int v0, v1;      int v0, v1;
# Line 87  static int is_cpuid_supported(void) Line 98  static int is_cpuid_supported(void)
98                    : "cc");                    : "cc");
99      return (v0 != v1);      return (v0 != v1);
100  }  }
101    #endif
102    
103  static void kqemu_update_cpuid(CPUState *env)  static void kqemu_update_cpuid(CPUState *env)
104  {  {
# Line 231  struct fpxstate { Line 243  struct fpxstate {
243      uint32_t mxcsr;      uint32_t mxcsr;
244      uint32_t mxcsr_mask;      uint32_t mxcsr_mask;
245      uint8_t fpregs1[8 * 16];      uint8_t fpregs1[8 * 16];
246      uint8_t xmm_regs[8 * 16];      uint8_t xmm_regs[16 * 16];
247      uint8_t dummy2[224];      uint8_t dummy2[96];
248  };  };
249    
250  static struct fpxstate fpx1 __attribute__((aligned(16)));  static struct fpxstate fpx1 __attribute__((aligned(16)));
# Line 308  static void restore_native_fp_fxrstor(CP Line 320  static void restore_native_fp_fxrstor(CP
320          fp->mxcsr = env->mxcsr;          fp->mxcsr = env->mxcsr;
321          /* XXX: check if DAZ is not available */          /* XXX: check if DAZ is not available */
322          fp->mxcsr_mask = 0xffff;          fp->mxcsr_mask = 0xffff;
323          memcpy(fp->xmm_regs, env->xmm_regs, 8 * 16);          memcpy(fp->xmm_regs, env->xmm_regs, CPU_NB_REGS * 16);
324      }      }
325      asm volatile ("fxrstor %0" : "=m" (*fp));      asm volatile ("fxrstor %0" : "=m" (*fp));
326  }  }
# Line 334  static void save_native_fp_fxsave(CPUSta Line 346  static void save_native_fp_fxsave(CPUSta
346      }      }
347      if (env->cpuid_features & CPUID_SSE) {      if (env->cpuid_features & CPUID_SSE) {
348          env->mxcsr = fp->mxcsr;          env->mxcsr = fp->mxcsr;
349          memcpy(env->xmm_regs, fp->xmm_regs, 8 * 16);          memcpy(env->xmm_regs, fp->xmm_regs, CPU_NB_REGS * 16);
350      }      }
351    
352      /* we must restore the default rounding state */      /* we must restore the default rounding state */
# Line 343  static void save_native_fp_fxsave(CPUSta Line 355  static void save_native_fp_fxsave(CPUSta
355      asm volatile("fldcw %0" : : "m" (fpuc));      asm volatile("fldcw %0" : : "m" (fpuc));
356  }  }
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    
407  int kqemu_cpu_exec(CPUState *env)  int kqemu_cpu_exec(CPUState *env)
408  {  {
409      struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;      struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
# Line 370  int kqemu_cpu_exec(CPUState *env) Line 431  int kqemu_cpu_exec(CPUState *env)
431      kenv->cr3 = env->cr[3];      kenv->cr3 = env->cr[3];
432      kenv->cr4 = env->cr[4];      kenv->cr4 = env->cr[4];
433      kenv->a20_mask = env->a20_mask;      kenv->a20_mask = env->a20_mask;
434    #ifdef __x86_64__
435        kenv->efer = env->efer;
436    #endif
437      if (env->dr[7] & 0xff) {      if (env->dr[7] & 0xff) {
438          kenv->dr7 = env->dr[7];          kenv->dr7 = env->dr[7];
439          kenv->dr0 = env->dr[0];          kenv->dr0 = env->dr[0];
# Line 435  int kqemu_cpu_exec(CPUState *env) Line 499  int kqemu_cpu_exec(CPUState *env)
499          fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);          fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
500      }      }
501  #endif  #endif
502        if (ret == KQEMU_RET_SYSCALL) {
503            /* syscall instruction */
504            return do_syscall(env, kenv);
505        } else
506      if ((ret & 0xff00) == KQEMU_RET_INT) {      if ((ret & 0xff00) == KQEMU_RET_INT) {
507          env->exception_index = ret & 0xff;          env->exception_index = ret & 0xff;
508          env->error_code = 0;          env->error_code = 0;
509          env->exception_is_int = 1;          env->exception_is_int = 1;
510          env->exception_next_eip = kenv->next_eip;          env->exception_next_eip = kenv->next_eip;
511  #ifdef DEBUG  #ifdef DEBUG
512      if (loglevel & CPU_LOG_INT) {          if (loglevel & CPU_LOG_INT) {
513          fprintf(logfile, "kqemu: interrupt v=%02x:\n",              fprintf(logfile, "kqemu: interrupt v=%02x:\n",
514                  env->exception_index);                      env->exception_index);
515          cpu_dump_state(env, logfile, fprintf, 0);              cpu_dump_state(env, logfile, fprintf, 0);
516      }          }
517  #endif  #endif
518          return 1;          return 1;
519      } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {      } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26