--- np2/i386c/ia32/instructions/system_inst.c 2004/01/14 16:14:50 1.6 +++ np2/i386c/ia32/instructions/system_inst.c 2004/01/26 15:23:55 1.10 @@ -1,4 +1,4 @@ -/* $Id: system_inst.c,v 1.6 2004/01/14 16:14:50 monaka Exp $ */ +/* $Id: system_inst.c,v 1.10 2004/01/26 15:23:55 monaka Exp $ */ /* * Copyright (c) 2003 NONAKA Kimihiro @@ -52,23 +52,14 @@ LGDT_Ms(DWORD op) } #if defined(DEBUG) -{ - DWORD v[2]; - DWORD i; - - VERBOSE(("LGDT_Ms: GDTR_BASE = 0x%08x, GDTR_LIMIT = 0x%04x", base, limit)); - for (i = 0; i < limit; i += 8) { - v[0] = cpu_lmemoryread_d(base + i); - v[1] = cpu_lmemoryread_d(base + i + 4); - VERBOSE(("LGDT_Ms: %08x: %08x%08x", base + i, v[0], v[1])); - } -} + gdtr_dump(base, limit); #endif CPU_GDTR_BASE = base; CPU_GDTR_LIMIT = limit; return; } + VERBOSE(("LGDT: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } EXCEPTION(UD_EXCEPTION, 0); @@ -114,8 +105,10 @@ LLDT_Ew(DWORD op) load_ldtr(src, GP_EXCEPTION); return; } + VERBOSE(("LLDT: CPL(%d) != 0", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } + VERBOSE(("LLDT: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -123,22 +116,25 @@ void SLDT_Ew(DWORD op) { DWORD madr; + WORD ldtr; if (CPU_STAT_PM && !CPU_STAT_VM86) { + ldtr = CPU_LDTR; if (op >= 0xc0) { CPU_WORKCLOCK(5); - if (!CPU_INST_OP32) { - *(reg16_b20[op]) = CPU_LDTR; + if (CPU_INST_OP32) { + *(reg32_b20[op]) = ldtr; } else { - *(reg32_b20[op]) = CPU_LDTR; + *(reg16_b20[op]) = ldtr; } } else { CPU_WORKCLOCK(11); madr = calc_ea_dst(op); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_LDTR); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, ldtr); } return; } + VERBOSE(("SLDT: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -160,8 +156,10 @@ LTR_Ew(DWORD op) load_tr(src); return; } + VERBOSE(("LTR: CPL(%d) != 0", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } + VERBOSE(("LTR: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -169,21 +167,24 @@ void STR_Ew(DWORD op) { DWORD madr; + WORD tr; if (CPU_STAT_PM && !CPU_STAT_VM86) { + tr = CPU_TR; if (op >= 0xc0) { CPU_WORKCLOCK(5); if (CPU_INST_OP32) { - *(reg16_b20[op]) = CPU_TR; + *(reg32_b20[op]) = tr; } else { - *(reg32_b20[op]) = CPU_TR; + *(reg16_b20[op]) = tr; } } else { CPU_WORKCLOCK(11); madr = calc_ea_dst(op); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_TR); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, tr); } } + VERBOSE(("STR: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -205,23 +206,14 @@ LIDT_Ms(DWORD op) } #if defined(DEBUG) -{ - DWORD v[2]; - DWORD i; - - VERBOSE(("LIDT_Ms: IDTR_BASE = 0x%08x, IDTR_LIMIT = 0x%04x", base, limit)); - for (i = 0; i < limit; i += 8) { - v[0] = cpu_lmemoryread_d(base + i); - v[1] = cpu_lmemoryread_d(base + i + 4); - VERBOSE(("LGDT_Ms: %08x: %08x%08x", base + i, v[0], v[1])); - } -} + idtr_dump(base, limit); #endif CPU_IDTR_BASE = base; CPU_IDTR_LIMIT = limit; return; } + VERBOSE(("LIDT: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } EXCEPTION(UD_EXCEPTION, 0); @@ -249,11 +241,6 @@ SIDT_Ms(DWORD op) EXCEPTION(UD_EXCEPTION, 0); } -/* XXX */ -static const char *reg32_str[] = { - "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI" -}; - void MOV_CdRd(void) { @@ -265,6 +252,7 @@ MOV_CdRd(void) GET_PCBYTE(op); if (op >= 0xc0) { if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("MOV_CdRd: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } @@ -303,7 +291,7 @@ MOV_CdRd(void) src |= CPU_CR0_ET; /* FPU present */ #endif CPU_CR0 = src; - VERBOSE(("MOV_CdRd: %04x:%08x: cr0: 0x%08x -> 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR0, reg32_str[op & 7])); + VERBOSE(("MOV_CdRd: %04x:%08x: cr0: 0x%08x <- 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR0, reg32_str[op & 7])); if ((reg ^ CPU_CR0) & (CPU_CR0_PE|CPU_CR0_PG)) { tlb_flush(FALSE); @@ -330,7 +318,7 @@ MOV_CdRd(void) case 2: /* CR2 */ reg = CPU_CR2; CPU_CR2 = src; /* page fault linear address */ - VERBOSE(("MOV_CdRd: %04x:%08x: cr2: 0x%08x -> 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR2, reg32_str[op & 7])); + VERBOSE(("MOV_CdRd: %04x:%08x: cr2: 0x%08x <- 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR2, reg32_str[op & 7])); break; case 3: /* CR3 */ @@ -340,11 +328,11 @@ MOV_CdRd(void) * 3 = PWT (page level write throgh) */ reg = CPU_CR3; - CPU_CR3 = src & 0xfffff018; - VERBOSE(("MOV_CdRd: %04x:%08x: cr3: 0x%08x -> 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR3, reg32_str[op & 7])); - tlb_flush(FALSE); + set_CR3(src); + VERBOSE(("MOV_CdRd: %04x:%08x: cr3: 0x%08x <- 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR3, reg32_str[op & 7])); break; +#if CPU_FAMILY >= 5 case 4: /* CR4 */ /* * 10 = OSXMMEXCPT (support non masking exception by OS) @@ -369,12 +357,13 @@ MOV_CdRd(void) reg = CPU_CR4; CPU_CR4 = src; - VERBOSE(("MOV_CdRd: %04x:%08x: cr4: 0x%08x -> 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR4, reg32_str[op & 7])); + VERBOSE(("MOV_CdRd: %04x:%08x: cr4: 0x%08x <- 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR4, reg32_str[op & 7])); if ((reg ^ CPU_CR4) & (CPU_CR4_PSE|CPU_CR4_PGE|CPU_CR4_PAE)) { tlb_flush(FALSE); } break; +#endif /* CPU_FAMILY >= 5 */ default: ia32_panic("MOV_CdRd: CR reg index (%d)", idx); @@ -397,6 +386,7 @@ MOV_RdCd(void) GET_PCBYTE(op); if (op >= 0xc0) { if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("MOV_CdRd: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } @@ -416,9 +406,11 @@ MOV_RdCd(void) *out = CPU_CR3; break; +#if CPU_FAMILY >= 5 case 4: *out = CPU_CR4; break; +#endif /* CPU_FAMILY >= 5 */ default: ia32_panic("MOV_RdCd: CR reg index (%d)", idx); @@ -455,6 +447,7 @@ LMSW_Ew(DWORD op) } return; } + VERBOSE(("LMSW: CPL(%d) != 0", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } @@ -478,7 +471,8 @@ CLTS(void) { CPU_WORKCLOCK(2); - if (CPU_STAT_PM && CPU_STAT_CPL != 0) { + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL != 0))) { + VERBOSE(("CLTS: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } CPU_CR0 &= ~CPU_CR0_TS; @@ -494,21 +488,30 @@ ARPL_EwGw(void) if (op >= 0xc0) { CPU_WORKCLOCK(2); dst = *(reg16_b20[op]); + if ((dst & 3) < (src & 3)) { + CPU_FLAGL |= Z_FLAG; + dst &= ~3; + dst |= (src & 3); + *(reg16_b20[op]) = dst; + } else { + CPU_FLAGL &= ~Z_FLAG; + } } else { CPU_WORKCLOCK(3); madr = calc_ea_dst(op); dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - } - - if ((dst & 3) < (src & 3)) { - dst &= ~3; - dst |= (src & 3); - CPU_FLAGL |= Z_FLAG; - } else { - CPU_FLAGL &= ~Z_FLAG; + if ((dst & 3) < (src & 3)) { + CPU_FLAGL |= Z_FLAG; + dst &= ~3; + dst |= (src & 3); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); + } else { + CPU_FLAGL &= ~Z_FLAG; + } } return; } + VERBOSE(("ARPL: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -561,6 +564,7 @@ LAR_GwEw(void) CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("LAR: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -610,6 +614,7 @@ LAR_GdEw(void) CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("LAR: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -656,6 +661,7 @@ LSL_GwEw(void) CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("LSL: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -702,6 +708,7 @@ LSL_GdEw(void) CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("LSL: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -748,6 +755,7 @@ VERR_Ew(DWORD op) CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("VERR: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -793,6 +801,7 @@ VERW_Ew(DWORD op) CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("VERW: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -816,6 +825,7 @@ INVD(void) CPU_WORKCLOCK(11); if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("INVD: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } /* nothing to do */ @@ -827,6 +837,7 @@ WBINVD(void) CPU_WORKCLOCK(11); if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("WBINVD: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } /* nothing to do */ @@ -838,6 +849,7 @@ INVLPG(DWORD op) DWORD madr; if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("INVLPG: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } @@ -862,6 +874,7 @@ HLT(void) { if (CPU_STAT_PM && CPU_STAT_CPL != 0) { + VERBOSE(("HLT: CPL(%d) != 0", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } @@ -882,6 +895,7 @@ RDMSR(void) int idx; if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("RDMSR: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } @@ -899,6 +913,7 @@ WRMSR(void) int idx; if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("WRMSR: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); }