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_U_MASK 0x04
|
||||||
#define PG_ERROR_RSVD_MASK 0x08
|
#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 EXCP00_DIVZ 0
|
||||||
#define EXCP01_SSTP 1
|
#define EXCP01_SSTP 1
|
||||||
#define EXCP02_NMI 2
|
#define EXCP02_NMI 2
|
||||||
|
@ -244,6 +253,11 @@ typedef struct CPUX86State {
|
||||||
SegmentCache tr;
|
SegmentCache tr;
|
||||||
SegmentCache gdt; /* only base and limit are used */
|
SegmentCache gdt; /* only base and limit are used */
|
||||||
SegmentCache idt; /* 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 */
|
/* exception/interrupt handling */
|
||||||
jmp_buf jmp_env;
|
jmp_buf jmp_env;
|
||||||
|
|
|
@ -159,6 +159,8 @@ void helper_idivl_EAX_T0(uint32_t eip);
|
||||||
void helper_cmpxchg8b(void);
|
void helper_cmpxchg8b(void);
|
||||||
void helper_cpuid(void);
|
void helper_cpuid(void);
|
||||||
void helper_rdtsc(void);
|
void helper_rdtsc(void);
|
||||||
|
void helper_rdmsr(void);
|
||||||
|
void helper_wrmsr(void);
|
||||||
void helper_lsl(void);
|
void helper_lsl(void);
|
||||||
void helper_lar(void);
|
void helper_lar(void);
|
||||||
|
|
||||||
|
|
15
exec.h
15
exec.h
|
@ -324,6 +324,7 @@ typedef int spinlock_t;
|
||||||
|
|
||||||
#define SPIN_LOCK_UNLOCKED 0
|
#define SPIN_LOCK_UNLOCKED 0
|
||||||
|
|
||||||
|
#if 1
|
||||||
static inline void spin_lock(spinlock_t *lock)
|
static inline void spin_lock(spinlock_t *lock)
|
||||||
{
|
{
|
||||||
while (testandset(lock));
|
while (testandset(lock));
|
||||||
|
@ -338,6 +339,20 @@ static inline int spin_trylock(spinlock_t *lock)
|
||||||
{
|
{
|
||||||
return !testandset(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;
|
extern spinlock_t tb_lock;
|
||||||
|
|
||||||
|
|
|
@ -947,6 +947,45 @@ void helper_rdtsc(void)
|
||||||
EDX = val >> 32;
|
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)
|
void helper_lsl(void)
|
||||||
{
|
{
|
||||||
unsigned int selector, limit;
|
unsigned int selector, limit;
|
||||||
|
|
10
op-i386.c
10
op-i386.c
|
@ -751,6 +751,16 @@ void OPPROTO op_cpuid(void)
|
||||||
helper_cpuid();
|
helper_cpuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_rdmsr(void)
|
||||||
|
{
|
||||||
|
helper_rdmsr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_wrmsr(void)
|
||||||
|
{
|
||||||
|
helper_wrmsr();
|
||||||
|
}
|
||||||
|
|
||||||
/* bcd */
|
/* bcd */
|
||||||
|
|
||||||
/* XXX: exception */
|
/* XXX: exception */
|
||||||
|
|
|
@ -1575,14 +1575,22 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||||
switch(f) {
|
switch(f) {
|
||||||
case 0: /* OP Ev, Gv */
|
case 0: /* OP Ev, Gv */
|
||||||
modrm = ldub(s->pc++);
|
modrm = ldub(s->pc++);
|
||||||
reg = ((modrm >> 3) & 7) + OR_EAX;
|
reg = ((modrm >> 3) & 7);
|
||||||
mod = (modrm >> 6) & 3;
|
mod = (modrm >> 6) & 3;
|
||||||
rm = modrm & 7;
|
rm = modrm & 7;
|
||||||
if (mod != 3) {
|
if (mod != 3) {
|
||||||
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
||||||
opreg = OR_TMP0;
|
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 {
|
} else {
|
||||||
opreg = OR_EAX + rm;
|
opreg = rm;
|
||||||
}
|
}
|
||||||
gen_op_mov_TN_reg[ot][1][reg]();
|
gen_op_mov_TN_reg[ot][1][reg]();
|
||||||
gen_op(s, op, ot, opreg);
|
gen_op(s, op, ot, opreg);
|
||||||
|
@ -1590,11 +1598,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
|
||||||
case 1: /* OP Gv, Ev */
|
case 1: /* OP Gv, Ev */
|
||||||
modrm = ldub(s->pc++);
|
modrm = ldub(s->pc++);
|
||||||
mod = (modrm >> 6) & 3;
|
mod = (modrm >> 6) & 3;
|
||||||
reg = ((modrm >> 3) & 7) + OR_EAX;
|
reg = ((modrm >> 3) & 7);
|
||||||
rm = modrm & 7;
|
rm = modrm & 7;
|
||||||
if (mod != 3) {
|
if (mod != 3) {
|
||||||
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
|
||||||
gen_op_ld_T1_A0[ot]();
|
gen_op_ld_T1_A0[ot]();
|
||||||
|
} else if (op == OP_XORL && rm == reg) {
|
||||||
|
goto xor_zero;
|
||||||
} else {
|
} else {
|
||||||
gen_op_mov_TN_reg[ot][1][rm]();
|
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);
|
gen_op_loop[s->aflag][b & 3](val, next_eip);
|
||||||
s->is_jmp = 1;
|
s->is_jmp = 1;
|
||||||
break;
|
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 */
|
case 0x131: /* rdtsc */
|
||||||
gen_op_rdtsc();
|
gen_op_rdtsc();
|
||||||
break;
|
break;
|
||||||
|
@ -4267,7 +4288,7 @@ void cpu_x86_update_cr0(CPUX86State *env)
|
||||||
void cpu_x86_update_cr3(CPUX86State *env)
|
void cpu_x86_update_cr3(CPUX86State *env)
|
||||||
{
|
{
|
||||||
if (env->cr[0] & CR0_PG_MASK) {
|
if (env->cr[0] & CR0_PG_MASK) {
|
||||||
#ifdef DEBUG_MMU
|
#if defined(DEBUG_MMU)
|
||||||
printf("CR3 update: CR3=%08x\n", env->cr[3]);
|
printf("CR3 update: CR3=%08x\n", env->cr[3]);
|
||||||
#endif
|
#endif
|
||||||
page_unmap();
|
page_unmap();
|
||||||
|
|
13
translate.c
13
translate.c
|
@ -179,7 +179,18 @@ int cpu_restore_state(TranslationBlock *tb,
|
||||||
#if defined(TARGET_I386)
|
#if defined(TARGET_I386)
|
||||||
{
|
{
|
||||||
int cc_op;
|
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;
|
env->eip = gen_opc_pc[j] - tb->cs_base;
|
||||||
cc_op = gen_opc_cc_op[j];
|
cc_op = gen_opc_cc_op[j];
|
||||||
if (cc_op != CC_OP_DYNAMIC)
|
if (cc_op != CC_OP_DYNAMIC)
|
||||||
|
|
Loading…
Reference in New Issue