From 308521e7ceedd838757c59cdff4f16e977222a0b Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Sun, 11 Jun 2006 21:37:22 +0000 Subject: [PATCH] Fixes in SYSCALL/SYSRET instructions Use parse_selector to avoid code duplication --- bochs/cpu/cpu.cc | 4 +- bochs/cpu/init.cc | 24 ++-- bochs/cpu/proc_ctrl.cc | 283 +++++++++++++++++++++++++++++------------ bochs/cpu/smm.cc | 16 +-- 4 files changed, 222 insertions(+), 105 deletions(-) diff --git a/bochs/cpu/cpu.cc b/bochs/cpu/cpu.cc index 63f464f59..acbc76c62 100644 --- a/bochs/cpu/cpu.cc +++ b/bochs/cpu/cpu.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.cc,v 1.159 2006-06-06 16:46:07 sshwarts Exp $ +// $Id: cpu.cc,v 1.160 2006-06-11 21:37:22 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -224,7 +224,7 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count) // the debugger may request that control is returned to it so that // the situation may be examined. if (bx_guard.special_unwind_stack) { - BX_ERROR(("CPU_LOOP bx_guard.special_unwind_stack=%d\n", bx_guard.special_unwind_stack)); + BX_ERROR(("CPU_LOOP bx_guard.special_unwind_stack=%d", bx_guard.special_unwind_stack)); return; } #endif diff --git a/bochs/cpu/init.cc b/bochs/cpu/init.cc index 5db79bf2f..280348028 100644 --- a/bochs/cpu/init.cc +++ b/bochs/cpu/init.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: init.cc,v 1.116 2006-06-06 18:36:50 vruppert Exp $ +// $Id: init.cc,v 1.117 2006-06-11 21:37:22 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -775,20 +775,19 @@ void BX_CPU_C::reset(unsigned source) * 286 F000 FF0000 FFFF FFF0 * 386+ F000 FFFF0000 FFFF FFF0 */ - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = 0xF000; -#if BX_CPU_LEVEL >= 2 - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = 0; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = 0; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 0; + parse_selector(0xf000, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector); + +#if BX_CPU_LEVEL >= 2 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 0; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = 11; /* executable/readable/access code segment */ - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; /* data/stack segment */ - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* normal expand up */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; /* executable segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* non-confirming */ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = 0xFFFF0000; @@ -809,12 +808,11 @@ void BX_CPU_C::reset(unsigned source) #endif /* DS (Data Segment) and descriptor cache */ - BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = 0x0000; -#if BX_CPU_LEVEL >= 2 - BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = 0; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti = 0; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl = 0; + parse_selector(0x0000, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector); + +#if BX_CPU_LEVEL >= 2 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl = 0; diff --git a/bochs/cpu/proc_ctrl.cc b/bochs/cpu/proc_ctrl.cc index 8d07a8b54..33e3186f4 100644 --- a/bochs/cpu/proc_ctrl.cc +++ b/bochs/cpu/proc_ctrl.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: proc_ctrl.cc,v 1.151 2006-06-09 22:29:07 sshwarts Exp $ +// $Id: proc_ctrl.cc,v 1.152 2006-06-11 21:37:22 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -1864,18 +1864,16 @@ do_exception: #endif } -void BX_CPU_C::SYSENTER (bxInstruction_c *i) +void BX_CPU_C::SYSENTER(bxInstruction_c *i) { #if BX_SUPPORT_SEP - if (!protected_mode ()) { - BX_INFO(("sysenter not from protected mode !")); + if (!protected_mode()) { + BX_ERROR(("sysenter not from protected mode !")); exception(BX_GP_EXCEPTION, 0, 0); - return; } if ((BX_CPU_THIS_PTR msr.sysenter_cs_msr & BX_SELECTOR_RPL_MASK) == 0) { - BX_INFO(("sysenter with zero sysenter_cs_msr !")); + BX_ERROR(("sysenter with zero sysenter_cs_msr !")); exception(BX_GP_EXCEPTION, 0, 0); - return; } invalidate_prefetch_q(); @@ -1884,10 +1882,9 @@ void BX_CPU_C::SYSENTER (bxInstruction_c *i) BX_CPU_THIS_PTR clear_IF(); BX_CPU_THIS_PTR clear_RF(); - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = BX_CPU_THIS_PTR msr.sysenter_cs_msr & BX_SELECTOR_RPL_MASK; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = BX_CPU_THIS_PTR msr.sysenter_cs_msr >> 3; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti =(BX_CPU_THIS_PTR msr.sysenter_cs_msr >> 2) & 1; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 0; + parse_selector(BX_CPU_THIS_PTR msr.sysenter_cs_msr & BX_SELECTOR_RPL_MASK, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector); + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; // code segment BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; // non-conforming BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; // readable @@ -1903,10 +1900,9 @@ void BX_CPU_C::SYSENTER (bxInstruction_c *i) BX_CPU_THIS_PTR updateFetchModeMask(); #endif - BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = (BX_CPU_THIS_PTR msr.sysenter_cs_msr + 8) & BX_SELECTOR_RPL_MASK; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = (BX_CPU_THIS_PTR msr.sysenter_cs_msr + 8) >> 3; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti =((BX_CPU_THIS_PTR msr.sysenter_cs_msr + 8) >> 2) & 1; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = 0; + parse_selector((BX_CPU_THIS_PTR msr.sysenter_cs_msr + 8) & BX_SELECTOR_RPL_MASK, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector); + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = 0; // data segment BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = 0; // expand-up BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w = 1; // writeable @@ -1926,15 +1922,15 @@ void BX_CPU_C::SYSENTER (bxInstruction_c *i) #endif } -void BX_CPU_C::SYSEXIT (bxInstruction_c *i) +void BX_CPU_C::SYSEXIT(bxInstruction_c *i) { #if BX_SUPPORT_SEP - if (!protected_mode ()) { - BX_INFO(("sysexit not from protected mode !")); + if (!protected_mode()) { + BX_ERROR(("sysexit not from protected mode !")); exception(BX_GP_EXCEPTION, 0, 0); } if ((BX_CPU_THIS_PTR msr.sysenter_cs_msr & BX_SELECTOR_RPL_MASK) == 0) { - BX_INFO(("sysexit with zero sysenter_cs_msr !")); + BX_ERROR(("sysexit with zero sysenter_cs_msr !")); exception(BX_GP_EXCEPTION, 0, 0); } if (CPL != 0) { @@ -1944,10 +1940,9 @@ void BX_CPU_C::SYSEXIT (bxInstruction_c *i) invalidate_prefetch_q(); - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = (BX_CPU_THIS_PTR msr.sysenter_cs_msr + 16) | 3; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = (BX_CPU_THIS_PTR msr.sysenter_cs_msr + 16) >> 3; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti =((BX_CPU_THIS_PTR msr.sysenter_cs_msr + 16) >> 2) & 1; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 3; + parse_selector((BX_CPU_THIS_PTR msr.sysenter_cs_msr + 16) | 3, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector); + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; // code segment BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; // non-conforming BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; // readable @@ -1963,10 +1958,9 @@ void BX_CPU_C::SYSEXIT (bxInstruction_c *i) BX_CPU_THIS_PTR updateFetchModeMask(); #endif - BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = (BX_CPU_THIS_PTR msr.sysenter_cs_msr + 24) | 3; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = (BX_CPU_THIS_PTR msr.sysenter_cs_msr + 24) >> 3; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti =((BX_CPU_THIS_PTR msr.sysenter_cs_msr + 24) >> 2) & 1; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = 3; + parse_selector((BX_CPU_THIS_PTR msr.sysenter_cs_msr + 24) | 3, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector); + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = 0; // data segment BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = 0; // expand-up BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w = 1; // writeable @@ -2057,9 +2051,6 @@ SYSCALL_LEGACY_MODE: */ bx_address temp_RIP; - bx_descriptor_t cs_descriptor,ss_descriptor; - bx_selector_t cs_selector,ss_selector; - Bit32u dword1, dword2; BX_DEBUG(("Execute SYSCALL instruction")); @@ -2081,15 +2072,51 @@ SYSCALL_LEGACY_MODE: temp_RIP = MSR_CSTAR; } - parse_selector((MSR_STAR >> 32) & 0xFFFC, &cs_selector); - fetch_raw_descriptor(&cs_selector, &dword1, &dword2, BX_GP_EXCEPTION); - parse_descriptor(dword1, dword2, &cs_descriptor); - load_cs(&cs_selector, &cs_descriptor, 0); + // set up CS segment, flat, 64-bit DPL=0 + parse_selector((MSR_STAR >> 32) & BX_SELECTOR_RPL_MASK, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector); - parse_selector((MSR_STAR >> 32) + 8, &ss_selector); - fetch_raw_descriptor(&ss_selector, &dword1, &dword2, BX_GP_EXCEPTION); - parse_descriptor(dword1, dword2, &ss_descriptor); - load_ss(&ss_selector, &ss_descriptor, 0); + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 0; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = 11; /* executable/readable/access code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* non-conforming */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = 0; /* base address */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xFFFF; /* segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xFFFFFFFF; /* scaled segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 1; /* 4k granularity */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 0; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l = 1; /* 64-bit code */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; /* available for use by system */ + +#if BX_SUPPORT_ICACHE + BX_CPU_THIS_PTR updateFetchModeMask(); +#endif + + // set up SS segment, flat, 64-bit DPL=0 + parse_selector(((MSR_STAR >> 32) + 8) & BX_SELECTOR_RPL_MASK, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector); + + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = 0; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = 1; /* data/code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type = 3; /* read/write/access */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = 0; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = 0; /* normal expand up */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w = 1; /* writeable */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a = 1; /* accessed */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base = 0; /* base address */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit = 0xFFFF; /* segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled = 0xFFFFFFFF; /* scaled segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g = 1; /* 4k granularity */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b = 1; /* 32 bit stack */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.l = 0; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0; /* available for use by system */ writeEFlags(read_eflags() & (~MSR_FMASK), EFlagsValidMask); BX_CPU_THIS_PTR clear_RF(); @@ -2101,19 +2128,55 @@ SYSCALL_LEGACY_MODE: ECX = EIP; temp_RIP = MSR_STAR & 0xFFFFFFFF; - parse_selector((MSR_STAR >> 32) & 0xFFFC, &cs_selector); - fetch_raw_descriptor(&cs_selector, &dword1, &dword2, BX_GP_EXCEPTION); - parse_descriptor(dword1, dword2, &cs_descriptor); - load_cs(&cs_selector, &cs_descriptor, 0); + // set up CS segment, flat, 32-bit DPL=0 + parse_selector((MSR_STAR >> 32) & BX_SELECTOR_RPL_MASK, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector); - parse_selector((MSR_STAR >> 32) + 8, &ss_selector); - fetch_raw_descriptor(&ss_selector, &dword1, &dword2, BX_GP_EXCEPTION); - parse_descriptor(dword1, dword2, &ss_descriptor); - load_ss(&ss_selector, &ss_descriptor, 0); + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 0; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = 11; /* executable/readable/access code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* non-conforming */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = 0; /* base address */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xFFFF; /* segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xFFFFFFFF; /* scaled segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 1; /* 4k granularity */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l = 0; /* 32-bit code */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; /* available for use by system */ - BX_CPU_THIS_PTR clear_VM (); - BX_CPU_THIS_PTR clear_IF (); - BX_CPU_THIS_PTR clear_RF (); +#if BX_SUPPORT_ICACHE + BX_CPU_THIS_PTR updateFetchModeMask(); +#endif + + // set up SS segment, flat, 32-bit DPL=0 + parse_selector(((MSR_STAR >> 32) + 8) & BX_SELECTOR_RPL_MASK, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector); + + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = 0; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = 1; /* data/code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type = 3; /* read/write/access */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = 0; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = 0; /* normal expand up */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w = 1; /* writeable */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a = 1; /* accessed */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base = 0; /* base address */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit = 0xFFFF; /* segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled = 0xFFFFFFFF; /* scaled segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g = 1; /* 4k granularity */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b = 1; /* 32 bit stack */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.l = 0; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0; /* available for use by system */ + + BX_CPU_THIS_PTR clear_VM(); + BX_CPU_THIS_PTR clear_IF(); + BX_CPU_THIS_PTR clear_RF(); RIP = temp_RIP; } } @@ -2175,9 +2238,6 @@ SYSRET_NON_64BIT_MODE: */ bx_address temp_RIP; - bx_descriptor_t cs_descriptor,ss_descriptor; - bx_selector_t cs_selector,ss_selector; - Bit32u dword1, dword2; BX_DEBUG(("Execute SYSRET instruction")); @@ -2194,51 +2254,112 @@ SYSRET_NON_64BIT_MODE: if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) { - if (i->os64L()) { // Return to 64-bit mode - parse_selector(((MSR_STAR >> 48) + 16) | 3, &cs_selector); - fetch_raw_descriptor(&cs_selector, &dword1, &dword2, BX_GP_EXCEPTION); - parse_descriptor(dword1, dword2, &cs_descriptor); - load_cs(&cs_selector, &cs_descriptor, 3); + if (i->os64L()) { + // Return to 64-bit mode, set up CS segment, flat, 64-bit DPL=3 + parse_selector(((MSR_STAR >> 48) + 16) | 3, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector); + + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 3; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = 11; /* executable/readable/access code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* non-conforming */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = 0; /* base address */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xFFFF; /* segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xFFFFFFFF; /* scaled segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 1; /* 4k granularity */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 0; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l = 1; /* 64-bit code */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; /* available for use by system */ temp_RIP = RCX; } - else { // Return to 32-bit compatibility mode - parse_selector((MSR_STAR >> 48) | 3, &cs_selector); - fetch_raw_descriptor(&cs_selector, &dword1, &dword2, BX_GP_EXCEPTION); - parse_descriptor(dword1, dword2, &cs_descriptor); - load_cs(&cs_selector, &cs_descriptor, 3); + else { + // Return to 32-bit compatibility mode, set up CS segment, flat, 32-bit DPL=3 + parse_selector((MSR_STAR >> 48) | 3, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector); + + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 3; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = 11; /* executable/readable/access code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* non-conforming */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = 0; /* base address */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xFFFF; /* segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xFFFFFFFF; /* scaled segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 1; /* 4k granularity */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l = 0; /* 32-bit code */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; /* available for use by system */ temp_RIP = ECX; } - parse_selector((MSR_STAR >> 48) + 8, &ss_selector); - fetch_raw_descriptor(&ss_selector, &dword1, &dword2, BX_GP_EXCEPTION); - parse_descriptor(dword1, dword2, &ss_descriptor); - // SS base, limit, attributes unchanged. - load_ss(&ss_selector, &ss_descriptor, 0); +#if BX_SUPPORT_ICACHE + BX_CPU_THIS_PTR updateFetchModeMask(); +#endif + + // SS base, limit, attributes unchanged + parse_selector((MSR_STAR >> 48) + 8, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector); + + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = 3; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = 1; /* data/code segment */ writeEFlags(R11, EFlagsValidMask); RIP = temp_RIP; } else { // (!64BIT_MODE) - parse_selector((MSR_STAR >> 48) | 3, &cs_selector); - fetch_raw_descriptor(&cs_selector, &dword1, &dword2, BX_GP_EXCEPTION); - parse_descriptor(dword1, dword2, &cs_descriptor); - load_cs(&cs_selector, &cs_descriptor, 3); + // Return to 32-bit legacy mode, set up CS segment, flat, 32-bit DPL=3 + parse_selector((MSR_STAR >> 48) | 3, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector); + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 3; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = 11; /* executable/readable/access code segment */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* non-conforming */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = 0; /* base address */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xFFFF; /* segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xFFFFFFFF; /* scaled segment limit */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 1; /* 4k granularity */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l = 0; /* 32-bit code */ + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; /* available for use by system */ + +#if BX_SUPPORT_ICACHE + BX_CPU_THIS_PTR updateFetchModeMask(); +#endif + + // SS base, limit, attributes unchanged + parse_selector((MSR_STAR >> 48) + 8, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector); + + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = 1; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = 3; + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = 1; /* data/code segment */ + + BX_CPU_THIS_PTR assert_IF(); temp_RIP = ECX; - - parse_selector((MSR_STAR >> 48) + 8, &ss_selector); - fetch_raw_descriptor(&ss_selector, &dword1, &dword2, BX_GP_EXCEPTION); - parse_descriptor(dword1, dword2, &ss_descriptor); - // SS base, limit, attributes unchanged. - load_ss(&ss_selector, &ss_descriptor, 0); - - BX_CPU_THIS_PTR assert_IF (); - - RIP = temp_RIP; } + + RIP = temp_RIP; } void BX_CPU_C::SWAPGS(bxInstruction_c *i) diff --git a/bochs/cpu/smm.cc b/bochs/cpu/smm.cc index 649a61822..215247821 100755 --- a/bochs/cpu/smm.cc +++ b/bochs/cpu/smm.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: smm.cc,v 1.17 2006-05-21 20:41:48 sshwarts Exp $ +// $Id: smm.cc,v 1.18 2006-06-11 21:37:22 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2006 Stanislav Shwartsman @@ -153,10 +153,9 @@ void BX_CPU_C::enter_system_management_mode(void) BX_CPU_THIS_PTR msr.lma = 0; #endif - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = BX_CPU_THIS_PTR smbase >> 4; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = 0; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = 0; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 0; + parse_selector(BX_CPU_THIS_PTR smbase >> 4, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector); + BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 0; @@ -182,10 +181,9 @@ void BX_CPU_C::enter_system_management_mode(void) #endif /* DS (Data Segment) and descriptor cache */ - BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = 0x0000; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = 0; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti = 0; - BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl = 0; + parse_selector(0x0000, + &BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector); + BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl = 0;