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 125 #define PG_ERROR_U_MASK 0x04
126 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 137 #define EXCP00_DIVZ 0
129 138 #define EXCP01_SSTP 1
130 139 #define EXCP02_NMI 2
... ... @@ -244,6 +253,11 @@ typedef struct CPUX86State {
244 253 SegmentCache tr;
245 254 SegmentCache gdt; /* only base and limit are used */
246 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 262 /* exception/interrupt handling */
249 263 jmp_buf jmp_env;
... ...
exec-i386.h
... ... @@ -159,6 +159,8 @@ void helper_idivl_EAX_T0(uint32_t eip);
159 159 void helper_cmpxchg8b(void);
160 160 void helper_cpuid(void);
161 161 void helper_rdtsc(void);
  162 +void helper_rdmsr(void);
  163 +void helper_wrmsr(void);
162 164 void helper_lsl(void);
163 165 void helper_lar(void);
164 166  
... ...
... ... @@ -324,6 +324,7 @@ typedef int spinlock_t;
324 324  
325 325 #define SPIN_LOCK_UNLOCKED 0
326 326  
  327 +#if 1
327 328 static inline void spin_lock(spinlock_t *lock)
328 329 {
329 330 while (testandset(lock));
... ... @@ -338,6 +339,20 @@ static inline int spin_trylock(spinlock_t *lock)
338 339 {
339 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 357 extern spinlock_t tb_lock;
343 358  
... ...
helper-i386.c
... ... @@ -947,6 +947,45 @@ void helper_rdtsc(void)
947 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 989 void helper_lsl(void)
951 990 {
952 991 unsigned int selector, limit;
... ...
op-i386.c
... ... @@ -751,6 +751,16 @@ void OPPROTO op_cpuid(void)
751 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 764 /* bcd */
755 765  
756 766 /* XXX: exception */
... ...
translate-i386.c
... ... @@ -1575,14 +1575,22 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1575 1575 switch(f) {
1576 1576 case 0: /* OP Ev, Gv */
1577 1577 modrm = ldub(s->pc++);
1578   - reg = ((modrm >> 3) & 7) + OR_EAX;
  1578 + reg = ((modrm >> 3) & 7);
1579 1579 mod = (modrm >> 6) & 3;
1580 1580 rm = modrm & 7;
1581 1581 if (mod != 3) {
1582 1582 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1583 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 1592 } else {
1585   - opreg = OR_EAX + rm;
  1593 + opreg = rm;
1586 1594 }
1587 1595 gen_op_mov_TN_reg[ot][1][reg]();
1588 1596 gen_op(s, op, ot, opreg);
... ... @@ -1590,11 +1598,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1590 1598 case 1: /* OP Gv, Ev */
1591 1599 modrm = ldub(s->pc++);
1592 1600 mod = (modrm >> 6) & 3;
1593   - reg = ((modrm >> 3) & 7) + OR_EAX;
  1601 + reg = ((modrm >> 3) & 7);
1594 1602 rm = modrm & 7;
1595 1603 if (mod != 3) {
1596 1604 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1597 1605 gen_op_ld_T1_A0[ot]();
  1606 + } else if (op == OP_XORL && rm == reg) {
  1607 + goto xor_zero;
1598 1608 } else {
1599 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 3474 gen_op_loop[s->aflag][b & 3](val, next_eip);
3465 3475 s->is_jmp = 1;
3466 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 3488 case 0x131: /* rdtsc */
3468 3489 gen_op_rdtsc();
3469 3490 break;
... ... @@ -4267,7 +4288,7 @@ void cpu_x86_update_cr0(CPUX86State *env)
4267 4288 void cpu_x86_update_cr3(CPUX86State *env)
4268 4289 {
4269 4290 if (env->cr[0] & CR0_PG_MASK) {
4270   -#ifdef DEBUG_MMU
  4291 +#if defined(DEBUG_MMU)
4271 4292 printf("CR3 update: CR3=%08x\n", env->cr[3]);
4272 4293 #endif
4273 4294 page_unmap();
... ...
translate.c
... ... @@ -179,7 +179,18 @@ int cpu_restore_state(TranslationBlock *tb,
179 179 #if defined(TARGET_I386)
180 180 {
181 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 194 env->eip = gen_opc_pc[j] - tb->cs_base;
184 195 cc_op = gen_opc_cc_op[j];
185 196 if (cc_op != CC_OP_DYNAMIC)
... ...