- update patch so it apply cleanly

This commit is contained in:
Christophe Bothamy 2003-01-20 19:56:03 +00:00
parent 44502c00dc
commit 298903fbed

View File

@ -1,102 +1,224 @@
----------------------------------------------------------------------
Patch name: patch.sysenterexit-mrieker
Author: Mike Rieker
Date: 27 June 2002
Author: Mike Rieker, updated by cbothamy
Date: Mon Jan 20 14:42:21 CET 2003
Detailed description:
This patch adds sysenter/sysexit functions support
for cpu >= Pentium-Pro
For now, support must be explicitely enabled in config.h
#define BX_SUPPORT_SYSENTEREXIT 1
for cpu >= Pentium-Pro.
SEP is not implemented for x86-64 yet.
Support must be explicitely enabled with ./configure --enable-sep
Patch was created with:
cvs diff -u
Apply patch to what version:
cvs checked out on 27 June 2002
cvs checked out on Mon Jan 20 14:42:21 CET 2003
Instructions:
To patch, go to main bochs directory.
Type "patch -p0 < THIS_PATCH_FILE".
----------------------------------------------------------------------
Index: configure
===================================================================
RCS file: /cvsroot/bochs/bochs/configure,v
retrieving revision 1.197
diff -u -r1.197 configure
--- configure 10 Jan 2003 22:31:41 -0000 1.197
+++ configure 20 Jan 2003 14:36:47 -0000
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Id: configure.in,v 1.196 2003/01/04 19:22:47 bdenney Exp .
+# From configure.in Id: configure.in,v 1.197 2003/01/10 22:32:38 cbothamy Exp .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.53.
#
@@ -1041,6 +1041,7 @@
--enable-mmx compile in MMX emulation
--enable-fpu compile in FPU emulation
--enable-sse SSE/SSE2 support (--enable-sse=no|1|2)
+ --enable-sep SYSENTER/SYSEXIT support
--enable-x86-debugger x86 debugger support
--enable-cdrom CDROM support
--enable-sb16=xxx Sound Blaster 16 Support (xxx=dummy|win|linux|freebsd)
@@ -4207,7 +4208,7 @@
case $host in
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 4210 "configure"' > conftest.$ac_ext
+ echo '#line 4211 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -4757,7 +4758,7 @@
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
compiler_c_o=no
-if { (eval echo configure:4760: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+if { (eval echo configure:4761: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
if test -s out/conftest.err; then
@@ -6588,7 +6589,7 @@
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 6591 "configure"
+#line 6592 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -6686,7 +6687,7 @@
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 6689 "configure"
+#line 6690 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -8728,7 +8729,7 @@
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 8731 "configure"
+#line 8732 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -20607,6 +20608,39 @@
_ACEOF
fi
+
+echo "$as_me:$LINENO: checking for SEP support" >&5
+echo $ECHO_N "checking for SEP support... $ECHO_C" >&6
+# Check whether --enable-sep or --disable-sep was given.
+if test "${enable_sep+set}" = set; then
+ enableval="$enable_sep"
+ if test "$enableval" = yes; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ cat >>confdefs.h <<\_ACEOF
+#define BX_SUPPORT_SEP 1
+_ACEOF
+
+ elif test "$enableval" = no; then
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ cat >>confdefs.h <<\_ACEOF
+#define BX_SUPPORT_SEP 0
+_ACEOF
+
+ fi
+
+else
+
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ cat >>confdefs.h <<\_ACEOF
+#define BX_SUPPORT_SEP 0
+_ACEOF
+
+
+
+fi;
echo "$as_me:$LINENO: checking for x86 debugger support" >&5
echo $ECHO_N "checking for x86 debugger support... $ECHO_C" >&6
Index: configure.in
===================================================================
RCS file: /cvsroot/bochs/bochs/configure.in,v
retrieving revision 1.197
diff -u -r1.197 configure.in
--- configure.in 10 Jan 2003 22:32:38 -0000 1.197
+++ configure.in 20 Jan 2003 14:36:48 -0000
@@ -1371,6 +1371,23 @@
AC_DEFINE(BX_SUPPORT_SSE, 0)
fi
+AC_MSG_CHECKING(for SEP support)
+AC_ARG_ENABLE(sep,
+ [ --enable-sep SYSENTER/SYSEXIT support],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_SUPPORT_SEP, 1)
+ elif test "$enableval" = no; then
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_SUPPORT_SEP, 0)
+ fi
+ ],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_SUPPORT_SEP, 0)
+ ]
+ )
+
AC_MSG_CHECKING(for x86 debugger support)
AC_ARG_ENABLE(x86-debugger,
[ --enable-x86-debugger x86 debugger support],
Index: config.h.in
===================================================================
RCS file: /cvsroot/bochs/bochs/config.h.in,v
retrieving revision 1.50
diff -u -r1.50 config.h.in
--- config.h.in 5 Jun 2002 03:59:30 -0000 1.50
+++ config.h.in 27 Jun 2002 21:27:40 -0000
@@ -189,6 +189,13 @@
retrieving revision 1.102
diff -u -r1.102 config.h.in
--- config.h.in 10 Jan 2003 22:32:42 -0000 1.102
+++ config.h.in 20 Jan 2003 14:36:48 -0000
@@ -683,6 +683,7 @@
#define BX_SUPPORT_FPU 0
#define BX_SUPPORT_MMX 0
#define BX_SUPPORT_SSE 0
+#define BX_SUPPORT_SEP 0
#define BX_SUPPORT_4MEG_PAGES 0
#define BX_SupportGuest2HostTLB 0
#define BX_SupportRepeatSpeedups 0
@@ -735,6 +736,10 @@
#endif
#endif
#define BX_SUPPORT_V8086_MODE 1
+// SYSENTER / SYSEXIT support
+#define BX_SUPPORT_SYSENTEREXIT 0
+
+#if (BX_CPU_LEVEL<6 && BX_SUPPORT_SYSENTEREXIT)
+#if (BX_CPU_LEVEL<6 && BX_SUPPORT_SEP)
+#error SYSENTER/SYSEXIT only supported with CPU_LEVEL >= 6
+#endif
+
// Support shadowing of ROM from C0000 to FFFFF.
// This allows that region to be written to.
#define BX_SHADOW_RAM 0
#if BX_SUPPORT_X86_64
// Sanity checks to ensure that you cannot accidently use conflicting options.
@@ -752,6 +757,10 @@
#endif
#if !BX_SUPPORT_4MEG_PAGES
#error X86-64 requires Page Size Extension (PSE)
+#endif
+
+#if BX_SUPPORT_SEP
+#error SYSENTER/SYSEXIT not implemented for X86-64
#endif
#endif
Index: cpu/cpu.h
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/cpu.h,v
retrieving revision 1.22
diff -u -r1.22 cpu.h
--- cpu/cpu.h 5 Jun 2002 21:51:30 -0000 1.22
+++ cpu/cpu.h 27 Jun 2002 21:27:47 -0000
@@ -219,6 +219,11 @@
#define BX_MSR_BBL_CR_TRIG 0x011a
#define BX_MSR_BBL_CR_BUSY 0x011b
#define BX_MSR_BBL_CR_CTL3 0x011e
+#if BX_SUPPORT_SYSENTEREXIT
+# define BX_MSR_SYSENTER_CS 0x0174
+# define BX_MSR_SYSENTER_ESP 0x0175
+# define BX_MSR_SYSENTER_EIP 0x0176
retrieving revision 1.125
diff -u -r1.125 cpu.h
--- cpu/cpu.h 22 Dec 2002 20:48:45 -0000 1.125
+++ cpu/cpu.h 20 Jan 2003 14:36:49 -0000
@@ -289,6 +289,11 @@
#define BX_MSR_BBL_CR_TRIG 0x011a
#define BX_MSR_BBL_CR_BUSY 0x011b
#define BX_MSR_BBL_CR_CTL3 0x011e
+#if BX_SUPPORT_SEP
+# define BX_MSR_SYSENTER_CS 0x0174
+# define BX_MSR_SYSENTER_ESP 0x0175
+# define BX_MSR_SYSENTER_EIP 0x0176
+#endif
#define BX_MSR_MCG_CAP 0x0179
#define BX_MSR_MCG_STATUS 0x017a
#define BX_MSR_MCG_CTL 0x017b
@@ -276,7 +281,6 @@
#endif
} bx_flags_reg_t;
-
#if BX_CPU_LEVEL >= 2
typedef struct {
Bit32u val32; // 32bit value of register
@@ -581,6 +585,7 @@
virtual ~bx_generic_apic_c ();
virtual void init ();
virtual void hwreset () { }
+ virtual BX_CPU_C *get_cpu (void);
Bit32u get_base (void) { return base_addr; }
void set_base (Bit32u newbase);
void set_id (Bit8u newid);
@@ -641,7 +646,7 @@
BX_CPU_C *cpu;
virtual void hwreset ();
virtual void init ();
- BX_CPU_C *get_cpu (Bit8u id);
+ virtual BX_CPU_C *get_cpu (void);
void set_id (Bit8u newid); // redefine to set cpu->name
virtual char *get_name();
virtual void write (Bit32u addr, Bit32u *data, unsigned len);
@@ -820,6 +825,7 @@
volatile Boolean async_event;
volatile Boolean INTR;
volatile Boolean kill_bochs_request;
+ volatile Boolean nmi_queued;
/* wether this CPU is the BSP always set for UP */
Boolean bsp;
@@ -871,6 +877,13 @@
bx_guard_found_t guard_found;
#define BX_MSR_MCG_CAP 0x0179
#define BX_MSR_MCG_STATUS 0x017a
#define BX_MSR_MCG_CTL 0x017b
@@ -1504,6 +1509,13 @@
#define TLB_GENERATION_MAX (BX_TLB_SIZE-1)
#endif
+ // SYSENTER/SYSEXIT instruction msr's
+#if BX_SUPPORT_SYSENTEREXIT
+#if BX_SUPPORT_SEP
+ Bit32u sysenter_cs_msr;
+ Bit32u sysenter_esp_msr;
+ Bit32u sysenter_eip_msr;
@ -105,115 +227,110 @@ diff -u -r1.22 cpu.h
// for paging
#if BX_USE_TLB
struct {
@@ -1349,6 +1362,8 @@
BX_SMF void WRMSR(BxInstruction_t *);
BX_SMF void RDTSC(BxInstruction_t *);
BX_SMF void RDMSR(BxInstruction_t *);
+ BX_SMF void SYSENTER(BxInstruction_t *);
+ BX_SMF void SYSEXIT(BxInstruction_t *);
@@ -2498,6 +2510,8 @@
BX_SMF void WRMSR(bxInstruction_c *);
BX_SMF void RDTSC(bxInstruction_c *);
BX_SMF void RDMSR(bxInstruction_c *);
+ BX_SMF void SYSENTER(bxInstruction_c *);
+ BX_SMF void SYSEXIT(bxInstruction_c *);
BX_SMF void SetCR0(Bit32u val_32);
BX_SMF void dynamic_translate(void);
BX_SMF void dynamic_init(void);
#if BX_CPU_LEVEL >= 4
BX_SMF void SetCR4(Bit32u val_32);
Index: cpu/fetchdecode.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/fetchdecode.cc,v
retrieving revision 1.7
diff -u -r1.7 fetchdecode.cc
--- cpu/fetchdecode.cc 3 Oct 2001 13:10:37 -0000 1.7
+++ cpu/fetchdecode.cc 27 Jun 2002 21:27:48 -0000
@@ -1174,8 +1174,13 @@
/* 0F 31 */ { 0, &BX_CPU_C::RDTSC },
/* 0F 32 */ { 0, &BX_CPU_C::RDMSR },
/* 0F 33 */ { 0, &BX_CPU_C::BxError },
retrieving revision 1.41
diff -u -r1.41 fetchdecode.cc
--- cpu/fetchdecode.cc 22 Dec 2002 21:48:22 -0000 1.41
+++ cpu/fetchdecode.cc 20 Jan 2003 14:36:50 -0000
@@ -1620,8 +1620,13 @@
/* 0F 31 */ { 0, &BX_CPU_C::RDTSC },
/* 0F 32 */ { 0, &BX_CPU_C::RDMSR },
/* 0F 33 */ { 0, &BX_CPU_C::BxError },
- /* 0F 34 */ { 0, &BX_CPU_C::BxError },
- /* 0F 35 */ { 0, &BX_CPU_C::BxError },
+#if BX_SUPPORT_SYSENTEREXIT
+ /* 0F 34 */ { 0, &BX_CPU_C::SYSENTER },
+ /* 0F 35 */ { 0, &BX_CPU_C::SYSEXIT },
+#else
/* 0F 34 */ { 0, &BX_CPU_C::BxError },
/* 0F 35 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 34 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 35 */ { 0, &BX_CPU_C::BxError },
+#endif
/* 0F 36 */ { 0, &BX_CPU_C::BxError },
/* 0F 37 */ { 0, &BX_CPU_C::BxError },
/* 0F 38 */ { 0, &BX_CPU_C::BxError },
/* 0F 36 */ { 0, &BX_CPU_C::BxError },
/* 0F 37 */ { 0, &BX_CPU_C::BxError },
/* 0F 38 */ { 0, &BX_CPU_C::BxError },
Index: cpu/proc_ctrl.cc
===================================================================
RCS file: /cvsroot/bochs/bochs/cpu/proc_ctrl.cc,v
retrieving revision 1.22
diff -u -r1.22 proc_ctrl.cc
--- cpu/proc_ctrl.cc 19 Jun 2002 15:49:07 -0000 1.22
+++ cpu/proc_ctrl.cc 27 Jun 2002 21:27:48 -0000
@@ -968,8 +968,8 @@
// ECX: vendor ID string
EAX = 1; // 486 or pentium
EBX = 0x756e6547; // "Genu"
- EDX = 0x49656e69; // "ineI"
- ECX = 0x6c65746e; // "ntel"
+ EDX = 0x42656e69; // "ineB"
+ ECX = 0x7368636f; // "ochs"
break;
retrieving revision 1.65
diff -u -r1.65 proc_ctrl.cc
--- cpu/proc_ctrl.cc 14 Jan 2003 07:46:05 -0000 1.65
+++ cpu/proc_ctrl.cc 20 Jan 2003 14:36:51 -0000
@@ -1358,7 +1358,8 @@
// [7:7] MCE: Machine Check Exception
// [8:8] CXS: CMPXCHG8B instruction
// [9:9] APIC: APIC on Chip
- // [11:10] Reserved
+ // [10:10] Reserved
+ // [11:11] SYSENTER/SYSEXIT support
// [12:12] MTRR: Memory Type Range Reg
// [13:13] PGE/PTE Global Bit
// [14:14] MCA: Machine Check Architecture
@@ -1413,7 +1414,11 @@
#endif
case 1:
@@ -1030,16 +1030,20 @@
model = 1; // Pentium Pro
stepping = 3; // ???
features |= (1<<4); // implement TSC
+ features |= (1<<3); // implement 4M pages
# if BX_SUPPORT_APIC
features |= (1<<9); // APIC on chip
# endif
# if BX_SUPPORT_FPU
features |= 0x01; // has FPU
# endif
+# if BX_SUPPORT_SYSENTEREXIT
+ features |= (1<<11); // SYSENTER/SYSEXIT
+# endif
#if BX_SUPPORT_X86_64
- features |= (1<<5); //AMD specific MSR's
+ features |= (1<<5); // AMD specific MSR's
+#endif
+
#else
BX_PANIC(("CPUID: not implemented for > 6"));
-#endif
- features |= 8; // support page-size extension (4m pages)
+#endif
+#if BX_SUPPORT_SEP
+ features |= (1<<11); // SYSENTER/SYSEXIT
#endif
EAX = (family <<8) | (model<<4) | stepping;
EBX = ECX = 0; // reserved
@@ -1160,6 +1164,11 @@
return features;
@@ -1732,6 +1737,13 @@
/* We have the requested MSR register in ECX */
switch(ECX) {
+#if BX_SUPPORT_SYSENTEREXIT
+ case BX_MSR_SYSENTER_CS: { EAX = BX_CPU_THIS_PTR sysenter_cs_msr; EDX = 0; return; }
+ case BX_MSR_SYSENTER_ESP: { EAX = BX_CPU_THIS_PTR sysenter_esp_msr; EDX = 0; return; }
+ case BX_MSR_SYSENTER_EIP: { EAX = BX_CPU_THIS_PTR sysenter_eip_msr; EDX = 0; return; }
+#endif
/* We have the requested MSR register in ECX */
switch(ECX) {
+
+#if BX_SUPPORT_SEP
+ case BX_MSR_SYSENTER_CS: { EAX = BX_CPU_THIS_PTR sysenter_cs_msr; EDX = 0; return; }
+ case BX_MSR_SYSENTER_ESP: { EAX = BX_CPU_THIS_PTR sysenter_esp_msr; EDX = 0; return; }
+ case BX_MSR_SYSENTER_EIP: { EAX = BX_CPU_THIS_PTR sysenter_eip_msr; EDX = 0; return; }
+#endif
+
#if BX_CPU_LEVEL == 5
/* The following registers are defined for Pentium only */
case BX_MSR_P5_MC_ADDR:
@@ -1236,6 +1245,15 @@
/* The following registers are defined for Pentium only */
case BX_MSR_P5_MC_ADDR:
@@ -1857,6 +1869,17 @@
/* ECX has the MSR to write to */
switch(ECX) {
+#if BX_SUPPORT_SYSENTEREXIT
+ case BX_MSR_SYSENTER_CS: {
+ if (EAX & 3) BX_PANIC (("writing sysenter_cs_msr with non-kernel mode selector %X", EAX)); // not a bug according to book
+ BX_CPU_THIS_PTR sysenter_cs_msr = EAX; // ... but very stOOpid
+ return;
+ }
+ case BX_MSR_SYSENTER_ESP: { BX_CPU_THIS_PTR sysenter_esp_msr = EAX; return; }
+ case BX_MSR_SYSENTER_EIP: { BX_CPU_THIS_PTR sysenter_eip_msr = EAX; return; }
/* ECX has the MSR to write to */
switch(ECX) {
+
+#if BX_SUPPORT_SEP
+ case BX_MSR_SYSENTER_CS: {
+ if (EAX & 3) BX_PANIC (("writing sysenter_cs_msr with non-kernel mode selector %X", EAX)); // not a bug according to book
+ BX_CPU_THIS_PTR sysenter_cs_msr = EAX; // ... but very stOOpid
+ return;
+ }
+ case BX_MSR_SYSENTER_ESP: { BX_CPU_THIS_PTR sysenter_esp_msr = EAX; return; }
+ case BX_MSR_SYSENTER_EIP: { BX_CPU_THIS_PTR sysenter_eip_msr = EAX; return; }
+#endif
+
#if BX_CPU_LEVEL == 5
/* The following registers are defined for Pentium only */
case BX_MSR_P5_MC_ADDR:
@@ -1283,6 +1301,127 @@
/* The following registers are defined for Pentium only */
case BX_MSR_P5_MC_ADDR:
@@ -1943,6 +1966,127 @@
do_exception:
exception(BX_GP_EXCEPTION, 0, 0);
exception(BX_GP_EXCEPTION, 0, 0);
+}
+
+ void
+BX_CPU_C::SYSENTER (BxInstruction_t *i)
+BX_CPU_C::SYSENTER (bxInstruction_c *i)
+{
+#if BX_SUPPORT_SYSENTEREXIT
+#if BX_SUPPORT_SEP
+ if (!protected_mode ()) {
+ BX_INFO (("sysenter not from protected mode"));
+ exception (BX_GP_EXCEPTION, 0, 0);
@ -227,39 +344,39 @@ diff -u -r1.22 proc_ctrl.cc
+
+ invalidate_prefetch_q ();
+
+ BX_CPU_THIS_PTR eflags.vm = 0; // do this just like the book says to do
+ BX_CPU_THIS_PTR eflags.if_ = 0;
+ BX_CPU_THIS_PTR eflags.rf = 0;
+ BX_CPU_THIS_PTR set_VM(0); // do this just like the book says to do
+ BX_CPU_THIS_PTR set_IF(0);
+ BX_CPU_THIS_PTR set_RF(0);
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = BX_CPU_THIS_PTR sysenter_cs_msr;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = BX_CPU_THIS_PTR sysenter_cs_msr >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = (BX_CPU_THIS_PTR sysenter_cs_msr >> 2) & 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 0;
+ 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
+ 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; // 32-bit mode
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; // available for use by system
+ 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
+ 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; // 32-bit mode
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; // available for use by system
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = BX_CPU_THIS_PTR sysenter_cs_msr + 8;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = (BX_CPU_THIS_PTR sysenter_cs_msr + 8) >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti = (BX_CPU_THIS_PTR sysenter_cs_msr >> 2) & 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = 0;
+ 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
+ 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 mode
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0; // available for use by system
+ 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
+ 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 mode
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0; // available for use by system
+
+ // BX_INFO (("sysenter: old eip %X, esp %x, new eip %x, esp %X, edx %X", BX_CPU_THIS_PTR prev_eip, ESP, BX_CPU_THIS_PTR sysenter_eip_msr, BX_CPU_THIS_PTR sysenter_esp_msr, EDX));
+
@ -271,9 +388,9 @@ diff -u -r1.22 proc_ctrl.cc
+}
+
+ void
+BX_CPU_C::SYSEXIT (BxInstruction_t *i)
+BX_CPU_C::SYSEXIT (bxInstruction_c *i)
+{
+#if BX_SUPPORT_SYSENTEREXIT
+#if BX_SUPPORT_SEP
+ if (!protected_mode ()) {
+ BX_INFO (("sysexit not from protected mode"));
+ exception (BX_GP_EXCEPTION, 0, 0);
@ -296,31 +413,31 @@ diff -u -r1.22 proc_ctrl.cc
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = (BX_CPU_THIS_PTR sysenter_cs_msr + 16) >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = (BX_CPU_THIS_PTR sysenter_cs_msr >> 2) & 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 3;
+ 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
+ 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; // 32-bit mode
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; // available for use by system
+ 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
+ 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; // 32-bit mode
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; // available for use by system
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 24) | 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = (BX_CPU_THIS_PTR sysenter_cs_msr + 24) >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti = (BX_CPU_THIS_PTR sysenter_cs_msr >> 2) & 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = 3;
+ 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
+ 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 mode
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0; // available for use by system
+ 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
+ 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 mode
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0; // available for use by system
+
+ // BX_INFO (("sysexit: old eip %X, esp %x, new eip %x, esp %X, eax %X", BX_CPU_THIS_PTR prev_eip, ESP, EDX, ECX, EAX));
+
@ -331,4 +448,4 @@ diff -u -r1.22 proc_ctrl.cc
+#endif
}
#if BX_X86_DEBUGGER
#if BX_SUPPORT_X86_64