Merged X2APIC + X2APIC virtualization
This commit is contained in:
parent
df7db31fb4
commit
6e1204cb84
@ -4,6 +4,7 @@
|
||||
|
||||
./configure \
|
||||
--enable-smp \
|
||||
--enable-x2apic \
|
||||
--enable-x86-64 \
|
||||
--enable-all-optimizations \
|
||||
--enable-long-phy-address \
|
||||
|
@ -4,6 +4,7 @@ Brief summary :
|
||||
- Major configure/cpu rework allowing to enable/disable CPU options at runtime
|
||||
through .bochsrc (Stanislav)
|
||||
- Bugfixes for CPU emulation correctness and stability
|
||||
- Implemented X2APIC extensions (Stanislav)
|
||||
- Implemented Intel VMXx2 extensions (Stanislav)
|
||||
- Extended VMX capability MSRs, APIC Virtualization,
|
||||
Extended Page Tables (EPT), VPID, new VMX controls support
|
||||
@ -38,6 +39,7 @@ Detailed change log :
|
||||
|
||||
- CPU
|
||||
- Implemented PCLMULQDQ AES instruction
|
||||
- Implemented X2APIC extensions / enable extended topology CPUID leaf (0xb)
|
||||
- Implemented Intel VMXx2 extensions:
|
||||
- Enabled extended VMX capability MSRs
|
||||
- Implemented VMX controls for loading/storing of MSR_PAT and MSR_EFER
|
||||
@ -46,6 +48,7 @@ Detailed change log :
|
||||
- Implemented Extended Page Tables (EPT) mode
|
||||
- Implemented Descriptor Table Access VMEXIT control
|
||||
- Implemented RDTSCP VMEXIT control
|
||||
- Implemented Virtualize X2APIC mode control
|
||||
- Implemented Virtual Process ID (VPID)
|
||||
- Implemented WBINVD VMEXIT control
|
||||
In order to enable emulation of VMXx2 extensions configure with
|
||||
@ -70,6 +73,7 @@ Detailed change log :
|
||||
- Updated Bochs TESTFORM to version 0.5
|
||||
|
||||
- SF patches applied
|
||||
[2864402] outstanding x2apic patches by Stanislav
|
||||
[2960379] Fix build with -Wformat -Werror=format-security by Per Oyvind Karlsen
|
||||
[2938273] allow instrumentation to change execute by Konrad Grochowski
|
||||
[2926072] Indirection operators in expressions by Derek Peschel
|
||||
|
@ -761,6 +761,12 @@ typedef
|
||||
#define BX_SUPPORT_APIC 0
|
||||
#endif
|
||||
|
||||
#define BX_SUPPORT_X2APIC 0
|
||||
|
||||
#if (BX_SUPPORT_X2APIC && !BX_SUPPORT_APIC)
|
||||
#error APIC is required for X2APIC emulation !
|
||||
#endif
|
||||
|
||||
#define BX_HAVE_GETENV 0
|
||||
#define BX_HAVE_SETENV 0
|
||||
#define BX_HAVE_SELECT 0
|
||||
|
86
bochs/configure
vendored
86
bochs/configure
vendored
@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# From configure.in Id: configure.in,v 1.432 2010/04/03 07:30:23 sshwarts Exp .
|
||||
# From configure.in Id: configure.in,v 1.433 2010/04/04 18:37:53 sshwarts Exp .
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.65.
|
||||
#
|
||||
@ -951,6 +951,7 @@ enable_pcidev
|
||||
enable_usb
|
||||
enable_usb_ohci
|
||||
enable_pnic
|
||||
enable_x2apic
|
||||
enable_1g_pages
|
||||
enable_repeat_speedups
|
||||
enable_trace_cache
|
||||
@ -1669,6 +1670,7 @@ Optional Features:
|
||||
--enable-usb enable limited USB UHCI support
|
||||
--enable-usb-ohci enable limited USB OHCI support
|
||||
--enable-pnic enable PCI pseudo NIC support
|
||||
--enable-x2apic support for X2APIC
|
||||
--enable-1g-pages support for 1G pages in long mode
|
||||
--enable-repeat-speedups support repeated IO and mem copy speedups
|
||||
--enable-trace-cache support instruction trace cache
|
||||
@ -5099,7 +5101,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 5102 "configure"' > conftest.$ac_ext
|
||||
echo '#line 5104 "configure"' > conftest.$ac_ext
|
||||
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@ -6788,11 +6790,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:6791: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6793: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:6795: \$? = $ac_status" >&5
|
||||
echo "$as_me:6797: \$? = $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
|
||||
@ -7021,11 +7023,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:7024: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7026: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:7028: \$? = $ac_status" >&5
|
||||
echo "$as_me:7030: \$? = $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
|
||||
@ -7088,11 +7090,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:7091: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7093: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7095: \$? = $ac_status" >&5
|
||||
echo "$as_me:7097: \$? = $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
|
||||
@ -8878,7 +8880,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 8881 "configure"
|
||||
#line 8883 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -8976,7 +8978,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 8979 "configure"
|
||||
#line 8981 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -11091,11 +11093,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:11094: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:11096: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:11098: \$? = $ac_status" >&5
|
||||
echo "$as_me:11100: \$? = $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
|
||||
@ -11158,11 +11160,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:11161: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:11163: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:11165: \$? = $ac_status" >&5
|
||||
echo "$as_me:11167: \$? = $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
|
||||
@ -12183,7 +12185,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 12186 "configure"
|
||||
#line 12188 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -12281,7 +12283,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 12284 "configure"
|
||||
#line 12286 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -13104,11 +13106,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:13107: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:13109: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:13111: \$? = $ac_status" >&5
|
||||
echo "$as_me:13113: \$? = $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
|
||||
@ -13171,11 +13173,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:13174: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:13176: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:13178: \$? = $ac_status" >&5
|
||||
echo "$as_me:13180: \$? = $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
|
||||
@ -15136,11 +15138,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:15139: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15141: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:15143: \$? = $ac_status" >&5
|
||||
echo "$as_me:15145: \$? = $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
|
||||
@ -15369,11 +15371,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:15372: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15374: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:15376: \$? = $ac_status" >&5
|
||||
echo "$as_me:15378: \$? = $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
|
||||
@ -15436,11 +15438,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:15439: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15441: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:15443: \$? = $ac_status" >&5
|
||||
echo "$as_me:15445: \$? = $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
|
||||
@ -17226,7 +17228,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 17229 "configure"
|
||||
#line 17231 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -17324,7 +17326,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 17327 "configure"
|
||||
#line 17329 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -19011,7 +19013,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 19014 "configure"
|
||||
#line 19016 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -22215,6 +22217,32 @@ fi
|
||||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X2APIC support" >&5
|
||||
$as_echo_n "checking for X2APIC support... " >&6; }
|
||||
# Check whether --enable-x2apic was given.
|
||||
if test "${enable_x2apic+set}" = set; then :
|
||||
enableval=$enable_x2apic; if test "$enableval" = yes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
$as_echo "#define BX_SUPPORT_X2APIC 1" >>confdefs.h
|
||||
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
$as_echo "#define BX_SUPPORT_X2APIC 0" >>confdefs.h
|
||||
|
||||
fi
|
||||
else
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
$as_echo "#define BX_SUPPORT_X2APIC 0" >>confdefs.h
|
||||
|
||||
|
||||
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long mode 1G pages support" >&5
|
||||
$as_echo_n "checking for long mode 1G pages support... " >&6; }
|
||||
# Check whether --enable-1g-pages was given.
|
||||
|
@ -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.433 2010-04-04 18:37:53 sshwarts Exp $]])
|
||||
AC_REVISION([[$Id: configure.in,v 1.434 2010-04-08 15:50:39 sshwarts Exp $]])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADER(ltdlconf.h)
|
||||
|
||||
@ -860,6 +860,22 @@ fi
|
||||
|
||||
AC_SUBST(NETLOW_OBJS)
|
||||
|
||||
AC_MSG_CHECKING(for X2APIC support)
|
||||
AC_ARG_ENABLE(x2apic,
|
||||
[ --enable-x2apic support for X2APIC],
|
||||
[if test "$enableval" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(BX_SUPPORT_X2APIC, 1)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(BX_SUPPORT_X2APIC, 0)
|
||||
fi],
|
||||
[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_DEFINE(BX_SUPPORT_X2APIC, 0)
|
||||
]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING(for long mode 1G pages support)
|
||||
AC_ARG_ENABLE(1g-pages,
|
||||
[ --enable-1g-pages support for 1G pages in long mode],
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: apic.cc,v 1.142 2010-04-05 09:36:17 sshwarts Exp $
|
||||
// $Id: apic.cc,v 1.143 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2002-2009 Zwane Mwaikambo, Stanislav Shwartsman
|
||||
@ -241,6 +241,10 @@ void bx_local_apic_c::reset(unsigned type)
|
||||
|
||||
void bx_local_apic_c::set_base(bx_phy_address newbase)
|
||||
{
|
||||
#if BX_SUPPORT_X2APIC
|
||||
if (mode == BX_APIC_X2APIC_MODE)
|
||||
ldr = ((apic_id & 0xfffffff0) << 16) | (1 << (apic_id & 0xf));
|
||||
#endif
|
||||
mode = (newbase >> 10) & 3;
|
||||
newbase &= ~((bx_phy_address) 0xfff);
|
||||
base_addr = newbase;
|
||||
@ -808,6 +812,17 @@ bx_bool bx_local_apic_c::match_logical_addr(apic_dest_t address)
|
||||
{
|
||||
bx_bool match = 0;
|
||||
|
||||
#if BX_SUPPORT_X2APIC
|
||||
if (mode == BX_APIC_X2APIC_MODE) {
|
||||
// only cluster model supported in x2apic mode
|
||||
if (address == 0xffffffff) // // broadcast all
|
||||
return 1;
|
||||
if ((address & 0xffff0000) == (ldr & 0xffff0000))
|
||||
match = ((address & ldr & 0x0000ffff) != 0);
|
||||
return match;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dest_format == 0xf) {
|
||||
// flat model
|
||||
match = ((address & ldr) != 0);
|
||||
@ -962,6 +977,167 @@ void bx_local_apic_c::set_initial_timer_count(Bit32u value)
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X2APIC
|
||||
// return false when x2apic is not supported/not readable
|
||||
bx_bool bx_local_apic_c::read_x2apic(unsigned index, Bit64u *val_64)
|
||||
{
|
||||
index = (index - 0x800) << 4;
|
||||
|
||||
switch(index) {
|
||||
// return full 32-bit lapic id
|
||||
case BX_LAPIC_ID:
|
||||
*val_64 = apic_id;
|
||||
break;
|
||||
case BX_LAPIC_LDR:
|
||||
*val_64 = ldr;
|
||||
break;
|
||||
// full 64-bit access to ICR
|
||||
case BX_LAPIC_ICR_LO:
|
||||
*val_64 = ((Bit64u) icr_lo) | (((Bit64u) icr_hi) << 32);
|
||||
break;
|
||||
// not supported/not readable in x2apic mode
|
||||
case BX_LAPIC_ARBITRATION_PRIORITY:
|
||||
case BX_LAPIC_DESTINATION_FORMAT:
|
||||
case BX_LAPIC_ICR_HI:
|
||||
case BX_LAPIC_EOI: // write only
|
||||
case BX_LAPIC_SELF_IPI: // write only
|
||||
return 0;
|
||||
// compatible to legacy lapic mode
|
||||
case BX_LAPIC_VERSION:
|
||||
case BX_LAPIC_TPR:
|
||||
case BX_LAPIC_PPR:
|
||||
case BX_LAPIC_SPURIOUS_VECTOR:
|
||||
case BX_LAPIC_ISR1:
|
||||
case BX_LAPIC_ISR2:
|
||||
case BX_LAPIC_ISR3:
|
||||
case BX_LAPIC_ISR4:
|
||||
case BX_LAPIC_ISR5:
|
||||
case BX_LAPIC_ISR6:
|
||||
case BX_LAPIC_ISR7:
|
||||
case BX_LAPIC_ISR8:
|
||||
case BX_LAPIC_TMR1:
|
||||
case BX_LAPIC_TMR2:
|
||||
case BX_LAPIC_TMR3:
|
||||
case BX_LAPIC_TMR4:
|
||||
case BX_LAPIC_TMR5:
|
||||
case BX_LAPIC_TMR6:
|
||||
case BX_LAPIC_TMR7:
|
||||
case BX_LAPIC_TMR8:
|
||||
case BX_LAPIC_IRR1:
|
||||
case BX_LAPIC_IRR2:
|
||||
case BX_LAPIC_IRR3:
|
||||
case BX_LAPIC_IRR4:
|
||||
case BX_LAPIC_IRR5:
|
||||
case BX_LAPIC_IRR6:
|
||||
case BX_LAPIC_IRR7:
|
||||
case BX_LAPIC_IRR8:
|
||||
case BX_LAPIC_ESR:
|
||||
case BX_LAPIC_LVT_TIMER:
|
||||
case BX_LAPIC_LVT_THERMAL:
|
||||
case BX_LAPIC_LVT_PERFMON:
|
||||
case BX_LAPIC_LVT_LINT0:
|
||||
case BX_LAPIC_LVT_LINT1:
|
||||
case BX_LAPIC_LVT_ERROR:
|
||||
case BX_LAPIC_TIMER_INITIAL_COUNT:
|
||||
case BX_LAPIC_TIMER_CURRENT_COUNT:
|
||||
case BX_LAPIC_TIMER_DIVIDE_CFG:
|
||||
*val_64 = read_aligned(index);
|
||||
break;
|
||||
default:
|
||||
BX_DEBUG(("read_x2apic: not supported apic register 0x%08x", index));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// return false when x2apic is not supported/not writeable
|
||||
bx_bool bx_local_apic_c::write_x2apic(unsigned index, Bit64u val_64)
|
||||
{
|
||||
Bit32u val32_lo = GET32L(val_64);
|
||||
|
||||
index = (index - 0x800) << 4;
|
||||
|
||||
switch(index) {
|
||||
// read only/not available in x2apic mode
|
||||
case BX_LAPIC_ID:
|
||||
case BX_LAPIC_VERSION:
|
||||
case BX_LAPIC_ARBITRATION_PRIORITY:
|
||||
case BX_LAPIC_PPR:
|
||||
case BX_LAPIC_LDR:
|
||||
case BX_LAPIC_DESTINATION_FORMAT:
|
||||
case BX_LAPIC_ISR1:
|
||||
case BX_LAPIC_ISR2:
|
||||
case BX_LAPIC_ISR3:
|
||||
case BX_LAPIC_ISR4:
|
||||
case BX_LAPIC_ISR5:
|
||||
case BX_LAPIC_ISR6:
|
||||
case BX_LAPIC_ISR7:
|
||||
case BX_LAPIC_ISR8:
|
||||
case BX_LAPIC_TMR1:
|
||||
case BX_LAPIC_TMR2:
|
||||
case BX_LAPIC_TMR3:
|
||||
case BX_LAPIC_TMR4:
|
||||
case BX_LAPIC_TMR5:
|
||||
case BX_LAPIC_TMR6:
|
||||
case BX_LAPIC_TMR7:
|
||||
case BX_LAPIC_TMR8:
|
||||
case BX_LAPIC_IRR1:
|
||||
case BX_LAPIC_IRR2:
|
||||
case BX_LAPIC_IRR3:
|
||||
case BX_LAPIC_IRR4:
|
||||
case BX_LAPIC_IRR5:
|
||||
case BX_LAPIC_IRR6:
|
||||
case BX_LAPIC_IRR7:
|
||||
case BX_LAPIC_IRR8:
|
||||
case BX_LAPIC_ICR_HI:
|
||||
case BX_LAPIC_TIMER_CURRENT_COUNT:
|
||||
return 0;
|
||||
// send self ipi
|
||||
case BX_LAPIC_SELF_IPI:
|
||||
trigger_irq(val32_lo & 0xff, APIC_EDGE_TRIGGERED);
|
||||
break;
|
||||
// handle full 64-bit write
|
||||
case BX_LAPIC_ICR_LO:
|
||||
send_ipi(GET32H(val_64), val32_lo);
|
||||
break;
|
||||
case BX_LAPIC_TPR:
|
||||
// handle reserved bits, only bits 0-7 are writeable
|
||||
if ((val32_lo & 0xffffff00) != 0)
|
||||
return 0;
|
||||
break; // use legacy write
|
||||
case BX_LAPIC_SPURIOUS_VECTOR:
|
||||
// handle reserved bits, only bits 0-8, 12 are writeable
|
||||
// we do not support directed EOI capability, so reserve bit 12 as well
|
||||
if ((val32_lo & 0xfffffe00) != 0)
|
||||
return 0;
|
||||
break; // use legacy write
|
||||
case BX_LAPIC_EOI:
|
||||
case BX_LAPIC_ESR:
|
||||
if (val_64 != 0) return 0;
|
||||
break; // use legacy write
|
||||
case BX_LAPIC_LVT_TIMER:
|
||||
case BX_LAPIC_LVT_THERMAL:
|
||||
case BX_LAPIC_LVT_PERFMON:
|
||||
case BX_LAPIC_LVT_LINT0:
|
||||
case BX_LAPIC_LVT_LINT1:
|
||||
case BX_LAPIC_LVT_ERROR:
|
||||
case BX_LAPIC_TIMER_INITIAL_COUNT:
|
||||
case BX_LAPIC_TIMER_DIVIDE_CFG:
|
||||
break; // use legacy write
|
||||
default:
|
||||
BX_DEBUG(("write_x2apic: not supported apic register 0x%08x", index));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (GET32H(val_64) != 0) // upper 32-bit are reserved for all x2apic MSRs
|
||||
return 0;
|
||||
|
||||
write_aligned(index, val32_lo);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void bx_local_apic_c::register_state(bx_param_c *parent)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: apic.h,v 1.54 2010-03-27 09:56:30 sshwarts Exp $
|
||||
// $Id: apic.h,v 1.55 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2002-2009 Zwane Mwaikambo, Stanislav Shwartsman
|
||||
@ -71,6 +71,7 @@ class BOCHSAPI bx_local_apic_c : public logfunctions
|
||||
#define APIC_ERR_ILLEGAL_ADDR 0x80
|
||||
#define APIC_ERR_RX_ILLEGAL_VEC 0x40
|
||||
#define APIC_ERR_TX_ILLEGAL_VEC 0x20
|
||||
#define X2APIC_ERR_REDIRECTIBLE_IPI 0x08
|
||||
#define APIC_ERR_RX_ACCEPT_ERR 0x08
|
||||
#define APIC_ERR_TX_ACCEPT_ERR 0x04
|
||||
#define APIC_ERR_RX_CHECKSUM 0x02
|
||||
@ -128,7 +129,10 @@ public:
|
||||
void write(bx_phy_address addr, void *data, unsigned len);
|
||||
void write_aligned(bx_phy_address addr, Bit32u data);
|
||||
Bit32u read_aligned(bx_phy_address address);
|
||||
void startup_msg(Bit8u vector);
|
||||
#if BX_SUPPORT_X2APIC
|
||||
bx_bool read_x2apic(unsigned index, Bit64u *msr);
|
||||
bx_bool write_x2apic(unsigned index, Bit64u msr);
|
||||
#endif
|
||||
// on local APIC, trigger means raise the CPU's INTR line. For now
|
||||
// I also have to raise pc_system.INTR but that should be replaced
|
||||
// with the cpu-specific INTR signals.
|
||||
@ -152,6 +156,7 @@ public:
|
||||
void periodic(void);
|
||||
void set_divide_configuration(Bit32u value);
|
||||
void set_initial_timer_count(Bit32u value);
|
||||
void startup_msg(Bit8u vector);
|
||||
void register_state(bx_param_c *parent);
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.666 2010-04-07 17:12:17 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.667 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2010 The Bochs Project
|
||||
@ -610,7 +610,7 @@ typedef struct
|
||||
#define BX_CPU_P6 0x00000008 /* P6 new instruction */
|
||||
#define BX_CPU_MMX 0x00000010 /* MMX instruction */
|
||||
#define BX_CPU_3DNOW 0x00000020 /* 3DNow! instruction */
|
||||
#define BX_CPU_FXSAVE_FXRSTOR 0x00000040 /* SYSENTER/SYSEXIT instruction */
|
||||
#define BX_CPU_FXSAVE_FXRSTOR 0x00000040 /* FXSAVE/FXRSTOR instruction */
|
||||
#define BX_CPU_SYSENTER_SYSEXIT 0x00000080 /* SYSENTER/SYSEXIT instruction */
|
||||
#define BX_CPU_CLFLUSH 0x00000100 /* CLFLUSH instruction */
|
||||
#define BX_CPU_SSE 0x00000200 /* SSE instruction */
|
||||
@ -3122,7 +3122,6 @@ public: // for now...
|
||||
#endif
|
||||
BX_SMF void TLB_flush(void);
|
||||
BX_SMF void TLB_invlpg(bx_address laddr);
|
||||
BX_SMF void TLB_init(void);
|
||||
BX_SMF void set_INTR(bx_bool value);
|
||||
BX_SMF const char *strseg(bx_segment_reg_t *seg);
|
||||
BX_SMF void interrupt(Bit8u vector, unsigned type, bx_bool push_error,
|
||||
@ -3265,6 +3264,10 @@ public: // for now...
|
||||
|
||||
BX_SMF void init_isa_features_bitmask(void);
|
||||
BX_SMF void init_FetchDecodeTables(void);
|
||||
#if BX_SUPPORT_X2APIC
|
||||
BX_SMF void bx_cpuid_extended_topology_leaf(Bit32u subfunction);
|
||||
#endif
|
||||
BX_SMF void bx_cpuid_xsave_leaf(Bit32u subfunction);
|
||||
|
||||
BX_SMF BX_CPP_INLINE unsigned which_cpu(void) { return BX_CPU_THIS_PTR bx_cpuid; }
|
||||
BX_SMF BX_CPP_INLINE const bx_gen_reg_t *get_gen_regfile() { return BX_CPU_THIS_PTR gen_reg; }
|
||||
@ -3407,7 +3410,7 @@ public: // for now...
|
||||
BX_SMF Bit16u VMX_Get_Current_VPID(void);
|
||||
#endif
|
||||
BX_SMF Bit32u VMX_Read_VTPR(void);
|
||||
BX_SMF void VMX_Write_TPR_Shadow(Bit8u tpr_shadow);
|
||||
BX_SMF void VMX_Write_VTPR(Bit8u vtpr);
|
||||
BX_SMF Bit64s VMX_TSC_Offset(void);
|
||||
// vmexit reasons
|
||||
BX_SMF void VMexit_Instruction(bxInstruction_c *i, Bit32u reason) BX_CPP_AttrRegparmN(2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpuid.cc,v 1.111 2010-04-03 05:59:07 sshwarts Exp $
|
||||
// $Id: cpuid.cc,v 1.112 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2007-2010 Stanislav Shwartsman
|
||||
@ -164,47 +164,51 @@ Bit32u BX_CPU_C::get_extended_cpuid_features(void)
|
||||
Bit32u features = 0;
|
||||
|
||||
// support SSE3
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_SSE3)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_SSE3))
|
||||
features |= (1<<0);
|
||||
|
||||
// support for PCLMULQDQ
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_AES_PCLMULQDQ)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_AES_PCLMULQDQ))
|
||||
features |= (1<<1);
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_MONITOR_MWAIT)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_MONITOR_MWAIT))
|
||||
features |= (1<<3);
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_VMX)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_VMX))
|
||||
features |= (1<<5);
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_SSSE3)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_SSSE3))
|
||||
features |= (1<<9);
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
// support CMPXCHG16B
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_X86_64)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_X86_64))
|
||||
features |= (1<<13);
|
||||
#endif
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_SSE4_1)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_SSE4_1))
|
||||
features |= (1<<19);
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_SSE4_2)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_SSE4_2))
|
||||
features |= (1<<20);
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_MOVBE)
|
||||
#if BX_SUPPORT_X2APIC
|
||||
features |= (1<<21); // support X2APIC
|
||||
#endif
|
||||
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_MOVBE))
|
||||
features |= (1<<22);
|
||||
|
||||
// enable POPCNT if SSE4_2 is enabled
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_SSE4_2)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_SSE4_2))
|
||||
features |= (1<<23);
|
||||
|
||||
// support for AES
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_AES_PCLMULQDQ)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_AES_PCLMULQDQ))
|
||||
features |= (1<<25);
|
||||
|
||||
// support XSAVE extensions
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_XSAVE)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE))
|
||||
features |= (1<<26) | (1<<27);
|
||||
|
||||
return features;
|
||||
@ -248,11 +252,11 @@ Bit32u BX_CPU_C::get_std_cpuid_features(void)
|
||||
|
||||
Bit32u features = 0;
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_X87)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_X87))
|
||||
features |= (1<<0);
|
||||
|
||||
#if BX_CPU_LEVEL >= 5
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_PENTIUM) {
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_PENTIUM)) {
|
||||
// Pentium only features
|
||||
features |= (1<<1); // support VME
|
||||
features |= (1<<3); // support PSE
|
||||
@ -272,19 +276,19 @@ Bit32u BX_CPU_C::get_std_cpuid_features(void)
|
||||
features |= (1<<9); // APIC on chip
|
||||
#endif
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_SYSENTER_SYSEXIT)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_SYSENTER_SYSEXIT))
|
||||
features |= (1<<11);
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_CLFLUSH)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_CLFLUSH))
|
||||
features |= (1<<19);
|
||||
|
||||
#if BX_CPU_LEVEL >= 5
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_MMX)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_MMX))
|
||||
features |= (1<<23);
|
||||
#endif
|
||||
|
||||
#if BX_CPU_LEVEL >= 6
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_P6) {
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_P6)) {
|
||||
features |= (1<<6); // support PAE
|
||||
features |= (1<<12); // support MTRRs
|
||||
features |= (1<<13); // support Global pages
|
||||
@ -293,13 +297,13 @@ Bit32u BX_CPU_C::get_std_cpuid_features(void)
|
||||
features |= (1<<17); // support PSE-36
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_FXSAVE_FXRSTOR)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_FXSAVE_FXRSTOR))
|
||||
features |= (1<<24); // support FSAVE/FXRSTOR instructions
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_SSE)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_SSE))
|
||||
features |= (1<<25);
|
||||
|
||||
if (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_SSE2)
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_SSE2))
|
||||
features |= (1<<26);
|
||||
#endif
|
||||
|
||||
@ -330,16 +334,20 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::CPUID(bxInstruction_c *i)
|
||||
|
||||
if(function < 0x80000000) {
|
||||
if(function <= max_std_function) {
|
||||
#if BX_SUPPORT_X2APIC
|
||||
if (function == 0xb) {
|
||||
bx_cpuid_extended_topology_leaf(subfunction);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (function == 0xd) {
|
||||
bx_cpuid_xsave_leaf(subfunction);
|
||||
return;
|
||||
}
|
||||
RAX = BX_CPU_THIS_PTR cpuid_std_function[function].eax;
|
||||
RBX = BX_CPU_THIS_PTR cpuid_std_function[function].ebx;
|
||||
RCX = BX_CPU_THIS_PTR cpuid_std_function[function].ecx;
|
||||
RDX = BX_CPU_THIS_PTR cpuid_std_function[function].edx;
|
||||
if (function == 0xD && subfunction > 0) {
|
||||
RAX = 0;
|
||||
RBX = 0;
|
||||
RCX = 0;
|
||||
RDX = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -406,8 +414,11 @@ void BX_CPU_C::set_cpuid_defaults(void)
|
||||
if (! cpuid_limit_winnt) {
|
||||
if (BX_SUPPORT_MONITOR_MWAIT)
|
||||
cpuid->eax = 0x5;
|
||||
#if BX_SUPPORT_X2APIC
|
||||
cpuid->eax = 0xb;
|
||||
#endif
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE))
|
||||
cpuid->eax = 0xD;
|
||||
cpuid->eax = 0xd;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -582,10 +593,10 @@ void BX_CPU_C::set_cpuid_defaults(void)
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------
|
||||
// CPUID function 0x0000000D
|
||||
// CPUID function 0x0000000d
|
||||
if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE))
|
||||
{
|
||||
cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[0xD]);
|
||||
cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[0xd]);
|
||||
|
||||
// EAX - XCR0 lower 32 bits
|
||||
// EBX - Maximum size (in bytes) required by enabled features
|
||||
@ -792,6 +803,123 @@ void BX_CPU_C::set_cpuid_defaults(void)
|
||||
#endif // BX_CPU_LEVEL >= 6
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X2APIC
|
||||
|
||||
#include <math.h>
|
||||
|
||||
void BX_CPU_C::bx_cpuid_extended_topology_leaf(Bit32u subfunction)
|
||||
{
|
||||
static int nthreads = SIM->get_param_num(BXPN_CPU_NTHREADS)->get();
|
||||
static int ncores = SIM->get_param_num(BXPN_CPU_NCORES)->get();
|
||||
static int nprocessors = SIM->get_param_num(BXPN_CPU_NPROCESSORS)->get();
|
||||
|
||||
switch(subfunction) {
|
||||
case 0:
|
||||
if (nthreads > 1) {
|
||||
RAX = (bx_address) ceil(log(nthreads)/log(2));
|
||||
RBX = nthreads;
|
||||
RCX = subfunction | (1<<8);
|
||||
}
|
||||
else if (ncores > 1) {
|
||||
RAX = (bx_address) ceil(log(ncores)/log(2));
|
||||
RBX = ncores;
|
||||
RCX = subfunction | (2<<8);
|
||||
}
|
||||
else if (nprocessors > 1) {
|
||||
RAX = (bx_address) ceil(log(nprocessors)/log(2));
|
||||
RBX = nprocessors;
|
||||
RCX = subfunction;
|
||||
}
|
||||
else {
|
||||
RAX = 0;
|
||||
RBX = 0;
|
||||
RCX = subfunction;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (nthreads > 1) {
|
||||
if (ncores > 1) {
|
||||
RAX = (bx_address) ceil(log(ncores)/log(2));
|
||||
RBX = ncores;
|
||||
RCX = subfunction | (2<<8);
|
||||
}
|
||||
else if (nprocessors > 1) {
|
||||
RAX = (bx_address) ceil(log(nprocessors)/log(2));
|
||||
RBX = nprocessors;
|
||||
RCX = subfunction;
|
||||
}
|
||||
else {
|
||||
RAX = 0;
|
||||
RBX = 0;
|
||||
RCX = subfunction;
|
||||
}
|
||||
}
|
||||
else if (ncores > 1) {
|
||||
if (nprocessors > 1) {
|
||||
RAX = (bx_address) ceil(log(nprocessors)/log(2));
|
||||
RBX = nprocessors;
|
||||
RCX = subfunction;
|
||||
}
|
||||
else {
|
||||
RAX = 0;
|
||||
RBX = 0;
|
||||
RCX = subfunction;
|
||||
}
|
||||
} else {
|
||||
RAX = 0;
|
||||
RBX = 0;
|
||||
RCX = subfunction;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (nthreads > 1) {
|
||||
if (nprocessors > 1) {
|
||||
RAX = (bx_address) ceil(log(nprocessors)/log(2));
|
||||
RBX = nprocessors;
|
||||
}
|
||||
else {
|
||||
RAX = 0;
|
||||
RBX = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
RAX = 0;
|
||||
RBX = 0;
|
||||
}
|
||||
RCX = subfunction;
|
||||
break;
|
||||
|
||||
default:
|
||||
RAX = 0;
|
||||
RBX = 0;
|
||||
RCX = subfunction;
|
||||
break;
|
||||
}
|
||||
|
||||
RDX = BX_CPU_THIS_PTR lapic.get_id(); // x2apic ID
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::bx_cpuid_xsave_leaf(Bit32u subfunction)
|
||||
{
|
||||
BX_ASSERT(BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE));
|
||||
if (subfunction == 0) {
|
||||
RAX = BX_CPU_THIS_PTR cpuid_std_function[0xd].eax;
|
||||
RBX = BX_CPU_THIS_PTR cpuid_std_function[0xd].ebx;
|
||||
RCX = BX_CPU_THIS_PTR cpuid_std_function[0xd].ecx;
|
||||
RDX = BX_CPU_THIS_PTR cpuid_std_function[0xd].edx;
|
||||
}
|
||||
else {
|
||||
RAX = 0; // reserved
|
||||
RBX = 0; // reserved
|
||||
RCX = 0; // reserved
|
||||
RDX = 0; // reserved
|
||||
}
|
||||
}
|
||||
|
||||
void BX_CPU_C::init_isa_features_bitmask(void)
|
||||
{
|
||||
Bit32u features_bitmask = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: crregs.cc,v 1.10 2010-04-06 19:26:02 sshwarts Exp $
|
||||
// $Id: crregs.cc,v 1.11 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2010 Stanislav Shwartsman
|
||||
@ -575,11 +575,11 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_CqRq(bxInstruction_c *i)
|
||||
}
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && VMEXIT(VMX_VM_EXEC_CTRL2_TPR_SHADOW)) {
|
||||
VMX_Write_TPR_Shadow(val_64 & 0xF);
|
||||
VMX_Write_VTPR((val_64 & 0xF) << 4);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
BX_CPU_THIS_PTR lapic.set_tpr((val_64 & 0xF) << 0x4);
|
||||
BX_CPU_THIS_PTR lapic.set_tpr((val_64 & 0xF) << 4);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: init.cc,v 1.238 2010-04-06 19:26:03 sshwarts Exp $
|
||||
// $Id: init.cc,v 1.239 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2009 The Bochs Project
|
||||
@ -993,7 +993,8 @@ void BX_CPU_C::reset(unsigned source)
|
||||
|
||||
BX_CPU_THIS_PTR EXT = 0;
|
||||
|
||||
TLB_init();
|
||||
TLB_flush();
|
||||
BX_CPU_THIS_PTR PDPTR_CACHE.valid = 0;
|
||||
|
||||
// invalidate the prefetch queue
|
||||
BX_CPU_THIS_PTR eipPageBias = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: msr.cc,v 1.47 2010-04-07 17:12:17 sshwarts Exp $
|
||||
// $Id: msr.cc,v 1.48 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2008-2010 Stanislav Shwartsman
|
||||
@ -40,6 +40,15 @@ bx_bool BX_CPP_AttrRegparmN(2) BX_CPU_C::rdmsr(Bit32u index, Bit64u *msr)
|
||||
if ((index & 0x3FFFFFFF) >= BX_MSR_MAX_INDEX)
|
||||
return 0;
|
||||
|
||||
#if BX_SUPPORT_X2APIC
|
||||
if (index >= 0x800 && index <= 0xBFF) {
|
||||
if (BX_CPU_THIS_PTR msr.apicbase & 0x400) // X2APIC mode
|
||||
return BX_CPU_THIS_PTR lapic.read_x2apic(index, msr);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(index) {
|
||||
|
||||
#if BX_CPU_LEVEL >= 6
|
||||
@ -273,6 +282,16 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDMSR(bxInstruction_c *i)
|
||||
VMexit_MSR(i, VMX_VMEXIT_RDMSR, index);
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && index == 0x808) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE)) {
|
||||
RAX = VMX_Read_VTPR() & 0xff;
|
||||
RDX = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!rdmsr(index, &val64))
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
|
||||
@ -341,6 +360,15 @@ bx_bool BX_CPP_AttrRegparmN(2) BX_CPU_C::wrmsr(Bit32u index, Bit64u val_64)
|
||||
if ((index & 0x3FFFFFFF) >= BX_MSR_MAX_INDEX)
|
||||
return 0;
|
||||
|
||||
#if BX_SUPPORT_X2APIC
|
||||
if (index >= 0x800 && index <= 0xBFF) {
|
||||
if (BX_CPU_THIS_PTR msr.apicbase & 0x400) // X2APIC mode
|
||||
return BX_CPU_THIS_PTR lapic.write_x2apic(index, val_64);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(index) {
|
||||
|
||||
#if BX_CPU_LEVEL >= 6
|
||||
@ -636,7 +664,7 @@ bx_bool BX_CPU_C::relocate_apic(Bit64u val_64)
|
||||
* [M:63] Reserved
|
||||
*/
|
||||
|
||||
#define BX_MSR_APICBASE_RESERVED_BITS 0x6ff
|
||||
#define BX_MSR_APICBASE_RESERVED_BITS (0x2ff | (BX_SUPPORT_X2APIC ? 0 : 0x400))
|
||||
|
||||
if (BX_CPU_THIS_PTR msr.apicbase & 0x800) {
|
||||
Bit32u val32_hi = GET32H(val_64), val32_lo = GET32L(val_64);
|
||||
@ -651,6 +679,20 @@ bx_bool BX_CPU_C::relocate_apic(Bit64u val_64)
|
||||
BX_ERROR(("relocate_apic: attempt to set reserved bits"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X2APIC
|
||||
unsigned apic_state = (BX_CPU_THIS_PTR msr.apicbase >> 10) & 3;
|
||||
unsigned new_state = (val32_lo >> 10) & 3;
|
||||
if (new_state == BX_APIC_STATE_INVALID) {
|
||||
BX_ERROR(("relocate_apic: attempt to set invalid apic state"));
|
||||
return 0;
|
||||
}
|
||||
if (apic_state == BX_APIC_X2APIC_MODE && new_state != BX_APIC_GLOBALLY_DISABLED) {
|
||||
BX_ERROR(("relocate_apic: attempt to switch from x2apic -> xapic"));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
BX_CPU_THIS_PTR msr.apicbase = (bx_phy_address) val_64;
|
||||
BX_CPU_THIS_PTR lapic.set_base(BX_CPU_THIS_PTR msr.apicbase);
|
||||
// TLB flush is required for emulation correctness
|
||||
@ -685,6 +727,15 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::WRMSR(bxInstruction_c *i)
|
||||
VMexit_MSR(i, VMX_VMEXIT_WRMSR, index);
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && index == 0x808) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE)) {
|
||||
VMX_Write_VTPR(AL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! wrmsr(index, val_64))
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: paging.cc,v 1.216 2010-04-07 17:12:17 sshwarts Exp $
|
||||
// $Id: paging.cc,v 1.217 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2010 The Bochs Project
|
||||
@ -253,7 +253,14 @@
|
||||
// | +------------> u/s of current access
|
||||
// +---------------> Current CR0.WP value
|
||||
|
||||
static Bit8u priv_check[BX_PRIV_CHECK_SIZE];
|
||||
/* 0xff0bbb0b */
|
||||
static const Bit8u priv_check[BX_PRIV_CHECK_SIZE] =
|
||||
{
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1
|
||||
#endif
|
||||
};
|
||||
|
||||
#define BX_PAGING_PHY_ADDRESS_RESERVED_BITS \
|
||||
(BX_PHY_ADDRESS_RESERVED_BITS & BX_CONST64(0xfffffffffffff))
|
||||
@ -360,47 +367,6 @@ static unsigned tlbNonGlobalFlushes=0;
|
||||
|
||||
// ==============================================================
|
||||
|
||||
// Called to initialize the TLB upon startup.
|
||||
// Unconditional initialization of all TLB entries.
|
||||
void BX_CPU_C::TLB_init(void)
|
||||
{
|
||||
unsigned n, wp, us_combined, rw_combined, us_current, rw_current;
|
||||
|
||||
//
|
||||
// Setup privilege check matrix.
|
||||
//
|
||||
for (n=0; n<BX_PRIV_CHECK_SIZE; n++) {
|
||||
wp = (n & 0x10) >> 4;
|
||||
us_current = (n & 0x08) >> 3;
|
||||
us_combined = (n & 0x04) >> 2;
|
||||
rw_combined = (n & 0x02) >> 1;
|
||||
rw_current = (n & 0x01) >> 0;
|
||||
if (wp) { // when write protect on
|
||||
if (us_current > us_combined) // user access, supervisor page
|
||||
priv_check[n] = 0;
|
||||
else if (rw_current > rw_combined) // RW access, RO page
|
||||
priv_check[n] = 0;
|
||||
else
|
||||
priv_check[n] = 1;
|
||||
}
|
||||
else { // when write protect off
|
||||
if (us_current == 0) // Supervisor mode access, anything goes
|
||||
priv_check[n] = 1;
|
||||
else {
|
||||
// user mode access
|
||||
if (us_combined == 0) // user access, supervisor Page
|
||||
priv_check[n] = 0;
|
||||
else if (rw_current > rw_combined) // RW access, RO page
|
||||
priv_check[n] = 0;
|
||||
else
|
||||
priv_check[n] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TLB_flush();
|
||||
}
|
||||
|
||||
void BX_CPU_C::TLB_flush(void)
|
||||
{
|
||||
#if InstrumentTLB
|
||||
@ -857,6 +823,7 @@ bx_phy_address BX_CPU_C::translate_linear_PAE(bx_address laddr, Bit32u &lpf_mask
|
||||
#endif
|
||||
|
||||
if (! BX_CPU_THIS_PTR PDPTR_CACHE.valid) {
|
||||
BX_ERROR(("PDPTR_CACHE not valid !"));
|
||||
if (! CheckPDPTR(BX_CPU_THIS_PTR cr3)) {
|
||||
BX_ERROR(("translate_linear_PAE(): PDPTR check failed !"));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
@ -1350,12 +1317,13 @@ bx_bool BX_CPU_C::dbg_translate_guest_physical(bx_phy_address guest_paddr, bx_ph
|
||||
{
|
||||
VMCS_CACHE *vm = &BX_CPU_THIS_PTR vmcs;
|
||||
bx_phy_address pt_address = LPFOf(vm->eptptr);
|
||||
bx_phy_address offset_mask = 0xfff;
|
||||
Bit64u offset_mask = BX_CONST64(0x0000ffffffffffff);
|
||||
|
||||
for (int level = 3; level >= 0; --level) {
|
||||
Bit64u pte;
|
||||
pt_address += ((guest_paddr >> (9 + 9*level)) & 0xff8);
|
||||
BX_MEM(0)->readPhysicalPage(BX_CPU_THIS, pt_address, 8, &pte);
|
||||
offset_mask >>= 9;
|
||||
|
||||
switch(pte & 7) {
|
||||
case BX_EPT_ENTRY_NOT_PRESENT:
|
||||
@ -1370,14 +1338,12 @@ bx_bool BX_CPU_C::dbg_translate_guest_physical(bx_phy_address guest_paddr, bx_ph
|
||||
|
||||
if (pte & 0x80) {
|
||||
if (level == BX_LEVEL_PDE) { // 2M page
|
||||
offset_mask = 0x1fffff;
|
||||
pt_address &= BX_CONST64(0x000fffffffffe000);
|
||||
if (pt_address & offset_mask) return 0;
|
||||
break;
|
||||
}
|
||||
#if BX_SUPPORT_1G_PAGES
|
||||
if (level == BX_LEVEL_PDPE) { // 1G page
|
||||
offset_mask = 0x3fffffff;
|
||||
pt_address &= BX_CONST64(0x000fffffffffe000);
|
||||
if (pt_address & offset_mask) return 0;
|
||||
break;
|
||||
@ -1401,7 +1367,6 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy)
|
||||
|
||||
bx_phy_address paddress;
|
||||
bx_phy_address pt_address = BX_CPU_THIS_PTR cr3 & BX_CR3_PAGING_MASK;
|
||||
bx_address offset_mask = 0xfff;
|
||||
|
||||
// see if page is in the TLB first
|
||||
bx_address lpf = LPFOf(laddr);
|
||||
@ -1416,10 +1381,15 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy)
|
||||
|
||||
#if BX_CPU_LEVEL >= 6
|
||||
if (BX_CPU_THIS_PTR cr4.get_PAE()) {
|
||||
if (! long_mode()) pt_address &= BX_CR3_LEGACY_PAE_PAGING_MASK;
|
||||
Bit64u offset_mask = BX_CONST64(0x0000ffffffffffff);
|
||||
if (! long_mode()) {
|
||||
pt_address &= BX_CR3_LEGACY_PAE_PAGING_MASK;
|
||||
offset_mask >>= 9;
|
||||
}
|
||||
for (int level = 2 + long_mode(); level >= 0; --level) {
|
||||
Bit64u pte;
|
||||
pt_address += ((laddr >> (9 + 9*level)) & 0xff8);
|
||||
offset_mask >>= 9;
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest) {
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_ENABLE)) {
|
||||
@ -1434,9 +1404,9 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy)
|
||||
if (pte & BX_PAGING_PHY_ADDRESS_RESERVED_BITS)
|
||||
goto page_fault;
|
||||
pt_address = bx_phy_address(pte & BX_CONST64(0x000ffffffffff000));
|
||||
if (level == BX_LEVEL_PTE) break;
|
||||
if (pte & 0x80) {
|
||||
if (level == BX_LEVEL_PDE) { // 2M page
|
||||
offset_mask = 0x1fffff;
|
||||
pt_address &= BX_CONST64(0x000fffffffffe000);
|
||||
if (pt_address & offset_mask)
|
||||
goto page_fault;
|
||||
@ -1444,15 +1414,13 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy)
|
||||
}
|
||||
#if BX_SUPPORT_1G_PAGES
|
||||
if (level == BX_LEVEL_PDPE && long_mode()) { // 1G page
|
||||
offset_mask = 0x3fffffff;
|
||||
pt_address &= BX_CONST64(0x000fffffffffe000);
|
||||
if (pt_address & offset_mask)
|
||||
goto page_fault;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (level != BX_LEVEL_PTE)
|
||||
goto page_fault;
|
||||
goto page_fault;
|
||||
}
|
||||
}
|
||||
paddress = pt_address + (bx_phy_address)(laddr & offset_mask);
|
||||
@ -1460,6 +1428,7 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy)
|
||||
else // not PAE
|
||||
#endif
|
||||
{
|
||||
Bit32u offset_mask = 0xfff;
|
||||
for (int level = 1; level >= 0; --level) {
|
||||
Bit32u pte;
|
||||
pt_address += ((laddr >> (10 + 10*level)) & 0xffc);
|
||||
@ -1473,14 +1442,14 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy)
|
||||
#endif
|
||||
BX_MEM(0)->readPhysicalPage(BX_CPU_THIS, pt_address, 4, &pte);
|
||||
if (!(pte & 1))
|
||||
goto page_fault;
|
||||
goto page_fault;
|
||||
pt_address = pte & 0xfffff000;
|
||||
if (level == BX_LEVEL_PDE && (pte & 0x80)) { // PSE page
|
||||
offset_mask = 0x3fffff;
|
||||
offset_mask = 0x3fffff;
|
||||
#if BX_PHY_ADDRESS_WIDTH > 32
|
||||
pt_address += ((bx_phy_address)(pte & 0x003fe000)) << 19;
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
paddress = pt_address + (bx_phy_address)(laddr & offset_mask);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: vmexit.cc,v 1.24 2010-04-07 17:12:17 sshwarts Exp $
|
||||
// $Id: vmexit.cc,v 1.25 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2009-2010 Stanislav Shwartsman
|
||||
@ -688,15 +688,16 @@ Bit32u BX_CPU_C::VMX_Read_VTPR(void)
|
||||
return vtpr;
|
||||
}
|
||||
|
||||
void BX_CPU_C::VMX_Write_TPR_Shadow(Bit8u tpr_shadow)
|
||||
void BX_CPU_C::VMX_Write_VTPR(Bit8u vtpr)
|
||||
{
|
||||
VMCS_CACHE *vm = &BX_CPU_THIS_PTR vmcs;
|
||||
bx_phy_address pAddr = vm->virtual_apic_page_addr + 0x80;
|
||||
Bit32u field32 = tpr_shadow << 4;
|
||||
Bit32u field32 = vtpr;
|
||||
|
||||
access_write_physical(pAddr, 4, (Bit8u*)(&field32));
|
||||
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, pAddr, 4, BX_WRITE, (Bit8u*)(&field32));
|
||||
|
||||
Bit8u tpr_shadow = vtpr >> 4;
|
||||
if (tpr_shadow < vm->vm_tpr_threshold) {
|
||||
// commit current instruction to produce trap-like VMexit
|
||||
BX_CPU_THIS_PTR prev_rip = RIP; // commit new RIP
|
||||
@ -750,7 +751,7 @@ void BX_CPU_C::VMX_Virtual_Apic_Write(bx_phy_address paddr, unsigned len, void *
|
||||
|
||||
if (VMEXIT(VMX_VM_EXEC_CTRL2_TPR_SHADOW) && offset == 0x80 && len <= 4) {
|
||||
// VTPR access
|
||||
VMX_Write_TPR_Shadow(*((Bit8u *) data));
|
||||
VMX_Write_VTPR(*((Bit8u *) data));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: vmx.cc,v 1.59 2010-04-07 17:12:17 sshwarts Exp $
|
||||
// $Id: vmx.cc,v 1.60 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2009-2010 Stanislav Shwartsman
|
||||
@ -447,9 +447,16 @@ VMX_error_code BX_CPU_C::VMenterLoadCheckVmControls(void)
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE) {
|
||||
// 'use TPR shadow' must be set and "virtualize APIC accesses" must be clear
|
||||
if (!(vm->vmexec_ctrls2 & VMX_VM_EXEC_CTRL2_TPR_SHADOW) ||
|
||||
(vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES)) {
|
||||
BX_ERROR(("VMFAIL: VMCS EXEC CTRL: virtualize X2APIC mode misconfigured"));
|
||||
return VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm->vmexec_ctrls3 & VMX_VM_EXEC_CTRL3_EPT_ENABLE) {
|
||||
vm->eptptr = (bx_phy_address) VMread64(VMCS_64BIT_CONTROL_EPTPTR);
|
||||
if (! is_eptptr_valid(vm->eptptr)) {
|
||||
@ -1626,6 +1633,11 @@ Bit32u BX_CPU_C::LoadMSRs(Bit32u msr_cnt, bx_phy_address pAddr)
|
||||
return msr;
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_X2APIC
|
||||
if ((index & 0xfffff800) == 0x800) // X2APIC range
|
||||
return msr;
|
||||
#endif
|
||||
|
||||
if (! wrmsr(index, msr_hi))
|
||||
return msr;
|
||||
|
||||
@ -1648,6 +1660,11 @@ Bit32u BX_CPU_C::StoreMSRs(Bit32u msr_cnt, bx_phy_address pAddr)
|
||||
|
||||
Bit32u index = GET32L(msr_lo);
|
||||
|
||||
#if BX_SUPPORT_X2APIC
|
||||
if ((index & 0xfffff800) == 0x800) // X2APIC range
|
||||
return msr;
|
||||
#endif
|
||||
|
||||
if (! rdmsr(index, &msr_hi))
|
||||
return msr;
|
||||
|
||||
@ -3183,8 +3200,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::INVEPT(bxInstruction_c *i)
|
||||
if (i->os64L()) {
|
||||
type = BX_READ_64BIT_REG(i->nnn());
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
type = BX_READ_32BIT_REG(i->nnn());
|
||||
}
|
||||
|
||||
@ -3245,8 +3261,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::INVVPID(bxInstruction_c *i)
|
||||
if (i->os64L()) {
|
||||
type = BX_READ_64BIT_REG(i->nnn());
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
type = BX_READ_32BIT_REG(i->nnn());
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: vmx.h,v 1.27 2010-04-07 17:12:17 sshwarts Exp $
|
||||
// $Id: vmx.h,v 1.28 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2009 Stanislav Shwartsman
|
||||
@ -594,6 +594,7 @@ typedef struct bx_VMCS
|
||||
VMX_VM_EXEC_CTRL3_EPT_ENABLE | \
|
||||
VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT | \
|
||||
VMX_VM_EXEC_CTRL3_RDTSCP | \
|
||||
VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE | \
|
||||
VMX_VM_EXEC_CTRL3_VPID_ENABLE | \
|
||||
VMX_VM_EXEC_CTRL3_WBINVD_VMEXIT)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: disasm.h,v 1.61 2010-04-02 19:01:17 sshwarts Exp $
|
||||
// $Id: disasm.h,v 1.62 2010-04-08 15:50:39 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2005-2009 Stanislav Shwartsman
|
||||
@ -45,7 +45,7 @@
|
||||
#define IA_P6 0x00000008 /* P6 new instruction */
|
||||
#define IA_MMX 0x00000010 /* MMX instruction */
|
||||
#define IA_3DNOW 0x00000020 /* 3DNow! instruction */
|
||||
#define IA_FXSAVE_FXRSTOR 0x00000040 /* SYSENTER/SYSEXIT instruction */
|
||||
#define IA_FXSAVE_FXRSTOR 0x00000040 /* FXSAVE/FXRSTOR instruction */
|
||||
#define IA_SYSENTER_SYSEXIT 0x00000080 /* SYSENTER/SYSEXIT instruction */
|
||||
#define IA_CLFLUSH 0x00000100 /* CLFLUSH instruction */
|
||||
#define IA_SSE 0x00000200 /* SSE instruction */
|
||||
|
Loading…
Reference in New Issue
Block a user