Commit 3c1cf9fa865927759a78d476a218a7759fb38fb4
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
Showing
7 changed files
with
117 additions
and
5 deletions
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 | ... | ... |
exec.h
| ... | ... | @@ -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, ®_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, ®_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) | ... | ... |