#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
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;
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);
#define SPIN_LOCK_UNLOCKED 0
+#if 1
static inline void spin_lock(spinlock_t *lock)
{
while (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;
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;
helper_cpuid();
}
+void OPPROTO op_rdmsr(void)
+{
+ helper_rdmsr();
+}
+
+void OPPROTO op_wrmsr(void)
+{
+ helper_wrmsr();
+}
+
/* bcd */
/* XXX: exception */
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);
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]();
}
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;
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();
#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)