]> rtime.felk.cvut.cz Git - lisovros/qemu_apohw.git/commitdiff
dummy rdmsr and wrmsr support - xor reg, reg optimization
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 7 Jul 2003 11:30:47 +0000 (11:30 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 7 Jul 2003 11:30:47 +0000 (11:30 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@311 c046a42c-6fe2-441c-8c8c-71466251a162

cpu-i386.h
exec-i386.h
exec.h
helper-i386.c
op-i386.c
translate-i386.c
translate.c

index 4029746c80fc8a66110cead4326edf4c61c3f52c..e6318fb7f2ddcd177f4526d8afce6cfd1a4c7bfb 100644 (file)
 #define PG_ERROR_U_MASK    0x04
 #define PG_ERROR_RSVD_MASK 0x08
 
+#define MSR_IA32_APICBASE               0x1b
+#define MSR_IA32_APICBASE_BSP           (1<<8)
+#define MSR_IA32_APICBASE_ENABLE        (1<<11)
+#define MSR_IA32_APICBASE_BASE          (0xfffff<<12)
+
+#define MSR_IA32_SYSENTER_CS            0x174
+#define MSR_IA32_SYSENTER_ESP           0x175
+#define MSR_IA32_SYSENTER_EIP           0x176
+
 #define EXCP00_DIVZ    0
 #define EXCP01_SSTP    1
 #define EXCP02_NMI     2
@@ -244,6 +253,11 @@ typedef struct CPUX86State {
     SegmentCache tr;
     SegmentCache gdt; /* only base and limit are used */
     SegmentCache idt; /* only base and limit are used */
+
+    /* sysenter registers */
+    uint32_t sysenter_cs;
+    uint32_t sysenter_esp;
+    uint32_t sysenter_eip;
     
     /* exception/interrupt handling */
     jmp_buf jmp_env;
index 12e22bb412d9735737a4538de8e1067788e16159..84a1dabf09a2047df66593649c6f7243825b1ee4 100644 (file)
@@ -159,6 +159,8 @@ void helper_idivl_EAX_T0(uint32_t eip);
 void helper_cmpxchg8b(void);
 void helper_cpuid(void);
 void helper_rdtsc(void);
+void helper_rdmsr(void);
+void helper_wrmsr(void);
 void helper_lsl(void);
 void helper_lar(void);
 
diff --git a/exec.h b/exec.h
index 92b248db0342af84d6c9a59329573e125ee00ea9..1f46e4a469f317a1eab51d85615b2b86a9f50561 100644 (file)
--- a/exec.h
+++ b/exec.h
@@ -324,6 +324,7 @@ typedef int spinlock_t;
 
 #define SPIN_LOCK_UNLOCKED 0
 
+#if 1
 static inline void spin_lock(spinlock_t *lock)
 {
     while (testandset(lock));
@@ -338,6 +339,20 @@ static inline int spin_trylock(spinlock_t *lock)
 {
     return !testandset(lock);
 }
+#else
+static inline void spin_lock(spinlock_t *lock)
+{
+}
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+}
+
+static inline int spin_trylock(spinlock_t *lock)
+{
+    return 1;
+}
+#endif
 
 extern spinlock_t tb_lock;
 
index fef7c351e634d0e7a8c32ea8e387c1b411a1b741..72b75a5c2115e9ed12c7292796cdb1ffd8070ea9 100644 (file)
@@ -947,6 +947,45 @@ void helper_rdtsc(void)
     EDX = val >> 32;
 }
 
+void helper_wrmsr(void)
+{
+    switch(ECX) {
+    case MSR_IA32_SYSENTER_CS:
+        env->sysenter_cs = EAX & 0xffff;
+        break;
+    case MSR_IA32_SYSENTER_ESP:
+        env->sysenter_esp = EAX;
+        break;
+    case MSR_IA32_SYSENTER_EIP:
+        env->sysenter_eip = EAX;
+        break;
+    default:
+        /* XXX: exception ? */
+        break; 
+    }
+}
+
+void helper_rdmsr(void)
+{
+    switch(ECX) {
+    case MSR_IA32_SYSENTER_CS:
+        EAX = env->sysenter_cs;
+        EDX = 0;
+        break;
+    case MSR_IA32_SYSENTER_ESP:
+        EAX = env->sysenter_esp;
+        EDX = 0;
+        break;
+    case MSR_IA32_SYSENTER_EIP:
+        EAX = env->sysenter_eip;
+        EDX = 0;
+        break;
+    default:
+        /* XXX: exception ? */
+        break; 
+    }
+}
+
 void helper_lsl(void)
 {
     unsigned int selector, limit;
index ee951b1da9dadf3ff76280dc59e395b234f768a6..84b75d07b06656b8434f8d1422d3c74f95982e93 100644 (file)
--- a/op-i386.c
+++ b/op-i386.c
@@ -751,6 +751,16 @@ void OPPROTO op_cpuid(void)
     helper_cpuid();
 }
 
+void OPPROTO op_rdmsr(void)
+{
+    helper_rdmsr();
+}
+
+void OPPROTO op_wrmsr(void)
+{
+    helper_wrmsr();
+}
+
 /* bcd */
 
 /* XXX: exception */
index c8bd12f3d9617a24a13add98e9e1ea13f5190355..fdbd5ee92247669263bf6749569e0855f83a9b0b 100644 (file)
@@ -1575,14 +1575,22 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
             switch(f) {
             case 0: /* OP Ev, Gv */
                 modrm = ldub(s->pc++);
-                reg = ((modrm >> 3) & 7) + OR_EAX;
+                reg = ((modrm >> 3) & 7);
                 mod = (modrm >> 6) & 3;
                 rm = modrm & 7;
                 if (mod != 3) {
                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                     opreg = OR_TMP0;
+                } else if (op == OP_XORL && rm == reg) {
+                xor_zero:
+                    /* xor reg, reg optimisation */
+                    gen_op_movl_T0_0();
+                    s->cc_op = CC_OP_LOGICB + ot;
+                    gen_op_mov_reg_T0[ot][reg]();
+                    gen_op_update1_cc();
+                    break;
                 } else {
-                    opreg = OR_EAX + rm;
+                    opreg = rm;
                 }
                 gen_op_mov_TN_reg[ot][1][reg]();
                 gen_op(s, op, ot, opreg);
@@ -1590,11 +1598,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
             case 1: /* OP Gv, Ev */
                 modrm = ldub(s->pc++);
                 mod = (modrm >> 6) & 3;
-                reg = ((modrm >> 3) & 7) + OR_EAX;
+                reg = ((modrm >> 3) & 7);
                 rm = modrm & 7;
                 if (mod != 3) {
                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                     gen_op_ld_T1_A0[ot]();
+                } else if (op == OP_XORL && rm == reg) {
+                    goto xor_zero;
                 } else {
                     gen_op_mov_TN_reg[ot][1][rm]();
                 }
@@ -3464,6 +3474,17 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
         gen_op_loop[s->aflag][b & 3](val, next_eip);
         s->is_jmp = 1;
         break;
+    case 0x130: /* wrmsr */
+    case 0x132: /* rdmsr */
+        if (s->cpl != 0) {
+            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+        } else {
+            if (b & 2)
+                gen_op_rdmsr();
+            else
+                gen_op_wrmsr();
+        }
+        break;
     case 0x131: /* rdtsc */
         gen_op_rdtsc();
         break;
@@ -4267,7 +4288,7 @@ void cpu_x86_update_cr0(CPUX86State *env)
 void cpu_x86_update_cr3(CPUX86State *env)
 {
     if (env->cr[0] & CR0_PG_MASK) {
-#ifdef DEBUG_MMU
+#if defined(DEBUG_MMU)
         printf("CR3 update: CR3=%08x\n", env->cr[3]);
 #endif
         page_unmap();
index 2f11dfc030e217e27a19b0f3bf94d54adc476fe8..72b4d24b79db0525e7ae1a8ddbc37633e298191a 100644 (file)
@@ -179,7 +179,18 @@ int cpu_restore_state(TranslationBlock *tb,
 #if defined(TARGET_I386)
     {
         int cc_op;
-        
+#ifdef DEBUG_DISAS
+        if (loglevel) {
+            int i;
+            for(i=0;i<=j; i++) {
+                if (gen_opc_instr_start[i]) {
+                    fprintf(logfile, "0x%04x: 0x%08x", i, gen_opc_pc[i]);
+                }
+            }
+            fprintf(logfile, "j=0x%x eip=0x%lx cs_base=%lx\n", 
+                    j, gen_opc_pc[j] - tb->cs_base, tb->cs_base);
+        }
+#endif
         env->eip = gen_opc_pc[j] - tb->cs_base;
         cc_op = gen_opc_cc_op[j];
         if (cc_op != CC_OP_DYNAMIC)