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
This commit is contained in:
parent
1f47a9223e
commit
3c1cf9fa86
14
cpu-i386.h
14
cpu-i386.h
@ -125,6 +125,15 @@
|
||||
#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;
|
||||
|
@ -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);
|
||||
|
||||
|
15
exec.h
15
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;
|
||||
|
||||
|
@ -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;
|
||||
|
10
op-i386.c
10
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 */
|
||||
|
@ -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, ®_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, ®_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();
|
||||
|
13
translate.c
13
translate.c
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user