diff --git a/bochs/.bochsrc b/bochs/.bochsrc index 6ba1b3e65..7b301938f 100644 --- a/bochs/.bochsrc +++ b/bochs/.bochsrc @@ -179,6 +179,10 @@ cpu: count=1, ips=50000000, reset_on_triple_fault=1, ignore_bad_msrs=1, msrs="ms # Enable Process-Context Identifiers (PCID) support in long mode. # This option exists only if Bochs compiled with x86-64 support. # +# FSGSBASE: +# Enable GS/GS BASE access instructions support in long mode. +# This option exists only if Bochs compiled with x86-64 support. +# # MWAIT_IS_NOP: # When this option is enabled MWAIT will not put the CPU into a sleep state. # This option exists only if Bochs compiled with --enable-monitor-mwait. diff --git a/bochs/PARAM_TREE.txt b/bochs/PARAM_TREE.txt index 30de120e5..656dc0334 100644 --- a/bochs/PARAM_TREE.txt +++ b/bochs/PARAM_TREE.txt @@ -1,4 +1,4 @@ -$Id: PARAM_TREE.txt,v 1.31 2010-07-03 05:34:27 vruppert Exp $ +$Id: PARAM_TREE.txt,v 1.32 2010-07-22 16:41:57 sshwarts Exp $ Starting from Bochs 2.3 the parameters are organized in a tree structure instead of a huge flat list. The parameter tree was required for implementing @@ -27,6 +27,7 @@ cpu cpuid cpuid_limit_winnt + stepping vendor_string brand_string mmx @@ -38,6 +39,7 @@ cpuid xapic 1g_pages pcid + fsgsbase mwait_is_nop memory diff --git a/bochs/bx_debug/dbg_main.cc b/bochs/bx_debug/dbg_main.cc index 9efb1b738..a9e917081 100644 --- a/bochs/bx_debug/dbg_main.cc +++ b/bochs/bx_debug/dbg_main.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: dbg_main.cc,v 1.237 2010-05-04 20:17:26 sshwarts Exp $ +// $Id: dbg_main.cc,v 1.238 2010-07-22 16:41:58 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001-2009 The Bochs Project @@ -850,9 +850,10 @@ void bx_dbg_info_control_regs_command(void) dbg_printf(" PWT=page-level write-through=%d\n", (cr3>>3) & 1); #if BX_CPU_LEVEL >= 4 Bit32u cr4 = SIM->get_param_num("CR4", dbg_cpu_list)->get(); - dbg_printf("CR4=0x%08x: %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", cr4, + dbg_printf("CR4=0x%08x: %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", cr4, (cr4 & (1<<18)) ? "OSXSAVE" : "osxsave", (cr4 & (1<<17)) ? "PCID" : "pcid", + (cr4 & (1<<16)) ? "FSGSBASE" : "fsgsbase", (cr4 & (1<<14)) ? "SMX" : "smx", (cr4 & (1<<13)) ? "VMX" : "vmx", (cr4 & (1<<10)) ? "OSXMMEXCPT" : "osxmmexcpt", diff --git a/bochs/config.cc b/bochs/config.cc index 1006f1558..481bd9f57 100755 --- a/bochs/config.cc +++ b/bochs/config.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: config.cc,v 1.209 2010-07-16 21:10:48 sshwarts Exp $ +// $Id: config.cc,v 1.210 2010-07-22 16:41:58 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002-2009 The Bochs Project @@ -366,7 +366,7 @@ void bx_init_options() cpu_param->set_options(menu->SHOW_PARENT); // cpuid subtree - bx_list_c *cpuid_param = new bx_list_c(root_param, "cpuid", "CPUID Options", 15); + bx_list_c *cpuid_param = new bx_list_c(root_param, "cpuid", "CPUID Options", 16); new bx_param_bool_c(cpuid_param, "cpuid_limit_winnt", "Limit max CPUID function to 3", @@ -446,6 +446,10 @@ void bx_init_options() "pcid", "PCID support in long mode", "Support for process context ID (PCID) in long mode", 0); + new bx_param_bool_c(cpuid_param, + "fsgsbase", "FS/GS BASE access instructions support", + "FS/GS BASE access instructions support in long mode", + 0); #endif #if BX_SUPPORT_MONITOR_MWAIT new bx_param_bool_c(cpuid_param, @@ -2717,6 +2721,10 @@ static int parse_line_formatted(const char *context, int num_params, char *param if (parse_param_bool(params[i], 5, BXPN_CPUID_PCID) < 0) { PARSE_ERR(("%s: cpuid directive malformed.", context)); } + } else if (!strncmp(params[i], "fsgsbase=", 9)) { + if (parse_param_bool(params[i], 9, BXPN_CPUID_FSGSBASE) < 0) { + PARSE_ERR(("%s: cpuid directive malformed.", context)); + } #endif #if BX_SUPPORT_MONITOR_MWAIT } else if (!strncmp(params[i], "mwait_is_nop=", 13)) { @@ -3893,9 +3901,10 @@ int bx_write_configuration(const char *rc, int overwrite) SIM->get_param_bool(BXPN_CPUID_XSAVE)->get(), SIM->get_param_bool(BXPN_CPUID_MOVBE)->get()); #if BX_SUPPORT_X86_64 - fprintf(fp, ", 1g_pages=%d, pcid=%d", + fprintf(fp, ", 1g_pages=%d, pcid=%d fsgsbase=%d", SIM->get_param_bool(BXPN_CPUID_1G_PAGES)->get(), - SIM->get_param_bool(BXPN_CPUID_PCID)->get()); + SIM->get_param_bool(BXPN_CPUID_PCID)->get(), + SIM->get_param_bool(BXPN_CPUID_FSGSBASE)->get()); #endif #if BX_SUPPORT_MONITOR_MWAIT fprintf(fp, ", mwait_is_nop=%d", SIM->get_param_bool(BXPN_CPUID_MWAIT_IS_NOP)->get()); diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 751014726..51110c235 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.h,v 1.681 2010-07-22 15:12:08 sshwarts Exp $ +// $Id: cpu.h,v 1.682 2010-07-22 16:41:58 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001-2010 The Bochs Project @@ -2735,10 +2735,15 @@ public: // for now... BX_SMF void SYSCALL(bxInstruction_c *) BX_CPP_AttrRegparmN(1); BX_SMF void SYSRET(bxInstruction_c *) BX_CPP_AttrRegparmN(1); - BX_SMF void SWAPGS(bxInstruction_c *) BX_CPP_AttrRegparmN(1); BX_SMF void RDTSCP(bxInstruction_c *) BX_CPP_AttrRegparmN(1); BX_SMF void CMPXCHG16B(bxInstruction_c *) BX_CPP_AttrRegparmN(1); + BX_SMF void SWAPGS(bxInstruction_c *) BX_CPP_AttrRegparmN(1); + BX_SMF void RDFSBASE(bxInstruction_c *) BX_CPP_AttrRegparmN(1); + BX_SMF void RDGSBASE(bxInstruction_c *) BX_CPP_AttrRegparmN(1); + BX_SMF void WRFSBASE(bxInstruction_c *) BX_CPP_AttrRegparmN(1); + BX_SMF void WRGSBASE(bxInstruction_c *) BX_CPP_AttrRegparmN(1); + BX_SMF void LOOPNE64_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1); BX_SMF void LOOPE64_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1); BX_SMF void LOOP64_Jb(bxInstruction_c *) BX_CPP_AttrRegparmN(1); @@ -3270,6 +3275,7 @@ public: // for now... BX_SMF BX_CPP_INLINE int bx_cpuid_support_pse(void); BX_SMF BX_CPP_INLINE int bx_cpuid_support_pse36(void); BX_SMF BX_CPP_INLINE int bx_cpuid_support_pcid(void); + BX_SMF BX_CPP_INLINE int bx_cpuid_support_fsgsbase(void); 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; } @@ -3693,6 +3699,15 @@ BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_pcid(void) #endif } +BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_fsgsbase(void) +{ +#if BX_SUPPORT_X86_64 + return BX_CPU_THIS_PTR cpuid_std_function[7].ecx & 0x1; +#else + return 0; +#endif +} + BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_vme(void) { return (BX_CPU_THIS_PTR cpuid_std_function[1].edx >> 1) & 0x1; diff --git a/bochs/cpu/cpuid.cc b/bochs/cpu/cpuid.cc index dd52cf2d8..ddca0a73a 100755 --- a/bochs/cpu/cpuid.cc +++ b/bochs/cpu/cpuid.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpuid.cc,v 1.121 2010-07-22 15:12:08 sshwarts Exp $ +// $Id: cpuid.cc,v 1.122 2010-07-22 16:41:59 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2007-2010 Stanislav Shwartsman @@ -218,9 +218,14 @@ Bit32u BX_CPU_C::get_extended_cpuid_features(void) Bit32u BX_CPU_C::get_ext2_cpuid_features(void) { - // [0:0] FS/GS BASE access instructions + Bit32u features = 0; - return 0; + // [0:0] FS/GS BASE access instructions + // [31:1] Reserved + if (BX_CPU_SUPPORT_ISA_EXTENSION(BX_CPU_FSGSBASE)) + features |= 1; + + return features; } /* Get CPU feature flags. Returned by CPUID functions 1 and 80000001. */ @@ -561,6 +566,7 @@ void BX_CPU_C::set_cpuid_defaults(void) else cpuid->eax = 0; /* leaf 7 not supported */ + BX_INFO(("CPUID[0x00000007]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, cpuid->ecx, cpuid->edx)); // ------------------------------------------------------ // CPUID function 0x0000000d @@ -932,6 +938,9 @@ void BX_CPU_C::init_isa_features_bitmask(void) xapic_enabled = SIM->get_param_bool(BXPN_CPUID_XAPIC)->get(); sse_enabled = SIM->get_param_enum(BXPN_CPUID_SSE)->get(); #endif +#if BX_SUPPORT_X86_64 + bx_bool fsgsbase_enabled = SIM->get_param_bool(BXPN_CPUID_FSGSBASE)->get(); +#endif // sanity checks #if BX_SUPPORT_3DNOW @@ -1074,6 +1083,9 @@ void BX_CPU_C::init_isa_features_bitmask(void) #if BX_SUPPORT_X86_64 features_bitmask |= BX_CPU_X86_64; + + if (fsgsbase_enabled) + features_bitmask |= BX_CPU_FSGSBASE; #endif BX_CPU_THIS_PTR isa_extensions_bitmask = features_bitmask; diff --git a/bochs/cpu/crregs.cc b/bochs/cpu/crregs.cc index 6886631ba..219f615d9 100755 --- a/bochs/cpu/crregs.cc +++ b/bochs/cpu/crregs.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: crregs.cc,v 1.18 2010-05-12 21:33:04 sshwarts Exp $ +// $Id: crregs.cc,v 1.19 2010-07-22 16:41:59 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2010 Stanislav Shwartsman @@ -909,7 +909,8 @@ Bit32u BX_CPU_C::get_cr4_allow_mask(void) // [31-19] Reserved, Must be Zero // [18] OSXSAVE: Operating System XSAVE Support R/W // [17] PCIDE: PCID Support R/W - // [16-15] Reserved, Must be Zero + // [16] FSGSBASE: FS/GS BASE access R/W + // [15] Reserved, Must be Zero // [14] SMXE: SMX Extensions R/W // [13] VMXE: VMX Extensions R/W // [12-11] Reserved, Must be Zero @@ -975,6 +976,9 @@ Bit32u BX_CPU_C::get_cr4_allow_mask(void) #if BX_SUPPORT_X86_64 if (bx_cpuid_support_pcid()) allowMask |= BX_CR4_PCIDE_MASK; + + if (bx_cpuid_support_fsgsbase()) + allowMask |= BX_CR4_FSGSBASE_MASK; #endif #if BX_CPU_LEVEL >= 6 diff --git a/bochs/cpu/fetchdecode.h b/bochs/cpu/fetchdecode.h index 3d2a71e29..1f01611a3 100755 --- a/bochs/cpu/fetchdecode.h +++ b/bochs/cpu/fetchdecode.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: fetchdecode.h,v 1.103 2010-05-18 07:28:04 sshwarts Exp $ +// $Id: fetchdecode.h,v 1.104 2010-07-22 16:41:59 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2005-2010 Stanislav Shwartsman @@ -971,4 +971,17 @@ static const BxOpcodeInfo_t BxOpcodeInfoG15R[8] = { /* 7 */ { BxPrefixSSE, BX_IA_SFENCE, BxOpcodeGroupSSE_ERR } }; +#if BX_SUPPORT_X86_64 +static const BxOpcodeInfo_t BxOpcodeInfoG15R64[8] = { + /* 0 */ { BxPrefixSSEF3, BX_IA_RDFSBASE }, + /* 1 */ { BxPrefixSSEF3, BX_IA_RDGSBASE }, + /* 2 */ { BxPrefixSSEF3, BX_IA_WRFSBASE }, + /* 3 */ { BxPrefixSSEF3, BX_IA_WRGSBASE }, + /* 4 */ { 0, BX_IA_ERROR }, + /* 5 */ { BxPrefixSSE, BX_IA_LFENCE, BxOpcodeGroupSSE_ERR }, + /* 6 */ { BxPrefixSSE, BX_IA_MFENCE, BxOpcodeGroupSSE_ERR }, + /* 7 */ { BxPrefixSSE, BX_IA_SFENCE, BxOpcodeGroupSSE_ERR } +}; +#endif + #endif // BX_COMMON_FETCHDECODE_TABLES_H diff --git a/bochs/cpu/fetchdecode64.cc b/bochs/cpu/fetchdecode64.cc index 28ec48fdb..f77839a7f 100644 --- a/bochs/cpu/fetchdecode64.cc +++ b/bochs/cpu/fetchdecode64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: fetchdecode64.cc,v 1.269 2010-05-26 18:37:54 sshwarts Exp $ +// $Id: fetchdecode64.cc,v 1.270 2010-07-22 16:41:59 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001-2010 The Bochs Project @@ -1017,7 +1017,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3*2] = { /* 0F AC /wm */ { BxImmediate_Ib, BX_IA_SHRD_EwGwM }, /* 0F AD /wr */ { 0, BX_IA_SHRD_EwGwR }, /* 0F AD /wm */ { 0, BX_IA_SHRD_EwGwM }, - /* 0F AE /wr */ { BxGroup15, BX_IA_ERROR, BxOpcodeInfoG15R }, + /* 0F AE /wr */ { BxGroup15, BX_IA_ERROR, BxOpcodeInfoG15R64 }, /* 0F AE /wm */ { BxGroup15, BX_IA_ERROR, BxOpcodeInfoG15M }, /* 0F AF /wr */ { 0, BX_IA_IMUL_GwEwR }, /* 0F AF /wm */ { 0, BX_IA_IMUL_GwEwM }, @@ -2044,7 +2044,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3*2] = { /* 0F AC /dm */ { BxImmediate_Ib, BX_IA_SHRD_EdGdM }, /* 0F AD /dr */ { 0, BX_IA_SHRD_EdGdR }, /* 0F AD /dm */ { 0, BX_IA_SHRD_EdGdM }, - /* 0F AE /dr */ { BxGroup15, BX_IA_ERROR, BxOpcodeInfoG15R }, + /* 0F AE /dr */ { BxGroup15, BX_IA_ERROR, BxOpcodeInfoG15R64 }, /* 0F AE /dm */ { BxGroup15, BX_IA_ERROR, BxOpcodeInfoG15M }, /* 0F AF /dr */ { 0, BX_IA_IMUL_GdEdR }, /* 0F AF /dm */ { 0, BX_IA_IMUL_GdEdM }, @@ -3071,7 +3071,7 @@ static const BxOpcodeInfo_t BxOpcodeInfo64[512*3*2] = { /* 0F AC /qm */ { BxImmediate_Ib, BX_IA_SHRD_EqGqM }, /* 0F AD /qr */ { 0, BX_IA_SHRD_EqGqR }, /* 0F AD /qm */ { 0, BX_IA_SHRD_EqGqM }, - /* 0F AE /qr */ { BxGroup15, BX_IA_ERROR, BxOpcodeInfoG15R }, + /* 0F AE /qr */ { BxGroup15, BX_IA_ERROR, BxOpcodeInfoG15R64 }, /* 0F AE /qm */ { BxGroup15, BX_IA_ERROR, BxOpcodeInfoG15M }, /* 0F AF /qr */ { 0, BX_IA_IMUL_GqEqR }, /* 0F AF /qm */ { 0, BX_IA_IMUL_GqEqM }, diff --git a/bochs/cpu/ia_opcodes.h b/bochs/cpu/ia_opcodes.h index a9155da5a..b31a4392f 100644 --- a/bochs/cpu/ia_opcodes.h +++ b/bochs/cpu/ia_opcodes.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ia_opcodes.h,v 1.49 2010-05-18 07:28:04 sshwarts Exp $ +// $Id: ia_opcodes.h,v 1.50 2010-07-22 16:41:59 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2008-2010 Stanislav Shwartsman @@ -1620,7 +1620,6 @@ bx_define_opcode(BX_IA_SGDT64_Ms, &BX_CPU_C::SGDT64_Ms, NULL, BX_CPU_X86_64) bx_define_opcode(BX_IA_SIDT64_Ms, &BX_CPU_C::SIDT64_Ms, NULL, BX_CPU_X86_64) bx_define_opcode(BX_IA_LGDT64_Ms, &BX_CPU_C::LGDT64_Ms, NULL, BX_CPU_X86_64) bx_define_opcode(BX_IA_LIDT64_Ms, &BX_CPU_C::LIDT64_Ms, NULL, BX_CPU_X86_64) -bx_define_opcode(BX_IA_SWAPGS, &BX_CPU_C::SWAPGS, NULL, BX_CPU_X86_64) bx_define_opcode(BX_IA_RDTSCP, &BX_CPU_C::RDTSCP, NULL, BX_CPU_X86_64) bx_define_opcode(BX_IA_CMPXCHG16B, &BX_CPU_C::CMPXCHG16B, NULL, BX_CPU_X86_64) bx_define_opcode(BX_IA_LOOPNE64_Jb, &BX_CPU_C::LOOPNE64_Jb, NULL, BX_CPU_X86_64) @@ -1636,6 +1635,11 @@ bx_define_opcode(BX_IA_MOVQ_VdqEqM, &BX_CPU_C::MOVQ_VqWqM, NULL, BX_CPU_X86_64) bx_define_opcode(BX_IA_MOVNTI_MqGq, &BX_CPU_C::MOVNTI_MqGq, NULL, BX_CPU_X86_64) bx_define_opcode(BX_IA_SYSCALL, &BX_CPU_C::SYSCALL, NULL, BX_CPU_X86_64) bx_define_opcode(BX_IA_SYSRET, &BX_CPU_C::SYSRET, NULL, BX_CPU_X86_64) +bx_define_opcode(BX_IA_SWAPGS, &BX_CPU_C::SWAPGS, NULL, BX_CPU_X86_64) +bx_define_opcode(BX_IA_RDFSBASE, &BX_CPU_C::RDFSBASE, NULL, BX_CPU_X86_64 | BX_CPU_FSGSBASE) +bx_define_opcode(BX_IA_RDGSBASE, &BX_CPU_C::RDGSBASE, NULL, BX_CPU_X86_64 | BX_CPU_FSGSBASE) +bx_define_opcode(BX_IA_WRFSBASE, &BX_CPU_C::WRFSBASE, NULL, BX_CPU_X86_64 | BX_CPU_FSGSBASE) +bx_define_opcode(BX_IA_WRGSBASE, &BX_CPU_C::WRGSBASE, NULL, BX_CPU_X86_64 | BX_CPU_FSGSBASE) #endif // VMX diff --git a/bochs/cpu/proc_ctrl.cc b/bochs/cpu/proc_ctrl.cc index 05d18fc6b..d69b2d147 100644 --- a/bochs/cpu/proc_ctrl.cc +++ b/bochs/cpu/proc_ctrl.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: proc_ctrl.cc,v 1.334 2010-07-15 20:18:03 sshwarts Exp $ +// $Id: proc_ctrl.cc,v 1.335 2010-07-22 16:41:59 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001-2010 The Bochs Project @@ -1274,4 +1274,72 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SWAPGS(bxInstruction_c *i) MSR_GSBASE = MSR_KERNELGSBASE; MSR_KERNELGSBASE = temp_GS_base; } + +/* F3 0F AE /0 */ +void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDFSBASE(bxInstruction_c *i) +{ + if (! BX_CPU_THIS_PTR cr4.get_FSGSBASE()) + exception(BX_UD_EXCEPTION, 0); + + if (i->os64L()) { + BX_WRITE_64BIT_REG(i->rm(), MSR_FSBASE); + } + else { + BX_WRITE_32BIT_REGZ(i->rm(), (Bit32u) MSR_FSBASE); + } +} + +/* F3 0F AE /1 */ +void BX_CPP_AttrRegparmN(1) BX_CPU_C::RDGSBASE(bxInstruction_c *i) +{ + if (! BX_CPU_THIS_PTR cr4.get_FSGSBASE()) + exception(BX_UD_EXCEPTION, 0); + + if (i->os64L()) { + BX_WRITE_64BIT_REG(i->rm(), MSR_GSBASE); + } + else { + BX_WRITE_32BIT_REGZ(i->rm(), (Bit32u) MSR_GSBASE); + } +} + +/* F3 0F AE /2 */ +void BX_CPP_AttrRegparmN(1) BX_CPU_C::WRFSBASE(bxInstruction_c *i) +{ + if (! BX_CPU_THIS_PTR cr4.get_FSGSBASE()) + exception(BX_UD_EXCEPTION, 0); + + if (i->os64L()) { + Bit64u fsbase = BX_READ_64BIT_REG(i->rm()); + if (!IsCanonical(fsbase)) { + BX_ERROR(("WRFSBASE: canonical failure !")); + exception(BX_GP_EXCEPTION, 0); + } + MSR_FSBASE = fsbase; + } + else { + // 32-bit value is always canonical + MSR_FSBASE = BX_READ_32BIT_REG(i->rm()); + } +} + +/* F3 0F AE /3 */ +void BX_CPP_AttrRegparmN(1) BX_CPU_C::WRGSBASE(bxInstruction_c *i) +{ + if (! BX_CPU_THIS_PTR cr4.get_FSGSBASE()) + exception(BX_UD_EXCEPTION, 0); + + if (i->os64L()) { + Bit64u gsbase = BX_READ_64BIT_REG(i->rm()); + if (!IsCanonical(gsbase)) { + BX_ERROR(("WRGSBASE: canonical failure !")); + exception(BX_GP_EXCEPTION, 0); + } + MSR_GSBASE = gsbase; + } + else { + // 32-bit value is always canonical + MSR_GSBASE = BX_READ_32BIT_REG(i->rm()); + } +} #endif diff --git a/bochs/param_names.h b/bochs/param_names.h index 64ea11dfb..9b0f2e8f2 100755 --- a/bochs/param_names.h +++ b/bochs/param_names.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: param_names.h,v 1.10 2010-07-16 21:03:52 sshwarts Exp $ +// $Id: param_names.h,v 1.11 2010-07-22 16:41:58 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2009 The Bochs Project @@ -54,6 +54,7 @@ #define BXPN_CPUID_MWAIT_IS_NOP "cpuid.mwait_is_nop" #define BXPN_CPUID_1G_PAGES "cpuid.1g_pages" #define BXPN_CPUID_PCID "cpuid.pcid" +#define BXPN_CPUID_FSGSBASE "cpuid.fsgsbase" #define BXPN_MEM_SIZE "memory.standard.ram.size" #define BXPN_HOST_MEM_SIZE "memory.standard.ram.host_size" #define BXPN_ROM_PATH "memory.standard.rom.path"