Implement modern BIOS mode for limiting max reported CPUID function to 3.

This mode is required in order to correctly boot and install WinNT guest
This commit is contained in:
Stanislav Shwartsman 2008-09-22 21:38:15 +00:00
parent b0abb5d6a6
commit 3b276bc9fe
7 changed files with 56 additions and 18 deletions

View File

@ -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

View File

@ -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

View File

@ -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());

View File

@ -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]);

View File

@ -1,7 +1,7 @@
<!--
================================================================
doc/docbook/user/user.dbk
$Id: user.dbk,v 1.245 2008-08-19 16:43:06 sshwarts Exp $
$Id: user.dbk,v 1.246 2008-09-22 21:38:11 sshwarts Exp $
This is the top level file for the Bochs Users Manual.
================================================================
@ -3065,12 +3065,17 @@ Maximum amount of instructions allowed to execute by processor before
returning control to another cpu. This option exists only in Bochs
binary compiled with SMP support.
</para>
<para><command>reset-on-triple-fault</command></para>
<para><command>reset_on_triple_fault</command></para>
<para>
Reset the CPU when triple fault occur (highly recommended) rather than PANIC.
Remember that if you are trying to continue after triple fault the simulation
will be completely bogus !
</para>
<para><command>cpuid_limit_winnt</command></para>
<para>
Determine whether to limit maximum CPUID function to 3. This mode is required
to workaround WinNT installation and boot issues.
</para>
<para><command>vendor_string</command></para>
<para>
Set the CPUID vendor string returned by CPUID(0x0). This should be a
@ -3111,7 +3116,7 @@ speed.</para></footnote>.
</row>
</thead>
<tbody>
<row><entry>2.3.7</entry><entry>2.6Ghz</entry><entry>Intel Core 2 Q9770 with WinXP/g++ 3.4 </entry><entry> 50 to 55 MIPS</entry></row>
<row><entry>2.3.7</entry><entry>3.2Ghz</entry><entry>Intel Core 2 Q9770 with WinXP/g++ 3.4 </entry><entry> 50 to 55 MIPS</entry></row>
<row><entry>2.3.7</entry><entry>2.6Ghz</entry><entry>Intel Core 2 Duo with WinXP/g++ 3.4 </entry><entry> 38 to 43 MIPS</entry></row>
<row><entry>2.2.6</entry><entry>2.6Ghz</entry><entry>Intel Core 2 Duo with WinXP/g++ 3.4 </entry><entry> 21 to 25 MIPS</entry></row>
<row><entry>2.2.6</entry><entry>2.1Ghz</entry><entry>Athlon XP with Linux 2.6/g++ 3.4 </entry><entry> 12 to 15 MIPS</entry></row>

View File

@ -137,6 +137,11 @@ Reset the CPU when triple fault occur (highly recommended) rather than
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

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: siminterface.h,v 1.217 2008-09-18 17:18:36 sshwarts Exp $
// $Id: siminterface.h,v 1.218 2008-09-22 21:38:15 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Intro to siminterface by Bryce Denney:
@ -132,6 +132,7 @@ typedef enum {
#define BXPN_IPS "cpu.ips"
#define BXPN_SMP_QUANTUM "cpu.quantum"
#define BXPN_RESET_ON_TRIPLE_FAULT "cpu.reset_on_triple_fault"
#define BXPN_CPUID_LIMIT_WINNT "cpu.cpuid_limit_winnt"
#define BXPN_VENDOR_STRING "cpu.vendor_string"
#define BXPN_BRAND_STRING "cpu.brand_string"
#define BXPN_MEM_SIZE "memory.standard.ram.size"