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) | ... | ... |