--- np2/i386c/ia32/instructions/system_inst.c 2003/12/08 00:55:32 1.1 +++ np2/i386c/ia32/instructions/system_inst.c 2004/01/07 14:50:21 1.4 @@ -1,4 +1,4 @@ -/* $Id: system_inst.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ +/* $Id: system_inst.c,v 1.4 2004/01/07 14:50:21 monaka Exp $ */ /* * Copyright (c) 2003 NONAKA Kimihiro @@ -151,14 +151,18 @@ SLDT_Ew(DWORD op) { DWORD madr; - if (op >= 0xc0) { - CPU_WORKCLOCK(5); - *(reg16_b20[op]) = CPU_LDTR; - } else { - CPU_WORKCLOCK(11); - madr = calc_ea_dst(op); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_LDTR); + if (CPU_STAT_PM && !CPU_STAT_VM86) { + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + *(reg16_b20[op]) = CPU_LDTR; + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_LDTR); + } + return; } + EXCEPTION(UD_EXCEPTION, 0); } void @@ -166,14 +170,18 @@ SLDT_Ed(DWORD op) { DWORD madr; - if (op >= 0xc0) { - CPU_WORKCLOCK(5); - *(reg32_b20[op]) = CPU_LDTR; - } else { - CPU_WORKCLOCK(11); - madr = calc_ea_dst(op); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, CPU_LDTR); + if (CPU_STAT_PM && !CPU_STAT_VM86) { + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + *(reg32_b20[op]) = CPU_LDTR; + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_LDTR); + } + return; } + EXCEPTION(UD_EXCEPTION, 0); } void @@ -236,7 +244,6 @@ LIDT16_Ms(DWORD op) DWORD base; WORD limit; - GET_PCBYTE(op); if (op < 0xc0) { CPU_WORKCLOCK(11); madr = get_ea(op); @@ -257,7 +264,6 @@ LIDT32_Ms(DWORD op) DWORD base; WORD limit; - GET_PCBYTE(op); if (op < 0xc0) { CPU_WORKCLOCK(11); madr = get_ea(op); @@ -277,7 +283,6 @@ SIDT16_Ms(DWORD op) DWORD base; WORD limit; - GET_PCBYTE(op); if (op < 0xc0) { CPU_WORKCLOCK(11); base = CPU_IDTR_BASE & 0x00ffffff; @@ -357,6 +362,7 @@ MOV_CdRd(void) src |= CPU_CR0_ET; /* FPU present */ #endif CPU_CR0 = src; + VERBOSE(("cr0: 0x%08x -> 0x%08x", reg, CPU_CR0)); if ((reg ^ CPU_CR0) & (CPU_CR0_PE|CPU_CR0_PG)) { tlb_flush(FALSE); @@ -381,7 +387,9 @@ MOV_CdRd(void) break; case 2: /* CR2 */ + reg = CPU_CR2; CPU_CR2 = src; /* page fault linear address */ + VERBOSE(("cr2: 0x%08x -> 0x%08x", reg, CPU_CR2)); break; case 3: /* CR3 */ @@ -390,7 +398,9 @@ MOV_CdRd(void) * 4 = PCD (page level cache diable) * 3 = PWT (page level write throgh) */ + reg = CPU_CR3; CPU_CR3 = src & 0xfffff018; + VERBOSE(("cr3: 0x%08x -> 0x%08x", reg, CPU_CR3)); tlb_flush(FALSE); break; @@ -416,8 +426,9 @@ MOV_CdRd(void) ia32_warning("MOV_CdRd: CR4 <- 0x%08x", src); } - reg = CPU_CR0; + reg = CPU_CR4; CPU_CR4 = src; + VERBOSE(("cr4: 0x%08x -> 0x%08x", reg, CPU_CR4)); if ((reg ^ CPU_CR4) & (CPU_CR4_PSE|CPU_CR4_PGE|CPU_CR4_PAE)) { tlb_flush(FALSE); @@ -478,6 +489,7 @@ void LMSW_Ew(DWORD op) { DWORD src, madr; + DWORD cr0; if (CPU_STAT_PM && CPU_STAT_CPL != 0) { EXCEPTION(GP_EXCEPTION, 0); @@ -492,9 +504,10 @@ LMSW_Ew(DWORD op) src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); } - CPU_CR0 &= ~0xfffffffe; /* can't switch back from protected mode */ + cr0 = CPU_CR0; + CPU_CR0 &= ~0xe; /* can't switch back from protected mode */ CPU_CR0 |= (src & 0xf); /* TS, EM, MP, PE */ - if ((src ^ CPU_CR0) & CPU_CR0_PE) { + if (!(cr0 & CPU_CR0_PE) && (src & CPU_CR0_PE)) { change_pm(1); /* switch to protected mode */ } } @@ -521,7 +534,7 @@ SMSW_Ed(DWORD op) if (op >= 0xc0) { CPU_WORKCLOCK(2); - *(reg32_b20[op]) = CPU_CR0; + *(reg32_b20[op]) = (WORD)CPU_CR0; } else { CPU_WORKCLOCK(3); madr = calc_ea_dst(op);