--- np2/i386c/ia32/instructions/system_inst.c 2004/03/07 04:09:27 1.21 +++ np2/i386c/ia32/instructions/system_inst.c 2004/03/12 15:10:38 1.25 @@ -1,4 +1,4 @@ -/* $Id: system_inst.c,v 1.21 2004/03/07 04:09:27 yui Exp $ */ +/* $Id: system_inst.c,v 1.25 2004/03/12 15:10:38 monaka Exp $ */ /* * Copyright (c) 2003 NONAKA Kimihiro @@ -90,7 +90,8 @@ SGDT_Ms(UINT32 op) void LLDT_Ew(UINT32 op) { - UINT32 src, madr; + UINT32 madr; + UINT16 src; if (CPU_STAT_PM && !CPU_STAT_VM86) { if (CPU_STAT_CPL == 0) { @@ -102,7 +103,7 @@ LLDT_Ew(UINT32 op) madr = calc_ea_dst(op); src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); } - load_ldtr((UINT16)src, GP_EXCEPTION); + load_ldtr(src, GP_EXCEPTION); return; } VERBOSE(("LLDT: CPL(%d) != 0", CPU_STAT_CPL)); @@ -287,7 +288,8 @@ MOV_CdRd(void) reg = CPU_CR0; src &= 0xe005003f; #ifndef USE_FPU - src &= ~CPU_CR0_ET; /* FPU not present */ + src |= CPU_CR0_EM | CPU_CR0_NE; + src &= ~(CPU_CR0_MP | CPU_CR0_ET); #else src |= CPU_CR0_ET; /* FPU present */ #endif @@ -484,7 +486,8 @@ CLTS(void) void ARPL_EwGw(void) { - UINT32 op, src, dst, madr; + UINT32 op, src, madr; + UINT16 dst; if (CPU_STAT_PM && !CPU_STAT_VM86) { PREPART_EA_REG16(op, src); @@ -495,7 +498,7 @@ ARPL_EwGw(void) CPU_FLAGL |= Z_FLAG; dst &= ~3; dst |= (src & 3); - *(reg16_b20[op]) = (UINT16)dst; + *(reg16_b20[op]) = dst; } else { CPU_FLAGL &= ~Z_FLAG; } @@ -507,7 +510,7 @@ ARPL_EwGw(void) CPU_FLAGL |= Z_FLAG; dst &= ~3; dst |= (src & 3); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)dst); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, dst); } else { CPU_FLAGL &= ~Z_FLAG; } @@ -840,59 +843,140 @@ VERW_Ew(UINT32 op) void MOV_DdRd(void) { -#if 1 - UINT32 op; UINT32 src; + UINT op; int idx; + int i; CPU_WORKCLOCK(11); GET_PCBYTE(op); if (op >= 0xc0) { if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { - TRACEOUT(("MOV_DdRd: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + VERBOSE(("MOV_DdRd: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } + if (CPU_DR7 & CPU_DR7_GD) { + CPU_DR6 |= CPU_DR6_BD; + CPU_DR7 &= ~CPU_DR7_GD; + EXCEPTION(DB_EXCEPTION, 0); + } + src = *(reg32_b20[op]); idx = (op >> 3) & 7; - CPU_STATSAVE.cpu_regs.dr[idx] = src; - TRACEOUT(("MOV_DdRd: %04x:%08x: dr%d: 0x%08x <- %s", CPU_CS, CPU_PREV_EIP, idx, src, reg32_str[op & 7])); + CPU_DR(idx) = src; + switch (idx) { + case 0: + case 1: + case 2: + case 3: + CPU_DR(idx) = src; + break; + +#if CPU_FAMILY >= 5 + case 4: + if (CPU_CR4 & CPU_CR4_DE) { + EXCEPTION(UD_EXCEPTION, 0); + } +#endif + case 6: + CPU_DR6 = src; + break; + +#if CPU_FAMILY >= 5 + case 5: + if (CPU_CR4 & CPU_CR4_DE) { + EXCEPTION(UD_EXCEPTION, 0); + } +#endif + case 7: + CPU_DR7 = src; + CPU_STAT_BP = 0; +#if defined(IA32_SUPPORT_DEBUG_REGISTER) + for (i = 0; i < CPU_DEBUG_REG_INDEX_NUM; i++) { + if (CPU_DR7 & (CPU_DR7_L(i)|CPU_DR7_G(i))) { + CPU_STAT_BP |= (1 << i); + } + } +#endif /* IA32_SUPPORT_DEBUG_REGISTER */ + break; + + default: + ia32_panic("MOV_DdRd: DR reg index (%d)", idx); + /*NOTREACHED*/ + break; + } + return; } EXCEPTION(UD_EXCEPTION, 0); -#else - ia32_panic("MOV_DdRd: not implemented yet!"); -#endif } void MOV_RdDd(void) { -#if 1 UINT32 *out; - UINT32 op; + UINT op; int idx; CPU_WORKCLOCK(11); GET_PCBYTE(op); if (op >= 0xc0) { if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { - TRACEOUT(("MOV_RdDd: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + VERBOSE(("MOV_RdDd: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } + if (CPU_DR7 & CPU_DR7_GD) { + CPU_DR6 |= CPU_DR6_BD; + CPU_DR7 &= ~CPU_DR7_GD; + EXCEPTION(DB_EXCEPTION, 0); + } + out = reg32_b20[op]; idx = (op >> 3) & 7; - *out = CPU_STATSAVE.cpu_regs.dr[idx]; - TRACEOUT(("MOV_RdDd: %04x:%08x: dr%d: 0x%08x -> %s", CPU_CS, CPU_PREV_EIP, idx, *out, reg32_str[op & 7])); + switch (idx) { + case 0: + case 1: + case 2: + case 3: + *out = CPU_DR(idx); + break; + + case 4: +#if CPU_FAMILY >= 5 + if (CPU_CR4 & CPU_CR4_DE) { + EXCEPTION(UD_EXCEPTION, 0); + } +#endif + case 6: +#if CPU_FAMILY == 4 + *out = (CPU_DR6 & 0x0000f00f) | 0xffff0ff0; +#elif CPU_FAMILY >= 5 + *out = (CPU_DR6 & 0x0000e00f) | 0xffff0ff0; +#endif + break; + +#if CPU_FAMILY >= 5 + case 5: + if (CPU_CR4 & CPU_CR4_DE) { + EXCEPTION(UD_EXCEPTION, 0); + } +#endif + case 7: + *out = CPU_DR7; + break; + + default: + ia32_panic("MOV_RdDd: DR reg index (%d)", idx); + /*NOTREACHED*/ + break; + } return; } EXCEPTION(UD_EXCEPTION, 0); -#else - ia32_panic("MOV_DdRd: not implemented yet!"); -#endif } void @@ -904,7 +988,8 @@ INVD(void) VERBOSE(("INVD: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } - /* nothing to do */ + + tlb_flush(TRUE); } void @@ -916,7 +1001,8 @@ WBINVD(void) VERBOSE(("WBINVD: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } - /* nothing to do */ + + tlb_flush(TRUE); } void @@ -964,14 +1050,11 @@ INVLPG(UINT32 op) break; } tlb_flush_page(sd->u.seg.segbase + madr); + return; } - return; - + exc = UD_EXCEPTION; err: -#if 0 /* XXX */ EXCEPTION(exc, 0); -#endif - return; } void @@ -992,6 +1075,9 @@ HLT(void) CPU_HALT(); CPU_EIP--; +#if defined(IA32_SUPPORT_PREFETCH_QUEUE) + CPU_PREFETCHQ_REMAIN++; +#endif CPU_STAT_HLT = 1; }