Started first implementation of MONITOR/MWAIT

This commit is contained in:
Stanislav Shwartsman 2007-10-11 21:29:01 +00:00
parent f6ed95785f
commit 8adbbcf17c
11 changed files with 225 additions and 187 deletions

View File

@ -733,6 +733,7 @@ typedef
#define BX_SUPPORT_SEP 0
#define BX_SUPPORT_VME 0
#define BX_SUPPORT_POPCNT 0
#define BX_SUPPORT_MONITOR_MWAIT 0
#define BX_SUPPORT_MTRR 0
#define BX_SUPPORT_LARGE_PAGES 0

92
bochs/configure vendored
View File

@ -1,5 +1,5 @@
#! /bin/sh
# From configure.in Id: configure.in,v 1.345 2007/09/28 20:26:33 sshwarts Exp .
# From configure.in Id: configure.in,v 1.346 2007/10/08 19:46:37 sshwarts Exp .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.60.
#
@ -1583,6 +1583,7 @@ Optional Features:
--enable-misaligned-sse misaligned SSE support
--enable-sep SYSENTER/SYSEXIT support
--enable-popcnt support for POPCNT instruction
--enable-monitor-mwait support for MONITOR/MWAIT instructions
--enable-x86-debugger x86 debugger support
--enable-cdrom CDROM support
--enable-sb16=xxx Sound Blaster 16 Support (xxx=dummy|win|linux|freebsd|osx)
@ -4502,7 +4503,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 4505 "configure"' > conftest.$ac_ext
echo '#line 4506 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@ -6868,11 +6869,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6871: $lt_compile\"" >&5)
(eval echo "\"\$as_me:6872: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:6875: \$? = $ac_status" >&5
echo "$as_me:6876: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -7101,11 +7102,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7104: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7105: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7108: \$? = $ac_status" >&5
echo "$as_me:7109: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -7168,11 +7169,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7171: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7172: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7175: \$? = $ac_status" >&5
echo "$as_me:7176: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -9441,7 +9442,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 9444 "configure"
#line 9445 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -9539,7 +9540,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 9542 "configure"
#line 9543 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -11746,11 +11747,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:11749: $lt_compile\"" >&5)
(eval echo "\"\$as_me:11750: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:11753: \$? = $ac_status" >&5
echo "$as_me:11754: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -11813,11 +11814,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:11816: $lt_compile\"" >&5)
(eval echo "\"\$as_me:11817: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:11820: \$? = $ac_status" >&5
echo "$as_me:11821: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -13235,7 +13236,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 13238 "configure"
#line 13239 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -13333,7 +13334,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 13336 "configure"
#line 13337 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -14156,11 +14157,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:14159: $lt_compile\"" >&5)
(eval echo "\"\$as_me:14160: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:14163: \$? = $ac_status" >&5
echo "$as_me:14164: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -14223,11 +14224,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:14226: $lt_compile\"" >&5)
(eval echo "\"\$as_me:14227: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:14230: \$? = $ac_status" >&5
echo "$as_me:14231: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -16266,11 +16267,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:16269: $lt_compile\"" >&5)
(eval echo "\"\$as_me:16270: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:16273: \$? = $ac_status" >&5
echo "$as_me:16274: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -16499,11 +16500,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:16502: $lt_compile\"" >&5)
(eval echo "\"\$as_me:16503: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:16506: \$? = $ac_status" >&5
echo "$as_me:16507: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
@ -16566,11 +16567,11 @@ else
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:16569: $lt_compile\"" >&5)
(eval echo "\"\$as_me:16570: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:16573: \$? = $ac_status" >&5
echo "$as_me:16574: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -18839,7 +18840,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 18842 "configure"
#line 18843 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -18937,7 +18938,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 18940 "configure"
#line 18941 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -21318,7 +21319,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 21321 "configure"
#line 21322 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -39364,6 +39365,39 @@ _ACEOF
fi
{ echo "$as_me:$LINENO: checking for MONITOR/MWAIT instructions support" >&5
echo $ECHO_N "checking for MONITOR/MWAIT instructions support... $ECHO_C" >&6; }
# Check whether --enable-monitor_mwait was given.
if test "${enable_monitor_mwait+set}" = set; then
enableval=$enable_monitor_mwait; if test "$enableval" = yes; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<\_ACEOF
#define BX_SUPPORT_MONITOR_MWAIT 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_MONITOR_MWAIT 0
_ACEOF
fi
else
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
cat >>confdefs.h <<\_ACEOF
#define BX_SUPPORT_MONITOR_MWAIT 0
_ACEOF
fi

View File

@ -2,7 +2,7 @@ dnl // Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_INIT(bochs.h)
AC_REVISION([[$Id: configure.in,v 1.346 2007-10-08 19:46:37 sshwarts Exp $]])
AC_REVISION([[$Id: configure.in,v 1.347 2007-10-11 21:28:57 sshwarts Exp $]])
AC_CONFIG_HEADER(config.h)
AC_CONFIG_HEADER(ltdlconf.h)
@ -1724,6 +1724,23 @@ AC_ARG_ENABLE(popcnt,
]
)
AC_MSG_CHECKING(for MONITOR/MWAIT instructions support)
AC_ARG_ENABLE(monitor_mwait,
[ --enable-monitor-mwait support for MONITOR/MWAIT instructions],
[if test "$enableval" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(BX_SUPPORT_MONITOR_MWAIT, 1)
elif test "$enableval" = no; then
AC_MSG_RESULT(no)
AC_DEFINE(BX_SUPPORT_MONITOR_MWAIT, 0)
fi
],
[
AC_MSG_RESULT(no)
AC_DEFINE(BX_SUPPORT_MONITOR_MWAIT, 0)
]
)
AC_MSG_CHECKING(for x86 debugger support)
AC_ARG_ENABLE(x86-debugger,
[ --enable-x86-debugger x86 debugger support],

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.332 2007-10-11 18:11:58 sshwarts Exp $
// $Id: cpu.h,v 1.333 2007-10-11 21:28:58 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -588,17 +588,6 @@ typedef struct
} bx_regs_msr_t;
#endif
#if BX_SUPPORT_X86_64
typedef struct bx_efer_t {
// x86-64 EFER bits
bx_bool sce; // system call extensions
bx_bool lme; // long mode enable
bx_bool lma; // long mode active
bx_bool nxe; // no-execute enable
bx_bool ffxsr; // fast FXSAVE/FXRSTOR
} bx_efer_t;
#endif
#include "crregs.h"
#include "descriptor.h"
@ -2588,6 +2577,9 @@ public: // for now...
BX_SMF void SYSENTER(bxInstruction_c *);
BX_SMF void SYSEXIT(bxInstruction_c *);
BX_SMF void MONITOR(bxInstruction_c *);
BX_SMF void MWAIT(bxInstruction_c *);
BX_SMF unsigned fetchDecode32(Bit8u *, bxInstruction_c *, unsigned);
#if BX_SUPPORT_X86_64
BX_SMF unsigned fetchDecode64(Bit8u *, bxInstruction_c *, unsigned);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpuid.cc,v 1.50 2007-10-01 21:08:26 sshwarts Exp $
// $Id: cpuid.cc,v 1.51 2007-10-11 21:28:58 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -41,6 +41,7 @@
#define RDX EDX
#endif
#define CACHE_LINE_SIZE 64
/* Get CPU version information. */
Bit32u BX_CPU_C::get_cpu_version_information()
@ -148,6 +149,9 @@ Bit32u BX_CPU_C::get_extended_cpuid_features()
#if BX_SUPPORT_SSE >= 3
features |= 0x1; // support SSE3
#endif
#if BX_SUPPORT_MONITOR_MWAIT
features |= (1<<3); // support MONITOR/MWAIT
#endif
#if (BX_SUPPORT_SSE >= 4) || (BX_SUPPORT_SSE >= 3 && BX_SUPPORT_SSE_EXTENSION > 0)
features |= (1<<9); // support SSE3E
#endif
@ -260,8 +264,10 @@ void BX_CPU_C::CPUID(bxInstruction_c *i)
// EAX: highest input value understood by CPUID
#if BX_CPU_LEVEL <= 5
RAX = 1; // 486 and Pentium processors
#elif BX_SUPPORT_MONITOR_MWAIT
RAX = 5; // support MONITOR/MWAIT leaf
#else
RAX = 2; // for Pentium Pro, Pentium II, Pentium 4 processors
RAX = 2; // for Pentium Pro, Pentium II, Pentium 4 processors
#endif
// EBX: vendor ID string
// EDX: vendor ID string
@ -346,7 +352,7 @@ void BX_CPU_C::CPUID(bxInstruction_c *i)
RBX |= (BX_CPU_THIS_PTR local_apic.get_id() << 24);
#endif
#if BX_SUPPORT_CLFLUSH
RBX |= 8 << 8; // 64 byte cache line size
RBX |= (CACHE_LINE_SIZE / 8) << 8;
#endif
#if BX_SUPPORT_SMP
n_logical_processors = SIM->get_param_num(BXPN_CPU_NCORES)->get()*SIM->get_param_num(BXPN_CPU_NTHREADS)->get();
@ -365,6 +371,30 @@ void BX_CPU_C::CPUID(bxInstruction_c *i)
RDX = 0;
break;
#if BX_SUPPORT_MONITOR_MWAIT
case 3:
case 4:
RAX = 0;
RBX = 0;
RCX = 0;
RDX = 0;
break;
case 5:
// EAX - Smallest monitor-line size in bytes
// EBX - Largest monitor-line size in bytes
// ECX -
// [32:2] - reserved
// [1:1] - exit MWAIT even with EFLAGS.IF = 0
// [0:0] - MONITOR/MWAIT extensions are supported
// EDX - Reserved
RAX = CACHE_LINE_SIZE;
RBX = CACHE_LINE_SIZE;
RCX = 3;
RDX = 0;
break;
#endif
#if BX_SUPPORT_SSE >= 2
#if BX_SUPPORT_X86_64

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: crregs.h,v 1.2 2007-09-10 16:04:41 sshwarts Exp $
// $Id: crregs.h,v 1.3 2007-10-11 21:28:58 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2007 MandrakeSoft S.A.
@ -106,6 +106,17 @@ struct bx_cr4_t {
#define CR4_VME_ENABLED (0)
#endif
#if BX_SUPPORT_X86_64
typedef struct bx_efer_t {
// x86-64 EFER bits
bx_bool sce; // system call extensions
bx_bool lme; // long mode enable
bx_bool lma; // long mode active
bx_bool nxe; // no-execute enable
bx_bool ffxsr; // fast FXSAVE/FXRSTOR
} bx_efer_t;
#endif
#undef IMPLEMENT_CRREG_ACCESSORS
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode.cc,v 1.109 2007-09-19 19:38:09 sshwarts Exp $
// $Id: fetchdecode.cc,v 1.110 2007-10-11 21:28:58 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -282,7 +282,6 @@ static const BxOpcodeInfo_t BxOpcodeInfoG5d[8] = {
};
static const BxOpcodeInfo_t BxOpcodeInfoG6[8] = {
// attributes defined in main area
/* 0 */ { 0, &BX_CPU_C::SLDT_Ew },
/* 1 */ { 0, &BX_CPU_C::STR_Ew },
/* 2 */ { 0, &BX_CPU_C::LLDT_Ew },
@ -293,10 +292,20 @@ static const BxOpcodeInfo_t BxOpcodeInfoG6[8] = {
/* 7 */ { 0, &BX_CPU_C::BxError }
};
static const BxOpcodeInfo_t opcodesGroupRmMONITOR[8] = {
/* 0 */ { 0, &BX_CPU_C::MONITOR },
/* 1 */ { 0, &BX_CPU_C::MWAIT },
/* 2 */ { 0, &BX_CPU_C::BxError },
/* 3 */ { 0, &BX_CPU_C::BxError },
/* 4 */ { 0, &BX_CPU_C::BxError },
/* 5 */ { 0, &BX_CPU_C::BxError },
/* 6 */ { 0, &BX_CPU_C::BxError },
/* 7 */ { 0, &BX_CPU_C::BxError }
};
static const BxOpcodeInfo_t BxOpcodeInfoG7R[8] = {
// attributes defined in main area
/* 0 */ { 0, &BX_CPU_C::BxError },
/* 1 */ { 0, &BX_CPU_C::BxError },
/* 1 */ { BxRMGroup, NULL, opcodesGroupRmMONITOR },
/* 2 */ { 0, &BX_CPU_C::BxError },
/* 3 */ { 0, &BX_CPU_C::BxError },
/* 4 */ { 0, &BX_CPU_C::SMSW_Ew },

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: fetchdecode64.cc,v 1.114 2007-09-19 19:38:10 sshwarts Exp $
// $Id: fetchdecode64.cc,v 1.115 2007-10-11 21:29:01 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -354,7 +354,6 @@ static const BxOpcodeInfo_t BxOpcodeInfo64G4[8] = {
};
static const BxOpcodeInfo_t BxOpcodeInfo64G5w[8] = {
// attributes defined in main area
/* 0 */ { BxLockable, &BX_CPU_C::INC_Ew },
/* 1 */ { BxLockable, &BX_CPU_C::DEC_Ew },
/* 2 */ { 0, &BX_CPU_C::CALL_Eq },
@ -366,7 +365,6 @@ static const BxOpcodeInfo_t BxOpcodeInfo64G5w[8] = {
};
static const BxOpcodeInfo_t BxOpcodeInfo64G5d[8] = {
// attributes defined in main area
/* 0 */ { BxLockable, &BX_CPU_C::INC_Ed },
/* 1 */ { BxLockable, &BX_CPU_C::DEC_Ed },
/* 2 */ { 0, &BX_CPU_C::CALL_Eq },
@ -378,7 +376,6 @@ static const BxOpcodeInfo_t BxOpcodeInfo64G5d[8] = {
};
static const BxOpcodeInfo_t BxOpcodeInfo64G5q[8] = {
// attributes defined in main area
/* 0 */ { BxLockable, &BX_CPU_C::INC_Eq },
/* 1 */ { BxLockable, &BX_CPU_C::DEC_Eq },
/* 2 */ { 0, &BX_CPU_C::CALL_Eq },
@ -390,7 +387,6 @@ static const BxOpcodeInfo_t BxOpcodeInfo64G5q[8] = {
};
static const BxOpcodeInfo_t BxOpcodeInfo64G6[8] = {
// attributes defined in main area
/* 0 */ { 0, &BX_CPU_C::SLDT_Ew },
/* 1 */ { 0, &BX_CPU_C::STR_Ew },
/* 2 */ { 0, &BX_CPU_C::LLDT_Ew },
@ -410,7 +406,6 @@ static const BxOpcodeInfo_t BxOpcodeInfo64G6[8] = {
// MOD == 11 7 2-7 | #UD | #UD
static const BxOpcodeInfo_t opcodesGroup64RmINVLPG[8] = {
// attributes defined in main area
/* 0 */ { 0, &BX_CPU_C::SWAPGS },
/* 1 */ { 0, &BX_CPU_C::RDTSCP },
/* 2 */ { 0, &BX_CPU_C::BxError },
@ -421,10 +416,20 @@ static const BxOpcodeInfo_t opcodesGroup64RmINVLPG[8] = {
/* 7 */ { 0, &BX_CPU_C::BxError }
};
static const BxOpcodeInfo_t opcodesGroup64RmMONITOR[8] = {
/* 0 */ { 0, &BX_CPU_C::MONITOR },
/* 1 */ { 0, &BX_CPU_C::MWAIT },
/* 2 */ { 0, &BX_CPU_C::BxError },
/* 3 */ { 0, &BX_CPU_C::BxError },
/* 4 */ { 0, &BX_CPU_C::BxError },
/* 5 */ { 0, &BX_CPU_C::BxError },
/* 6 */ { 0, &BX_CPU_C::BxError },
/* 7 */ { 0, &BX_CPU_C::BxError }
};
static const BxOpcodeInfo_t BxOpcodeInfo64G7R[8] = {
// attributes defined in main area
/* 0 */ { 0, &BX_CPU_C::BxError },
/* 1 */ { 0, &BX_CPU_C::BxError },
/* 1 */ { BxRMGroup, NULL, opcodesGroup64RmMONITOR },
/* 2 */ { 0, &BX_CPU_C::BxError },
/* 3 */ { 0, &BX_CPU_C::BxError },
/* 4 */ { 0, &BX_CPU_C::SMSW_Ew },
@ -434,7 +439,6 @@ static const BxOpcodeInfo_t BxOpcodeInfo64G7R[8] = {
};
static const BxOpcodeInfo_t BxOpcodeInfo64G7M[8] = {
// attributes defined in main area
/* 0 */ { 0, &BX_CPU_C::SGDT64_Ms },
/* 1 */ { 0, &BX_CPU_C::SIDT64_Ms },
/* 2 */ { 0, &BX_CPU_C::LGDT64_Ms },

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: proc_ctrl.cc,v 1.173 2007-10-11 18:12:00 sshwarts Exp $
// $Id: proc_ctrl.cc,v 1.174 2007-10-11 21:29:01 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1894,15 +1894,73 @@ void BX_CPU_C::WRMSR(bxInstruction_c *i)
#endif
}
void BX_CPU_C::MONITOR(bxInstruction_c *i)
{
#if BX_SUPPORT_MONITOR_MWAIT
// TODO: #UD when CPL > 0 and
// MSR 0xC0010015[MONITOR_MWAIT_USER_UNABLE] = 1
BX_INFO(("MONITOR instruction executed"));
if (RCX != 0) {
BX_ERROR(("MONITOR: no optional extensions supported"));
exception(BX_GP_EXCEPTION, 0, 0);
}
bx_address addr;
#if BX_SUPPORT_X86_64
if (i->as64L()) {
addr = RAX;
}
else
#endif
if (i->as32L()) {
addr = EAX;
}
else {
addr = AX;
}
read_virtual_checks(&BX_CPU_THIS_PTR sregs[i->seg()], addr, 1);
// TODO: Implemented actual MONITOR functionality
#else
BX_INFO(("MONITOR: use --enable-monitor-mwait to enable MONITOR/MWAIT support"));
UndefinedOpcode (i);
#endif
}
void BX_CPU_C::MWAIT(bxInstruction_c *i)
{
#if BX_SUPPORT_MONITOR_MWAIT
// TODO: #UD when CPL > 0 and
// MSR 0xC0010015[MONITOR_MWAIT_USER_UNABLE] = 1
BX_INFO(("MWAIT instruction executed"));
// only one extension is supported
// ECX[0] - interrupt MWAIT even if EFLAGS.IF = 0
if (RCX & ~((Bit64u)(1))) {
BX_ERROR(("MWAIT: incorrect optional extensions in RCX"));
exception(BX_GP_EXCEPTION, 0, 0);
}
// TODO: Implemented actual MWAIT functionality
#else
BX_INFO(("MWAIT: use --enable-monitor-mwait to enable MONITOR/MWAIT support"));
UndefinedOpcode (i);
#endif
}
void BX_CPU_C::SYSENTER(bxInstruction_c *i)
{
#if BX_SUPPORT_SEP
if (!protected_mode()) {
BX_ERROR(("sysenter not from protected mode !"));
BX_ERROR(("SYSENTER 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_ERROR(("sysenter with zero sysenter_cs_msr !"));
BX_ERROR(("SYSENTER with zero sysenter_cs_msr !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
@ -1958,15 +2016,15 @@ void BX_CPU_C::SYSEXIT(bxInstruction_c *i)
{
#if BX_SUPPORT_SEP
if (!protected_mode()) {
BX_ERROR(("sysexit not from 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_ERROR(("sysexit with zero sysenter_cs_msr !"));
BX_ERROR(("SYSEXIT with zero sysenter_cs_msr !"));
exception(BX_GP_EXCEPTION, 0, 0);
}
if (CPL != 0) {
BX_ERROR(("sysexit at non-zero cpl %u !", CPL));
BX_ERROR(("SYSEXIT at non-zero cpl %u !", CPL));
exception(BX_GP_EXCEPTION, 0, 0);
}
@ -2017,73 +2075,6 @@ void BX_CPU_C::SYSEXIT(bxInstruction_c *i)
#if BX_SUPPORT_X86_64
void BX_CPU_C::SYSCALL(bxInstruction_c *i)
{
/* pseudo code from AMD manual.
SYSCALL_START:
IF (MSR_EFER.SCE = 0) // Check if syscall/sysret are enabled.
EXCEPTION [#UD]
IF (LONG_MODE)
SYSCALL_LONG_MODE
ELSE // (LEGACY_MODE)
SYSCALL_LEGACY_MODE
SYSCALL_LONG_MODE:
RCX.q = next_RIP
R11.q = RFLAGS // with rf cleared
IF (64BIT_MODE)
temp_RIP.q = MSR_LSTAR
ELSE // (COMPATIBILITY_MODE)
temp_RIP.q = MSR_CSTAR
CS.sel = MSR_STAR.SYSCALL_CS AND 0xFFFC
CS.attr = 64-bit code,dpl0 // Always switch to 64-bit mode in long mode.
CS.base = 0x00000000
CS.limit = 0xFFFFFFFF
SS.sel = MSR_STAR.SYSCALL_CS + 8
SS.attr = 64-bit stack,dpl0
SS.base = 0x00000000
SS.limit = 0xFFFFFFFF
RFLAGS = RFLAGS AND ~MSR_SFMASK
RFLAGS.RF = 0
CPL = 0
RIP = temp_RIP
EXIT
SYSCALL_LEGACY_MODE:
RCX.d = next_RIP
temp_RIP.d = MSR_STAR.EIP
CS.sel = MSR_STAR.SYSCALL_CS AND 0xFFFC
CS.attr = 32-bit code,dpl0 // Always switch to 32-bit mode in legacy mode.
CS.base = 0x00000000
CS.limit = 0xFFFFFFFF
SS.sel = MSR_STAR.SYSCALL_CS + 8
SS.attr = 32-bit stack,dpl0
SS.base = 0x00000000
SS.limit = 0xFFFFFFFF
RFLAGS.VM,IF,RF=0
CPL = 0
RIP = temp_RIP
EXIT
*/
bx_address temp_RIP;
BX_DEBUG(("Execute SYSCALL instruction"));
@ -2201,60 +2192,6 @@ SYSCALL_LEGACY_MODE:
void BX_CPU_C::SYSRET(bxInstruction_c *i)
{
/* from AMD manual
SYSRET_START:
IF (MSR_EFER.SCE = 0) // Check if syscall/sysret are enabled.
EXCEPTION [#UD]
IF ((!PROTECTED_MODE) || (CPL != 0))
EXCEPTION [#GP(0)] // SYSRET requires protected mode, cpl0
IF (64BIT_MODE)
SYSRET_64BIT_MODE
ELSE // (!64BIT_MODE)
SYSRET_NON_64BIT_MODE
SYSRET_64BIT_MODE:
IF (OPERAND_SIZE = 64) // Return to 64-bit mode.
{
CS.sel = (MSR_STAR.SYSRET_CS + 16) OR 3
CS.base = 0x00000000
CS.limit = 0xFFFFFFFF
CS.attr = 64-bit code,dpl3
temp_RIP.q = RCX
}
ELSE // Return to 32-bit compatibility mode.
{
CS.sel = MSR_STAR.SYSRET_CS OR 3
CS.base = 0x00000000
CS.limit = 0xFFFFFFFF
CS.attr = 32-bit code,dpl3
temp_RIP.d = RCX
}
SS.sel = MSR_STAR.SYSRET_CS + 8 // SS selector is changed,
// SS base, limit, attributes unchanged.
RFLAGS.q = R11 // RF=0,VM=0
CPL = 3
RIP = temp_RIP
EXIT
SYSRET_NON_64BIT_MODE:
CS.sel = MSR_STAR.SYSRET_CS OR 3 // Return to 32-bit legacy protected mode.
CS.base = 0x00000000
CS.limit = 0xFFFFFFFF
CS.attr = 32-bit code,dpl3
temp_RIP.d = RCX
SS.sel = MSR_STAR.SYSRET_CS + 8 // SS selector is changed.
// SS base, limit, attributes unchanged.
RFLAGS.IF = 1
CPL = 3
RIP = temp_RIP
EXIT
*/
bx_address temp_RIP;
BX_DEBUG(("Execute SYSRET instruction"));

View File

@ -42,3 +42,5 @@ TODO (know issues in CPU model):
[!] More flexible CPUID - vendor and etc
[!] SSE4A, SSE5, VMX, SVM
[!] MONITOR/MWAIT functionality

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: main.cc,v 1.357 2007-09-28 19:51:42 sshwarts Exp $
// $Id: main.cc,v 1.358 2007-10-11 21:28:57 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -991,6 +991,7 @@ int bx_init_hardware()
BX_INFO((" PSE support: %s",BX_SUPPORT_LARGE_PAGES?"yes":"no"));
BX_INFO((" x86-64 support: %s",BX_SUPPORT_X86_64?"yes":"no"));
BX_INFO((" SEP support: %s",BX_SUPPORT_SEP?"yes":"no"));
BX_INFO((" MWAIT support: %s",BX_SUPPORT_MONITOR_MWAIT?"yes":"no"));
BX_INFO(("Optimization configuration"));
BX_INFO((" Guest2HostTLB support: %s",BX_SupportGuest2HostTLB?"yes":"no"));
BX_INFO((" RepeatSpeedups support: %s",BX_SupportRepeatSpeedups?"yes":"no"));