2001-10-03 16:56:51 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2011-02-25 01:05:47 +03:00
|
|
|
// $Id$
|
2001-10-03 16:56:51 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2011-04-24 00:39:27 +04:00
|
|
|
// Copyright (C) 2001-2011 The Bochs Project
|
2001-04-10 05:04:59 +04:00
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
2009-08-22 23:30:23 +04:00
|
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
#include "bochs.h"
|
2011-08-16 23:58:56 +04:00
|
|
|
#include "bxversion.h"
|
2010-02-26 17:18:19 +03:00
|
|
|
#include "param_names.h"
|
2009-02-23 14:06:53 +03:00
|
|
|
#include "gui/textconfig.h"
|
2011-12-15 23:33:06 +04:00
|
|
|
#if BX_USE_TEXTCONFIG && defined(WIN32) && (BX_WITH_WIN32 || BX_WITH_SDL)
|
2009-03-24 19:28:03 +03:00
|
|
|
#include "gui/win32dialog.h"
|
|
|
|
#endif
|
2006-03-07 01:03:16 +03:00
|
|
|
#include "cpu/cpu.h"
|
2004-06-19 19:20:15 +04:00
|
|
|
#include "iodev/iodev.h"
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2003-08-04 20:03:09 +04:00
|
|
|
#ifdef HAVE_LOCALE_H
|
|
|
|
#include <locale.h>
|
|
|
|
#endif
|
|
|
|
|
2002-10-02 03:34:52 +04:00
|
|
|
#if BX_WITH_SDL
|
|
|
|
// since SDL redefines main() to SDL_main(), we must include SDL.h so that the
|
2008-02-06 01:57:43 +03:00
|
|
|
// C language prototype is found. Otherwise SDL_main() will get its name
|
2002-10-02 03:34:52 +04:00
|
|
|
// mangled and not match what the SDL library is expecting.
|
2004-08-06 19:49:55 +04:00
|
|
|
#include <SDL.h>
|
2002-10-02 23:23:01 +04:00
|
|
|
|
|
|
|
#if defined(macintosh)
|
|
|
|
// Work around a bug in SDL 1.2.4 on MacOS X, which redefines getenv to
|
|
|
|
// SDL_getenv, but then neglects to provide SDL_getenv. It happens
|
|
|
|
// because we are defining -Dmacintosh.
|
|
|
|
#undef getenv
|
|
|
|
#endif
|
2002-10-02 03:34:52 +04:00
|
|
|
#endif
|
|
|
|
|
2002-11-01 20:53:52 +03:00
|
|
|
#if BX_WITH_CARBON
|
|
|
|
#include <Carbon/Carbon.h>
|
|
|
|
#endif
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
extern "C" {
|
|
|
|
#include <signal.h>
|
|
|
|
}
|
|
|
|
|
2002-11-11 20:09:57 +03:00
|
|
|
#if BX_GUI_SIGHANDLER
|
|
|
|
bx_bool bx_gui_sighandler = 0;
|
|
|
|
#endif
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
// some prototypes from iodev/
|
|
|
|
// I want to stay away from including iodev/iodev.h here
|
|
|
|
Bit32u bx_unmapped_io_read_handler(Bit32u address, unsigned io_len);
|
|
|
|
void bx_unmapped_io_write_handler(Bit32u address, Bit32u value,
|
|
|
|
unsigned io_len);
|
|
|
|
|
2007-10-16 20:17:48 +04:00
|
|
|
void bx_init_hardware(void);
|
|
|
|
void bx_init_options(void);
|
2006-10-24 21:53:47 +04:00
|
|
|
void bx_init_bx_dbg(void);
|
2007-10-16 20:17:48 +04:00
|
|
|
|
2007-10-25 03:29:40 +04:00
|
|
|
static const char *divider = "========================================================================";
|
2002-10-25 01:07:56 +04:00
|
|
|
static logfunctions thePluginLog;
|
|
|
|
logfunctions *pluginlog = &thePluginLog;
|
2001-05-23 06:37:52 +04:00
|
|
|
|
2002-11-01 18:19:48 +03:00
|
|
|
bx_startup_flags_t bx_startup_flags;
|
2003-05-27 22:19:13 +04:00
|
|
|
bx_bool bx_user_quit;
|
2006-01-18 21:35:38 +03:00
|
|
|
Bit8u bx_cpu_count;
|
2011-04-21 17:27:42 +04:00
|
|
|
#if BX_SUPPORT_APIC
|
2010-02-28 17:52:17 +03:00
|
|
|
Bit32u apic_id_mask; // determinted by XAPIC option
|
2010-04-03 14:14:42 +04:00
|
|
|
bx_bool simulate_xapic;
|
2011-04-21 17:27:42 +04:00
|
|
|
#endif
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
/* typedefs */
|
|
|
|
|
2001-06-19 20:25:41 +04:00
|
|
|
#define LOG_THIS genlog->
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
bx_pc_system_c bx_pc_system;
|
|
|
|
|
|
|
|
bx_debug_t bx_dbg;
|
|
|
|
|
2006-01-18 21:35:38 +03:00
|
|
|
typedef BX_CPU_C *BX_CPU_C_PTR;
|
|
|
|
|
|
|
|
#if BX_SUPPORT_SMP
|
|
|
|
// multiprocessor simulation, we need an array of cpus
|
|
|
|
BOCHSAPI BX_CPU_C_PTR *bx_cpu_array = NULL;
|
2006-01-06 00:39:11 +03:00
|
|
|
#else
|
2006-01-18 21:35:38 +03:00
|
|
|
// single processor simulation, so there's one of everything
|
|
|
|
BOCHSAPI BX_CPU_C bx_cpu;
|
2006-01-15 22:35:39 +03:00
|
|
|
#endif
|
|
|
|
|
2007-11-01 21:03:48 +03:00
|
|
|
BOCHSAPI BX_MEM_C bx_mem;
|
|
|
|
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
char *bochsrc_filename = NULL;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2009-03-26 12:51:22 +03:00
|
|
|
void bx_print_header()
|
2001-06-19 20:25:41 +04:00
|
|
|
{
|
2009-03-26 12:51:22 +03:00
|
|
|
printf("%s\n", divider);
|
2001-06-19 20:25:41 +04:00
|
|
|
char buffer[128];
|
|
|
|
sprintf (buffer, "Bochs x86 Emulator %s\n", VER_STRING);
|
2009-03-26 12:51:22 +03:00
|
|
|
bx_center_print(stdout, buffer, 72);
|
2001-06-19 20:25:41 +04:00
|
|
|
if (REL_STRING[0]) {
|
2009-03-26 12:51:22 +03:00
|
|
|
sprintf(buffer, "%s\n", REL_STRING);
|
|
|
|
bx_center_print(stdout, buffer, 72);
|
2010-10-03 00:52:47 +04:00
|
|
|
#ifdef __DATE__
|
|
|
|
#ifdef __TIME__
|
2011-04-01 20:19:15 +04:00
|
|
|
sprintf(buffer, "Compiled on %s at %s\n", __DATE__, __TIME__);
|
2010-10-03 00:52:47 +04:00
|
|
|
#else
|
2011-04-01 20:19:15 +04:00
|
|
|
sprintf(buffer, "Compiled on %s\n", __DATE__);
|
2010-10-03 00:52:47 +04:00
|
|
|
#endif
|
|
|
|
bx_center_print(stdout, buffer, 72);
|
|
|
|
#endif
|
2001-06-19 20:25:41 +04:00
|
|
|
}
|
2009-03-26 12:51:22 +03:00
|
|
|
printf("%s\n", divider);
|
2001-06-19 20:25:41 +04:00
|
|
|
}
|
|
|
|
|
2001-09-26 07:19:25 +04:00
|
|
|
#if BX_WITH_CARBON
|
2001-09-26 04:12:12 +04:00
|
|
|
/* Original code by Darrell Walisser - dwaliss1@purdue.edu */
|
|
|
|
|
2008-02-15 22:03:54 +03:00
|
|
|
static void setupWorkingDirectory(char *path)
|
2001-09-26 04:12:12 +04:00
|
|
|
{
|
2008-02-15 22:03:54 +03:00
|
|
|
char parentdir[MAXPATHLEN];
|
|
|
|
char *c;
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2008-02-15 22:03:54 +03:00
|
|
|
strncpy (parentdir, path, MAXPATHLEN);
|
|
|
|
c = (char*) parentdir;
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2008-02-15 22:03:54 +03:00
|
|
|
while (*c != '\0') /* go to end */
|
|
|
|
c++;
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2008-02-15 22:03:54 +03:00
|
|
|
while (*c != '/') /* back up to parent */
|
|
|
|
c--;
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2008-02-15 22:03:54 +03:00
|
|
|
*c = '\0'; /* cut off last part (binary name) */
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2008-02-15 22:03:54 +03:00
|
|
|
/* chdir to the binary app's parent */
|
|
|
|
int n;
|
|
|
|
n = chdir (parentdir);
|
|
|
|
if (n) BX_PANIC (("failed to change dir to parent"));
|
|
|
|
/* chdir to the .app's parent */
|
|
|
|
n = chdir ("../../../");
|
|
|
|
if (n) BX_PANIC (("failed to change to ../../.."));
|
2001-09-26 04:12:12 +04:00
|
|
|
}
|
2002-11-25 20:53:53 +03:00
|
|
|
|
|
|
|
/* Panic button to display fatal errors.
|
|
|
|
Completely self contained, can't rely on carbon.cc being available */
|
|
|
|
static void carbonFatalDialog(const char *error, const char *exposition)
|
|
|
|
{
|
|
|
|
DialogRef alertDialog;
|
|
|
|
CFStringRef cfError;
|
|
|
|
CFStringRef cfExposition;
|
|
|
|
DialogItemIndex index;
|
|
|
|
AlertStdCFStringAlertParamRec alertParam = {0};
|
|
|
|
fprintf(stderr, "Entering carbonFatalDialog: %s\n", error);
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2002-11-25 20:53:53 +03:00
|
|
|
// Init libraries
|
|
|
|
InitCursor();
|
|
|
|
// Assemble dialog
|
|
|
|
cfError = CFStringCreateWithCString(NULL, error, kCFStringEncodingASCII);
|
|
|
|
if(exposition != NULL)
|
|
|
|
{
|
|
|
|
cfExposition = CFStringCreateWithCString(NULL, exposition, kCFStringEncodingASCII);
|
|
|
|
}
|
|
|
|
else { cfExposition = NULL; }
|
|
|
|
alertParam.version = kStdCFStringAlertVersionOne;
|
|
|
|
alertParam.defaultText = CFSTR("Quit");
|
|
|
|
alertParam.position = kWindowDefaultPosition;
|
|
|
|
alertParam.defaultButton = kAlertStdAlertOKButton;
|
|
|
|
// Display Dialog
|
|
|
|
CreateStandardAlert(
|
|
|
|
kAlertStopAlert,
|
|
|
|
cfError,
|
|
|
|
cfExposition, /* can be NULL */
|
|
|
|
&alertParam, /* can be NULL */
|
|
|
|
&alertDialog);
|
2008-02-16 01:05:43 +03:00
|
|
|
RunStandardAlert(alertDialog, NULL, &index);
|
2002-11-25 20:53:53 +03:00
|
|
|
// Cleanup
|
2008-02-15 22:03:54 +03:00
|
|
|
CFRelease(cfError);
|
|
|
|
if(cfExposition != NULL) { CFRelease(cfExposition); }
|
2002-11-25 20:53:53 +03:00
|
|
|
}
|
2001-09-26 04:12:12 +04:00
|
|
|
#endif
|
|
|
|
|
2006-11-13 00:25:06 +03:00
|
|
|
#if BX_DEBUGGER
|
2006-02-17 00:44:17 +03:00
|
|
|
void print_tree(bx_param_c *node, int level)
|
|
|
|
{
|
|
|
|
int i;
|
2006-03-07 20:54:27 +03:00
|
|
|
char tmpstr[BX_PATHNAME_LEN], tmpbyte[4];
|
|
|
|
|
2006-02-17 00:44:17 +03:00
|
|
|
for (i=0; i<level; i++)
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf(" ");
|
2006-02-17 00:44:17 +03:00
|
|
|
if (node == NULL) {
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf("NULL pointer\n");
|
2006-02-17 00:44:17 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (node->get_type()) {
|
|
|
|
case BXT_PARAM_NUM:
|
2006-05-30 23:46:31 +04:00
|
|
|
if (((bx_param_num_c*)node)->get_base() == BASE_DEC) {
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf("%s = " FMT_LL "d (number)\n", node->get_name(), ((bx_param_num_c*)node)->get64());
|
2006-02-17 00:44:17 +03:00
|
|
|
} else {
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf("%s = 0x" FMT_LL "x (hex number)\n", node->get_name(), ((bx_param_num_c*)node)->get64());
|
2006-02-17 00:44:17 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case BXT_PARAM_BOOL:
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf("%s = %s (boolean)\n", node->get_name(), ((bx_param_bool_c*)node)->get()?"true":"false");
|
2006-02-17 00:44:17 +03:00
|
|
|
break;
|
|
|
|
case BXT_PARAM_ENUM:
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf("%s = '%s' (enum)\n", node->get_name(), ((bx_param_enum_c*)node)->get_selected());
|
2006-02-26 22:11:20 +03:00
|
|
|
break;
|
2006-02-17 00:44:17 +03:00
|
|
|
case BXT_PARAM_STRING:
|
2009-03-17 22:47:52 +03:00
|
|
|
if (((bx_param_string_c*)node)->get_options() & bx_param_string_c::RAW_BYTES) {
|
2006-03-07 20:54:27 +03:00
|
|
|
tmpstr[0] = 0;
|
|
|
|
for (i = 0; i < ((bx_param_string_c*)node)->get_maxsize(); i++) {
|
|
|
|
if (i > 0) {
|
|
|
|
tmpbyte[0] = ((bx_param_string_c*)node)->get_separator();
|
|
|
|
tmpbyte[1] = 0;
|
|
|
|
strcat(tmpstr, tmpbyte);
|
|
|
|
}
|
|
|
|
sprintf(tmpbyte, "%02x", (Bit8u)((bx_param_string_c*)node)->getptr()[i]);
|
|
|
|
strcat(tmpstr, tmpbyte);
|
|
|
|
}
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf("%s = '%s' (raw byte string)\n", node->get_name(), tmpstr);
|
2006-03-07 20:54:27 +03:00
|
|
|
} else {
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf("%s = '%s' (string)\n", node->get_name(), ((bx_param_string_c*)node)->getptr());
|
2006-03-07 20:54:27 +03:00
|
|
|
}
|
2006-02-17 00:44:17 +03:00
|
|
|
break;
|
|
|
|
case BXT_LIST:
|
|
|
|
{
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf("%s = \n", node->get_name());
|
2006-02-17 00:44:17 +03:00
|
|
|
bx_list_c *list = (bx_list_c*)node;
|
2006-02-26 22:11:20 +03:00
|
|
|
for (i=0; i < list->get_size(); i++) {
|
2006-02-17 00:44:17 +03:00
|
|
|
print_tree(list->get(i), level+1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2006-04-16 13:29:02 +04:00
|
|
|
case BXT_PARAM_DATA:
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf("%s = 'size=%d' (binary data)\n", node->get_name(), ((bx_shadow_data_c*)node)->get_size());
|
2006-04-16 13:29:02 +04:00
|
|
|
break;
|
|
|
|
default:
|
2006-11-13 00:25:06 +03:00
|
|
|
dbg_printf("%s (unknown parameter type)\n", node->get_name());
|
2006-02-17 00:44:17 +03:00
|
|
|
}
|
|
|
|
}
|
2006-11-13 00:25:06 +03:00
|
|
|
#endif
|
2006-02-17 00:44:17 +03:00
|
|
|
|
2012-03-02 20:51:45 +04:00
|
|
|
int bxmain(void)
|
|
|
|
{
|
2003-08-04 20:03:09 +04:00
|
|
|
#ifdef HAVE_LOCALE_H
|
|
|
|
// Initialize locale (for isprint() and other functions)
|
|
|
|
setlocale (LC_ALL, "");
|
|
|
|
#endif
|
2003-05-27 22:19:13 +04:00
|
|
|
bx_user_quit = 0;
|
2007-10-16 20:17:48 +04:00
|
|
|
bx_init_siminterface(); // create the SIM object
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
static jmp_buf context;
|
|
|
|
if (setjmp (context) == 0) {
|
|
|
|
SIM->set_quit_context (&context);
|
2008-10-01 15:36:04 +04:00
|
|
|
BX_INSTR_INIT_ENV();
|
2012-03-02 20:51:45 +04:00
|
|
|
if (bx_init_main(bx_startup_flags.argc, bx_startup_flags.argv) < 0) {
|
|
|
|
BX_INSTR_EXIT_ENV();
|
2002-11-01 18:19:48 +03:00
|
|
|
return 0;
|
2008-10-01 15:36:04 +04:00
|
|
|
}
|
2002-10-25 01:07:56 +04:00
|
|
|
// read a param to decide which config interface to start.
|
|
|
|
// If one exists, start it. If not, just begin.
|
2006-02-22 00:35:09 +03:00
|
|
|
bx_param_enum_c *ci_param = SIM->get_param_enum(BXPN_SEL_CONFIG_INTERFACE);
|
2007-10-25 03:29:40 +04:00
|
|
|
const char *ci_name = ci_param->get_selected();
|
2002-10-29 23:18:32 +03:00
|
|
|
if (!strcmp(ci_name, "textconfig")) {
|
2004-01-29 21:50:33 +03:00
|
|
|
#if BX_USE_TEXTCONFIG
|
2006-02-22 00:35:09 +03:00
|
|
|
init_text_config_interface(); // in textconfig.h
|
2004-01-29 21:50:33 +03:00
|
|
|
#else
|
|
|
|
BX_PANIC(("configuration interface 'textconfig' not present"));
|
2009-03-24 19:28:03 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (!strcmp(ci_name, "win32config")) {
|
2011-12-15 23:33:06 +04:00
|
|
|
#if BX_USE_TEXTCONFIG && defined(WIN32) && (BX_WITH_WIN32 || BX_WITH_SDL)
|
2009-03-24 19:28:03 +03:00
|
|
|
init_win32_config_interface();
|
|
|
|
#else
|
|
|
|
BX_PANIC(("configuration interface 'win32config' not present"));
|
2004-01-29 21:50:33 +03:00
|
|
|
#endif
|
2002-10-25 01:07:56 +04:00
|
|
|
}
|
|
|
|
#if BX_WITH_WX
|
|
|
|
else if (!strcmp(ci_name, "wx")) {
|
|
|
|
PLUG_load_plugin(wx, PLUGTYPE_CORE);
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
}
|
2002-10-25 01:07:56 +04:00
|
|
|
#endif
|
|
|
|
else {
|
2006-02-22 00:35:09 +03:00
|
|
|
BX_PANIC(("unsupported configuration interface '%s'", ci_name));
|
2002-10-25 01:07:56 +04:00
|
|
|
}
|
2006-02-22 00:35:09 +03:00
|
|
|
ci_param->set_enabled(0);
|
|
|
|
int status = SIM->configuration_interface(ci_name, CI_START);
|
2002-12-17 08:58:45 +03:00
|
|
|
if (status == CI_ERR_NO_TEXT_CONSOLE)
|
2006-02-22 00:35:09 +03:00
|
|
|
BX_PANIC(("Bochs needed the text console, but it was not usable"));
|
2002-10-25 01:07:56 +04:00
|
|
|
// user quit the config interface, so just quit
|
- use setjmp() and longjmp() to quit the simulation thread cleanly.
I use setjmp() to save the context just before calling
bx_continue_after_config_interface(). Then, in
bx_real_sim_c:quit_sim, I use longjmp() to jump back to that context.
This happens in main.cc and in gui/wxmain.cc (wxWindows only).
I haven't tested with the debugger yet. Possibly with debugger
the quit longjmp() should jump back to the debugger prompt loop
instead of actually quitting the program.
- clean up BX_ASYNC_EVT_LOG_MSG implementation by creating a different,
synchronous event called BX_SYNC_EVT_LOG_ASK. The async event
could be used to simply tell the CI that an event has occurred,
for example if the user wanted to view the events on screen
(not implemented). The sync event is used when you want the user
to respond before the simulation can continue, such as a for the
"panic=ask" behavior.
- in wxmain.cc, move the updates to the Start,Stop,Pause,Resume menu
items into a separate method simStatusChanged(). This makes the code that
does important stuff more readable.
- remove wxMutexGuiEnter()/Leave() from MyFrame::OnSim2CuiEvent().
This method is an event handler called in the gui thread, so it
already has the gui lock. This call caused thread lock on my linux
box.
2002-08-27 22:11:13 +04:00
|
|
|
} else {
|
|
|
|
// quit via longjmp
|
|
|
|
}
|
2006-02-22 00:35:09 +03:00
|
|
|
SIM->set_quit_context(NULL);
|
2002-11-26 21:15:56 +03:00
|
|
|
#if defined(WIN32)
|
2003-05-27 22:19:13 +04:00
|
|
|
if (!bx_user_quit) {
|
|
|
|
// ask user to press ENTER before exiting, so that they can read messages
|
|
|
|
// before the console window is closed. This isn't necessary after pressing
|
|
|
|
// the power button.
|
2006-02-22 00:35:09 +03:00
|
|
|
fprintf(stderr, "\nBochs is exiting. Press ENTER when you're ready to close this window.\n");
|
2003-05-27 22:19:13 +04:00
|
|
|
char buf[16];
|
2006-02-22 00:35:09 +03:00
|
|
|
fgets(buf, sizeof(buf), stdin);
|
2003-05-27 22:19:13 +04:00
|
|
|
}
|
2002-11-26 21:15:56 +03:00
|
|
|
#endif
|
2008-10-01 15:36:04 +04:00
|
|
|
BX_INSTR_EXIT_ENV();
|
2006-02-22 00:35:09 +03:00
|
|
|
return SIM->get_exit_code();
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
|
2002-11-26 21:15:56 +03:00
|
|
|
#if defined(__WXMSW__)
|
2002-11-14 08:12:28 +03:00
|
|
|
|
|
|
|
// win32 applications get the whole command line in one long string.
|
|
|
|
// This function is used to split up the string into argc and argv,
|
|
|
|
// so that the command line can be used on win32 just like on every
|
|
|
|
// other platform.
|
2002-11-25 21:17:13 +03:00
|
|
|
//
|
|
|
|
// I'm sure other people have written this same function, and they may have
|
|
|
|
// done it better, but I don't know where to find it. -BBD
|
2002-12-01 17:18:37 +03:00
|
|
|
#ifndef MAX_ARGLEN
|
|
|
|
#define MAX_ARGLEN 80
|
|
|
|
#endif
|
2011-07-31 22:43:46 +04:00
|
|
|
int split_string_into_argv(char *string, int *argc_out, char **argv, int max_argv)
|
2002-11-14 08:12:28 +03:00
|
|
|
{
|
|
|
|
char *buf0 = new char[strlen(string)+1];
|
|
|
|
strcpy (buf0, string);
|
|
|
|
char *buf = buf0;
|
|
|
|
int in_double_quote = 0, in_single_quote = 0;
|
2008-02-06 01:57:43 +03:00
|
|
|
for (int i=0; i<max_argv; i++)
|
2002-11-14 08:12:28 +03:00
|
|
|
argv[i] = NULL;
|
|
|
|
argv[0] = new char[6];
|
|
|
|
strcpy (argv[0], "bochs");
|
|
|
|
int argc = 1;
|
|
|
|
argv[argc] = new char[MAX_ARGLEN];
|
|
|
|
char *outp = &argv[argc][0];
|
|
|
|
// trim leading and trailing spaces
|
|
|
|
while (*buf==' ') buf++;
|
|
|
|
char *p;
|
|
|
|
char *last_nonspace = buf;
|
|
|
|
for (p=buf; *p; p++) {
|
|
|
|
if (*p!=' ') last_nonspace = p;
|
|
|
|
}
|
2002-11-17 01:50:51 +03:00
|
|
|
if (last_nonspace != buf) *(last_nonspace+1) = 0;
|
2002-11-14 08:12:28 +03:00
|
|
|
p = buf;
|
2002-11-17 01:50:51 +03:00
|
|
|
bx_bool done = false;
|
|
|
|
while (!done) {
|
2002-11-15 21:53:52 +03:00
|
|
|
//fprintf (stderr, "parsing '%c' with singlequote=%d, dblquote=%d\n", *p, in_single_quote, in_double_quote);
|
2002-11-14 08:12:28 +03:00
|
|
|
switch (*p) {
|
2002-11-17 01:50:51 +03:00
|
|
|
case '\0':
|
|
|
|
done = true;
|
|
|
|
// fall through into behavior for space
|
|
|
|
case ' ':
|
2008-02-06 01:57:43 +03:00
|
|
|
if (in_double_quote || in_single_quote)
|
2002-11-17 01:50:51 +03:00
|
|
|
goto do_default;
|
|
|
|
*outp = 0;
|
|
|
|
//fprintf (stderr, "completed arg %d = '%s'\n", argc, argv[argc]);
|
|
|
|
argc++;
|
|
|
|
if (argc >= max_argv) {
|
|
|
|
fprintf (stderr, "too many arguments. Increase MAX_ARGUMENTS\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
argv[argc] = new char[MAX_ARGLEN];
|
|
|
|
outp = &argv[argc][0];
|
|
|
|
while (*p==' ') p++;
|
|
|
|
break;
|
|
|
|
case '"':
|
|
|
|
if (in_single_quote) goto do_default;
|
|
|
|
in_double_quote = !in_double_quote;
|
|
|
|
p++;
|
|
|
|
break;
|
|
|
|
case '\'':
|
|
|
|
if (in_double_quote) goto do_default;
|
|
|
|
in_single_quote = !in_single_quote;
|
|
|
|
p++;
|
|
|
|
break;
|
|
|
|
do_default:
|
|
|
|
default:
|
|
|
|
if (outp-&argv[argc][0] >= MAX_ARGLEN) {
|
|
|
|
//fprintf (stderr, "command line arg %d exceeded max size %d\n", argc, MAX_ARGLEN);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*(outp++) = *(p++);
|
2002-11-14 08:12:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (in_single_quote) {
|
2002-11-17 01:50:51 +03:00
|
|
|
fprintf (stderr, "end of string with mismatched single quote (')\n");
|
|
|
|
return -1;
|
2002-11-14 08:12:28 +03:00
|
|
|
}
|
|
|
|
if (in_double_quote) {
|
2002-11-17 01:50:51 +03:00
|
|
|
fprintf (stderr, "end of string with mismatched double quote (\")\n");
|
|
|
|
return -1;
|
2002-11-14 08:12:28 +03:00
|
|
|
}
|
2002-11-17 01:50:51 +03:00
|
|
|
*argc_out = argc;
|
2002-11-14 08:12:28 +03:00
|
|
|
return 0;
|
|
|
|
}
|
2002-11-26 21:15:56 +03:00
|
|
|
#endif /* if defined(__WXMSW__) */
|
2002-11-14 08:12:28 +03:00
|
|
|
|
2002-11-26 21:15:56 +03:00
|
|
|
#if defined(__WXMSW__) || (BX_WITH_SDL && defined(WIN32))
|
2002-11-15 21:53:52 +03:00
|
|
|
// The RedirectIOToConsole() function is copied from an article called "Adding
|
|
|
|
// Console I/O to a Win32 GUI App" in Windows Developer Journal, December 1997.
|
2002-11-25 21:17:13 +03:00
|
|
|
// It creates a console window.
|
|
|
|
//
|
|
|
|
// NOTE: It could probably be written so that it can safely be called for all
|
2006-10-15 14:45:15 +04:00
|
|
|
// win32 builds.
|
|
|
|
int RedirectIOToConsole()
|
2002-11-15 21:53:52 +03:00
|
|
|
{
|
|
|
|
int hConHandle;
|
|
|
|
long lStdHandle;
|
|
|
|
FILE *fp;
|
|
|
|
// allocate a console for this app
|
2012-03-02 20:51:45 +04:00
|
|
|
FreeConsole();
|
2006-10-15 14:45:15 +04:00
|
|
|
if (!AllocConsole()) {
|
|
|
|
MessageBox(NULL, "Failed to create text console", "Error", MB_ICONERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
2002-11-15 21:53:52 +03:00
|
|
|
// redirect unbuffered STDOUT to the console
|
|
|
|
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
|
2006-06-22 00:42:26 +04:00
|
|
|
fp = _fdopen(hConHandle, "w");
|
2002-11-15 21:53:52 +03:00
|
|
|
*stdout = *fp;
|
2008-02-15 22:03:54 +03:00
|
|
|
setvbuf(stdout, NULL, _IONBF, 0);
|
2002-11-15 21:53:52 +03:00
|
|
|
// redirect unbuffered STDIN to the console
|
|
|
|
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
|
|
|
|
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
|
2006-06-22 00:42:26 +04:00
|
|
|
fp = _fdopen(hConHandle, "r");
|
2002-11-15 21:53:52 +03:00
|
|
|
*stdin = *fp;
|
2008-02-15 22:03:54 +03:00
|
|
|
setvbuf(stdin, NULL, _IONBF, 0);
|
2002-11-15 21:53:52 +03:00
|
|
|
// redirect unbuffered STDERR to the console
|
|
|
|
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
|
|
|
|
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
|
2008-02-16 01:05:43 +03:00
|
|
|
fp = _fdopen(hConHandle, "w");
|
2002-11-15 21:53:52 +03:00
|
|
|
*stderr = *fp;
|
2006-06-22 00:42:26 +04:00
|
|
|
setvbuf(stderr, NULL, _IONBF, 0);
|
2006-10-15 14:45:15 +04:00
|
|
|
return 1;
|
2002-11-15 21:53:52 +03:00
|
|
|
}
|
2002-11-26 21:15:56 +03:00
|
|
|
#endif /* if defined(__WXMSW__) || (BX_WITH_SDL && defined(WIN32)) */
|
2002-11-14 08:12:28 +03:00
|
|
|
|
2002-11-26 21:15:56 +03:00
|
|
|
#if defined(__WXMSW__)
|
2005-01-05 22:54:32 +03:00
|
|
|
// only used for wxWidgets/win32.
|
|
|
|
// This works ok in Cygwin with a standard wxWidgets compile. In
|
|
|
|
// VC++ wxWidgets must be compiled with -DNOMAIN=1.
|
2002-11-17 01:50:51 +03:00
|
|
|
int WINAPI WinMain(
|
2002-11-01 18:19:48 +03:00
|
|
|
HINSTANCE hInstance,
|
|
|
|
HINSTANCE hPrevInstance,
|
|
|
|
LPSTR m_lpCmdLine, int nCmdShow)
|
|
|
|
{
|
|
|
|
bx_startup_flags.hInstance = hInstance;
|
|
|
|
bx_startup_flags.hPrevInstance = hPrevInstance;
|
|
|
|
bx_startup_flags.m_lpCmdLine = m_lpCmdLine;
|
|
|
|
bx_startup_flags.nCmdShow = nCmdShow;
|
2002-11-14 08:12:28 +03:00
|
|
|
int max_argv = 20;
|
|
|
|
bx_startup_flags.argv = (char**) malloc (max_argv * sizeof (char*));
|
2006-06-22 00:42:26 +04:00
|
|
|
split_string_into_argv(m_lpCmdLine, &bx_startup_flags.argc, bx_startup_flags.argv, max_argv);
|
2012-03-02 20:51:45 +04:00
|
|
|
int arg = 1;
|
|
|
|
bx_bool bx_noconsole = 0;
|
|
|
|
while (arg < bx_startup_flags.argc) {
|
|
|
|
if (!strcmp("-noconsole", bx_startup_flags.argv[arg])) {
|
|
|
|
bx_noconsole = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
arg++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!bx_noconsole) {
|
|
|
|
if (!RedirectIOToConsole()) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
SetConsoleTitle("Bochs for Windows (wxWidgets port) - Console");
|
|
|
|
}
|
2006-06-22 00:42:26 +04:00
|
|
|
return bxmain();
|
2002-11-26 21:15:56 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !defined(__WXMSW__)
|
|
|
|
// normal main function, presently in for all cases except for
|
2005-01-05 22:54:32 +03:00
|
|
|
// wxWidgets under win32.
|
2008-04-08 00:20:04 +04:00
|
|
|
int CDECL main(int argc, char *argv[])
|
2002-11-26 21:15:56 +03:00
|
|
|
{
|
|
|
|
bx_startup_flags.argc = argc;
|
|
|
|
bx_startup_flags.argv = argv;
|
2012-03-02 20:51:45 +04:00
|
|
|
#ifdef WIN32
|
|
|
|
int arg = 1;
|
|
|
|
bx_bool bx_noconsole = 0;
|
|
|
|
while (arg < argc) {
|
|
|
|
if (!strcmp("-noconsole", argv[arg])) {
|
|
|
|
bx_noconsole = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
arg++;
|
2006-10-15 14:45:15 +04:00
|
|
|
}
|
2012-03-02 20:51:45 +04:00
|
|
|
|
|
|
|
if (bx_noconsole) {
|
|
|
|
FreeConsole();
|
|
|
|
} else {
|
|
|
|
#if BX_WITH_SDL
|
|
|
|
// if SDL/win32, try to create a console window.
|
|
|
|
if (!RedirectIOToConsole()) {
|
|
|
|
return 1;
|
|
|
|
}
|
2005-08-20 20:41:41 +04:00
|
|
|
#endif
|
2012-03-02 20:51:45 +04:00
|
|
|
SetConsoleTitle("Bochs for Windows - Console");
|
|
|
|
}
|
2002-11-26 21:15:56 +03:00
|
|
|
#endif
|
2006-06-22 00:42:26 +04:00
|
|
|
return bxmain();
|
2002-11-01 18:19:48 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-04-08 00:20:04 +04:00
|
|
|
void print_usage(void)
|
2001-04-10 05:04:59 +04:00
|
|
|
{
|
2008-02-06 01:57:43 +03:00
|
|
|
fprintf(stderr,
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
"Usage: bochs [flags] [bochsrc options]\n\n"
|
2002-11-24 16:41:07 +03:00
|
|
|
" -n no configuration file\n"
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
" -f configfile specify configuration file\n"
|
2002-11-15 17:47:58 +03:00
|
|
|
" -q quick start (skip configuration interface)\n"
|
2007-09-22 19:59:41 +04:00
|
|
|
" -benchmark n run bochs in benchmark mode for millions of emulated ticks\n"
|
2006-05-27 19:54:49 +04:00
|
|
|
" -r path restore the Bochs state from path\n"
|
2008-10-18 21:12:37 +04:00
|
|
|
" -log filename specify Bochs log file name\n"
|
2006-10-24 21:53:47 +04:00
|
|
|
#if BX_DEBUGGER
|
|
|
|
" -rc filename execute debugger commands stored in file\n"
|
2008-10-18 21:12:37 +04:00
|
|
|
" -dbglog filename specify Bochs internal debugger log file name\n"
|
2012-03-02 20:51:45 +04:00
|
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
|
|
" -noconsole disable console window\n"
|
2006-04-07 00:42:51 +04:00
|
|
|
#endif
|
2011-08-22 08:07:10 +04:00
|
|
|
" --help display this help and exit\n"
|
2012-07-07 14:49:46 +04:00
|
|
|
" --help features display available features / devices and exit\n"
|
2011-08-22 08:07:10 +04:00
|
|
|
#if BX_CPU_LEVEL > 4
|
|
|
|
" --help cpu display supported CPU models and exit\n"
|
|
|
|
#endif
|
|
|
|
"\nFor information on Bochs configuration file arguments, see the\n"
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
#if (!defined(WIN32)) && !BX_WITH_MACOS
|
|
|
|
"bochsrc section in the user documentation or the man page of bochsrc.\n");
|
|
|
|
#else
|
|
|
|
"bochsrc section in the user documentation.\n");
|
2002-08-25 19:51:46 +04:00
|
|
|
#endif
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
}
|
2002-08-25 12:31:16 +04:00
|
|
|
|
2007-10-16 20:17:48 +04:00
|
|
|
int bx_init_main(int argc, char *argv[])
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
{
|
2001-06-10 00:01:12 +04:00
|
|
|
// To deal with initialization order problems inherent in C++, use the macros
|
|
|
|
// SAFE_GET_IOFUNC and SAFE_GET_GENLOG to retrieve "io" and "genlog" in all
|
|
|
|
// constructors or functions called by constructors. The macros test for
|
|
|
|
// NULL and create the object if necessary, then return it. Ensure that io
|
|
|
|
// and genlog get created, by making one reference to each macro right here.
|
2002-08-31 01:41:29 +04:00
|
|
|
// All other code can reference io and genlog directly. Because these
|
|
|
|
// objects are required for logging, and logging is so fundamental to
|
|
|
|
// knowing what the program is doing, they are never free()d.
|
|
|
|
SAFE_GET_IOFUNC(); // never freed
|
|
|
|
SAFE_GET_GENLOG(); // never freed
|
merge in BRANCH-io-cleanup.
To see the commit logs for this use either cvsweb or
cvs update -r BRANCH-io-cleanup and then 'cvs log' the various files.
In general this provides a generic interface for logging.
logfunctions:: is a class that is inherited by some classes, and also
. allocated as a standalone global called 'genlog'. All logging uses
. one of the ::info(), ::error(), ::ldebug(), ::panic() methods of this
. class through 'BX_INFO(), BX_ERROR(), BX_DEBUG(), BX_PANIC()' macros
. respectively.
.
. An example usage:
. BX_INFO(("Hello, World!\n"));
iofunctions:: is a class that is allocated once by default, and assigned
as the iofunction of each logfunctions instance. It is this class that
maintains the file descriptor and other output related code, at this
point using vfprintf(). At some future point, someone may choose to
write a gui 'console' for bochs to which messages would be redirected
simply by assigning a different iofunction class to the various logfunctions
objects.
More cleanup is coming, but this works for now. If you want to see alot
of debugging output, in main.cc, change onoff[LOGLEV_DEBUG]=0 to =1.
Comments, bugs, flames, to me: todd@fries.net
2001-05-15 18:49:57 +04:00
|
|
|
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
// initalization must be done early because some destructors expect
|
2006-03-05 13:24:29 +03:00
|
|
|
// the bochs config options to exist by the time they are called.
|
|
|
|
bx_init_bx_dbg();
|
|
|
|
bx_init_options();
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
|
2006-03-05 13:24:29 +03:00
|
|
|
bx_print_header();
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
|
2006-03-05 13:24:29 +03:00
|
|
|
SIM->get_param_enum(BXPN_BOCHS_START)->set(BX_RUN_START);
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
|
|
|
|
// interpret the args that start with -, like -q, -f, etc.
|
2011-08-22 08:07:10 +04:00
|
|
|
int arg = 1, load_rcfile=1, i = 0;
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
while (arg < argc) {
|
|
|
|
// parse next arg
|
2006-10-24 21:53:47 +04:00
|
|
|
if (!strcmp("--help", argv[arg]) || !strncmp("-h", argv[arg], 2)
|
2005-08-07 13:03:15 +04:00
|
|
|
#if defined(WIN32)
|
2006-10-24 21:53:47 +04:00
|
|
|
|| !strncmp("/?", argv[arg], 2)
|
2005-08-07 13:03:15 +04:00
|
|
|
#endif
|
|
|
|
) {
|
2011-08-22 08:07:10 +04:00
|
|
|
if ((arg+1) < argc) {
|
2012-07-07 14:49:46 +04:00
|
|
|
if (!strcmp("features", argv[arg+1])) {
|
|
|
|
fprintf(stderr, "Supported features:\n\n");
|
|
|
|
#if BX_SUPPORT_CLGD54XX
|
|
|
|
fprintf(stderr, "cirrus\n");
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_PCI
|
|
|
|
fprintf(stderr, "pci\n");
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_PCIDEV
|
|
|
|
fprintf(stderr, "pcidev\n");
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_NE2K
|
|
|
|
fprintf(stderr, "ne2k\n");
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_PCIPNIC
|
|
|
|
fprintf(stderr, "pcipnic\n");
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_E1000
|
|
|
|
fprintf(stderr, "e1000\n");
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_SB16
|
|
|
|
fprintf(stderr, "sb16\n");
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_ES1370
|
|
|
|
fprintf(stderr, "es1370\n");
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_USB_OHCI
|
|
|
|
fprintf(stderr, "usb_ohci\n");
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_USB_UHCI
|
|
|
|
fprintf(stderr, "usb_uhci\n");
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_USB_XHCI
|
|
|
|
fprintf(stderr, "usb_xhci\n");
|
|
|
|
#endif
|
|
|
|
#if BX_GDBSTUB
|
|
|
|
fprintf(stderr, "gdbstub\n");
|
|
|
|
#endif
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
arg++;
|
|
|
|
}
|
|
|
|
#if BX_CPU_LEVEL > 4
|
|
|
|
else if (!strcmp("cpu", argv[arg+1])) {
|
2011-08-22 08:07:10 +04:00
|
|
|
fprintf(stderr, "Supported CPU models:\n\n");
|
|
|
|
do {
|
|
|
|
fprintf(stderr, "%s\n", SIM->get_param_enum(BXPN_CPU_MODEL)->get_choice(i));
|
|
|
|
} while (i++ < SIM->get_param_enum(BXPN_CPU_MODEL)->get_max());
|
2011-08-29 00:14:53 +04:00
|
|
|
fprintf(stderr, "\n");
|
2011-08-22 08:07:10 +04:00
|
|
|
arg++;
|
|
|
|
}
|
|
|
|
#endif
|
2012-07-07 14:49:46 +04:00
|
|
|
} else {
|
2011-08-22 08:07:10 +04:00
|
|
|
print_usage();
|
|
|
|
}
|
2006-10-24 21:53:47 +04:00
|
|
|
SIM->quit_sim(0);
|
2002-08-25 19:51:46 +04:00
|
|
|
}
|
2006-10-24 21:53:47 +04:00
|
|
|
else if (!strcmp("-n", argv[arg])) {
|
2002-11-24 16:41:07 +03:00
|
|
|
load_rcfile = 0;
|
|
|
|
}
|
2006-10-24 21:53:47 +04:00
|
|
|
else if (!strcmp("-q", argv[arg])) {
|
2006-03-05 13:24:29 +03:00
|
|
|
SIM->get_param_enum(BXPN_BOCHS_START)->set(BX_QUICK_START);
|
2002-08-25 19:51:46 +04:00
|
|
|
}
|
2008-10-18 21:12:37 +04:00
|
|
|
else if (!strcmp("-log", argv[arg])) {
|
|
|
|
if (++arg >= argc) BX_PANIC(("-log must be followed by a filename"));
|
|
|
|
else SIM->get_param_string(BXPN_LOG_FILENAME)->set(argv[arg]);
|
|
|
|
}
|
|
|
|
#if BX_DEBUGGER
|
|
|
|
else if (!strcmp("-dbglog", argv[arg])) {
|
|
|
|
if (++arg >= argc) BX_PANIC(("-dbglog must be followed by a filename"));
|
|
|
|
else SIM->get_param_string(BXPN_DEBUGGER_LOG_FILENAME)->set(argv[arg]);
|
|
|
|
}
|
|
|
|
#endif
|
2006-10-24 21:53:47 +04:00
|
|
|
else if (!strcmp("-f", argv[arg])) {
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
if (++arg >= argc) BX_PANIC(("-f must be followed by a filename"));
|
|
|
|
else bochsrc_filename = argv[arg];
|
2002-09-25 23:05:01 +04:00
|
|
|
}
|
2006-10-24 21:53:47 +04:00
|
|
|
else if (!strcmp("-qf", argv[arg])) {
|
2006-03-05 13:24:29 +03:00
|
|
|
SIM->get_param_enum(BXPN_BOCHS_START)->set(BX_QUICK_START);
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
if (++arg >= argc) BX_PANIC(("-qf must be followed by a filename"));
|
|
|
|
else bochsrc_filename = argv[arg];
|
2002-08-18 20:59:26 +04:00
|
|
|
}
|
2007-09-22 19:59:41 +04:00
|
|
|
else if (!strcmp("-benchmark", argv[arg])) {
|
|
|
|
SIM->get_param_enum(BXPN_BOCHS_START)->set(BX_QUICK_START);
|
|
|
|
if (++arg >= argc) BX_PANIC(("-benchmark must be followed by a number"));
|
|
|
|
else SIM->get_param_num(BXPN_BOCHS_BENCHMARK)->set(atoi(argv[arg]));
|
|
|
|
}
|
2006-10-24 21:53:47 +04:00
|
|
|
else if (!strcmp("-r", argv[arg])) {
|
2006-04-07 00:42:51 +04:00
|
|
|
if (++arg >= argc) BX_PANIC(("-r must be followed by a path"));
|
|
|
|
else {
|
|
|
|
SIM->get_param_enum(BXPN_BOCHS_START)->set(BX_QUICK_START);
|
|
|
|
SIM->get_param_bool(BXPN_RESTORE_FLAG)->set(1);
|
|
|
|
SIM->get_param_string(BXPN_RESTORE_PATH)->set(argv[arg]);
|
|
|
|
}
|
|
|
|
}
|
2012-03-02 20:51:45 +04:00
|
|
|
#ifdef WIN32
|
|
|
|
else if (!strcmp("-noconsole", argv[arg])) {
|
|
|
|
// already handled in main() / WinMain()
|
|
|
|
}
|
|
|
|
#endif
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
#if BX_WITH_CARBON
|
2006-10-24 21:53:47 +04:00
|
|
|
else if (!strncmp("-psn", argv[arg], 4)) {
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
// "-psn" is passed if we are launched by double-clicking
|
|
|
|
// ugly hack. I don't know how to open a window to print messages in,
|
|
|
|
// so put them in /tmp/early-bochs-out.txt. Sorry. -bbd
|
|
|
|
io->init_log("/tmp/early-bochs-out.txt");
|
|
|
|
BX_INFO (("I was launched by double clicking. Fixing home directory."));
|
|
|
|
arg = argc; // ignore all other args.
|
|
|
|
setupWorkingDirectory (argv[0]);
|
|
|
|
// there is no stdin/stdout so disable the text-based config interface.
|
2006-03-05 13:24:29 +03:00
|
|
|
SIM->get_param_enum(BXPN_BOCHS_START)->set(BX_QUICK_START);
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
char cwd[MAXPATHLEN];
|
2003-10-02 15:33:42 +04:00
|
|
|
getwd (cwd);
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
BX_INFO (("Now my working directory is %s", cwd));
|
|
|
|
// if it was started from command line, there could be some args still.
|
|
|
|
for (int a=0; a<argc; a++) {
|
|
|
|
BX_INFO (("argument %d is %s", a, argv[a]));
|
|
|
|
}
|
2002-07-14 17:22:38 +04:00
|
|
|
}
|
2006-10-24 21:53:47 +04:00
|
|
|
#endif
|
|
|
|
#if BX_DEBUGGER
|
|
|
|
else if (!strcmp("-rc", argv[arg])) {
|
|
|
|
// process "-rc filename" option, if it exists
|
|
|
|
if (++arg >= argc) BX_PANIC(("-rc must be followed by a filename"));
|
|
|
|
else bx_dbg_set_rcfile(argv[arg]);
|
|
|
|
}
|
2001-06-10 00:01:12 +04:00
|
|
|
#endif
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
else if (argv[arg][0] == '-') {
|
|
|
|
print_usage();
|
|
|
|
BX_PANIC (("command line arg '%s' was not understood", argv[arg]));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// the arg did not start with -, so stop interpreting flags
|
|
|
|
break;
|
2001-06-10 00:01:12 +04:00
|
|
|
}
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
arg++;
|
2001-06-10 00:01:12 +04:00
|
|
|
}
|
2002-12-17 23:58:18 +03:00
|
|
|
#if BX_WITH_CARBON
|
|
|
|
if(!getenv("BXSHARE"))
|
|
|
|
{
|
|
|
|
CFBundleRef mainBundle;
|
|
|
|
CFURLRef bxshareDir;
|
|
|
|
char bxshareDirPath[MAXPATHLEN];
|
|
|
|
BX_INFO (("fixing default bxshare location ..."));
|
|
|
|
// set bxshare to the directory that contains our application
|
|
|
|
mainBundle = CFBundleGetMainBundle();
|
|
|
|
BX_ASSERT(mainBundle != NULL);
|
|
|
|
bxshareDir = CFBundleCopyBundleURL(mainBundle);
|
|
|
|
BX_ASSERT(bxshareDir != NULL);
|
|
|
|
// translate this to a unix style full path
|
|
|
|
if(!CFURLGetFileSystemRepresentation(bxshareDir, true, (UInt8 *)bxshareDirPath, MAXPATHLEN))
|
|
|
|
{
|
|
|
|
BX_PANIC(("Unable to work out bxshare path! (Most likely path too long!)"));
|
|
|
|
return -1;
|
|
|
|
}
|
2008-02-06 01:57:43 +03:00
|
|
|
char *c;
|
2002-12-17 23:58:18 +03:00
|
|
|
c = (char*) bxshareDirPath;
|
|
|
|
while (*c != '\0') /* go to end */
|
|
|
|
c++;
|
|
|
|
while (*c != '/') /* back up to parent */
|
|
|
|
c--;
|
|
|
|
*c = '\0'; /* cut off last part (binary name) */
|
|
|
|
setenv("BXSHARE", bxshareDirPath, 1);
|
|
|
|
BX_INFO (("now my BXSHARE is %s", getenv("BXSHARE")));
|
|
|
|
CFRelease(bxshareDir);
|
|
|
|
}
|
|
|
|
#endif
|
2002-11-18 05:32:53 +03:00
|
|
|
#if BX_PLUGINS
|
|
|
|
// set a default plugin path, in case the user did not specify one
|
|
|
|
#if BX_WITH_CARBON
|
2002-11-01 20:53:52 +03:00
|
|
|
// if there is no stdin, then we must create our own LTDL_LIBRARY_PATH.
|
|
|
|
// also if there is no LTDL_LIBRARY_PATH, but we have a bundle since we're here
|
|
|
|
// This is here so that it is available whenever --with-carbon is defined but
|
|
|
|
// the above code might be skipped, as in --with-sdl --with-carbon
|
|
|
|
if(!isatty(STDIN_FILENO) || !getenv("LTDL_LIBRARY_PATH"))
|
|
|
|
{
|
|
|
|
CFBundleRef mainBundle;
|
|
|
|
CFURLRef libDir;
|
2002-11-23 15:35:42 +03:00
|
|
|
char libDirPath[MAXPATHLEN];
|
2002-11-01 20:53:52 +03:00
|
|
|
if(!isatty(STDIN_FILENO))
|
|
|
|
{
|
|
|
|
// there is no stdin/stdout so disable the text-based config interface.
|
2006-03-05 13:24:29 +03:00
|
|
|
SIM->get_param_enum(BXPN_BOCHS_START)->set(BX_QUICK_START);
|
2002-11-01 20:53:52 +03:00
|
|
|
}
|
|
|
|
BX_INFO (("fixing default lib location ..."));
|
|
|
|
// locate the lib directory within the application bundle.
|
|
|
|
// our libs have been placed in bochs.app/Contents/(current platform aka MacOS)/lib
|
|
|
|
// This isn't quite right, but they are platform specific and we haven't put
|
|
|
|
// our plugins into true frameworks and bundles either
|
|
|
|
mainBundle = CFBundleGetMainBundle();
|
|
|
|
BX_ASSERT(mainBundle != NULL);
|
2008-02-16 01:05:43 +03:00
|
|
|
libDir = CFBundleCopyAuxiliaryExecutableURL(mainBundle, CFSTR("lib"));
|
2002-11-01 20:53:52 +03:00
|
|
|
BX_ASSERT(libDir != NULL);
|
|
|
|
// translate this to a unix style full path
|
2002-11-23 15:35:42 +03:00
|
|
|
if(!CFURLGetFileSystemRepresentation(libDir, true, (UInt8 *)libDirPath, MAXPATHLEN))
|
2002-11-01 20:53:52 +03:00
|
|
|
{
|
|
|
|
BX_PANIC(("Unable to work out ltdl library path within bochs bundle! (Most likely path too long!)"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
setenv("LTDL_LIBRARY_PATH", libDirPath, 1);
|
2002-11-23 15:35:42 +03:00
|
|
|
BX_INFO (("now my LTDL_LIBRARY_PATH is %s", getenv("LTDL_LIBRARY_PATH")));
|
2002-11-01 20:53:52 +03:00
|
|
|
CFRelease(libDir);
|
|
|
|
}
|
2002-11-18 05:32:53 +03:00
|
|
|
#elif BX_HAVE_GETENV && BX_HAVE_SETENV
|
|
|
|
if (getenv("LTDL_LIBRARY_PATH") != NULL) {
|
|
|
|
BX_INFO (("LTDL_LIBRARY_PATH is set to '%s'", getenv("LTDL_LIBRARY_PATH")));
|
|
|
|
} else {
|
2008-02-06 01:57:43 +03:00
|
|
|
BX_INFO (("LTDL_LIBRARY_PATH not set. using compile time default '%s'",
|
2003-02-07 02:16:56 +03:00
|
|
|
BX_PLUGIN_PATH));
|
2002-11-18 05:32:53 +03:00
|
|
|
setenv("LTDL_LIBRARY_PATH", BX_PLUGIN_PATH, 1);
|
|
|
|
}
|
2002-12-15 01:18:00 +03:00
|
|
|
if (getenv("BXSHARE") != NULL) {
|
|
|
|
BX_INFO (("BXSHARE is set to '%s'", getenv("BXSHARE")));
|
2002-11-25 21:00:05 +03:00
|
|
|
} else {
|
2008-02-06 01:57:43 +03:00
|
|
|
BX_INFO (("BXSHARE not set. using compile time default '%s'",
|
2003-02-07 02:16:56 +03:00
|
|
|
BX_SHARE_PATH));
|
2002-12-15 01:18:00 +03:00
|
|
|
setenv("BXSHARE", BX_SHARE_PATH, 1);
|
2002-11-25 21:00:05 +03:00
|
|
|
}
|
2002-11-18 05:32:53 +03:00
|
|
|
#else
|
|
|
|
// we don't have getenv or setenv. Do nothing.
|
2002-11-01 20:53:52 +03:00
|
|
|
#endif
|
2002-11-18 05:32:53 +03:00
|
|
|
#endif /* if BX_PLUGINS */
|
2002-11-09 17:12:10 +03:00
|
|
|
|
2009-01-05 00:46:20 +03:00
|
|
|
// initialize plugin system. This must happen before we attempt to
|
|
|
|
// load any modules.
|
|
|
|
plugin_startup();
|
|
|
|
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
int norcfile = 1;
|
2002-11-24 16:41:07 +03:00
|
|
|
|
2006-04-07 16:49:50 +04:00
|
|
|
if (SIM->get_param_bool(BXPN_RESTORE_FLAG)->get()) {
|
|
|
|
load_rcfile = 0;
|
|
|
|
norcfile = 0;
|
|
|
|
}
|
2012-07-14 19:48:48 +04:00
|
|
|
// load pre-defined optional plugins before parsing configuration
|
|
|
|
SIM->opt_plugin_ctrl("*", 1);
|
2012-08-19 15:45:50 +04:00
|
|
|
SIM->init_save_restore();
|
2002-11-24 16:41:07 +03:00
|
|
|
if (load_rcfile) {
|
2012-07-06 21:19:32 +04:00
|
|
|
// parse configuration file and command line arguments
|
2004-02-04 22:54:58 +03:00
|
|
|
#ifdef WIN32
|
2004-02-18 00:40:05 +03:00
|
|
|
int length;
|
2004-02-04 22:54:58 +03:00
|
|
|
if (bochsrc_filename != NULL) {
|
2004-02-26 21:12:21 +03:00
|
|
|
lstrcpy(bx_startup_flags.initial_dir, bochsrc_filename);
|
|
|
|
length = lstrlen(bx_startup_flags.initial_dir);
|
|
|
|
while ((length > 1) && (bx_startup_flags.initial_dir[length-1] != 92)) length--;
|
2004-02-18 00:40:05 +03:00
|
|
|
bx_startup_flags.initial_dir[length] = 0;
|
2004-02-04 22:54:58 +03:00
|
|
|
} else {
|
|
|
|
bx_startup_flags.initial_dir[0] = 0;
|
|
|
|
}
|
|
|
|
#endif
|
2002-11-24 16:41:07 +03:00
|
|
|
if (bochsrc_filename == NULL) bochsrc_filename = bx_find_bochsrc ();
|
|
|
|
if (bochsrc_filename)
|
2006-06-22 00:42:26 +04:00
|
|
|
norcfile = bx_read_configuration(bochsrc_filename);
|
2002-11-24 16:41:07 +03:00
|
|
|
}
|
2002-11-09 17:12:10 +03:00
|
|
|
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
if (norcfile) {
|
|
|
|
// No configuration was loaded, so the current settings are unusable.
|
|
|
|
// Switch off quick start so that we will drop into the configuration
|
|
|
|
// interface.
|
2006-03-05 13:24:29 +03:00
|
|
|
if (SIM->get_param_enum(BXPN_BOCHS_START)->get() == BX_QUICK_START) {
|
|
|
|
if (!SIM->test_for_text_console())
|
2002-12-17 08:58:45 +03:00
|
|
|
BX_PANIC(("Unable to start Bochs without a bochsrc.txt and without a text console"));
|
2008-02-06 01:57:43 +03:00
|
|
|
else
|
2006-05-27 19:54:49 +04:00
|
|
|
BX_ERROR(("Switching off quick start, because no configuration file was found."));
|
2002-11-15 17:47:58 +03:00
|
|
|
}
|
2006-03-05 13:24:29 +03:00
|
|
|
SIM->get_param_enum(BXPN_BOCHS_START)->set(BX_LOAD_START);
|
2001-10-07 02:31:31 +04:00
|
|
|
}
|
2002-11-09 17:12:10 +03:00
|
|
|
|
2006-05-27 19:54:49 +04:00
|
|
|
if (SIM->get_param_bool(BXPN_RESTORE_FLAG)->get()) {
|
|
|
|
if (arg < argc) {
|
|
|
|
BX_ERROR(("WARNING: bochsrc options are ignored in restore mode!"));
|
|
|
|
}
|
|
|
|
}
|
2007-09-28 23:52:08 +04:00
|
|
|
else {
|
2006-05-27 19:54:49 +04:00
|
|
|
// parse the rest of the command line. This is done after reading the
|
|
|
|
// configuration file so that the command line arguments can override
|
|
|
|
// the settings from the file.
|
|
|
|
if (bx_parse_cmdline(arg, argc, argv)) {
|
|
|
|
BX_PANIC(("There were errors while parsing the command line"));
|
|
|
|
return -1;
|
|
|
|
}
|
2001-10-07 02:31:31 +04:00
|
|
|
}
|
- clean up the command line argument parsing. Before, we had two slightly
different versions of the code for wxWindows and non-wxWindows and the GDB
stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
1) read the bochsrc immediately, 2) start simulation immediately without
going into the config interface. This has changed in a subtle way.
Now, we always try to read the bochsrc immediately. Then if the quick
start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu. It was
already there in wx. Now the default choice is always "5. Begin simulation"
and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
or wx interfaces, reset all bochs parameters first, then read in the
new file. This means that every time you read a configuration file
you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
so that wxWindows and non-wxWindows code uses the same logic. There was
only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
a big if/else. This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
devices) was only called if the configuration interface was on; I'm not
sure why. Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit. Now OnInit
and main() are very similar. They both call bx_init_siminterface, then
bx_init_main (and quit if it fails), then show the config interface if
quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
2002-10-14 17:37:20 +04:00
|
|
|
return 0;
|
2002-04-18 04:22:20 +04:00
|
|
|
}
|
|
|
|
|
2008-04-08 00:20:04 +04:00
|
|
|
bx_bool load_and_init_display_lib(void)
|
2005-04-16 23:37:53 +04:00
|
|
|
{
|
2002-10-25 01:07:56 +04:00
|
|
|
if (bx_gui != NULL) {
|
|
|
|
// bx_gui has already been filled in. This happens when you start
|
|
|
|
// the simulation for the second time.
|
2005-01-05 22:54:32 +03:00
|
|
|
// Also, if you load wxWidgets as the configuration interface. Its
|
|
|
|
// plugin_init will install wxWidgets as the bx_gui.
|
2002-10-25 01:07:56 +04:00
|
|
|
return true;
|
|
|
|
}
|
2006-02-22 00:35:09 +03:00
|
|
|
BX_ASSERT(bx_gui == NULL);
|
|
|
|
bx_param_enum_c *ci_param = SIM->get_param_enum(BXPN_SEL_CONFIG_INTERFACE);
|
2007-10-25 03:29:40 +04:00
|
|
|
const char *ci_name = ci_param->get_selected();
|
2006-02-22 00:35:09 +03:00
|
|
|
bx_param_enum_c *gui_param = SIM->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY);
|
2007-10-25 03:29:40 +04:00
|
|
|
const char *gui_name = gui_param->get_selected();
|
2003-07-10 23:13:28 +04:00
|
|
|
if (!strcmp(ci_name, "wx")) {
|
|
|
|
BX_ERROR(("change of the config interface to wx not implemented yet"));
|
|
|
|
}
|
2006-02-22 00:35:09 +03:00
|
|
|
if (!strcmp(gui_name, "wx")) {
|
2002-10-25 01:07:56 +04:00
|
|
|
// they must not have used wx as the configuration interface, or bx_gui
|
|
|
|
// would already be initialized. Sorry, it doesn't work that way.
|
2006-02-22 00:35:09 +03:00
|
|
|
BX_ERROR(("wxWidgets was not used as the configuration interface, so it cannot be used as the display library"));
|
2002-10-25 01:07:56 +04:00
|
|
|
// choose another, hopefully different!
|
|
|
|
gui_param->set (0);
|
2006-02-22 00:35:09 +03:00
|
|
|
gui_name = gui_param->get_selected();
|
2002-10-25 01:07:56 +04:00
|
|
|
if (!strcmp (gui_name, "wx")) {
|
2006-02-22 00:35:09 +03:00
|
|
|
BX_PANIC(("no alternative display libraries are available"));
|
2002-10-25 01:07:56 +04:00
|
|
|
return false;
|
|
|
|
}
|
2006-02-22 00:35:09 +03:00
|
|
|
BX_ERROR(("changing display library to '%s' instead", gui_name));
|
2002-10-25 01:07:56 +04:00
|
|
|
}
|
|
|
|
#if BX_WITH_AMIGAOS
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(gui_name, "amigaos"))
|
2002-10-25 01:07:56 +04:00
|
|
|
PLUG_load_plugin (amigaos, PLUGTYPE_OPTIONAL);
|
|
|
|
#endif
|
|
|
|
#if BX_WITH_CARBON
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(gui_name, "carbon"))
|
2002-10-25 01:07:56 +04:00
|
|
|
PLUG_load_plugin (carbon, PLUGTYPE_OPTIONAL);
|
|
|
|
#endif
|
|
|
|
#if BX_WITH_MACOS
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(gui_name, "macos"))
|
2002-10-25 01:07:56 +04:00
|
|
|
PLUG_load_plugin (macintosh, PLUGTYPE_OPTIONAL);
|
|
|
|
#endif
|
|
|
|
#if BX_WITH_NOGUI
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(gui_name, "nogui"))
|
2002-10-25 01:07:56 +04:00
|
|
|
PLUG_load_plugin (nogui, PLUGTYPE_OPTIONAL);
|
|
|
|
#endif
|
|
|
|
#if BX_WITH_RFB
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(gui_name, "rfb"))
|
2002-10-25 01:07:56 +04:00
|
|
|
PLUG_load_plugin (rfb, PLUGTYPE_OPTIONAL);
|
|
|
|
#endif
|
|
|
|
#if BX_WITH_SDL
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(gui_name, "sdl"))
|
2002-10-25 01:07:56 +04:00
|
|
|
PLUG_load_plugin (sdl, PLUGTYPE_OPTIONAL);
|
|
|
|
#endif
|
2002-11-21 22:26:07 +03:00
|
|
|
#if BX_WITH_SVGA
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(gui_name, "svga"))
|
2002-11-21 22:26:07 +03:00
|
|
|
PLUG_load_plugin (svga, PLUGTYPE_OPTIONAL);
|
|
|
|
#endif
|
2002-10-25 01:07:56 +04:00
|
|
|
#if BX_WITH_TERM
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(gui_name, "term"))
|
2002-10-25 01:07:56 +04:00
|
|
|
PLUG_load_plugin (term, PLUGTYPE_OPTIONAL);
|
|
|
|
#endif
|
|
|
|
#if BX_WITH_WIN32
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(gui_name, "win32"))
|
2002-10-25 01:07:56 +04:00
|
|
|
PLUG_load_plugin (win32, PLUGTYPE_OPTIONAL);
|
|
|
|
#endif
|
|
|
|
#if BX_WITH_X11
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(gui_name, "x"))
|
2002-10-25 01:07:56 +04:00
|
|
|
PLUG_load_plugin (x, PLUGTYPE_OPTIONAL);
|
|
|
|
#endif
|
2002-11-11 20:09:57 +03:00
|
|
|
|
|
|
|
#if BX_GUI_SIGHANDLER
|
|
|
|
// set the flag for guis requiring a GUI sighandler.
|
|
|
|
// useful when guis are compiled as plugins
|
|
|
|
// only term for now
|
2006-02-22 00:35:09 +03:00
|
|
|
if (!strcmp(gui_name, "term")) {
|
2002-11-11 20:09:57 +03:00
|
|
|
bx_gui_sighandler = 1;
|
2006-02-22 00:35:09 +03:00
|
|
|
}
|
2002-11-11 20:09:57 +03:00
|
|
|
#endif
|
|
|
|
|
2006-02-22 00:35:09 +03:00
|
|
|
BX_ASSERT(bx_gui != NULL);
|
2002-10-25 01:07:56 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2006-02-11 18:28:43 +03:00
|
|
|
int bx_begin_simulation (int argc, char *argv[])
|
2002-04-18 04:22:20 +04:00
|
|
|
{
|
2006-04-07 00:42:51 +04:00
|
|
|
if (SIM->get_param_bool(BXPN_RESTORE_FLAG)->get()) {
|
2006-05-28 20:39:25 +04:00
|
|
|
if (!SIM->restore_config()) {
|
|
|
|
BX_PANIC(("cannot restore configuration"));
|
|
|
|
SIM->get_param_bool(BXPN_RESTORE_FLAG)->set(0);
|
|
|
|
}
|
2012-07-06 21:19:32 +04:00
|
|
|
} else {
|
|
|
|
// make sure all optional plugins have been loaded
|
|
|
|
SIM->opt_plugin_ctrl("*", 1);
|
2006-04-07 00:42:51 +04:00
|
|
|
}
|
2007-09-28 23:52:08 +04:00
|
|
|
|
2002-10-25 01:07:56 +04:00
|
|
|
// deal with gui selection
|
|
|
|
if (!load_and_init_display_lib ()) {
|
|
|
|
BX_PANIC (("no gui module was loaded"));
|
|
|
|
return 0;
|
|
|
|
}
|
2006-02-11 18:28:43 +03:00
|
|
|
|
2006-02-18 19:53:18 +03:00
|
|
|
bx_cpu_count = SIM->get_param_num(BXPN_CPU_NPROCESSORS)->get() *
|
|
|
|
SIM->get_param_num(BXPN_CPU_NCORES)->get() *
|
|
|
|
SIM->get_param_num(BXPN_CPU_NTHREADS)->get();
|
2006-02-11 18:28:43 +03:00
|
|
|
|
2011-04-21 17:27:42 +04:00
|
|
|
#if BX_SUPPORT_APIC
|
|
|
|
simulate_xapic = (SIM->get_param_enum(BXPN_CPUID_APIC)->get() >= BX_CPUID_SUPPORT_XAPIC);
|
2006-02-11 18:28:43 +03:00
|
|
|
|
2010-02-28 17:52:17 +03:00
|
|
|
// For P6 and Pentium family processors the local APIC ID feild is 4 bits
|
|
|
|
// APIC_MAX_ID indicate broadcast so it can't be used as valid APIC ID
|
2010-04-03 14:14:42 +04:00
|
|
|
apic_id_mask = simulate_xapic ? 0xFF : 0xF;
|
2010-02-28 17:52:17 +03:00
|
|
|
|
|
|
|
// leave one APIC ID to I/O APIC
|
|
|
|
unsigned max_smp_threads = apic_id_mask - 1;
|
|
|
|
if (bx_cpu_count > max_smp_threads) {
|
|
|
|
BX_PANIC(("cpu: too many SMP threads defined, only %u threads supported by %sAPIC",
|
2010-04-03 14:14:42 +04:00
|
|
|
max_smp_threads, simulate_xapic ? "x" : "legacy "));
|
2010-02-28 17:52:17 +03:00
|
|
|
}
|
2011-04-21 17:27:42 +04:00
|
|
|
#endif
|
2010-02-28 17:52:17 +03:00
|
|
|
|
|
|
|
BX_ASSERT(bx_cpu_count > 0);
|
2010-02-26 01:04:31 +03:00
|
|
|
|
2006-05-30 23:46:31 +04:00
|
|
|
bx_init_hardware();
|
|
|
|
|
|
|
|
if (SIM->get_param_enum(BXPN_LOAD32BITOS_WHICH)->get()) {
|
|
|
|
void bx_load32bitOSimagehack(void);
|
|
|
|
bx_load32bitOSimagehack();
|
|
|
|
}
|
|
|
|
|
|
|
|
SIM->set_init_done(1);
|
|
|
|
|
|
|
|
// update headerbar buttons since drive status can change during init
|
|
|
|
bx_gui->update_drive_status_buttons();
|
2007-09-28 23:52:08 +04:00
|
|
|
|
2006-05-30 23:46:31 +04:00
|
|
|
// iniialize statusbar and set all items inactive
|
2006-09-07 22:50:51 +04:00
|
|
|
if (!SIM->get_param_bool(BXPN_RESTORE_FLAG)->get())
|
|
|
|
{
|
2006-07-21 22:26:53 +04:00
|
|
|
bx_gui->statusbar_setitem(-1, 0);
|
|
|
|
}
|
2006-05-30 23:46:31 +04:00
|
|
|
|
|
|
|
// The set handler for mouse_enabled does not actually update the gui
|
|
|
|
// until init_done is set. This forces the set handler to be called,
|
|
|
|
// which sets up the mouse enabled GUI-specific stuff correctly.
|
|
|
|
// Not a great solution but it works. BBD
|
|
|
|
SIM->get_param_bool(BXPN_MOUSE_ENABLED)->set(SIM->get_param_bool(BXPN_MOUSE_ENABLED)->get());
|
|
|
|
|
2004-11-06 13:50:03 +03:00
|
|
|
#if BX_DEBUGGER
|
2001-04-10 05:04:59 +04:00
|
|
|
// If using the debugger, it will take control and call
|
2001-06-10 00:01:12 +04:00
|
|
|
// bx_init_hardware() and cpu_loop()
|
2006-10-24 21:53:47 +04:00
|
|
|
bx_dbg_main();
|
2008-02-06 01:57:43 +03:00
|
|
|
#else
|
2004-11-06 13:50:03 +03:00
|
|
|
#if BX_GDBSTUB
|
|
|
|
// If using gdbstub, it will take control and call
|
|
|
|
// bx_init_hardware() and cpu_loop()
|
2006-10-26 21:27:04 +04:00
|
|
|
if (bx_dbg.gdbstub_enabled) bx_gdbstub_init();
|
2004-11-06 13:50:03 +03:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
2007-03-07 00:12:20 +03:00
|
|
|
if (BX_SMP_PROCESSORS == 1) {
|
|
|
|
// only one processor, run as fast as possible by not messing with
|
|
|
|
// quantums and loops.
|
2007-09-13 13:44:56 +04:00
|
|
|
while (1) {
|
2011-09-22 23:38:52 +04:00
|
|
|
BX_CPU(0)->cpu_loop();
|
2008-02-06 01:57:43 +03:00
|
|
|
if (bx_pc_system.kill_bochs_request)
|
2007-09-13 13:44:56 +04:00
|
|
|
break;
|
|
|
|
}
|
2007-03-07 00:12:20 +03:00
|
|
|
// for one processor, the only reason for cpu_loop to return is
|
|
|
|
// that kill_bochs_request was set by the GUI interface.
|
|
|
|
}
|
2011-07-10 02:17:16 +04:00
|
|
|
#if BX_SUPPORT_SMP
|
2007-03-07 00:12:20 +03:00
|
|
|
else {
|
|
|
|
// SMP simulation: do a few instructions on each processor, then switch
|
|
|
|
// to another. Increasing quantum speeds up overall performance, but
|
|
|
|
// reduces granularity of synchronization between processors.
|
2011-09-22 23:38:52 +04:00
|
|
|
// Current implementation uses dynamic quantum, each processor will
|
|
|
|
// execute exactly one trace then quit the cpu_loop and switch to
|
|
|
|
// the next processor.
|
|
|
|
|
|
|
|
static int quantum = SIM->get_param_num(BXPN_SMP_QUANTUM)->get();
|
|
|
|
Bit32u executed = 0, processor = 0;
|
|
|
|
|
2007-03-07 00:12:20 +03:00
|
|
|
while (1) {
|
2011-09-22 23:38:52 +04:00
|
|
|
// do some instructions in each processor
|
|
|
|
Bit64u icount = BX_CPU(processor)->icount_last_sync = BX_CPU(processor)->get_icount();
|
|
|
|
BX_CPU(processor)->cpu_run_trace();
|
|
|
|
|
|
|
|
// see how many instruction it was able to run
|
|
|
|
Bit32u n = (Bit32u)(BX_CPU(processor)->get_icount() - icount);
|
|
|
|
if (n == 0) n = quantum; // the CPU was halted
|
|
|
|
executed += n;
|
|
|
|
|
2011-09-23 01:48:54 +04:00
|
|
|
if (++processor == BX_SMP_PROCESSORS) {
|
|
|
|
processor = 0;
|
2011-09-22 23:38:52 +04:00
|
|
|
BX_TICKN(executed / BX_SMP_PROCESSORS);
|
|
|
|
executed %= BX_SMP_PROCESSORS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bx_pc_system.kill_bochs_request)
|
|
|
|
break;
|
2007-03-07 00:12:20 +03:00
|
|
|
}
|
2001-06-05 19:56:19 +04:00
|
|
|
}
|
2011-07-10 02:17:16 +04:00
|
|
|
#endif /* BX_SUPPORT_SMP */
|
2001-05-23 12:16:07 +04:00
|
|
|
}
|
2006-05-30 23:46:31 +04:00
|
|
|
#endif /* BX_DEBUGGER == 0 */
|
2006-03-12 01:40:32 +03:00
|
|
|
BX_INFO(("cpu loop quit, shutting down simulator"));
|
|
|
|
bx_atexit();
|
2001-04-10 05:04:59 +04:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2008-04-08 00:20:04 +04:00
|
|
|
void bx_stop_simulation(void)
|
2006-03-12 01:40:32 +03:00
|
|
|
{
|
|
|
|
// in wxWidgets, the whole simulator is running in a separate thread.
|
|
|
|
// our only job is to end the thread as soon as possible, NOT to shut
|
|
|
|
// down the whole application with an exit.
|
|
|
|
BX_CPU(0)->async_event = 1;
|
2006-03-14 21:11:22 +03:00
|
|
|
bx_pc_system.kill_bochs_request = 1;
|
2006-03-12 01:40:32 +03:00
|
|
|
// the cpu loop will exit very soon after this condition is set.
|
|
|
|
}
|
|
|
|
|
2006-05-14 19:47:37 +04:00
|
|
|
void bx_sr_after_restore_state(void)
|
|
|
|
{
|
2006-05-27 19:54:49 +04:00
|
|
|
#if BX_SUPPORT_SMP == 0
|
|
|
|
BX_CPU(0)->after_restore_state();
|
|
|
|
#else
|
|
|
|
for (unsigned i=0; i<BX_SMP_PROCESSORS; i++) {
|
|
|
|
BX_CPU(i)->after_restore_state();
|
|
|
|
}
|
|
|
|
#endif
|
2006-05-14 19:47:37 +04:00
|
|
|
DEV_after_restore_state();
|
|
|
|
}
|
|
|
|
|
2012-04-06 17:15:27 +04:00
|
|
|
void bx_set_log_actions_by_device(bx_bool panic_flag)
|
2011-12-29 23:51:54 +04:00
|
|
|
{
|
2012-04-06 17:15:27 +04:00
|
|
|
int id, l, m, val;
|
2011-12-30 15:13:37 +04:00
|
|
|
bx_list_c *loglev, *level;
|
2011-12-29 23:51:54 +04:00
|
|
|
bx_param_num_c *action;
|
|
|
|
|
2011-12-30 15:13:37 +04:00
|
|
|
loglev = (bx_list_c*) SIM->get_param("general.logfn");
|
|
|
|
for (l = 0; l < loglev->get_size(); l++) {
|
|
|
|
level = (bx_list_c*) loglev->get(l);
|
|
|
|
for (m = 0; m < level->get_size(); m++) {
|
|
|
|
action = (bx_param_num_c*) level->get(m);
|
|
|
|
id = SIM->get_logfn_id(action->get_name());
|
2012-04-06 17:15:27 +04:00
|
|
|
val = action->get();
|
2011-12-30 15:13:37 +04:00
|
|
|
if (id < 0) {
|
2012-04-06 17:15:27 +04:00
|
|
|
if (panic_flag) {
|
|
|
|
BX_PANIC(("unknown log function module '%s'", action->get_name()));
|
|
|
|
}
|
|
|
|
} else if (val >= 0) {
|
|
|
|
SIM->set_log_action(id, l, val);
|
|
|
|
// mark as 'done'
|
|
|
|
action->set(-1);
|
2011-12-29 23:51:54 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-16 20:17:48 +04:00
|
|
|
void bx_init_hardware()
|
2001-04-10 05:04:59 +04:00
|
|
|
{
|
2004-06-05 02:06:55 +04:00
|
|
|
// all configuration has been read, now initialize everything.
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2006-03-05 13:24:29 +03:00
|
|
|
if (SIM->get_param_enum(BXPN_BOCHS_START)->get()==BX_QUICK_START) {
|
2002-01-02 12:57:58 +03:00
|
|
|
for (int level=0; level<N_LOGLEV; level++) {
|
2006-06-22 00:42:26 +04:00
|
|
|
int action = SIM->get_default_log_action(level);
|
|
|
|
io->set_log_action(level, action);
|
2002-01-02 12:57:58 +03:00
|
|
|
}
|
2001-06-22 01:24:05 +04:00
|
|
|
}
|
2001-05-23 06:37:52 +04:00
|
|
|
|
2006-03-14 21:11:22 +03:00
|
|
|
bx_pc_system.initialize(SIM->get_param_num(BXPN_IPS)->get());
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2006-03-05 13:24:29 +03:00
|
|
|
if (SIM->get_param_string(BXPN_LOG_FILENAME)->getptr()[0]!='-') {
|
|
|
|
BX_INFO (("using log file %s", SIM->get_param_string(BXPN_LOG_FILENAME)->getptr()));
|
|
|
|
io->init_log(SIM->get_param_string(BXPN_LOG_FILENAME)->getptr());
|
2001-05-22 23:07:53 +04:00
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2006-03-05 13:24:29 +03:00
|
|
|
io->set_log_prefix(SIM->get_param_string(BXPN_LOG_PREFIX)->getptr());
|
2002-06-28 18:03:47 +04:00
|
|
|
|
2005-08-07 13:03:15 +04:00
|
|
|
// Output to the log file the cpu and device settings
|
2003-02-05 21:19:03 +03:00
|
|
|
// This will by handy for bug reports
|
|
|
|
BX_INFO(("Bochs x86 Emulator %s", VER_STRING));
|
|
|
|
BX_INFO((" %s", REL_STRING));
|
2010-10-03 00:52:47 +04:00
|
|
|
#ifdef __DATE__
|
|
|
|
#ifdef __TIME__
|
2011-04-01 20:19:15 +04:00
|
|
|
BX_INFO(("Compiled on %s at %s", __DATE__, __TIME__));
|
2010-10-03 00:52:47 +04:00
|
|
|
#else
|
2011-04-01 20:19:15 +04:00
|
|
|
BX_INFO(("Compiled on %s", __DATE__));
|
2010-10-03 00:52:47 +04:00
|
|
|
#endif
|
|
|
|
#endif
|
2003-02-05 21:19:03 +03:00
|
|
|
BX_INFO(("System configuration"));
|
2006-02-11 18:28:43 +03:00
|
|
|
BX_INFO((" processors: %d (cores=%u, HT threads=%u)", BX_SMP_PROCESSORS,
|
2006-02-18 19:53:18 +03:00
|
|
|
SIM->get_param_num(BXPN_CPU_NCORES)->get(), SIM->get_param_num(BXPN_CPU_NTHREADS)->get()));
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" A20 line support: %s", BX_SUPPORT_A20?"yes":"no"));
|
2008-12-28 23:49:03 +03:00
|
|
|
#if BX_CONFIGURE_MSRS
|
|
|
|
const char *msrs_file = SIM->get_param_string(BXPN_CONFIGURABLE_MSRS_PATH)->getptr();
|
|
|
|
if(strlen(msrs_file) > 0)
|
2008-12-28 23:53:31 +03:00
|
|
|
BX_INFO((" load configurable MSRs from file \"%s\"", msrs_file));
|
2008-12-28 23:49:03 +03:00
|
|
|
#endif
|
2011-05-04 23:26:11 +04:00
|
|
|
BX_INFO(("IPS is set to %d", (Bit32u) SIM->get_param_num(BXPN_IPS)->get()));
|
2003-02-05 21:19:03 +03:00
|
|
|
BX_INFO(("CPU configuration"));
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" level: %d", BX_CPU_LEVEL));
|
2006-06-22 00:42:26 +04:00
|
|
|
#if BX_SUPPORT_SMP
|
|
|
|
BX_INFO((" SMP support: yes, quantum=%d", SIM->get_param_num(BXPN_SMP_QUANTUM)->get()));
|
|
|
|
#else
|
|
|
|
BX_INFO((" SMP support: no"));
|
|
|
|
#endif
|
2011-08-04 00:29:24 +04:00
|
|
|
|
|
|
|
unsigned cpu_model = SIM->get_param_enum(BXPN_CPU_MODEL)->get();
|
|
|
|
if (! cpu_model) {
|
|
|
|
#if BX_CPU_LEVEL >= 5
|
|
|
|
BX_INFO((" APIC support: %s", SIM->get_param_enum(BXPN_CPUID_APIC)->get_selected()));
|
2011-04-21 17:27:42 +04:00
|
|
|
#else
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" APIC support: no"));
|
2011-04-21 17:27:42 +04:00
|
|
|
#endif
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" FPU support: %s", BX_SUPPORT_FPU?"yes":"no"));
|
2010-03-01 21:53:53 +03:00
|
|
|
#if BX_CPU_LEVEL >= 5
|
2011-12-22 23:12:37 +04:00
|
|
|
bx_bool mmx_enabled = SIM->get_param_bool(BXPN_CPUID_MMX)->get();
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" MMX support: %s", mmx_enabled?"yes":"no"));
|
|
|
|
BX_INFO((" 3dnow! support: %s", BX_SUPPORT_3DNOW?"yes":"no"));
|
2008-12-18 22:37:05 +03:00
|
|
|
#endif
|
2010-03-01 21:53:53 +03:00
|
|
|
#if BX_CPU_LEVEL >= 6
|
2011-12-22 23:12:37 +04:00
|
|
|
bx_bool sep_enabled = SIM->get_param_bool(BXPN_CPUID_SEP)->get();
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" SEP support: %s", sep_enabled?"yes":"no"));
|
2011-12-22 23:12:37 +04:00
|
|
|
bx_bool sse4a_enabled = SIM->get_param_bool(BXPN_CPUID_SSE4A)->get();
|
2011-09-18 20:18:22 +04:00
|
|
|
BX_INFO((" SSE support: %s%s", SIM->get_param_enum(BXPN_CPUID_SSE)->get_selected(),
|
|
|
|
sse4a_enabled ? "+sse4a" : ""));
|
2011-12-22 23:12:37 +04:00
|
|
|
bx_bool xsave_enabled = SIM->get_param_bool(BXPN_CPUID_XSAVE)->get();
|
|
|
|
bx_bool xsaveopt_enabled = SIM->get_param_bool(BXPN_CPUID_XSAVEOPT)->get();
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" XSAVE support: %s %s",
|
|
|
|
xsave_enabled?"xsave":"no", xsaveopt_enabled?"xsaveopt":""));
|
2011-12-22 23:12:37 +04:00
|
|
|
bx_bool aes_enabled = SIM->get_param_bool(BXPN_CPUID_AES)->get();
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" AES support: %s", aes_enabled?"yes":"no"));
|
2011-12-22 23:12:37 +04:00
|
|
|
bx_bool movbe_enabled = SIM->get_param_bool(BXPN_CPUID_MOVBE)->get();
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" MOVBE support: %s", movbe_enabled?"yes":"no"));
|
2012-07-12 18:51:54 +04:00
|
|
|
bx_bool adx_enabled = SIM->get_param_bool(BXPN_CPUID_ADX)->get();
|
|
|
|
BX_INFO((" ADX support: %s", adx_enabled?"yes":"no"));
|
2010-03-01 21:53:53 +03:00
|
|
|
#if BX_SUPPORT_X86_64
|
2011-12-22 23:12:37 +04:00
|
|
|
bx_bool x86_64_enabled = SIM->get_param_bool(BXPN_CPUID_X86_64)->get();
|
2011-09-25 21:36:20 +04:00
|
|
|
BX_INFO((" x86-64 support: %s", x86_64_enabled?"yes":"no"));
|
2011-12-25 23:35:29 +04:00
|
|
|
bx_bool xlarge_enabled = SIM->get_param_bool(BXPN_CPUID_1G_PAGES)->get();
|
|
|
|
BX_INFO((" 1G paging support: %s", xlarge_enabled?"yes":"no"));
|
2011-09-25 21:36:20 +04:00
|
|
|
#else
|
|
|
|
BX_INFO((" x86-64 support: no"));
|
2010-03-01 21:53:53 +03:00
|
|
|
#endif
|
2010-11-21 15:02:12 +03:00
|
|
|
#if BX_SUPPORT_MONITOR_MWAIT
|
2011-12-22 23:12:37 +04:00
|
|
|
bx_bool mwait_enabled = SIM->get_param_bool(BXPN_CPUID_MWAIT)->get();
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" MWAIT support: %s", mwait_enabled?"yes":"no"));
|
2010-11-21 15:02:12 +03:00
|
|
|
#endif
|
2011-05-25 00:33:36 +04:00
|
|
|
#if BX_SUPPORT_AVX
|
2011-12-22 23:12:37 +04:00
|
|
|
unsigned avx_enabled = SIM->get_param_num(BXPN_CPUID_AVX)->get();
|
|
|
|
bx_bool avx_fma_enabled = SIM->get_param_bool(BXPN_CPUID_AVX_FMA)->get();
|
2011-09-30 02:20:56 +04:00
|
|
|
if (avx_enabled) {
|
|
|
|
BX_INFO((" AVX support: %d%s", avx_enabled, avx_fma_enabled ? " (with FMA)" : ""));
|
|
|
|
}
|
|
|
|
else {
|
2011-08-27 17:47:16 +04:00
|
|
|
BX_INFO((" AVX support: no"));
|
2011-09-30 02:20:56 +04:00
|
|
|
}
|
2011-05-25 00:33:36 +04:00
|
|
|
#endif
|
2010-04-03 14:14:42 +04:00
|
|
|
#if BX_SUPPORT_VMX
|
2011-12-22 23:12:37 +04:00
|
|
|
unsigned vmx_enabled = SIM->get_param_num(BXPN_CPUID_VMX)->get();
|
|
|
|
if (vmx_enabled) {
|
|
|
|
BX_INFO((" VMX support: %d", vmx_enabled));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BX_INFO((" VMX support: no"));
|
|
|
|
}
|
2010-03-01 21:53:53 +03:00
|
|
|
#endif
|
2011-12-25 23:35:29 +04:00
|
|
|
#if BX_SUPPORT_SVM
|
|
|
|
bx_bool svm_enabled = SIM->get_param_bool(BXPN_CPUID_SVM)->get();
|
|
|
|
BX_INFO((" SVM support: %s", svm_enabled?"yes":"no"));
|
|
|
|
#endif
|
2011-12-22 23:12:37 +04:00
|
|
|
#endif // BX_CPU_LEVEL >= 6
|
2011-08-04 00:29:24 +04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
BX_INFO((" Using pre-defined CPU configuration: %s",
|
|
|
|
SIM->get_param_enum(BXPN_CPU_MODEL)->get_selected()));
|
|
|
|
}
|
|
|
|
|
2003-02-05 21:19:03 +03:00
|
|
|
BX_INFO(("Optimization configuration"));
|
2011-08-21 18:31:08 +04:00
|
|
|
BX_INFO((" RepeatSpeedups support: %s", BX_SUPPORT_REPEAT_SPEEDUPS?"yes":"no"));
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" Fast function calls: %s", BX_FAST_FUNC_CALL?"yes":"no"));
|
2011-08-21 18:31:08 +04:00
|
|
|
BX_INFO((" Handlers Chaining speedups: %s", BX_SUPPORT_HANDLERS_CHAINING_SPEEDUPS?"yes":"no"));
|
2005-08-07 13:03:15 +04:00
|
|
|
BX_INFO(("Devices configuration"));
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" NE2000 support: %s", BX_SUPPORT_NE2K?"yes":"no"));
|
|
|
|
BX_INFO((" PCI support: %s, enabled=%s", BX_SUPPORT_PCI?"yes":"no",
|
2009-08-10 19:30:43 +04:00
|
|
|
SIM->get_param_bool(BXPN_I440FX_SUPPORT)->get() ? "yes" : "no"));
|
2011-08-04 00:29:24 +04:00
|
|
|
BX_INFO((" SB16 support: %s", BX_SUPPORT_SB16?"yes":"no"));
|
|
|
|
BX_INFO((" USB support: %s", BX_SUPPORT_PCIUSB?"yes":"no"));
|
2011-03-07 22:01:22 +03:00
|
|
|
BX_INFO((" VGA extension support: vbe %s", BX_SUPPORT_CLGD54XX?"cirrus":""));
|
2003-02-05 21:19:03 +03:00
|
|
|
|
2002-11-09 17:12:10 +03:00
|
|
|
// Check if there is a romimage
|
2006-02-18 01:27:38 +03:00
|
|
|
if (strcmp(SIM->get_param_string(BXPN_ROM_PATH)->getptr(),"") == 0) {
|
2002-11-09 17:12:10 +03:00
|
|
|
BX_ERROR(("No romimage to load. Is your bochsrc file loaded/valid ?"));
|
|
|
|
}
|
|
|
|
|
2007-09-22 19:59:41 +04:00
|
|
|
// set one shot timer for benchmark mode if needed, the timer will fire
|
|
|
|
// once and kill Bochs simulation after predefined amount of emulated
|
|
|
|
// ticks
|
|
|
|
int benchmark_mode = SIM->get_param_num(BXPN_BOCHS_BENCHMARK)->get();
|
|
|
|
if (benchmark_mode) {
|
|
|
|
BX_INFO(("Bochs benchmark mode is ON (~%d millions of ticks)", benchmark_mode));
|
|
|
|
bx_pc_system.register_timer_ticks(&bx_pc_system, bx_pc_system_c::benchmarkTimer,
|
|
|
|
(Bit64u) benchmark_mode * 1000000, 0, 1, "benchmark.timer");
|
|
|
|
}
|
|
|
|
|
2006-01-10 09:13:26 +03:00
|
|
|
// set up memory and CPU objects
|
2006-02-18 01:27:38 +03:00
|
|
|
bx_param_num_c *bxp_memsize = SIM->get_param_num(BXPN_MEM_SIZE);
|
2009-10-17 22:17:28 +04:00
|
|
|
Bit64u memSize = bxp_memsize->get64() * BX_CONST64(1024*1024);
|
2005-04-10 23:42:48 +04:00
|
|
|
|
2009-10-17 21:38:58 +04:00
|
|
|
bx_param_num_c *bxp_host_memsize = SIM->get_param_num(BXPN_HOST_MEM_SIZE);
|
2009-10-17 22:17:28 +04:00
|
|
|
Bit64u hostMemSize = bxp_host_memsize->get64() * BX_CONST64(1024*1024);
|
2009-10-17 21:38:58 +04:00
|
|
|
|
2009-10-17 21:52:26 +04:00
|
|
|
// do not allocate more host memory than needed for emulation of guest RAM
|
|
|
|
if (memSize < hostMemSize) hostMemSize = memSize;
|
|
|
|
|
2009-10-17 21:38:58 +04:00
|
|
|
BX_MEM(0)->init_memory(memSize, hostMemSize);
|
2002-07-24 21:52:34 +04:00
|
|
|
|
2011-07-03 19:31:16 +04:00
|
|
|
// First load the system BIOS (VGABIOS loading moved to the vga code)
|
2006-02-18 01:27:38 +03:00
|
|
|
BX_MEM(0)->load_ROM(SIM->get_param_string(BXPN_ROM_PATH)->getptr(),
|
|
|
|
SIM->get_param_num(BXPN_ROM_ADDRESS)->get(), 0);
|
2004-09-01 22:12:23 +04:00
|
|
|
|
|
|
|
// Then load the optional ROM images
|
2006-02-18 01:27:38 +03:00
|
|
|
if (strcmp(SIM->get_param_string(BXPN_OPTROM1_PATH)->getptr(), "") !=0)
|
|
|
|
BX_MEM(0)->load_ROM(SIM->get_param_string(BXPN_OPTROM1_PATH)->getptr(), SIM->get_param_num(BXPN_OPTROM1_ADDRESS)->get(), 2);
|
|
|
|
if (strcmp(SIM->get_param_string(BXPN_OPTROM2_PATH)->getptr(), "") !=0)
|
|
|
|
BX_MEM(0)->load_ROM(SIM->get_param_string(BXPN_OPTROM2_PATH)->getptr(), SIM->get_param_num(BXPN_OPTROM2_ADDRESS)->get(), 2);
|
|
|
|
if (strcmp(SIM->get_param_string(BXPN_OPTROM3_PATH)->getptr(), "") !=0)
|
|
|
|
BX_MEM(0)->load_ROM(SIM->get_param_string(BXPN_OPTROM3_PATH)->getptr(), SIM->get_param_num(BXPN_OPTROM3_ADDRESS)->get(), 2);
|
|
|
|
if (strcmp(SIM->get_param_string(BXPN_OPTROM4_PATH)->getptr(), "") !=0)
|
|
|
|
BX_MEM(0)->load_ROM(SIM->get_param_string(BXPN_OPTROM4_PATH)->getptr(), SIM->get_param_num(BXPN_OPTROM4_ADDRESS)->get(), 2);
|
2002-07-24 21:52:34 +04:00
|
|
|
|
2005-10-28 04:12:27 +04:00
|
|
|
// Then load the optional RAM images
|
2006-02-18 01:27:38 +03:00
|
|
|
if (strcmp(SIM->get_param_string(BXPN_OPTRAM1_PATH)->getptr(), "") !=0)
|
|
|
|
BX_MEM(0)->load_RAM(SIM->get_param_string(BXPN_OPTRAM1_PATH)->getptr(), SIM->get_param_num(BXPN_OPTRAM1_ADDRESS)->get(), 2);
|
|
|
|
if (strcmp(SIM->get_param_string(BXPN_OPTRAM2_PATH)->getptr(), "") !=0)
|
|
|
|
BX_MEM(0)->load_RAM(SIM->get_param_string(BXPN_OPTRAM2_PATH)->getptr(), SIM->get_param_num(BXPN_OPTRAM2_ADDRESS)->get(), 2);
|
|
|
|
if (strcmp(SIM->get_param_string(BXPN_OPTRAM3_PATH)->getptr(), "") !=0)
|
|
|
|
BX_MEM(0)->load_RAM(SIM->get_param_string(BXPN_OPTRAM3_PATH)->getptr(), SIM->get_param_num(BXPN_OPTRAM3_ADDRESS)->get(), 2);
|
|
|
|
if (strcmp(SIM->get_param_string(BXPN_OPTRAM4_PATH)->getptr(), "") !=0)
|
|
|
|
BX_MEM(0)->load_RAM(SIM->get_param_string(BXPN_OPTRAM4_PATH)->getptr(), SIM->get_param_num(BXPN_OPTRAM4_ADDRESS)->get(), 2);
|
2006-01-11 21:22:12 +03:00
|
|
|
|
2006-01-18 21:35:38 +03:00
|
|
|
#if BX_SUPPORT_SMP == 0
|
2008-04-27 23:49:02 +04:00
|
|
|
BX_CPU(0)->initialize();
|
2004-04-09 19:34:59 +04:00
|
|
|
BX_CPU(0)->sanity_checks();
|
2006-05-27 19:54:49 +04:00
|
|
|
BX_CPU(0)->register_state();
|
2008-11-18 23:58:09 +03:00
|
|
|
BX_INSTR_INITIALIZE(0);
|
2001-06-05 21:35:08 +04:00
|
|
|
#else
|
2006-01-18 21:35:38 +03:00
|
|
|
bx_cpu_array = new BX_CPU_C_PTR[BX_SMP_PROCESSORS];
|
|
|
|
|
|
|
|
for (unsigned i=0; i<BX_SMP_PROCESSORS; i++) {
|
2005-11-27 00:36:51 +03:00
|
|
|
BX_CPU(i) = new BX_CPU_C(i);
|
2008-04-27 23:49:02 +04:00
|
|
|
BX_CPU(i)->initialize(); // assign local apic id in 'initialize' method
|
2004-04-09 19:34:59 +04:00
|
|
|
BX_CPU(i)->sanity_checks();
|
2006-05-27 19:54:49 +04:00
|
|
|
BX_CPU(i)->register_state();
|
2008-11-18 23:58:09 +03:00
|
|
|
BX_INSTR_INITIALIZE(i);
|
2001-05-23 12:16:07 +04:00
|
|
|
}
|
2001-06-05 21:35:08 +04:00
|
|
|
#endif
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2002-10-25 01:07:56 +04:00
|
|
|
DEV_init_devices();
|
2012-07-14 19:48:48 +04:00
|
|
|
// unload optional plugins which are unused and marked for removal
|
|
|
|
SIM->opt_plugin_ctrl("*", 0);
|
2006-05-27 19:54:49 +04:00
|
|
|
bx_pc_system.register_state();
|
2006-04-15 21:03:59 +04:00
|
|
|
DEV_register_state();
|
2006-04-09 13:05:30 +04:00
|
|
|
if (SIM->get_param_bool(BXPN_RESTORE_FLAG)->get()) {
|
2006-05-28 20:39:25 +04:00
|
|
|
if (!SIM->restore_logopts()) {
|
|
|
|
BX_PANIC(("cannot restore log options"));
|
|
|
|
SIM->get_param_bool(BXPN_RESTORE_FLAG)->set(0);
|
|
|
|
}
|
2011-12-29 16:44:38 +04:00
|
|
|
} else {
|
2012-04-06 17:15:27 +04:00
|
|
|
bx_set_log_actions_by_device(1);
|
2006-04-09 13:05:30 +04:00
|
|
|
}
|
2007-09-28 23:52:08 +04:00
|
|
|
|
2006-03-08 23:10:29 +03:00
|
|
|
// will enable A20 line and reset CPU and devices
|
|
|
|
bx_pc_system.Reset(BX_RESET_HARDWARE);
|
2007-09-28 23:52:08 +04:00
|
|
|
|
2006-04-07 00:42:51 +04:00
|
|
|
if (SIM->get_param_bool(BXPN_RESTORE_FLAG)->get()) {
|
2006-05-28 20:39:25 +04:00
|
|
|
if (SIM->restore_hardware()) {
|
|
|
|
bx_sr_after_restore_state();
|
|
|
|
} else {
|
|
|
|
BX_PANIC(("cannot restore hardware state"));
|
|
|
|
SIM->get_param_bool(BXPN_RESTORE_FLAG)->set(0);
|
|
|
|
}
|
2006-04-07 00:42:51 +04:00
|
|
|
}
|
2007-09-28 23:52:08 +04:00
|
|
|
|
2006-03-08 23:10:29 +03:00
|
|
|
bx_gui->init_signal_handlers();
|
2001-04-10 05:04:59 +04:00
|
|
|
bx_pc_system.start_timers();
|
2006-03-08 23:10:29 +03:00
|
|
|
|
2001-06-10 00:01:12 +04:00
|
|
|
BX_DEBUG(("bx_init_hardware is setting signal handlers"));
|
2001-04-10 05:04:59 +04:00
|
|
|
// if not using debugger, then we can take control of SIGINT.
|
2002-09-05 19:51:03 +04:00
|
|
|
#if !BX_DEBUGGER
|
2001-04-10 05:04:59 +04:00
|
|
|
signal(SIGINT, bx_signal_handler);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if BX_SHOW_IPS
|
2009-05-13 21:26:45 +04:00
|
|
|
#if !defined(WIN32)
|
2012-08-25 17:20:55 +04:00
|
|
|
if (!SIM->is_wx_selected()) {
|
|
|
|
signal(SIGALRM, bx_signal_handler);
|
|
|
|
alarm(1);
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
#endif
|
2009-05-13 21:26:45 +04:00
|
|
|
#endif
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
2006-03-08 23:10:29 +03:00
|
|
|
void bx_init_bx_dbg(void)
|
2001-04-10 05:04:59 +04:00
|
|
|
{
|
2006-10-24 21:53:47 +04:00
|
|
|
#if BX_DEBUGGER
|
|
|
|
bx_dbg_init_infile();
|
|
|
|
#endif
|
2009-04-23 22:28:17 +04:00
|
|
|
memset(&bx_dbg, 0, sizeof(bx_debug_t));
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
2005-04-16 23:37:53 +04:00
|
|
|
int bx_atexit(void)
|
2001-04-10 05:04:59 +04:00
|
|
|
{
|
2006-09-23 13:07:15 +04:00
|
|
|
if (!SIM->get_init_done()) return 1; // protect from reentry
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2002-12-06 22:34:32 +03:00
|
|
|
// in case we ended up in simulation mode, change back to config mode
|
|
|
|
// so that the user can see any messages left behind on the console.
|
2006-06-22 00:42:26 +04:00
|
|
|
SIM->set_display_mode(DISP_MODE_CONFIG);
|
2002-09-03 08:54:28 +04:00
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
#if BX_DEBUGGER == 0
|
2006-06-22 00:42:26 +04:00
|
|
|
if (SIM && SIM->get_init_done()) {
|
2002-09-25 22:49:35 +04:00
|
|
|
for (int cpu=0; cpu<BX_SMP_PROCESSORS; cpu++)
|
2007-10-25 03:29:40 +04:00
|
|
|
#if BX_SUPPORT_SMP
|
|
|
|
if (BX_CPU(cpu))
|
|
|
|
#endif
|
|
|
|
BX_CPU(cpu)->atexit();
|
2002-09-25 22:49:35 +04:00
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
#endif
|
|
|
|
|
2006-09-15 21:02:52 +04:00
|
|
|
BX_MEM(0)->cleanup_memory();
|
|
|
|
|
2006-09-10 13:13:47 +04:00
|
|
|
bx_pc_system.exit();
|
2002-09-05 19:51:03 +04:00
|
|
|
|
|
|
|
// restore signal handling to defaults
|
2008-03-27 01:39:38 +03:00
|
|
|
#if BX_DEBUGGER == 0
|
2006-06-22 00:42:26 +04:00
|
|
|
BX_INFO(("restoring default signal behavior"));
|
2002-09-05 19:51:03 +04:00
|
|
|
signal(SIGINT, SIG_DFL);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if BX_SHOW_IPS
|
2008-03-27 01:39:38 +03:00
|
|
|
#if !defined(__MINGW32__) && !defined(_MSC_VER)
|
2012-08-25 17:20:55 +04:00
|
|
|
if (!SIM->is_wx_selected()) {
|
|
|
|
alarm(0);
|
|
|
|
signal(SIGALRM, SIG_DFL);
|
|
|
|
}
|
2002-09-05 19:51:03 +04:00
|
|
|
#endif
|
2001-04-10 05:04:59 +04:00
|
|
|
#endif
|
2005-04-16 23:37:53 +04:00
|
|
|
|
2012-02-14 22:13:54 +04:00
|
|
|
SIM->cleanup_save_restore();
|
2006-09-23 13:07:15 +04:00
|
|
|
SIM->set_init_done(0);
|
|
|
|
|
2005-04-16 23:37:53 +04:00
|
|
|
return 0;
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
2008-04-08 00:20:04 +04:00
|
|
|
void CDECL bx_signal_handler(int signum)
|
2001-04-10 05:04:59 +04:00
|
|
|
{
|
2002-09-05 11:48:39 +04:00
|
|
|
// in a multithreaded environment, a signal such as SIGINT can be sent to all
|
|
|
|
// threads. This function is only intended to handle signals in the
|
|
|
|
// simulator thread. It will simply return if called from any other thread.
|
|
|
|
// Otherwise the BX_PANIC() below can be called in multiple threads at
|
|
|
|
// once, leading to multiple threads trying to display a dialog box,
|
|
|
|
// leading to GUI deadlock.
|
2006-06-22 00:42:26 +04:00
|
|
|
if (!SIM->is_sim_thread()) {
|
2002-09-05 11:48:39 +04:00
|
|
|
BX_INFO (("bx_signal_handler: ignored sig %d because it wasn't called from the simulator thread", signum));
|
|
|
|
return;
|
|
|
|
}
|
2001-05-09 00:18:05 +04:00
|
|
|
#if BX_GUI_SIGHANDLER
|
2002-11-11 20:09:57 +03:00
|
|
|
if (bx_gui_sighandler) {
|
|
|
|
// GUI signal handler gets first priority, if the mask says it's wanted
|
2006-06-22 00:42:26 +04:00
|
|
|
if ((1<<signum) & bx_gui->get_sighandler_mask()) {
|
|
|
|
bx_gui->sighandler(signum);
|
2002-11-11 20:09:57 +03:00
|
|
|
return;
|
|
|
|
}
|
2001-05-09 00:18:05 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
#if BX_SHOW_IPS
|
2005-07-04 22:02:37 +04:00
|
|
|
static Bit64u ticks_count = 0;
|
2007-11-10 00:14:56 +03:00
|
|
|
static Bit64u counts = 0;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2005-04-16 23:37:53 +04:00
|
|
|
if (signum == SIGALRM)
|
|
|
|
{
|
2005-07-04 22:02:37 +04:00
|
|
|
// amount of system ticks passed from last time the handler was called
|
|
|
|
Bit64u ips_count = bx_pc_system.time_ticks() - ticks_count;
|
2005-04-16 23:37:53 +04:00
|
|
|
if (ips_count) {
|
2005-10-13 20:22:21 +04:00
|
|
|
bx_gui->show_ips((Bit32u) ips_count);
|
2005-07-04 22:02:37 +04:00
|
|
|
ticks_count = bx_pc_system.time_ticks();
|
2007-11-10 00:14:56 +03:00
|
|
|
counts++;
|
2007-11-20 21:36:26 +03:00
|
|
|
if (bx_dbg.print_timestamps) {
|
2008-02-06 01:57:43 +03:00
|
|
|
printf("IPS: %u\taverage = %u\t\t(%us)\n",
|
2007-11-20 21:36:26 +03:00
|
|
|
(unsigned) ips_count, (unsigned) (ticks_count/counts), (unsigned) counts);
|
2011-07-12 23:14:08 +04:00
|
|
|
fflush(stdout);
|
2007-11-20 21:36:26 +03:00
|
|
|
}
|
2005-04-16 23:37:53 +04:00
|
|
|
}
|
2009-05-13 21:26:45 +04:00
|
|
|
#if !defined(WIN32)
|
2012-08-25 17:20:55 +04:00
|
|
|
if (!SIM->is_wx_selected()) {
|
|
|
|
signal(SIGALRM, bx_signal_handler);
|
|
|
|
alarm(1);
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
#endif
|
|
|
|
return;
|
2005-04-16 23:37:53 +04:00
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
#endif
|
|
|
|
|
2001-05-23 12:16:07 +04:00
|
|
|
#if BX_GUI_SIGHANDLER
|
2002-11-11 20:09:57 +03:00
|
|
|
if (bx_gui_sighandler) {
|
|
|
|
if ((1<<signum) & bx_gui->get_sighandler_mask ()) {
|
2005-10-13 20:22:21 +04:00
|
|
|
bx_gui->sighandler(signum);
|
2002-11-11 20:09:57 +03:00
|
|
|
return;
|
|
|
|
}
|
2001-05-23 12:16:07 +04:00
|
|
|
}
|
|
|
|
#endif
|
2005-07-04 22:02:37 +04:00
|
|
|
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_PANIC(("SIGNAL %u caught", signum));
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|