diff --git a/bochs/.bochsrc b/bochs/.bochsrc index 3173f72f4..f501d3088 100644 --- a/bochs/.bochsrc +++ b/bochs/.bochsrc @@ -100,6 +100,10 @@ romimage: file=$BXSHARE/BIOS-bochs-latest # PANIC. Remember that if you trying to continue after triple fault the # simulation will be completely bogus ! # +# CPUID_LIMIT_WINNT: +# Determine whether to limit maximum CPUID function to 3. This mode is +# required to workaround WinNT installation and boot issues. +# # VENDOR_STRING: # Set the CPUID vendor string returned by CPUID(0x0). This should be a # twelve-character ASCII string. @@ -130,7 +134,7 @@ romimage: file=$BXSHARE/BIOS-bochs-latest # 2.2.6 2.1Ghz Athlon XP with Linux 2.6/g++ 3.4 12 to 15 Mips # 2.0.1 1.6Ghz Intel P4 with Win2000/g++ 3.3 5 to 7 Mips #======================================================================= -cpu: count=1, ips=10000000, reset_on_triple_fault=1 +cpu: count=1, ips=10000000, reset_on_triple_fault=1, cpuid_limit_winnt=0 #======================================================================= # MEGS diff --git a/bochs/PARAM_TREE.txt b/bochs/PARAM_TREE.txt index a88ee7cd5..79bfe1c88 100644 --- a/bochs/PARAM_TREE.txt +++ b/bochs/PARAM_TREE.txt @@ -1,4 +1,4 @@ -$Id: PARAM_TREE.txt,v 1.14 2008-02-05 22:57:39 sshwarts Exp $ +$Id: PARAM_TREE.txt,v 1.15 2008-09-22 21:38:11 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 @@ -23,6 +23,7 @@ cpu ips quantum reset_on_triple_fault + cpuid_limit_winnt memory standard diff --git a/bochs/config.cc b/bochs/config.cc index 36220aca9..57816511e 100755 --- a/bochs/config.cc +++ b/bochs/config.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: config.cc,v 1.138 2008-09-12 21:05:49 sshwarts Exp $ +// $Id: config.cc,v 1.139 2008-09-22 21:38:11 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. @@ -455,6 +455,10 @@ void bx_init_options() "reset_on_triple_fault", "Enable CPU reset on triple fault", "Enable CPU reset if triple fault occured (highly recommended)", 1); + new bx_param_bool_c(cpu_param, + "cpuid_limit_winnt", "Limit max CPUID function to 3", + "Limit max CPUID function reported to 3 to workaround WinNT issue", + 0); new bx_param_string_c(cpu_param, "vendor_string", "CPUID vendor string", @@ -2480,7 +2484,13 @@ static int parse_line_formatted(const char *context, int num_params, char *param #endif } else if (!strncmp(params[i], "reset_on_triple_fault=", 22)) { if (params[i][22] == '0' || params[i][22] == '1') { - SIM->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT)->set (params[i][22] - '0'); + SIM->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT)->set(params[i][22] - '0'); + } else { + PARSE_ERR(("%s: cpu directive malformed.", context)); + } + } else if (!strncmp(params[i], "cpuid_limit_winnt=", 18)) { + if (params[i][18] == '0' || params[i][18] == '1') { + SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->set(params[i][18] - '0'); } else { PARSE_ERR(("%s: cpu directive malformed.", context)); } @@ -2522,7 +2532,7 @@ static int parse_line_formatted(const char *context, int num_params, char *param PARSE_ERR(("%s: romimage directive malformed.", context)); } } else { - SIM->get_param_num(BXPN_ROM_ADDRESS)->set (0); + SIM->get_param_num(BXPN_ROM_ADDRESS)->set(0); } } else if (!strcmp(params[0], "vgaromimage")) { if (num_params != 2) { @@ -3524,14 +3534,17 @@ int bx_write_configuration(const char *rc, int overwrite) fprintf(fp, "vga_update_interval: %u\n", SIM->get_param_num(BXPN_VGA_UPDATE_INTERVAL)->get()); fprintf(fp, "vga: extension=%s\n", SIM->get_param_string(BXPN_VGA_EXTENSION)->getptr()); #if BX_SUPPORT_SMP - fprintf(fp, "cpu: count=%u:%u:%u, ips=%u, quantum=%d, reset_on_triple_fault=%d\n", + fprintf(fp, "cpu: count=%u:%u:%u, ips=%u, quantum=%d, reset_on_triple_fault=%d, cpuid_limit_winnt=%d\n", SIM->get_param_num(BXPN_CPU_NPROCESSORS)->get(), SIM->get_param_num(BXPN_CPU_NCORES)->get(), SIM->get_param_num(BXPN_CPU_NTHREADS)->get(), SIM->get_param_num(BXPN_IPS)->get(), SIM->get_param_num(BXPN_SMP_QUANTUM)->get(), - SIM->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT)->get()); + SIM->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT)->get(), + SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->get()); #else - fprintf(fp, "cpu: count=1, ips=%u, reset_on_triple_fault=%d\n", - SIM->get_param_num(BXPN_IPS)->get(), SIM->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT)->get()); + fprintf(fp, "cpu: count=1, ips=%u, reset_on_triple_fault=%d, cpuid_limit_winnt=%d\n", + SIM->get_param_num(BXPN_IPS)->get(), + SIM->get_param_bool(BXPN_RESET_ON_TRIPLE_FAULT)->get(), + SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->get()); #endif fprintf(fp, "text_snapshot_check: enabled=%d\n", SIM->get_param_bool(BXPN_TEXT_SNAPSHOT_CHECK)->get()); fprintf(fp, "private_colormap: enabled=%d\n", SIM->get_param_bool(BXPN_PRIVATE_COLORMAP)->get()); diff --git a/bochs/cpu/cpuid.cc b/bochs/cpu/cpuid.cc index fc1b9adb5..7e37fc55e 100755 --- a/bochs/cpu/cpuid.cc +++ b/bochs/cpu/cpuid.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpuid.cc,v 1.72 2008-08-19 16:43:06 sshwarts Exp $ +// $Id: cpuid.cc,v 1.73 2008-09-22 21:38:11 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2007 Stanislav Shwartsman @@ -327,6 +327,7 @@ void BX_CPU_C::set_cpuid_defaults(void) { Bit8u *vendor_string = (Bit8u *)SIM->get_param_string(BXPN_VENDOR_STRING)->getptr(); Bit8u *brand_string = (Bit8u *)SIM->get_param_string(BXPN_BRAND_STRING)->getptr(); + bool cpuid_limit_winnt = SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->get(); cpuid_function_t *cpuid; int i; @@ -360,10 +361,14 @@ void BX_CPU_C::set_cpuid_defaults(void) #else // for Pentium Pro, Pentium II, Pentium 4 processors cpuid->eax = 2; - if (BX_SUPPORT_MONITOR_MWAIT) - cpuid->eax = 0x5; - if (BX_SUPPORT_XSAVE) - cpuid->eax = 0xD; + // do not report CPUID functions above 0x3 if cpuid_limit_winnt is set + // to workaround WinNT issue. + if (! cpuid_limit_winnt) { + if (BX_SUPPORT_MONITOR_MWAIT) + cpuid->eax = 0x5; + if (BX_SUPPORT_XSAVE) + cpuid->eax = 0xD; + } #endif // CPUID vendor string (e.g. GenuineIntel, AuthenticAMD, CentaurHauls, ...) @@ -495,6 +500,10 @@ void BX_CPU_C::set_cpuid_defaults(void) cpuid->ecx = 0; cpuid->edx = 0; + // do not report CPUID functions above 0x3 if cpuid_limit_winnt is set + // to workaround WinNT issue. + if (! cpuid_limit_winnt) return; + // ------------------------------------------------------ // CPUID function 0x00000004 - Deterministic Cache Parameters cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[4]); diff --git a/bochs/doc/docbook/user/user.dbk b/bochs/doc/docbook/user/user.dbk index 50ec19cbe..3efbd22fa 100644 --- a/bochs/doc/docbook/user/user.dbk +++ b/bochs/doc/docbook/user/user.dbk @@ -1,7 +1,7 @@