--- np2/i386c/ia32/instructions/system_inst.c 2003/12/08 00:55:32 1.1 +++ np2/i386c/ia32/instructions/system_inst.c 2004/02/04 13:24:35 1.13 @@ -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.13 2004/02/04 13:24:35 monaka Exp $ */ /* * Copyright (c) 2003 NONAKA Kimihiro @@ -35,33 +35,7 @@ void -LGDT16_Ms(DWORD op) -{ - DWORD madr; - DWORD base; - WORD limit; - - if (op < 0xc0) { - if (!CPU_STAT_PM || !CPU_STAT_VM86 || CPU_STAT_CPL == 0) { - CPU_WORKCLOCK(11); - madr = get_ea(op); - limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); - base &= 0x00ffffff; - - VERBOSE(("LGDT16_Ms: GDTR_BASE = 0x%08x, GDTR_LIMIT = 0x%04x", base, limit)); - - CPU_GDTR_BASE = base; - CPU_GDTR_LIMIT = limit; - return; - } - EXCEPTION(GP_EXCEPTION, 0); - } - EXCEPTION(UD_EXCEPTION, 0); -} - -void -LGDT32_Ms(DWORD op) +LGDT_Ms(DWORD op) { DWORD madr; DWORD base; @@ -73,20 +47,26 @@ LGDT32_Ms(DWORD op) madr = get_ea(op); limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); + if (!CPU_INST_OP32) { + base &= 0x00ffffff; + } - VERBOSE(("LGDT32_Ms: GDTR_BASE = 0x%08x, GDTR_LIMIT = 0x%04x", base, limit)); +#if defined(MORE_DEBUG) + 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); } void -SGDT16_Ms(DWORD op) +SGDT_Ms(DWORD op) { DWORD madr; DWORD base; @@ -94,27 +74,11 @@ SGDT16_Ms(DWORD op) if (op < 0xc0) { CPU_WORKCLOCK(11); - base = CPU_GDTR_BASE & 0x00ffffff; limit = CPU_GDTR_LIMIT; - madr = get_ea(op); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, limit); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 2, base); - return; - } - EXCEPTION(UD_EXCEPTION, 0); -} - -void -SGDT32_Ms(DWORD op) -{ - DWORD madr; - DWORD base; - WORD limit; - - if (op < 0xc0) { - CPU_WORKCLOCK(11); base = CPU_GDTR_BASE; - limit = CPU_GDTR_LIMIT; + if (!CPU_INST_OP32) { + base &= 0x00ffffff; + } madr = get_ea(op); cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, limit); cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 2, base); @@ -141,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); } @@ -150,30 +116,26 @@ void SLDT_Ew(DWORD op) { DWORD madr; + WORD ldtr; - 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); - } -} - -void -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) { + ldtr = CPU_LDTR; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + if (CPU_INST_OP32) { + *(reg32_b20[op]) = ldtr; + } else { + *(reg16_b20[op]) = ldtr; + } + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, ldtr); + } + return; } + VERBOSE(("SLDT: VM86")); + EXCEPTION(UD_EXCEPTION, 0); } void @@ -194,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); } @@ -203,95 +167,61 @@ void STR_Ew(DWORD op) { DWORD madr; + WORD tr; - if (op >= 0xc0) { - CPU_WORKCLOCK(5); - *(reg16_b20[op]) = CPU_TR; - } else { - CPU_WORKCLOCK(11); - madr = calc_ea_dst(op); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_TR); - } -} - -void -STR_Ed(DWORD op) -{ - DWORD madr; - - if (op >= 0xc0) { - CPU_WORKCLOCK(5); - *(reg32_b20[op]) = CPU_TR; - } else { - CPU_WORKCLOCK(11); - madr = calc_ea_dst(op); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, CPU_TR); - } -} - -void -LIDT16_Ms(DWORD op) -{ - DWORD madr; - DWORD base; - WORD limit; - - GET_PCBYTE(op); - if (op < 0xc0) { - CPU_WORKCLOCK(11); - madr = get_ea(op); - limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); - base &= 0x00ffffff; - CPU_IDTR_BASE = base; - CPU_IDTR_LIMIT = limit; + if (CPU_STAT_PM && !CPU_STAT_VM86) { + tr = CPU_TR; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + if (CPU_INST_OP32) { + *(reg32_b20[op]) = tr; + } else { + *(reg16_b20[op]) = tr; + } + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, tr); + } return; } + VERBOSE(("STR: VM86")); EXCEPTION(UD_EXCEPTION, 0); } void -LIDT32_Ms(DWORD op) +LIDT_Ms(DWORD op) { DWORD madr; DWORD base; WORD limit; - GET_PCBYTE(op); if (op < 0xc0) { - CPU_WORKCLOCK(11); - madr = get_ea(op); - limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); - CPU_IDTR_BASE = base; - CPU_IDTR_LIMIT = limit; - return; - } - EXCEPTION(UD_EXCEPTION, 0); -} + if (!CPU_STAT_PM || !CPU_STAT_VM86 || CPU_STAT_CPL == 0) { + CPU_WORKCLOCK(11); + madr = get_ea(op); + limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); + if (!CPU_INST_OP32) { + base &= 0x00ffffff; + } -void -SIDT16_Ms(DWORD op) -{ - DWORD madr; - DWORD base; - WORD limit; +#if defined(MORE_DEBUG) + idtr_dump(base, limit); +#endif - GET_PCBYTE(op); - if (op < 0xc0) { - CPU_WORKCLOCK(11); - base = CPU_IDTR_BASE & 0x00ffffff; - limit = CPU_IDTR_LIMIT; - madr = get_ea(op); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, limit); - cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 2, base); - return; + 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); } void -SIDT32_Ms(DWORD op) +SIDT_Ms(DWORD op) { DWORD madr; DWORD base; @@ -299,8 +229,11 @@ SIDT32_Ms(DWORD op) if (op < 0xc0) { CPU_WORKCLOCK(11); - base = CPU_IDTR_BASE; limit = CPU_IDTR_LIMIT; + base = CPU_IDTR_BASE; + if (!CPU_INST_OP32) { + base &= 0x00ffffff; + } madr = get_ea(op); cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, limit); cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 2, base); @@ -320,11 +253,13 @@ 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); } src = *(reg32_b20[op]); idx = (op >> 3) & 7; + switch (idx) { case 0: /* CR0 */ /* @@ -357,6 +292,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])); if ((reg ^ CPU_CR0) & (CPU_CR0_PE|CPU_CR0_PG)) { tlb_flush(FALSE); @@ -381,7 +317,9 @@ MOV_CdRd(void) break; 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])); break; case 3: /* CR3 */ @@ -390,10 +328,12 @@ MOV_CdRd(void) * 4 = PCD (page level cache diable) * 3 = PWT (page level write throgh) */ - CPU_CR3 = src & 0xfffff018; - tlb_flush(FALSE); + reg = CPU_CR3; + 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) @@ -416,13 +356,15 @@ MOV_CdRd(void) ia32_warning("MOV_CdRd: CR4 <- 0x%08x", src); } - reg = CPU_CR0; + 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])); 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); @@ -439,15 +381,20 @@ MOV_RdCd(void) { DWORD *out; DWORD op; + int idx; CPU_WORKCLOCK(11); - PREPART_EA_REG32P(op, out); + 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); } - switch (op & 7) { + out = reg32_b20[op]; + idx = (op >> 3) & 7; + + switch (idx) { case 0: *out = CPU_CR0; break; @@ -460,15 +407,18 @@ 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)", op & 7); + ia32_panic("MOV_RdCd: CR reg index (%d)", idx); /*NOTREACHED*/ break; } + VERBOSE(("MOV_RdCd: %04x:%08x: cr%d: 0x%08x -> %s", CPU_CS, CPU_PREV_EIP, idx, *out, reg32_str[op & 7])); return; } EXCEPTION(UD_EXCEPTION, 0); @@ -478,25 +428,28 @@ void LMSW_Ew(DWORD op) { DWORD src, madr; + DWORD cr0; - if (CPU_STAT_PM && CPU_STAT_CPL != 0) { - EXCEPTION(GP_EXCEPTION, 0); - } - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - src = *(reg16_b20[op]); - } else { - CPU_WORKCLOCK(3); - madr = calc_ea_dst(op); - src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - } + if (!CPU_STAT_PM || CPU_STAT_CPL == 0) { + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } - CPU_CR0 &= ~0xfffffffe; /* can't switch back from protected mode */ - CPU_CR0 |= (src & 0xf); /* TS, EM, MP, PE */ - if ((src ^ CPU_CR0) & CPU_CR0_PE) { - change_pm(1); /* switch to protected mode */ + cr0 = CPU_CR0; + CPU_CR0 &= ~0xe; /* can't switch back from protected mode */ + CPU_CR0 |= (src & 0xf); /* TS, EM, MP, PE */ + if (!(cr0 & CPU_CR0_PE) && (src & CPU_CR0_PE)) { + change_pm(1); /* switch to protected mode */ + } + return; } + VERBOSE(("LMSW: CPL(%d) != 0", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); } void @@ -515,26 +468,12 @@ SMSW_Ew(DWORD op) } void -SMSW_Ed(DWORD op) -{ - DWORD madr; - - if (op >= 0xc0) { - CPU_WORKCLOCK(2); - *(reg32_b20[op]) = CPU_CR0; - } else { - CPU_WORKCLOCK(3); - madr = calc_ea_dst(op); - cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (WORD)CPU_CR0); - } -} - -void 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; @@ -550,21 +489,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); } @@ -577,13 +525,16 @@ LAR_GwEw(void) selector_t sel; WORD *out; DWORD op; + DWORD h; + int user_mode; int rv; WORD selector; if (CPU_STAT_PM && !CPU_STAT_VM86) { PREPART_REG16_EA(op, selector, out, 5, 11); - rv = parse_selector(&sel, selector); + user_mode = CPU_IS_USER_MODE(); + rv = parse_selector(&sel, selector, user_mode); if (rv < 0) { CPU_FLAGL &= ~Z_FLAG; return; @@ -613,10 +564,12 @@ LAR_GwEw(void) } } - *out = sel.desc.h & 0xff00; + h = cpu_lmemoryread_d(sel.addr + 4, user_mode); + *out = h & 0xff00; CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("LAR: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -626,13 +579,16 @@ LAR_GdEw(void) selector_t sel; DWORD *out; DWORD op; + DWORD h; + int user_mode; int rv; WORD selector; if (CPU_STAT_PM && !CPU_STAT_VM86) { PREPART_REG32_EA(op, selector, out, 5, 11); - rv = parse_selector(&sel, selector); + user_mode = CPU_IS_USER_MODE(); + rv = parse_selector(&sel, selector, user_mode); if (rv < 0) { CPU_FLAGL &= ~Z_FLAG; return; @@ -662,10 +618,12 @@ LAR_GdEw(void) } } - *out = sel.desc.h & 0x00ffff00; /* 0x00fxff00, x? */ + h = cpu_lmemoryread_d(sel.addr + 4, user_mode); + *out = h & 0x00ffff00; /* 0x00fxff00, x? */ CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("LAR: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -681,7 +639,7 @@ LSL_GwEw(void) if (CPU_STAT_PM && !CPU_STAT_VM86) { PREPART_REG16_EA(op, selector, out, 5, 11); - rv = parse_selector(&sel, selector); + rv = parse_selector(&sel, selector, CPU_IS_USER_MODE()); if (rv < 0) { CPU_FLAGL &= ~Z_FLAG; return; @@ -712,6 +670,7 @@ LSL_GwEw(void) CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("LSL: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -727,7 +686,7 @@ LSL_GdEw(void) if (CPU_STAT_PM && !CPU_STAT_VM86) { PREPART_REG32_EA(op, selector, out, 5, 11); - rv = parse_selector(&sel, selector); + rv = parse_selector(&sel, selector, CPU_IS_USER_MODE()); if (rv < 0) { CPU_FLAGL &= ~Z_FLAG; return; @@ -758,6 +717,7 @@ LSL_GdEw(void) CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("LSL: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -779,7 +739,7 @@ VERR_Ew(DWORD op) selector = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); } - rv = parse_selector(&sel, selector); + rv = parse_selector(&sel, selector, CPU_IS_USER_MODE()); if (rv < 0) { CPU_FLAGL &= ~Z_FLAG; return; @@ -804,6 +764,7 @@ VERR_Ew(DWORD op) CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("VERR: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -825,7 +786,7 @@ VERW_Ew(DWORD op) selector = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); } - rv = parse_selector(&sel, selector); + rv = parse_selector(&sel, selector, CPU_IS_USER_MODE()); if (rv < 0) { CPU_FLAGL &= ~Z_FLAG; return; @@ -837,7 +798,7 @@ VERW_Ew(DWORD op) return; } /* data segment is not writable */ - if (sel.desc.u.seg.c && !sel.desc.u.seg.wr) { + if (!sel.desc.u.seg.wr) { CPU_FLAGL &= ~Z_FLAG; return; } @@ -849,6 +810,7 @@ VERW_Ew(DWORD op) CPU_FLAGL |= Z_FLAG; return; } + VERBOSE(("VERW: VM86")); EXCEPTION(UD_EXCEPTION, 0); } @@ -872,6 +834,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 */ @@ -883,6 +846,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 */ @@ -894,6 +858,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); } @@ -918,6 +883,7 @@ HLT(void) { if (CPU_STAT_PM && CPU_STAT_CPL != 0) { + VERBOSE(("HLT: CPL(%d) != 0", CPU_STAT_CPL)); EXCEPTION(GP_EXCEPTION, 0); } @@ -935,28 +901,39 @@ RSM(void) void RDMSR(void) { + int idx; -#if 1 - EXCEPTION(UD_EXCEPTION, 0); -#else 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); } -#endif + + idx = CPU_ECX; + switch (idx) { + default: + EXCEPTION(GP_EXCEPTION, 0); + break; + } } void WRMSR(void) { + int idx; -#if 1 - EXCEPTION(UD_EXCEPTION, 0); -#else 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); - /* MTRR への書き込み時 tlb_flush(FALSE) */ } -#endif + + idx = CPU_ECX; + switch (idx) { + /* MTRR への書き込み時 tlb_flush(FALSE); */ + + default: + EXCEPTION(GP_EXCEPTION, 0); + break; + } } void