Commit 3c1cf9fa865927759a78d476a218a7759fb38fb4

Authored by bellard
1 parent 1f47a922

dummy rdmsr and wrmsr support - xor reg, reg optimization


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@311 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-i386.h
@@ -125,6 +125,15 @@ @@ -125,6 +125,15 @@
125 #define PG_ERROR_U_MASK 0x04 125 #define PG_ERROR_U_MASK 0x04
126 #define PG_ERROR_RSVD_MASK 0x08 126 #define PG_ERROR_RSVD_MASK 0x08
127 127
  128 +#define MSR_IA32_APICBASE 0x1b
  129 +#define MSR_IA32_APICBASE_BSP (1<<8)
  130 +#define MSR_IA32_APICBASE_ENABLE (1<<11)
  131 +#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
  132 +
  133 +#define MSR_IA32_SYSENTER_CS 0x174
  134 +#define MSR_IA32_SYSENTER_ESP 0x175
  135 +#define MSR_IA32_SYSENTER_EIP 0x176
  136 +
128 #define EXCP00_DIVZ 0 137 #define EXCP00_DIVZ 0
129 #define EXCP01_SSTP 1 138 #define EXCP01_SSTP 1
130 #define EXCP02_NMI 2 139 #define EXCP02_NMI 2
@@ -244,6 +253,11 @@ typedef struct CPUX86State { @@ -244,6 +253,11 @@ typedef struct CPUX86State {
244 SegmentCache tr; 253 SegmentCache tr;
245 SegmentCache gdt; /* only base and limit are used */ 254 SegmentCache gdt; /* only base and limit are used */
246 SegmentCache idt; /* only base and limit are used */ 255 SegmentCache idt; /* only base and limit are used */
  256 +
  257 + /* sysenter registers */
  258 + uint32_t sysenter_cs;
  259 + uint32_t sysenter_esp;
  260 + uint32_t sysenter_eip;
247 261
248 /* exception/interrupt handling */ 262 /* exception/interrupt handling */
249 jmp_buf jmp_env; 263 jmp_buf jmp_env;
exec-i386.h
@@ -159,6 +159,8 @@ void helper_idivl_EAX_T0(uint32_t eip); @@ -159,6 +159,8 @@ void helper_idivl_EAX_T0(uint32_t eip);
159 void helper_cmpxchg8b(void); 159 void helper_cmpxchg8b(void);
160 void helper_cpuid(void); 160 void helper_cpuid(void);
161 void helper_rdtsc(void); 161 void helper_rdtsc(void);
  162 +void helper_rdmsr(void);
  163 +void helper_wrmsr(void);
162 void helper_lsl(void); 164 void helper_lsl(void);
163 void helper_lar(void); 165 void helper_lar(void);
164 166
@@ -324,6 +324,7 @@ typedef int spinlock_t; @@ -324,6 +324,7 @@ typedef int spinlock_t;
324 324
325 #define SPIN_LOCK_UNLOCKED 0 325 #define SPIN_LOCK_UNLOCKED 0
326 326
  327 +#if 1
327 static inline void spin_lock(spinlock_t *lock) 328 static inline void spin_lock(spinlock_t *lock)
328 { 329 {
329 while (testandset(lock)); 330 while (testandset(lock));
@@ -338,6 +339,20 @@ static inline int spin_trylock(spinlock_t *lock) @@ -338,6 +339,20 @@ static inline int spin_trylock(spinlock_t *lock)
338 { 339 {
339 return !testandset(lock); 340 return !testandset(lock);
340 } 341 }
  342 +#else
  343 +static inline void spin_lock(spinlock_t *lock)
  344 +{
  345 +}
  346 +
  347 +static inline void spin_unlock(spinlock_t *lock)
  348 +{
  349 +}
  350 +
  351 +static inline int spin_trylock(spinlock_t *lock)
  352 +{
  353 + return 1;
  354 +}
  355 +#endif
341 356
342 extern spinlock_t tb_lock; 357 extern spinlock_t tb_lock;
343 358
helper-i386.c
@@ -947,6 +947,45 @@ void helper_rdtsc(void) @@ -947,6 +947,45 @@ void helper_rdtsc(void)
947 EDX = val >> 32; 947 EDX = val >> 32;
948 } 948 }
949 949
  950 +void helper_wrmsr(void)
  951 +{
  952 + switch(ECX) {
  953 + case MSR_IA32_SYSENTER_CS:
  954 + env->sysenter_cs = EAX & 0xffff;
  955 + break;
  956 + case MSR_IA32_SYSENTER_ESP:
  957 + env->sysenter_esp = EAX;
  958 + break;
  959 + case MSR_IA32_SYSENTER_EIP:
  960 + env->sysenter_eip = EAX;
  961 + break;
  962 + default:
  963 + /* XXX: exception ? */
  964 + break;
  965 + }
  966 +}
  967 +
  968 +void helper_rdmsr(void)
  969 +{
  970 + switch(ECX) {
  971 + case MSR_IA32_SYSENTER_CS:
  972 + EAX = env->sysenter_cs;
  973 + EDX = 0;
  974 + break;
  975 + case MSR_IA32_SYSENTER_ESP:
  976 + EAX = env->sysenter_esp;
  977 + EDX = 0;
  978 + break;
  979 + case MSR_IA32_SYSENTER_EIP:
  980 + EAX = env->sysenter_eip;
  981 + EDX = 0;
  982 + break;
  983 + default:
  984 + /* XXX: exception ? */
  985 + break;
  986 + }
  987 +}
  988 +
950 void helper_lsl(void) 989 void helper_lsl(void)
951 { 990 {
952 unsigned int selector, limit; 991 unsigned int selector, limit;
op-i386.c
@@ -751,6 +751,16 @@ void OPPROTO op_cpuid(void) @@ -751,6 +751,16 @@ void OPPROTO op_cpuid(void)
751 helper_cpuid(); 751 helper_cpuid();
752 } 752 }
753 753
  754 +void OPPROTO op_rdmsr(void)
  755 +{
  756 + helper_rdmsr();
  757 +}
  758 +
  759 +void OPPROTO op_wrmsr(void)
  760 +{
  761 + helper_wrmsr();
  762 +}
  763 +
754 /* bcd */ 764 /* bcd */
755 765
756 /* XXX: exception */ 766 /* XXX: exception */
translate-i386.c
@@ -1575,14 +1575,22 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1575,14 +1575,22 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1575 switch(f) { 1575 switch(f) {
1576 case 0: /* OP Ev, Gv */ 1576 case 0: /* OP Ev, Gv */
1577 modrm = ldub(s->pc++); 1577 modrm = ldub(s->pc++);
1578 - reg = ((modrm >> 3) & 7) + OR_EAX; 1578 + reg = ((modrm >> 3) & 7);
1579 mod = (modrm >> 6) & 3; 1579 mod = (modrm >> 6) & 3;
1580 rm = modrm & 7; 1580 rm = modrm & 7;
1581 if (mod != 3) { 1581 if (mod != 3) {
1582 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 1582 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1583 opreg = OR_TMP0; 1583 opreg = OR_TMP0;
  1584 + } else if (op == OP_XORL && rm == reg) {
  1585 + xor_zero:
  1586 + /* xor reg, reg optimisation */
  1587 + gen_op_movl_T0_0();
  1588 + s->cc_op = CC_OP_LOGICB + ot;
  1589 + gen_op_mov_reg_T0[ot][reg]();
  1590 + gen_op_update1_cc();
  1591 + break;
1584 } else { 1592 } else {
1585 - opreg = OR_EAX + rm; 1593 + opreg = rm;
1586 } 1594 }
1587 gen_op_mov_TN_reg[ot][1][reg](); 1595 gen_op_mov_TN_reg[ot][1][reg]();
1588 gen_op(s, op, ot, opreg); 1596 gen_op(s, op, ot, opreg);
@@ -1590,11 +1598,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -1590,11 +1598,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1590 case 1: /* OP Gv, Ev */ 1598 case 1: /* OP Gv, Ev */
1591 modrm = ldub(s->pc++); 1599 modrm = ldub(s->pc++);
1592 mod = (modrm >> 6) & 3; 1600 mod = (modrm >> 6) & 3;
1593 - reg = ((modrm >> 3) & 7) + OR_EAX; 1601 + reg = ((modrm >> 3) & 7);
1594 rm = modrm & 7; 1602 rm = modrm & 7;
1595 if (mod != 3) { 1603 if (mod != 3) {
1596 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 1604 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1597 gen_op_ld_T1_A0[ot](); 1605 gen_op_ld_T1_A0[ot]();
  1606 + } else if (op == OP_XORL && rm == reg) {
  1607 + goto xor_zero;
1598 } else { 1608 } else {
1599 gen_op_mov_TN_reg[ot][1][rm](); 1609 gen_op_mov_TN_reg[ot][1][rm]();
1600 } 1610 }
@@ -3464,6 +3474,17 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3464,6 +3474,17 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3464 gen_op_loop[s->aflag][b & 3](val, next_eip); 3474 gen_op_loop[s->aflag][b & 3](val, next_eip);
3465 s->is_jmp = 1; 3475 s->is_jmp = 1;
3466 break; 3476 break;
  3477 + case 0x130: /* wrmsr */
  3478 + case 0x132: /* rdmsr */
  3479 + if (s->cpl != 0) {
  3480 + gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
  3481 + } else {
  3482 + if (b & 2)
  3483 + gen_op_rdmsr();
  3484 + else
  3485 + gen_op_wrmsr();
  3486 + }
  3487 + break;
3467 case 0x131: /* rdtsc */ 3488 case 0x131: /* rdtsc */
3468 gen_op_rdtsc(); 3489 gen_op_rdtsc();
3469 break; 3490 break;
@@ -4267,7 +4288,7 @@ void cpu_x86_update_cr0(CPUX86State *env) @@ -4267,7 +4288,7 @@ void cpu_x86_update_cr0(CPUX86State *env)
4267 void cpu_x86_update_cr3(CPUX86State *env) 4288 void cpu_x86_update_cr3(CPUX86State *env)
4268 { 4289 {
4269 if (env->cr[0] & CR0_PG_MASK) { 4290 if (env->cr[0] & CR0_PG_MASK) {
4270 -#ifdef DEBUG_MMU 4291 +#if defined(DEBUG_MMU)
4271 printf("CR3 update: CR3=%08x\n", env->cr[3]); 4292 printf("CR3 update: CR3=%08x\n", env->cr[3]);
4272 #endif 4293 #endif
4273 page_unmap(); 4294 page_unmap();
translate.c
@@ -179,7 +179,18 @@ int cpu_restore_state(TranslationBlock *tb, @@ -179,7 +179,18 @@ int cpu_restore_state(TranslationBlock *tb,
179 #if defined(TARGET_I386) 179 #if defined(TARGET_I386)
180 { 180 {
181 int cc_op; 181 int cc_op;
182 - 182 +#ifdef DEBUG_DISAS
  183 + if (loglevel) {
  184 + int i;
  185 + for(i=0;i<=j; i++) {
  186 + if (gen_opc_instr_start[i]) {
  187 + fprintf(logfile, "0x%04x: 0x%08x", i, gen_opc_pc[i]);
  188 + }
  189 + }
  190 + fprintf(logfile, "j=0x%x eip=0x%lx cs_base=%lx\n",
  191 + j, gen_opc_pc[j] - tb->cs_base, tb->cs_base);
  192 + }
  193 +#endif
183 env->eip = gen_opc_pc[j] - tb->cs_base; 194 env->eip = gen_opc_pc[j] - tb->cs_base;
184 cc_op = gen_opc_cc_op[j]; 195 cc_op = gen_opc_cc_op[j];
185 if (cc_op != CC_OP_DYNAMIC) 196 if (cc_op != CC_OP_DYNAMIC)