2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2011-02-25 01:05:47 +03:00
|
|
|
// $Id$
|
2009-01-10 14:30:20 +03:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2020-08-06 23:21:14 +03:00
|
|
|
// Copyright (C) 2002-2020 The Bochs Project
|
2009-01-10 14:30:20 +03: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-02-08 12:05:52 +03:00
|
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2009-01-10 14:30:20 +03:00
|
|
|
//
|
2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2009-12-04 23:02:12 +03:00
|
|
|
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// See siminterface.h for description of the siminterface concept.
|
|
|
|
// Basically, the siminterface is visible from both the simulator and
|
|
|
|
// the configuration user interface, and allows them to talk to each other.
|
2001-06-08 11:20:07 +04:00
|
|
|
|
2010-02-26 17:18:19 +03:00
|
|
|
#include "param_names.h"
|
2004-06-19 19:20:15 +04:00
|
|
|
#include "iodev.h"
|
2011-08-15 14:37:41 +04:00
|
|
|
#include "virt_timer.h"
|
2001-06-08 11:20:07 +04:00
|
|
|
|
|
|
|
bx_simulator_interface_c *SIM = NULL;
|
2001-06-11 10:35:18 +04:00
|
|
|
logfunctions *siminterface_log = NULL;
|
2006-02-17 00:44:17 +03:00
|
|
|
bx_list_c *root_param = NULL;
|
2001-06-11 10:35:18 +04:00
|
|
|
#define LOG_THIS siminterface_log->
|
2001-06-08 11:20:07 +04:00
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
// bx_simulator_interface just defines the interface that the Bochs simulator
|
|
|
|
// and the gui will use to talk to each other. None of the methods of
|
|
|
|
// bx_simulator_interface are implemented; they are all virtual. The
|
|
|
|
// bx_real_sim_c class is a child of bx_simulator_interface_c, and it
|
|
|
|
// implements all the methods. The idea is that a gui needs to know only
|
|
|
|
// definition of bx_simulator_interface to talk to Bochs. The gui should
|
2008-02-06 01:57:43 +03:00
|
|
|
// not need to include bochs.h.
|
2002-04-18 04:22:20 +04:00
|
|
|
//
|
|
|
|
// I made this separation to ensure that all guis use the siminterface to do
|
|
|
|
// access bochs internals, instead of accessing things like
|
|
|
|
// bx_keyboard.s.internal_buffer[4] (or whatever) directly. -Bryce
|
2008-02-06 01:57:43 +03:00
|
|
|
//
|
2002-04-18 04:22:20 +04:00
|
|
|
|
2015-08-23 10:04:56 +03:00
|
|
|
static int rt_conf_id = 0;
|
|
|
|
|
2011-06-11 23:38:52 +04:00
|
|
|
typedef struct _rt_conf_entry_t {
|
2015-08-23 10:04:56 +03:00
|
|
|
int id;
|
2011-06-11 23:38:52 +04:00
|
|
|
void *device;
|
|
|
|
rt_conf_handler_t handler;
|
|
|
|
struct _rt_conf_entry_t *next;
|
|
|
|
} rt_conf_entry_t;
|
|
|
|
|
2011-12-23 14:03:10 +04:00
|
|
|
typedef struct _addon_option_t {
|
2009-01-06 00:15:17 +03:00
|
|
|
const char *name;
|
2011-12-23 14:03:10 +04:00
|
|
|
addon_option_parser_t parser;
|
|
|
|
addon_option_save_t savefn;
|
|
|
|
struct _addon_option_t *next;
|
|
|
|
} addon_option_t;
|
2009-01-06 00:15:17 +03:00
|
|
|
|
2001-06-08 11:20:07 +04:00
|
|
|
class bx_real_sim_c : public bx_simulator_interface_c {
|
2002-10-25 01:07:56 +04:00
|
|
|
bxevent_handler bxevent_callback;
|
|
|
|
void *bxevent_callback_data;
|
|
|
|
const char *registered_ci_name;
|
|
|
|
config_interface_callback_t ci_callback;
|
|
|
|
void *ci_callback_data;
|
2011-06-11 23:38:52 +04:00
|
|
|
rt_conf_entry_t *rt_conf_entries;
|
2011-12-23 14:03:10 +04:00
|
|
|
addon_option_t *addon_options;
|
2001-06-18 18:11:55 +04:00
|
|
|
int init_done;
|
2001-06-22 01:24:05 +04:00
|
|
|
int enabled;
|
- 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
|
|
|
// save context to jump to if we must quit unexpectedly
|
|
|
|
jmp_buf *quit_context;
|
2002-12-16 09:43:02 +03:00
|
|
|
int exit_code;
|
2006-02-19 18:43:03 +03:00
|
|
|
unsigned param_id;
|
2012-07-01 18:37:13 +04:00
|
|
|
bx_bool bx_debug_gui;
|
2014-01-12 12:26:04 +04:00
|
|
|
bx_bool bx_log_viewer;
|
2012-08-25 17:20:55 +04:00
|
|
|
bx_bool wxsel;
|
2001-06-11 18:03:35 +04:00
|
|
|
public:
|
2006-03-08 21:10:41 +03:00
|
|
|
bx_real_sim_c();
|
2006-05-30 02:33:38 +04:00
|
|
|
virtual ~bx_real_sim_c() {}
|
2006-03-08 21:10:41 +03:00
|
|
|
virtual void set_quit_context(jmp_buf *context) { quit_context = context; }
|
|
|
|
virtual int get_init_done() { return init_done; }
|
|
|
|
virtual int set_init_done(int n) { init_done = n; return 0;}
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual void reset_all_param();
|
2006-02-19 18:43:03 +03:00
|
|
|
// new param methods
|
2006-02-18 19:53:18 +03:00
|
|
|
virtual bx_param_c *get_param(const char *pname, bx_param_c *base=NULL);
|
2006-02-26 22:11:20 +03:00
|
|
|
virtual bx_param_num_c *get_param_num(const char *pname, bx_param_c *base=NULL);
|
|
|
|
virtual bx_param_string_c *get_param_string(const char *pname, bx_param_c *base=NULL);
|
|
|
|
virtual bx_param_bool_c *get_param_bool(const char *pname, bx_param_c *base=NULL);
|
|
|
|
virtual bx_param_enum_c *get_param_enum(const char *pname, bx_param_c *base=NULL);
|
2007-10-14 23:04:51 +04:00
|
|
|
virtual Bit32u gen_param_id() { return param_id++; }
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual int get_n_log_modules();
|
2012-01-11 23:57:38 +04:00
|
|
|
virtual const char *get_logfn_name(int mod);
|
2011-12-30 15:13:37 +04:00
|
|
|
virtual int get_logfn_id(const char *name);
|
2012-01-11 23:57:38 +04:00
|
|
|
virtual const char *get_prefix(int mod);
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual int get_log_action(int mod, int level);
|
|
|
|
virtual void set_log_action(int mod, int level, int action);
|
2012-01-11 23:57:38 +04:00
|
|
|
virtual const char *get_action_name(int action);
|
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/bochs.h ./bochs.h
--- /home/volker/bochs/bochs/bochs.h 2016-08-12 19:06:18.803209189 +0200
+++ ./bochs.h 2016-12-28 00:41:20.000627252 +0100
@@ -2,7 +2,7 @@
// $Id: bochs.h 12935 2016-08-12 17:06:14Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2001-2015 The Bochs Project
+// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -276,8 +276,9 @@
void error(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
void panic(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
void ldebug(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
- void fatal (const char *prefix, const char *fmt, va_list ap, int exit_status);
- void ask (int level, const char *prefix, const char *fmt, va_list ap);
+ void fatal(const char *prefix, const char *fmt, va_list ap, int exit_status);
+ void warn(int level, const char *prefix, const char *fmt, va_list ap);
+ void ask(int level, const char *prefix, const char *fmt, va_list ap);
void put(const char *p);
void put(const char *n, const char *p);
void setio(class iofunctions *);
@@ -334,7 +335,8 @@
void set_log_action(int loglevel, int action);
const char *getlevel(int i) const;
const char *getaction(int i) const;
-
+ int isaction(const char *val) const;
+
protected:
int n_logfn;
#define MAX_LOGFNS 512
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/CHANGES ./CHANGES
--- /home/volker/bochs/bochs/CHANGES 2016-12-26 10:45:44.000000000 +0100
+++ ./CHANGES 2016-12-28 15:54:25.127088081 +0100
@@ -1,5 +1,8 @@
Changes after 2.6.8 release:
+- General
+ - Added new log action "warn", designed to show a message box on error events.
+
- Configure and compile
- Added Android host platform support.
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/config.cc ./config.cc
--- /home/volker/bochs/bochs/config.cc 2016-05-03 21:15:09.158016000 +0200
+++ ./config.cc 2016-12-27 19:53:10.461420368 +0100
@@ -2062,15 +2062,8 @@
actstr = strtok(NULL, "");
if (actstr != NULL) {
def_action = !strcmp(module, "action");
- if (!strcmp(actstr, "fatal"))
- action = ACT_FATAL;
- else if (!strcmp (actstr, "report"))
- action = ACT_REPORT;
- else if (!strcmp (actstr, "ignore"))
- action = ACT_IGNORE;
- else if (!strcmp (actstr, "ask"))
- action = ACT_ASK;
- else {
+ action = SIM->is_action_name(actstr);
+ if (action < ACT_IGNORE) {
PARSE_ERR(("%s: %s directive malformed.", context, params[0]));
free(param);
return -1;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/sdl2.cc ./gui/sdl2.cc
--- /home/volker/bochs/bochs/gui/sdl2.cc 2016-08-12 19:06:18.811209142 +0200
+++ ./gui/sdl2.cc 2016-12-28 12:33:39.534288819 +0100
@@ -2,7 +2,7 @@
// $Id: sdl2.cc 12935 2016-08-12 17:06:14Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2014-2015 The Bochs Project
+// Copyright (C) 2014-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -1478,20 +1478,16 @@
SDL_MessageBoxData msgboxdata;
SDL_MessageBoxButtonData buttondata[4];
int level, retcode;
-#if BX_DEBUGGER || BX_GDBSTUB
- int defbtn = 3;
-#else
- int defbtn = 2;
-#endif
char message[512];
level = event->u.logmsg.level;
- sprintf(message, "%s %s", event->u.logmsg.prefix, event->u.logmsg.msg);
+ sprintf(message, "Device: %s\nMessage: %s", event->u.logmsg.prefix,
+ event->u.logmsg.msg);
msgboxdata.flags = SDL_MESSAGEBOX_ERROR;
msgboxdata.window = window;
msgboxdata.title = SIM->get_log_level_name(level);
msgboxdata.message = message;
- msgboxdata.numbuttons = defbtn + 1;
+ msgboxdata.numbuttons = 2;
msgboxdata.buttons = buttondata;
msgboxdata.colorScheme = NULL;
buttondata[0].flags = 0;
@@ -1500,14 +1496,18 @@
buttondata[1].flags = 0;
buttondata[1].buttonid = BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS;
buttondata[1].text = "Alwayscont";
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ msgboxdata.numbuttons = 3;
+ buttondata[2].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
+ buttondata[2].buttonid = BX_LOG_ASK_CHOICE_DIE;
+ buttondata[2].text = "Quit";
#if BX_DEBUGGER || BX_GDBSTUB
- buttondata[2].flags = 0;
- buttondata[2].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG;
- buttondata[2].text = "Debugger";
-#endif
- buttondata[defbtn].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
- buttondata[defbtn].buttonid = BX_LOG_ASK_CHOICE_DIE;
- buttondata[defbtn].text = "Quit";
+ msgboxdata.numbuttons = 4;
+ buttondata[3].flags = 0;
+ buttondata[3].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG;
+ buttondata[3].text = "Debugger";
+#endif
+ }
if (SDL_ShowMessageBox(&msgboxdata, &retcode) < 0) {
return -1;
} else {
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.cc ./gui/siminterface.cc
--- /home/volker/bochs/bochs/gui/siminterface.cc 2016-12-05 19:56:56.729685000 +0100
+++ ./gui/siminterface.cc 2016-12-28 11:14:02.004075717 +0100
@@ -2,7 +2,7 @@
// $Id: siminterface.cc 12981 2016-12-05 18:56:56Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2015 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -100,6 +100,7 @@
virtual int get_log_action(int mod, int level);
virtual void set_log_action(int mod, int level, int action);
virtual const char *get_action_name(int action);
+ virtual int is_action_name(const char *val);
virtual int get_default_log_action(int level) {
return logfunctions::get_default_action(level);
}
@@ -123,6 +124,7 @@
virtual void set_notify_callback(bxevent_handler func, void *arg);
virtual void get_notify_callback(bxevent_handler *func, void **arg);
virtual BxEvent* sim_to_ci_event(BxEvent *event);
+ virtual int log_warn(const char *prefix, int level, const char *msg);
virtual int log_ask(const char *prefix, int level, const char *msg);
virtual void log_msg(const char *prefix, int level, const char *msg);
virtual void set_log_viewer(bx_bool val) { bx_log_viewer = val; }
@@ -420,6 +422,11 @@
return io->getaction(action);
}
+int bx_real_sim_c::is_action_name(const char *val)
+{
+ return io->isaction(val);
+}
+
const char *bx_real_sim_c::get_log_level_name(int level)
{
return io->getlevel(level);
@@ -575,6 +582,21 @@
}
}
+int bx_real_sim_c::log_warn(const char *prefix, int level, const char *msg)
+{
+ BxEvent be;
+ be.type = BX_SYNC_EVT_LOG_ASK;
+ be.u.logmsg.prefix = prefix;
+ be.u.logmsg.level = level;
+ be.u.logmsg.msg = msg;
+ be.u.logmsg.flag = BX_LOG_ASK_MSGBOX_WARN;
+ // default return value in case something goes wrong.
+ be.retcode = BX_LOG_NOTIFY_FAILED;
+ // calling notify
+ sim_to_ci_event(&be);
+ return be.retcode;
+}
+
// returns 0 for continue, 1 for alwayscontinue, 2 for die.
int bx_real_sim_c::log_ask(const char *prefix, int level, const char *msg)
{
@@ -583,6 +605,7 @@
be.u.logmsg.prefix = prefix;
be.u.logmsg.level = level;
be.u.logmsg.msg = msg;
+ be.u.logmsg.flag = BX_LOG_ASK_ASKDLG;
// default return value in case something goes wrong.
be.retcode = BX_LOG_NOTIFY_FAILED;
// calling notify
@@ -1157,16 +1180,10 @@
} else if (!strncmp(string, "PANIC=", 6)) {
type = LOGLEV_PANIC;
}
- if (!strcmp(string+j, "ignore")) {
- action = ACT_IGNORE;
- } else if (!strcmp(string+j, "report")) {
- action = ACT_REPORT;
- } else if (!strcmp(string+j, "ask")) {
- action = ACT_ASK;
- } else if (!strcmp(string+j, "fatal")) {
- action = ACT_FATAL;
+ action = is_action_name(string+j);
+ if (action >= ACT_IGNORE) {
+ set_log_action(dev, type, action);
}
- set_log_action(dev, type, action);
} else {
if (i == 1) {
BX_ERROR(("restore_logopts(): log module '%s' not found", devname));
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.h ./gui/siminterface.h
--- /home/volker/bochs/bochs/gui/siminterface.h 2016-03-31 19:24:37.451025427 +0200
+++ ./gui/siminterface.h 2016-12-28 11:11:21.036683362 +0100
@@ -168,6 +168,7 @@
typedef enum {
ACT_IGNORE = 0,
ACT_REPORT,
+ ACT_WARN,
ACT_ASK,
ACT_FATAL,
N_ACT
@@ -178,11 +179,11 @@
// normally all action choices are available for all event types. The exclude
// expression allows some choices to be eliminated if they don't make any
// sense. For example, it would be stupid to ignore a panic.
-#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
- /* can't die or ask, on debug or info events */ \
- (type <= LOGLEV_INFO && (choice == ACT_ASK || choice == ACT_FATAL)) \
- /* can't ignore panics */ \
- || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
+#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
+ /* can't die, ask or warn, on debug or info events */ \
+ (type <= LOGLEV_INFO && (choice >= ACT_WARN)) \
+ /* can't ignore panics */ \
+ || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
)
// floppy / cdrom media status
@@ -392,6 +393,7 @@
// synchronizing threads, etc. for each.
typedef struct {
Bit8u level;
+ Bit8u flag;
const char *prefix;
const char *msg;
} BxLogMsgEvent;
@@ -419,6 +421,12 @@
BX_LOG_NOTIFY_FAILED
};
+enum {
+ BX_LOG_ASK_ASKDLG,
+ BX_LOG_ASK_MSGBOX_WARN,
+ BX_LOG_ASK_MSGBOX_QUIT
+};
+
// Event type: BX_SYNC_EVT_GET_DBG_COMMAND
//
// This is a synchronous event sent from the simulator to the debugger
@@ -675,6 +683,7 @@
virtual int get_default_log_action(int level) {return -1;}
virtual void set_default_log_action(int level, int action) {}
virtual const char *get_action_name(int action) {return NULL;}
+ virtual int is_action_name(const char *val) {return -1;}
virtual const char *get_log_level_name(int level) {return NULL;}
virtual int get_max_log_level() {return -1;}
@@ -715,6 +724,9 @@
// send an event from the simulator to the CI.
virtual BxEvent* sim_to_ci_event(BxEvent *event) {return NULL;}
+ // called from simulator when it hits errors, to warn the user
+ // before continuing simulation
+ virtual int log_warn(const char *prefix, int level, const char *msg) {return -1;}
// called from simulator when it hits serious errors, to ask if the user
// wants to continue or not
virtual int log_ask(const char *prefix, int level, const char *msg) {return -1;}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/textconfig.cc ./gui/textconfig.cc
--- /home/volker/bochs/bochs/gui/textconfig.cc 2016-12-05 20:15:59.112637000 +0100
+++ ./gui/textconfig.cc 2016-12-28 12:44:43.079411258 +0100
@@ -2,7 +2,7 @@
// $Id: textconfig.cc 12983 2016-12-05 19:15:59Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2013 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -552,8 +552,8 @@
}
static const char *log_options_prompt1 = "Enter the ID of the device to edit, or -1 to return: [-1] ";
-static const char *log_level_choices[] = { "ignore", "report", "ask", "fatal", "no change" };
-static int log_level_n_choices_normal = 4;
+static const char *log_level_choices[N_ACT+1] = { "ignore", "report", "warn", "ask", "fatal", "no change" };
+static int log_level_n_choices_normal = N_ACT;
void bx_log_options(int individual)
{
@@ -589,7 +589,7 @@
bx_print_log_action_table();
for (int level=0; level<SIM->get_max_log_level(); level++) {
char prompt[1024];
- int action, default_action = 4; // default to no change
+ int action, default_action = N_ACT; // default to no change
sprintf(prompt, "Enter action for %s event on all devices: [no change] ", SIM->get_log_level_name(level));
// do show the no change choice (choices=4)
if (ask_menu(prompt, "", log_level_n_choices_normal+1, log_level_choices, default_action, &action)<0)
@@ -718,47 +718,50 @@
event->retcode = event->u.param.param->text_ask(stdin, stderr);
return event;
case BX_SYNC_EVT_LOG_ASK:
- {
- int level = event->u.logmsg.level;
- fprintf(stderr, "========================================================================\n");
- fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level));
- fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix);
- fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg);
- fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
- fprintf(stderr, " cont - continue execution\n");
- fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n");
- fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
- fprintf(stderr, " die - stop execution now\n");
- fprintf(stderr, " abort - dump core %s\n",
- BX_HAVE_ABORT ? "" : "(Disabled)");
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ int level = event->u.logmsg.level;
+ fprintf(stderr, "========================================================================\n");
+ fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level));
+ fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix);
+ fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg);
+ fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
+ fprintf(stderr, " cont - continue execution\n");
+ fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n");
+ fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
+ fprintf(stderr, " die - stop execution now\n");
+ fprintf(stderr, " abort - dump core %s\n",
+ BX_HAVE_ABORT ? "" : "(Disabled)");
#if BX_DEBUGGER
- fprintf(stderr, " debug - continue and return to bochs debugger\n");
+ fprintf(stderr, " debug - continue and return to bochs debugger\n");
#endif
#if BX_GDBSTUB
- fprintf(stderr, " debug - hand control to gdb\n");
+ fprintf(stderr, " debug - hand control to gdb\n");
#endif
- int choice;
+ int choice;
ask:
- if (ask_menu("Choose one of the actions above: [%s] ", "",
- log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
- event->retcode = -1;
- // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
- if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
- fflush(stdout);
- fflush(stderr);
- event->retcode = choice;
- }
- return event;
- case BX_ASYNC_EVT_REFRESH:
- case BX_ASYNC_EVT_DBG_MSG:
- case BX_ASYNC_EVT_LOG_MSG:
- // The text mode interface does not use these events, so just ignore
- // them.
- return event;
- default:
- fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type);
- return event;
+ if (ask_menu("Choose one of the actions above: [%s] ", "",
+ log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
+ event->retcode = -1;
+ // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
+ if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
+ fflush(stdout);
+ fflush(stderr);
+ event->retcode = choice;
+ } else {
+ // warning prompt not implemented
+ event->retcode = 0;
+ }
+ return event;
+ case BX_ASYNC_EVT_REFRESH:
+ case BX_ASYNC_EVT_DBG_MSG:
+ case BX_ASYNC_EVT_LOG_MSG:
+ // The text mode interface does not use these events, so just ignore
+ // them.
+ return event;
+ default:
+ fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type);
+ return event;
}
assert(0); // switch statement should return
}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/win32dialog.cc ./gui/win32dialog.cc
--- /home/volker/bochs/bochs/gui/win32dialog.cc 2014-06-20 11:32:02.034026376 +0200
+++ ./gui/win32dialog.cc 2016-12-28 12:50:14.148888740 +0100
@@ -2,7 +2,7 @@
// $Id: win32dialog.cc 12381 2014-06-20 09:31:56Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2003-2014 The Bochs Project
+// Copyright (C) 2003-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@
#include "win32res.h"
#include "win32paramdlg.h"
-const char log_choices[5][16] = {"ignore", "log", "ask user", "end simulation", "no change"};
+const char log_choices[N_ACT+1][16] = {"ignore", "log", "warn user", "ask user", "end simulation", "no change"};
HWND GetBochsWindow()
{
@@ -97,12 +97,16 @@
SetWindowText(GetDlgItem(hDlg, IDASKMSG), event->u.logmsg.msg);
SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue");
SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and don't ask again");
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
#if BX_DEBUGGER
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
#endif
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
+ } else {
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 0, 0);
+ }
SetFocus(GetDlgItem(hDlg, IDASKLIST));
return FALSE;
case WM_CLOSE:
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.cc ./gui/wxdialog.cc
--- /home/volker/bochs/bochs/gui/wxdialog.cc 2015-01-07 17:17:40.447882000 +0100
+++ ./gui/wxdialog.cc 2016-12-27 20:30:44.997609007 +0100
@@ -2,7 +2,7 @@
// $Id: wxdialog.cc 12594 2015-01-07 16:17:40Z sshwarts $
/////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -208,7 +208,6 @@
: wxDialog(parent, id, wxT(""), wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
- //static int integers[LOG_OPTS_N_CHOICES_NORMAL] = {0, 1, 2, 3};
static wxString names[] = ADVLOG_OPTS_TYPE_NAMES;
SetTitle(ADVLOG_OPTS_TITLE);
vertSizer = new wxBoxSizer(wxVERTICAL);
@@ -1563,7 +1562,7 @@
bool includeNoChange)
{
static wxString choices[] = LOG_OPTS_CHOICES;
- static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4};
+ static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4, 5};
wxChoice *control = new wxChoice(parent, id, wxDefaultPosition, wxDefaultSize);
int lastChoice = 0; // remember index of last choice
int nchoice = includeNoChange? LOG_OPTS_N_CHOICES : LOG_OPTS_N_CHOICES_NORMAL;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.h ./gui/wxdialog.h
--- /home/volker/bochs/bochs/gui/wxdialog.h 2014-12-23 20:30:12.896090221 +0100
+++ ./gui/wxdialog.h 2016-12-27 20:34:28.518389938 +0100
@@ -2,7 +2,7 @@
// $Id: wxdialog.h 12576 2014-12-23 19:30:03Z vruppert $
////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -354,10 +354,10 @@
#define LOG_OPTS_PROMPT wxT("How should Bochs respond to each type of event?")
#define LOG_OPTS_TYPE_NAMES { wxT("Debug events"), wxT("Info events"), wxT("Error events"), wxT("Panic events") }
#define LOG_OPTS_N_TYPES 4
-#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("ask user"), wxT("end simulation"), wxT("no change") }
-#define LOG_OPTS_N_CHOICES_NORMAL 4
-#define LOG_OPTS_N_CHOICES 5 // number of choices, including "no change"
-#define LOG_OPTS_NO_CHANGE 4 // index of "no change"
+#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("warn user"), wxT("ask user"), wxT("end simulation"), wxT("no change") }
+#define LOG_OPTS_N_CHOICES_NORMAL 5
+#define LOG_OPTS_N_CHOICES 6 // number of choices, including "no change"
+#define LOG_OPTS_NO_CHANGE 5 // index of "no change"
#define LOG_OPTS_ADV wxT("For additional control over how each device responds to events, use the menu option \"Log ... By Device\".")
wxFlexGridSizer *gridSizer;
wxChoice *action[LOG_OPTS_N_TYPES];
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxmain.cc ./gui/wxmain.cc
--- /home/volker/bochs/bochs/gui/wxmain.cc 2016-12-26 17:12:57.470174541 +0100
+++ ./gui/wxmain.cc 2016-12-28 12:15:26.035961463 +0100
@@ -2,7 +2,7 @@
// $Id: wxmain.cc 13006 2016-12-26 16:12:54Z vruppert $
/////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -1158,6 +1158,10 @@
#if !BX_DEBUGGER && !BX_GDBSTUB
dlg.EnableButton(dlg.DEBUG, FALSE);
#endif
+ if (be->u.logmsg.flag != BX_LOG_ASK_ASKDLG) {
+ dlg.EnableButton(dlg.DIE, FALSE);
+ dlg.EnableButton(dlg.DUMP, FALSE);
+ }
dlg.SetContext(wxString(be->u.logmsg.prefix, wxConvUTF8));
dlg.SetMessage(wxString(be->u.logmsg.msg, wxConvUTF8));
int n = dlg.ShowModal();
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/x.cc ./gui/x.cc
--- /home/volker/bochs/bochs/gui/x.cc 2016-12-27 17:26:59.622665119 +0100
+++ ./gui/x.cc 2016-12-28 12:03:10.963351647 +0100
@@ -2687,11 +2687,7 @@
} else {
size_x = 30 + maxlen * 6;
}
- if (lines < 3) {
- size_y = 90;
- } else {
- size_y = 60 + lines * 15;
- }
+ size_y = 70 + lines * 15;
x11_dialog_c *xdlg = new x11_dialog_c(name, size_x, size_y,
(mode == XDLG_SIMPLE) ? 1 : 2);
ypos = 34;
@@ -2729,11 +2725,21 @@
bx_param_string_c *sparam;
bx_param_enum_c *eparam;
bx_list_c *list;
+ char message[256];
switch (event->type)
{
case BX_SYNC_EVT_LOG_ASK:
- event->retcode = x11_ask_dialog(event);
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ event->retcode = x11_ask_dialog(event);
+ } else if (event->u.logmsg.flag == BX_LOG_ASK_MSGBOX_WARN) {
+ const char *title = SIM->get_log_level_name(event->u.logmsg.level);
+ sprintf(message, "Device: %s\n\nMessage: %s", event->u.logmsg.prefix,
+ event->u.logmsg.msg);
+ bx_param_bool_c bparam(NULL, "warn", title, message, 1);
+ x11_message_box(&bparam, XDLG_SIMPLE);
+ event->retcode = 0;
+ }
return event;
case BX_SYNC_EVT_ASK_PARAM:
param = event->u.param.param;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/logio.cc ./logio.cc
--- /home/volker/bochs/bochs/logio.cc 2015-05-10 08:55:18.678940963 +0200
+++ ./logio.cc 2016-12-28 00:40:40.395736643 +0100
@@ -2,7 +2,7 @@
// $Id: logio.cc 12759 2015-05-10 06:55:16Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2001-2014 The Bochs Project
+// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -50,11 +50,25 @@
else return "?";
}
+static const char *act_name[N_ACT] = { "ignore", "report", "warn", "ask", "fatal" };
+
const char* iofunctions::getaction(int i) const
{
- static const char *name[] = { "ignore", "report", "ask", "fatal" };
assert (i>=ACT_IGNORE && i<N_ACT);
- return name[i];
+ return act_name[i];
+}
+
+int iofunctions::isaction(const char *val) const
+{
+ int action = -1;
+
+ for (int i = 0; i < N_ACT; i++) {
+ if (!strcmp(val, act_name[i])) {
+ action = ACT_IGNORE + i;
+ break;
+ }
+ }
+ return action;
}
void iofunctions::flush(void)
@@ -414,6 +428,11 @@
logio->out(LOGLEV_ERROR, prefix, fmt, ap);
va_end(ap);
+ if (onoff[LOGLEV_ERROR] == ACT_WARN) {
+ va_start(ap, fmt);
+ warn(LOGLEV_ERROR, prefix, fmt, ap);
+ va_end(ap);
+ }
if (onoff[LOGLEV_ERROR] == ACT_ASK) {
va_start(ap, fmt);
ask(LOGLEV_ERROR, prefix, fmt, ap);
@@ -438,6 +457,11 @@
logio->out(LOGLEV_PANIC, prefix, fmt, ap);
va_end(ap);
+ if (onoff[LOGLEV_PANIC] == ACT_WARN) {
+ va_start(ap, fmt);
+ warn(LOGLEV_PANIC, prefix, fmt, ap);
+ va_end(ap);
+ }
if (onoff[LOGLEV_PANIC] == ACT_ASK) {
va_start(ap, fmt);
ask(LOGLEV_PANIC, prefix, fmt, ap);
@@ -465,6 +489,36 @@
// the actions ask() and fatal() are not supported here
}
+void logfunctions::warn(int level, const char *prefix, const char *fmt, va_list ap)
+{
+ // Guard against reentry on warn() function. The danger is that some
+ // function that's called within warn() could trigger another
+ // BX_ERROR that could call warn() again, leading to infinite
+ // recursion and infinite asks.
+ static char in_warn_already = 0;
+ char buf1[1024];
+ if (in_warn_already) {
+ fprintf(stderr, "logfunctions::warn() should not reenter!!\n");
+ return;
+ }
+ in_warn_already = 1;
+ vsnprintf(buf1, sizeof(buf1), fmt, ap);
+ // FIXME: facility set to 0 because it's unknown.
+
+ // update vga screen. This is useful because sometimes useful messages
+ // are printed on the screen just before a panic. It's also potentially
+ // dangerous if this function calls ask again... That's why I added
+ // the reentry check above.
+ SIM->refresh_vga();
+
+ // ensure the text screen is showing
+ SIM->set_display_mode(DISP_MODE_CONFIG);
+ SIM->log_warn(prefix, level, buf1);
+ // return to simulation mode
+ SIM->set_display_mode(DISP_MODE_SIM);
+ in_warn_already = 0;
+}
+
void logfunctions::ask(int level, const char *prefix, const char *fmt, va_list ap)
{
// Guard against reentry on ask() function. The danger is that some
2016-12-28 18:06:34 +03:00
|
|
|
virtual int is_action_name(const char *val);
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual int get_default_log_action(int level) {
|
2011-12-30 15:13:37 +04:00
|
|
|
return logfunctions::get_default_action(level);
|
- How to handle default log options has been somewhat confused for a long
time, so I've tried to improve it. Now the logfunctions class has a
static field default_onoff[] which represents the default actions for
each kind of log message. Default_onoff[] is initialized with static
data so it should be valid by the time it's used. This can be reached by
static accesors logfunctions::set_default_action and
logfunctions::get_default_action. It seemed appropriate to put the defaults
inside the logfunctions class, rather than in bx_options or siminterface.
However, to make them accessible to the config interface, I added similar
methods in siminterface that map to the accessors in logfunctions.
- logio.cc had two different definitions of LOG_THIS for different halves
of the file, which was ugly and confusing. (LOG_THIS is needed for BX_INFO,
BX_DEBUG, etc.) I removed the first definition and fixed the minor compile
problems that ensued. In the initializers for iofunctions, everything
is complicated because of the unpredictable order that constructors get
called. They must use this->log to print things, because genlog hasn't
been initialized yet.
- now if SIM->set_log_action(int mod, int level, int action) is called
with mod<0, it sets the action for all modules/devices instead of just one.
- modified: bochs.h logio.cc main.cc gui/siminterface.cc gui/siminterface.h
2002-09-20 21:56:22 +04:00
|
|
|
}
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual void set_default_log_action(int level, int action) {
|
2011-12-30 15:13:37 +04:00
|
|
|
logfunctions::set_default_action(level, action);
|
- How to handle default log options has been somewhat confused for a long
time, so I've tried to improve it. Now the logfunctions class has a
static field default_onoff[] which represents the default actions for
each kind of log message. Default_onoff[] is initialized with static
data so it should be valid by the time it's used. This can be reached by
static accesors logfunctions::set_default_action and
logfunctions::get_default_action. It seemed appropriate to put the defaults
inside the logfunctions class, rather than in bx_options or siminterface.
However, to make them accessible to the config interface, I added similar
methods in siminterface that map to the accessors in logfunctions.
- logio.cc had two different definitions of LOG_THIS for different halves
of the file, which was ugly and confusing. (LOG_THIS is needed for BX_INFO,
BX_DEBUG, etc.) I removed the first definition and fixed the minor compile
problems that ensued. In the initializers for iofunctions, everything
is complicated because of the unpredictable order that constructors get
called. They must use this->log to print things, because genlog hasn't
been initialized yet.
- now if SIM->set_log_action(int mod, int level, int action) is called
with mod<0, it sets the action for all modules/devices instead of just one.
- modified: bochs.h logio.cc main.cc gui/siminterface.cc gui/siminterface.h
2002-09-20 21:56:22 +04:00
|
|
|
}
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual const char *get_log_level_name(int level);
|
2007-10-14 23:04:51 +04:00
|
|
|
virtual int get_max_log_level() { return N_LOGLEV; }
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual void quit_sim(int code);
|
|
|
|
virtual int get_exit_code() { return exit_code; }
|
|
|
|
virtual int get_default_rc(char *path, int len);
|
2006-03-13 21:55:53 +03:00
|
|
|
virtual int read_rc(const char *path);
|
|
|
|
virtual int write_rc(const char *path, int overwrite);
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual int get_log_file(char *path, int len);
|
2009-11-08 23:47:03 +03:00
|
|
|
virtual int set_log_file(const char *path);
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual int get_log_prefix(char *prefix, int len);
|
2009-11-08 23:47:03 +03:00
|
|
|
virtual int set_log_prefix(const char *prefix);
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual int get_debugger_log_file(char *path, int len);
|
2009-11-08 23:47:03 +03:00
|
|
|
virtual int set_debugger_log_file(const char *path);
|
2010-12-10 20:02:18 +03:00
|
|
|
virtual int hdimage_get_mode(const char *mode);
|
2006-03-05 13:24:29 +03:00
|
|
|
virtual void set_notify_callback(bxevent_handler func, void *arg);
|
|
|
|
virtual void get_notify_callback(bxevent_handler *func, void **arg);
|
|
|
|
virtual BxEvent* sim_to_ci_event(BxEvent *event);
|
2016-12-29 12:47:07 +03:00
|
|
|
virtual int log_dlg(const char *prefix, int level, const char *msg, int mode);
|
2014-01-12 12:26:04 +04:00
|
|
|
virtual void log_msg(const char *prefix, int level, const char *msg);
|
|
|
|
virtual void set_log_viewer(bx_bool val) { bx_log_viewer = val; }
|
|
|
|
virtual bx_bool has_log_viewer() const { return bx_log_viewer; }
|
2006-02-27 12:37:58 +03:00
|
|
|
virtual int ask_param(bx_param_c *param);
|
2006-02-22 22:18:29 +03:00
|
|
|
virtual int ask_param(const char *pname);
|
2002-04-18 04:22:20 +04:00
|
|
|
// ask the user for a pathname
|
2007-10-25 03:09:59 +04:00
|
|
|
virtual int ask_filename(const char *filename, int maxlen, const char *prompt, const char *the_default, int flags);
|
2006-06-01 00:12:43 +04:00
|
|
|
// yes/no dialog
|
2007-10-25 03:09:59 +04:00
|
|
|
virtual int ask_yes_no(const char *title, const char *prompt, bx_bool the_default);
|
2020-10-18 22:57:05 +03:00
|
|
|
// simple message box
|
|
|
|
virtual void message_box(const char *title, const char *message);
|
2002-04-18 04:22:20 +04:00
|
|
|
// called at a regular interval, currently by the keyboard handler.
|
2008-12-28 23:30:48 +03:00
|
|
|
virtual void periodic();
|
|
|
|
virtual int create_disk_image(const char *filename, int sectors, bx_bool overwrite);
|
|
|
|
virtual void refresh_ci();
|
|
|
|
virtual void refresh_vga() {
|
2012-10-28 12:23:39 +04:00
|
|
|
if (init_done) {
|
|
|
|
DEV_vga_refresh(0);
|
|
|
|
}
|
2002-09-23 21:41:42 +04:00
|
|
|
}
|
2008-12-28 23:30:48 +03:00
|
|
|
virtual void handle_events() {
|
2002-09-23 21:41:42 +04:00
|
|
|
// maybe need to check if something has been initialized yet?
|
2008-12-28 23:30:48 +03:00
|
|
|
bx_gui->handle_events();
|
2002-09-23 21:41:42 +04:00
|
|
|
}
|
2002-12-07 22:43:53 +03:00
|
|
|
// find first hard drive or cdrom
|
2006-02-26 22:11:20 +03:00
|
|
|
bx_param_c *get_first_atadevice(Bit32u search_type);
|
|
|
|
bx_param_c *get_first_cdrom() {
|
|
|
|
return get_first_atadevice(BX_ATA_DEVICE_CDROM);
|
2002-12-07 22:43:53 +03:00
|
|
|
}
|
2006-02-26 22:11:20 +03:00
|
|
|
bx_param_c *get_first_hd() {
|
|
|
|
return get_first_atadevice(BX_ATA_DEVICE_DISK);
|
2002-12-07 22:43:53 +03:00
|
|
|
}
|
2012-11-11 16:21:09 +04:00
|
|
|
virtual bx_bool is_pci_device(const char *name);
|
2018-02-25 23:59:30 +03:00
|
|
|
virtual bx_bool is_agp_device(const char *name);
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
#if BX_DEBUGGER
|
2008-12-28 23:30:48 +03:00
|
|
|
virtual void debug_break();
|
2014-01-12 12:26:04 +04:00
|
|
|
virtual void debug_interpret_cmd(char *cmd);
|
|
|
|
virtual char *debug_get_next_command();
|
2008-12-28 23:30:48 +03:00
|
|
|
virtual void debug_puts(const char *cmd);
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
#endif
|
2002-10-25 01:07:56 +04:00
|
|
|
virtual void register_configuration_interface (
|
2008-02-06 01:57:43 +03:00
|
|
|
const char* name,
|
2002-10-25 01:07:56 +04:00
|
|
|
config_interface_callback_t callback,
|
|
|
|
void *userdata);
|
|
|
|
virtual int configuration_interface(const char* name, ci_command_t command);
|
2008-12-28 23:30:48 +03:00
|
|
|
virtual int begin_simulation(int argc, char *argv[]);
|
2015-08-23 10:04:56 +03:00
|
|
|
virtual int register_runtime_config_handler(void *dev, rt_conf_handler_t handler);
|
|
|
|
virtual void unregister_runtime_config_handler(int id);
|
2011-06-11 23:38:52 +04:00
|
|
|
virtual void update_runtime_options();
|
2006-04-07 00:42:51 +04:00
|
|
|
virtual void set_sim_thread_func(is_sim_thread_func_t func) {}
|
|
|
|
virtual bx_bool is_sim_thread();
|
2012-07-01 18:37:13 +04:00
|
|
|
virtual void set_debug_gui(bx_bool val) { bx_debug_gui = val; }
|
|
|
|
virtual bx_bool has_debug_gui() const { return bx_debug_gui; }
|
2012-08-25 17:20:55 +04:00
|
|
|
virtual bx_bool is_wx_selected() const { return wxsel; }
|
2002-12-06 22:34:32 +03:00
|
|
|
// provide interface to bx_gui->set_display_mode() method for config
|
|
|
|
// interfaces to use.
|
2006-03-29 23:27:31 +04:00
|
|
|
virtual void set_display_mode(disp_mode_t newmode) {
|
2002-12-06 22:34:32 +03:00
|
|
|
if (bx_gui != NULL)
|
2006-03-29 23:27:31 +04:00
|
|
|
bx_gui->set_display_mode(newmode);
|
2002-12-06 22:34:32 +03:00
|
|
|
}
|
2006-04-07 00:42:51 +04:00
|
|
|
virtual bx_bool test_for_text_console();
|
2011-12-23 14:03:10 +04:00
|
|
|
// add-on config option support
|
|
|
|
virtual bx_bool register_addon_option(const char *keyword, addon_option_parser_t parser, addon_option_save_t save_func);
|
|
|
|
virtual bx_bool unregister_addon_option(const char *keyword);
|
|
|
|
virtual bx_bool is_addon_option(const char *keyword);
|
|
|
|
virtual Bit32s parse_addon_option(const char *context, int num_params, char *params []);
|
|
|
|
virtual Bit32s save_addon_options(FILE *fp);
|
2007-09-28 23:52:08 +04:00
|
|
|
|
2014-10-14 19:59:10 +04:00
|
|
|
// statistics
|
|
|
|
virtual void init_statistics();
|
|
|
|
virtual void cleanup_statistics();
|
|
|
|
virtual bx_list_c *get_statistics_root() {
|
|
|
|
return (bx_list_c*)get_param("statistics", NULL);
|
|
|
|
}
|
|
|
|
|
2006-04-07 00:42:51 +04:00
|
|
|
// save/restore support
|
2006-09-07 22:50:51 +04:00
|
|
|
virtual void init_save_restore();
|
2012-02-14 22:13:54 +04:00
|
|
|
virtual void cleanup_save_restore();
|
2006-04-07 16:49:50 +04:00
|
|
|
virtual bx_bool save_state(const char *checkpoint_path);
|
2006-04-07 00:42:51 +04:00
|
|
|
virtual bx_bool restore_config();
|
|
|
|
virtual bx_bool restore_logopts();
|
|
|
|
virtual bx_bool restore_hardware();
|
2007-09-28 23:52:08 +04:00
|
|
|
virtual bx_list_c *get_bochs_root() {
|
|
|
|
return (bx_list_c*)get_param("bochs", NULL);
|
2006-04-15 18:05:18 +04:00
|
|
|
}
|
2007-10-14 23:04:51 +04:00
|
|
|
virtual bx_bool restore_bochs_param(bx_list_c *root, const char *sr_path, const char *restore_name);
|
2012-01-16 21:11:16 +04:00
|
|
|
// special config parameter and options functions for plugins
|
2012-02-16 22:06:03 +04:00
|
|
|
virtual bx_bool opt_plugin_ctrl(const char *plugname, bx_bool load);
|
2012-01-16 21:11:16 +04:00
|
|
|
virtual void init_std_nic_options(const char *name, bx_list_c *menu);
|
|
|
|
virtual void init_usb_options(const char *usb_name, const char *pname, int maxports);
|
2013-01-26 22:17:23 +04:00
|
|
|
virtual int parse_param_from_list(const char *context, const char *param, bx_list_c *base);
|
2012-01-16 21:11:16 +04:00
|
|
|
virtual int parse_nic_params(const char *context, const char *param, bx_list_c *base);
|
|
|
|
virtual int parse_usb_port_params(const char *context, bx_bool devopt,
|
|
|
|
const char *param, int maxports, bx_list_c *base);
|
2020-12-05 00:09:18 +03:00
|
|
|
virtual int split_option_list(const char *msg, const char *rawopt, char **argv, int max_argv);
|
2013-01-20 02:37:15 +04:00
|
|
|
virtual int write_param_list(FILE *fp, bx_list_c *base, const char *optname, bx_bool multiline);
|
2012-01-16 21:11:16 +04:00
|
|
|
virtual int write_usb_options(FILE *fp, int maxports, bx_list_c *base);
|
2017-01-13 18:57:36 +03:00
|
|
|
#if BX_USE_GUI_CONSOLE
|
2017-01-01 20:45:06 +03:00
|
|
|
virtual int bx_printf(const char *fmt, ...);
|
|
|
|
virtual char* bx_gets(char *s, int size, FILE *stream);
|
|
|
|
#endif
|
2007-10-14 23:04:51 +04:00
|
|
|
|
2006-04-15 18:05:18 +04:00
|
|
|
private:
|
2007-10-14 04:20:30 +04:00
|
|
|
bx_bool save_sr_param(FILE *fp, bx_param_c *node, const char *sr_path, int level);
|
2001-06-08 11:20:07 +04:00
|
|
|
};
|
|
|
|
|
2006-02-17 00:44:17 +03:00
|
|
|
// recursive function to find parameters from the path
|
2006-03-07 01:03:16 +03:00
|
|
|
static bx_param_c *find_param(const char *full_pname, const char *rest_of_pname, bx_param_c *base)
|
2006-02-17 00:44:17 +03:00
|
|
|
{
|
|
|
|
const char *from = rest_of_pname;
|
|
|
|
char component[BX_PATHNAME_LEN];
|
|
|
|
char *to = component;
|
|
|
|
// copy the first piece of pname into component, stopping at first separator
|
|
|
|
// or at the end of the string
|
|
|
|
while (*from != 0 && *from != '.') {
|
|
|
|
*to = *from;
|
|
|
|
to++;
|
|
|
|
from++;
|
|
|
|
}
|
|
|
|
*to = 0;
|
|
|
|
if (!component[0]) {
|
2008-09-20 01:31:08 +04:00
|
|
|
BX_PANIC(("find_param: found empty component in parameter name '%s'", full_pname));
|
2006-02-17 00:44:17 +03:00
|
|
|
// or does that mean that we're done?
|
|
|
|
}
|
|
|
|
if (base->get_type() != BXT_LIST) {
|
2008-09-20 01:31:08 +04:00
|
|
|
BX_PANIC(("find_param: base was not a list!"));
|
2006-02-17 00:44:17 +03:00
|
|
|
}
|
|
|
|
BX_DEBUG(("searching for component '%s' in list '%s'", component, base->get_name()));
|
|
|
|
|
|
|
|
// find the component in the list.
|
|
|
|
bx_list_c *list = (bx_list_c *)base;
|
2006-03-05 13:24:29 +03:00
|
|
|
bx_param_c *child = list->get_by_name(component);
|
2006-02-17 00:44:17 +03:00
|
|
|
// if child not found, there is nothing else that can be done. return NULL.
|
|
|
|
if (child == NULL) return NULL;
|
|
|
|
if (from[0] == 0) {
|
|
|
|
// that was the end of the path, we're done
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
// continue parsing the path
|
|
|
|
BX_ASSERT(from[0] == '.');
|
|
|
|
from++; // skip over the separator
|
2006-03-05 13:24:29 +03:00
|
|
|
return find_param(full_pname, from, child);
|
2006-02-17 00:44:17 +03:00
|
|
|
}
|
|
|
|
|
2008-02-06 01:57:43 +03:00
|
|
|
bx_param_c *bx_real_sim_c::get_param(const char *pname, bx_param_c *base)
|
2006-02-17 00:44:17 +03:00
|
|
|
{
|
|
|
|
if (base == NULL)
|
|
|
|
base = root_param;
|
|
|
|
// to access top level object, look for parameter "."
|
|
|
|
if (pname[0] == '.' && pname[1] == 0)
|
|
|
|
return base;
|
2006-02-26 22:11:20 +03:00
|
|
|
return find_param(pname, pname, base);
|
2006-02-17 00:44:17 +03:00
|
|
|
}
|
|
|
|
|
2008-12-28 23:30:48 +03:00
|
|
|
bx_param_num_c *bx_real_sim_c::get_param_num(const char *pname, bx_param_c *base)
|
2006-05-30 02:33:38 +04:00
|
|
|
{
|
2009-03-26 12:19:56 +03:00
|
|
|
bx_param_c *gen = get_param(pname, base);
|
|
|
|
if (gen==NULL) {
|
2008-09-20 01:31:08 +04:00
|
|
|
BX_ERROR(("get_param_num(%s) could not find a parameter", pname));
|
2006-02-17 00:44:17 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-03-26 12:19:56 +03:00
|
|
|
int type = gen->get_type();
|
2006-02-17 00:44:17 +03:00
|
|
|
if (type == BXT_PARAM_NUM || type == BXT_PARAM_BOOL || type == BXT_PARAM_ENUM)
|
2009-03-26 12:19:56 +03:00
|
|
|
return (bx_param_num_c *)gen;
|
2018-01-19 23:27:04 +03:00
|
|
|
BX_ERROR(("get_param_num(%s) could not find a number parameter with that name", pname));
|
2006-02-17 00:44:17 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-05-30 02:33:38 +04:00
|
|
|
bx_param_string_c *bx_real_sim_c::get_param_string(const char *pname, bx_param_c *base)
|
|
|
|
{
|
2009-03-26 12:19:56 +03:00
|
|
|
bx_param_c *gen = get_param(pname, base);
|
|
|
|
if (gen==NULL) {
|
2008-09-20 01:31:08 +04:00
|
|
|
BX_ERROR(("get_param_string(%s) could not find a parameter", pname));
|
2006-02-17 00:44:17 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
2018-01-19 23:27:04 +03:00
|
|
|
if (gen->get_type() == BXT_PARAM_STRING || gen->get_type() == BXT_PARAM_BYTESTRING)
|
2009-03-26 12:19:56 +03:00
|
|
|
return (bx_param_string_c *)gen;
|
2018-01-19 23:27:04 +03:00
|
|
|
BX_ERROR(("get_param_string(%s) could not find a string parameter with that name", pname));
|
2006-02-17 00:44:17 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-05-30 02:33:38 +04:00
|
|
|
bx_param_bool_c *bx_real_sim_c::get_param_bool(const char *pname, bx_param_c *base)
|
|
|
|
{
|
2009-03-26 12:19:56 +03:00
|
|
|
bx_param_c *gen = get_param(pname, base);
|
|
|
|
if (gen==NULL) {
|
2008-09-20 01:31:08 +04:00
|
|
|
BX_ERROR(("get_param_bool(%s) could not find a parameter", pname));
|
2006-02-17 00:44:17 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-03-26 12:19:56 +03:00
|
|
|
if (gen->get_type () == BXT_PARAM_BOOL)
|
|
|
|
return (bx_param_bool_c *)gen;
|
2008-09-20 01:31:08 +04:00
|
|
|
BX_ERROR(("get_param_bool(%s) could not find a bool parameter with that name", pname));
|
2006-02-17 00:44:17 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-05-30 02:33:38 +04:00
|
|
|
bx_param_enum_c *bx_real_sim_c::get_param_enum(const char *pname, bx_param_c *base)
|
|
|
|
{
|
2009-03-26 12:19:56 +03:00
|
|
|
bx_param_c *gen = get_param(pname, base);
|
|
|
|
if (gen==NULL) {
|
2008-09-20 01:31:08 +04:00
|
|
|
BX_ERROR(("get_param_enum(%s) could not find a parameter", pname));
|
2006-02-17 00:44:17 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-03-26 12:19:56 +03:00
|
|
|
if (gen->get_type() == BXT_PARAM_ENUM)
|
|
|
|
return (bx_param_enum_c *)gen;
|
2008-09-20 01:31:08 +04:00
|
|
|
BX_ERROR(("get_param_enum(%s) could not find a enum parameter with that name", pname));
|
2006-02-17 00:44:17 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-03-06 21:50:55 +03:00
|
|
|
void bx_init_siminterface()
|
2001-06-08 11:20:07 +04:00
|
|
|
{
|
2013-12-29 12:45:28 +04:00
|
|
|
if (SIM == NULL) {
|
|
|
|
siminterface_log = new logfunctions();
|
|
|
|
siminterface_log->put("siminterface", "SIM");
|
2001-06-08 11:20:07 +04:00
|
|
|
SIM = new bx_real_sim_c();
|
2013-12-29 12:45:28 +04:00
|
|
|
}
|
2006-02-17 00:44:17 +03:00
|
|
|
if (root_param == NULL) {
|
2006-03-06 21:50:55 +03:00
|
|
|
root_param = new bx_list_c(NULL,
|
2006-03-07 20:54:27 +03:00
|
|
|
"bochs",
|
2012-02-12 22:43:20 +04:00
|
|
|
"list of top level bochs parameters"
|
|
|
|
);
|
2006-02-17 00:44:17 +03:00
|
|
|
}
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
|
|
|
|
2006-03-06 21:50:55 +03:00
|
|
|
bx_real_sim_c::bx_real_sim_c()
|
2001-06-11 18:03:35 +04:00
|
|
|
{
|
2002-10-25 01:07:56 +04:00
|
|
|
bxevent_callback = NULL;
|
|
|
|
bxevent_callback_data = NULL;
|
|
|
|
ci_callback = NULL;
|
|
|
|
ci_callback_data = NULL;
|
|
|
|
is_sim_thread_func = NULL;
|
2012-07-01 18:37:13 +04:00
|
|
|
bx_debug_gui = 0;
|
2014-01-12 12:26:04 +04:00
|
|
|
bx_log_viewer = 0;
|
2012-08-25 17:20:55 +04:00
|
|
|
wxsel = 0;
|
2008-02-06 01:57:43 +03:00
|
|
|
|
2002-04-18 04:22:20 +04:00
|
|
|
enabled = 1;
|
2001-06-19 08:55:01 +04:00
|
|
|
init_done = 0;
|
- 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
|
|
|
quit_context = NULL;
|
2002-12-16 09:43:02 +03:00
|
|
|
exit_code = 0;
|
2006-02-19 18:43:03 +03:00
|
|
|
param_id = BXP_NEW_PARAM_ID;
|
2011-06-11 23:38:52 +04:00
|
|
|
rt_conf_entries = NULL;
|
2011-12-23 14:03:10 +04:00
|
|
|
addon_options = NULL;
|
2001-06-18 18:11:55 +04:00
|
|
|
}
|
|
|
|
|
2006-03-07 20:54:27 +03:00
|
|
|
void bx_real_sim_c::reset_all_param()
|
2002-08-30 20:23:36 +04:00
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
bx_reset_options();
|
2002-08-30 20:23:36 +04:00
|
|
|
}
|
|
|
|
|
2006-03-07 20:54:27 +03:00
|
|
|
int bx_real_sim_c::get_n_log_modules()
|
2001-06-08 11:20:07 +04:00
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
return io->get_n_logfns();
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
|
|
|
|
2012-01-11 23:57:38 +04:00
|
|
|
const char *bx_real_sim_c::get_logfn_name(int mod)
|
2011-12-29 23:51:54 +04:00
|
|
|
{
|
|
|
|
logfunc_t *logfn = io->get_logfn(mod);
|
|
|
|
return logfn->get_name();
|
|
|
|
}
|
|
|
|
|
2011-12-30 15:13:37 +04:00
|
|
|
int bx_real_sim_c::get_logfn_id(const char *name)
|
|
|
|
{
|
|
|
|
logfunc_t *logfn;
|
|
|
|
int id = -1;
|
|
|
|
|
|
|
|
for (int i = 0; i < io->get_n_logfns(); i++) {
|
|
|
|
logfn = io->get_logfn(i);
|
|
|
|
if (!stricmp(name, logfn->get_name())) {
|
|
|
|
id = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2012-01-11 23:57:38 +04:00
|
|
|
const char *bx_real_sim_c::get_prefix(int mod)
|
2001-06-08 11:20:07 +04:00
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
logfunc_t *logfn = io->get_logfn(mod);
|
|
|
|
return logfn->getprefix();
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
|
|
|
|
2006-03-07 20:54:27 +03:00
|
|
|
int bx_real_sim_c::get_log_action(int mod, int level)
|
2001-06-08 11:20:07 +04:00
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
logfunc_t *logfn = io->get_logfn(mod);
|
|
|
|
return logfn->getonoff(level);
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
|
|
|
|
2006-03-07 20:54:27 +03:00
|
|
|
void bx_real_sim_c::set_log_action(int mod, int level, int action)
|
2001-06-08 11:20:07 +04:00
|
|
|
{
|
- How to handle default log options has been somewhat confused for a long
time, so I've tried to improve it. Now the logfunctions class has a
static field default_onoff[] which represents the default actions for
each kind of log message. Default_onoff[] is initialized with static
data so it should be valid by the time it's used. This can be reached by
static accesors logfunctions::set_default_action and
logfunctions::get_default_action. It seemed appropriate to put the defaults
inside the logfunctions class, rather than in bx_options or siminterface.
However, to make them accessible to the config interface, I added similar
methods in siminterface that map to the accessors in logfunctions.
- logio.cc had two different definitions of LOG_THIS for different halves
of the file, which was ugly and confusing. (LOG_THIS is needed for BX_INFO,
BX_DEBUG, etc.) I removed the first definition and fixed the minor compile
problems that ensued. In the initializers for iofunctions, everything
is complicated because of the unpredictable order that constructors get
called. They must use this->log to print things, because genlog hasn't
been initialized yet.
- now if SIM->set_log_action(int mod, int level, int action) is called
with mod<0, it sets the action for all modules/devices instead of just one.
- modified: bochs.h logio.cc main.cc gui/siminterface.cc gui/siminterface.h
2002-09-20 21:56:22 +04:00
|
|
|
// normal
|
|
|
|
if (mod >= 0) {
|
2006-03-07 20:54:27 +03:00
|
|
|
logfunc_t *logfn = io->get_logfn(mod);
|
|
|
|
logfn->setonoff(level, action);
|
|
|
|
return;
|
- How to handle default log options has been somewhat confused for a long
time, so I've tried to improve it. Now the logfunctions class has a
static field default_onoff[] which represents the default actions for
each kind of log message. Default_onoff[] is initialized with static
data so it should be valid by the time it's used. This can be reached by
static accesors logfunctions::set_default_action and
logfunctions::get_default_action. It seemed appropriate to put the defaults
inside the logfunctions class, rather than in bx_options or siminterface.
However, to make them accessible to the config interface, I added similar
methods in siminterface that map to the accessors in logfunctions.
- logio.cc had two different definitions of LOG_THIS for different halves
of the file, which was ugly and confusing. (LOG_THIS is needed for BX_INFO,
BX_DEBUG, etc.) I removed the first definition and fixed the minor compile
problems that ensued. In the initializers for iofunctions, everything
is complicated because of the unpredictable order that constructors get
called. They must use this->log to print things, because genlog hasn't
been initialized yet.
- now if SIM->set_log_action(int mod, int level, int action) is called
with mod<0, it sets the action for all modules/devices instead of just one.
- modified: bochs.h logio.cc main.cc gui/siminterface.cc gui/siminterface.h
2002-09-20 21:56:22 +04:00
|
|
|
}
|
|
|
|
// if called with mod<0 loop over all
|
2012-01-11 23:57:38 +04:00
|
|
|
int nmod = get_n_log_modules();
|
- How to handle default log options has been somewhat confused for a long
time, so I've tried to improve it. Now the logfunctions class has a
static field default_onoff[] which represents the default actions for
each kind of log message. Default_onoff[] is initialized with static
data so it should be valid by the time it's used. This can be reached by
static accesors logfunctions::set_default_action and
logfunctions::get_default_action. It seemed appropriate to put the defaults
inside the logfunctions class, rather than in bx_options or siminterface.
However, to make them accessible to the config interface, I added similar
methods in siminterface that map to the accessors in logfunctions.
- logio.cc had two different definitions of LOG_THIS for different halves
of the file, which was ugly and confusing. (LOG_THIS is needed for BX_INFO,
BX_DEBUG, etc.) I removed the first definition and fixed the minor compile
problems that ensued. In the initializers for iofunctions, everything
is complicated because of the unpredictable order that constructors get
called. They must use this->log to print things, because genlog hasn't
been initialized yet.
- now if SIM->set_log_action(int mod, int level, int action) is called
with mod<0, it sets the action for all modules/devices instead of just one.
- modified: bochs.h logio.cc main.cc gui/siminterface.cc gui/siminterface.h
2002-09-20 21:56:22 +04:00
|
|
|
for (mod=0; mod<nmod; mod++)
|
2006-03-07 20:54:27 +03:00
|
|
|
set_log_action(mod, level, action);
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
|
|
|
|
2012-01-11 23:57:38 +04:00
|
|
|
const char *bx_real_sim_c::get_action_name(int action)
|
2001-06-08 11:20:07 +04:00
|
|
|
{
|
2006-03-07 01:03:16 +03:00
|
|
|
return io->getaction(action);
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
|
|
|
|
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/bochs.h ./bochs.h
--- /home/volker/bochs/bochs/bochs.h 2016-08-12 19:06:18.803209189 +0200
+++ ./bochs.h 2016-12-28 00:41:20.000627252 +0100
@@ -2,7 +2,7 @@
// $Id: bochs.h 12935 2016-08-12 17:06:14Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2001-2015 The Bochs Project
+// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -276,8 +276,9 @@
void error(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
void panic(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
void ldebug(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
- void fatal (const char *prefix, const char *fmt, va_list ap, int exit_status);
- void ask (int level, const char *prefix, const char *fmt, va_list ap);
+ void fatal(const char *prefix, const char *fmt, va_list ap, int exit_status);
+ void warn(int level, const char *prefix, const char *fmt, va_list ap);
+ void ask(int level, const char *prefix, const char *fmt, va_list ap);
void put(const char *p);
void put(const char *n, const char *p);
void setio(class iofunctions *);
@@ -334,7 +335,8 @@
void set_log_action(int loglevel, int action);
const char *getlevel(int i) const;
const char *getaction(int i) const;
-
+ int isaction(const char *val) const;
+
protected:
int n_logfn;
#define MAX_LOGFNS 512
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/CHANGES ./CHANGES
--- /home/volker/bochs/bochs/CHANGES 2016-12-26 10:45:44.000000000 +0100
+++ ./CHANGES 2016-12-28 15:54:25.127088081 +0100
@@ -1,5 +1,8 @@
Changes after 2.6.8 release:
+- General
+ - Added new log action "warn", designed to show a message box on error events.
+
- Configure and compile
- Added Android host platform support.
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/config.cc ./config.cc
--- /home/volker/bochs/bochs/config.cc 2016-05-03 21:15:09.158016000 +0200
+++ ./config.cc 2016-12-27 19:53:10.461420368 +0100
@@ -2062,15 +2062,8 @@
actstr = strtok(NULL, "");
if (actstr != NULL) {
def_action = !strcmp(module, "action");
- if (!strcmp(actstr, "fatal"))
- action = ACT_FATAL;
- else if (!strcmp (actstr, "report"))
- action = ACT_REPORT;
- else if (!strcmp (actstr, "ignore"))
- action = ACT_IGNORE;
- else if (!strcmp (actstr, "ask"))
- action = ACT_ASK;
- else {
+ action = SIM->is_action_name(actstr);
+ if (action < ACT_IGNORE) {
PARSE_ERR(("%s: %s directive malformed.", context, params[0]));
free(param);
return -1;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/sdl2.cc ./gui/sdl2.cc
--- /home/volker/bochs/bochs/gui/sdl2.cc 2016-08-12 19:06:18.811209142 +0200
+++ ./gui/sdl2.cc 2016-12-28 12:33:39.534288819 +0100
@@ -2,7 +2,7 @@
// $Id: sdl2.cc 12935 2016-08-12 17:06:14Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2014-2015 The Bochs Project
+// Copyright (C) 2014-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -1478,20 +1478,16 @@
SDL_MessageBoxData msgboxdata;
SDL_MessageBoxButtonData buttondata[4];
int level, retcode;
-#if BX_DEBUGGER || BX_GDBSTUB
- int defbtn = 3;
-#else
- int defbtn = 2;
-#endif
char message[512];
level = event->u.logmsg.level;
- sprintf(message, "%s %s", event->u.logmsg.prefix, event->u.logmsg.msg);
+ sprintf(message, "Device: %s\nMessage: %s", event->u.logmsg.prefix,
+ event->u.logmsg.msg);
msgboxdata.flags = SDL_MESSAGEBOX_ERROR;
msgboxdata.window = window;
msgboxdata.title = SIM->get_log_level_name(level);
msgboxdata.message = message;
- msgboxdata.numbuttons = defbtn + 1;
+ msgboxdata.numbuttons = 2;
msgboxdata.buttons = buttondata;
msgboxdata.colorScheme = NULL;
buttondata[0].flags = 0;
@@ -1500,14 +1496,18 @@
buttondata[1].flags = 0;
buttondata[1].buttonid = BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS;
buttondata[1].text = "Alwayscont";
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ msgboxdata.numbuttons = 3;
+ buttondata[2].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
+ buttondata[2].buttonid = BX_LOG_ASK_CHOICE_DIE;
+ buttondata[2].text = "Quit";
#if BX_DEBUGGER || BX_GDBSTUB
- buttondata[2].flags = 0;
- buttondata[2].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG;
- buttondata[2].text = "Debugger";
-#endif
- buttondata[defbtn].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
- buttondata[defbtn].buttonid = BX_LOG_ASK_CHOICE_DIE;
- buttondata[defbtn].text = "Quit";
+ msgboxdata.numbuttons = 4;
+ buttondata[3].flags = 0;
+ buttondata[3].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG;
+ buttondata[3].text = "Debugger";
+#endif
+ }
if (SDL_ShowMessageBox(&msgboxdata, &retcode) < 0) {
return -1;
} else {
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.cc ./gui/siminterface.cc
--- /home/volker/bochs/bochs/gui/siminterface.cc 2016-12-05 19:56:56.729685000 +0100
+++ ./gui/siminterface.cc 2016-12-28 11:14:02.004075717 +0100
@@ -2,7 +2,7 @@
// $Id: siminterface.cc 12981 2016-12-05 18:56:56Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2015 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -100,6 +100,7 @@
virtual int get_log_action(int mod, int level);
virtual void set_log_action(int mod, int level, int action);
virtual const char *get_action_name(int action);
+ virtual int is_action_name(const char *val);
virtual int get_default_log_action(int level) {
return logfunctions::get_default_action(level);
}
@@ -123,6 +124,7 @@
virtual void set_notify_callback(bxevent_handler func, void *arg);
virtual void get_notify_callback(bxevent_handler *func, void **arg);
virtual BxEvent* sim_to_ci_event(BxEvent *event);
+ virtual int log_warn(const char *prefix, int level, const char *msg);
virtual int log_ask(const char *prefix, int level, const char *msg);
virtual void log_msg(const char *prefix, int level, const char *msg);
virtual void set_log_viewer(bx_bool val) { bx_log_viewer = val; }
@@ -420,6 +422,11 @@
return io->getaction(action);
}
+int bx_real_sim_c::is_action_name(const char *val)
+{
+ return io->isaction(val);
+}
+
const char *bx_real_sim_c::get_log_level_name(int level)
{
return io->getlevel(level);
@@ -575,6 +582,21 @@
}
}
+int bx_real_sim_c::log_warn(const char *prefix, int level, const char *msg)
+{
+ BxEvent be;
+ be.type = BX_SYNC_EVT_LOG_ASK;
+ be.u.logmsg.prefix = prefix;
+ be.u.logmsg.level = level;
+ be.u.logmsg.msg = msg;
+ be.u.logmsg.flag = BX_LOG_ASK_MSGBOX_WARN;
+ // default return value in case something goes wrong.
+ be.retcode = BX_LOG_NOTIFY_FAILED;
+ // calling notify
+ sim_to_ci_event(&be);
+ return be.retcode;
+}
+
// returns 0 for continue, 1 for alwayscontinue, 2 for die.
int bx_real_sim_c::log_ask(const char *prefix, int level, const char *msg)
{
@@ -583,6 +605,7 @@
be.u.logmsg.prefix = prefix;
be.u.logmsg.level = level;
be.u.logmsg.msg = msg;
+ be.u.logmsg.flag = BX_LOG_ASK_ASKDLG;
// default return value in case something goes wrong.
be.retcode = BX_LOG_NOTIFY_FAILED;
// calling notify
@@ -1157,16 +1180,10 @@
} else if (!strncmp(string, "PANIC=", 6)) {
type = LOGLEV_PANIC;
}
- if (!strcmp(string+j, "ignore")) {
- action = ACT_IGNORE;
- } else if (!strcmp(string+j, "report")) {
- action = ACT_REPORT;
- } else if (!strcmp(string+j, "ask")) {
- action = ACT_ASK;
- } else if (!strcmp(string+j, "fatal")) {
- action = ACT_FATAL;
+ action = is_action_name(string+j);
+ if (action >= ACT_IGNORE) {
+ set_log_action(dev, type, action);
}
- set_log_action(dev, type, action);
} else {
if (i == 1) {
BX_ERROR(("restore_logopts(): log module '%s' not found", devname));
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.h ./gui/siminterface.h
--- /home/volker/bochs/bochs/gui/siminterface.h 2016-03-31 19:24:37.451025427 +0200
+++ ./gui/siminterface.h 2016-12-28 11:11:21.036683362 +0100
@@ -168,6 +168,7 @@
typedef enum {
ACT_IGNORE = 0,
ACT_REPORT,
+ ACT_WARN,
ACT_ASK,
ACT_FATAL,
N_ACT
@@ -178,11 +179,11 @@
// normally all action choices are available for all event types. The exclude
// expression allows some choices to be eliminated if they don't make any
// sense. For example, it would be stupid to ignore a panic.
-#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
- /* can't die or ask, on debug or info events */ \
- (type <= LOGLEV_INFO && (choice == ACT_ASK || choice == ACT_FATAL)) \
- /* can't ignore panics */ \
- || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
+#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
+ /* can't die, ask or warn, on debug or info events */ \
+ (type <= LOGLEV_INFO && (choice >= ACT_WARN)) \
+ /* can't ignore panics */ \
+ || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
)
// floppy / cdrom media status
@@ -392,6 +393,7 @@
// synchronizing threads, etc. for each.
typedef struct {
Bit8u level;
+ Bit8u flag;
const char *prefix;
const char *msg;
} BxLogMsgEvent;
@@ -419,6 +421,12 @@
BX_LOG_NOTIFY_FAILED
};
+enum {
+ BX_LOG_ASK_ASKDLG,
+ BX_LOG_ASK_MSGBOX_WARN,
+ BX_LOG_ASK_MSGBOX_QUIT
+};
+
// Event type: BX_SYNC_EVT_GET_DBG_COMMAND
//
// This is a synchronous event sent from the simulator to the debugger
@@ -675,6 +683,7 @@
virtual int get_default_log_action(int level) {return -1;}
virtual void set_default_log_action(int level, int action) {}
virtual const char *get_action_name(int action) {return NULL;}
+ virtual int is_action_name(const char *val) {return -1;}
virtual const char *get_log_level_name(int level) {return NULL;}
virtual int get_max_log_level() {return -1;}
@@ -715,6 +724,9 @@
// send an event from the simulator to the CI.
virtual BxEvent* sim_to_ci_event(BxEvent *event) {return NULL;}
+ // called from simulator when it hits errors, to warn the user
+ // before continuing simulation
+ virtual int log_warn(const char *prefix, int level, const char *msg) {return -1;}
// called from simulator when it hits serious errors, to ask if the user
// wants to continue or not
virtual int log_ask(const char *prefix, int level, const char *msg) {return -1;}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/textconfig.cc ./gui/textconfig.cc
--- /home/volker/bochs/bochs/gui/textconfig.cc 2016-12-05 20:15:59.112637000 +0100
+++ ./gui/textconfig.cc 2016-12-28 12:44:43.079411258 +0100
@@ -2,7 +2,7 @@
// $Id: textconfig.cc 12983 2016-12-05 19:15:59Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2013 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -552,8 +552,8 @@
}
static const char *log_options_prompt1 = "Enter the ID of the device to edit, or -1 to return: [-1] ";
-static const char *log_level_choices[] = { "ignore", "report", "ask", "fatal", "no change" };
-static int log_level_n_choices_normal = 4;
+static const char *log_level_choices[N_ACT+1] = { "ignore", "report", "warn", "ask", "fatal", "no change" };
+static int log_level_n_choices_normal = N_ACT;
void bx_log_options(int individual)
{
@@ -589,7 +589,7 @@
bx_print_log_action_table();
for (int level=0; level<SIM->get_max_log_level(); level++) {
char prompt[1024];
- int action, default_action = 4; // default to no change
+ int action, default_action = N_ACT; // default to no change
sprintf(prompt, "Enter action for %s event on all devices: [no change] ", SIM->get_log_level_name(level));
// do show the no change choice (choices=4)
if (ask_menu(prompt, "", log_level_n_choices_normal+1, log_level_choices, default_action, &action)<0)
@@ -718,47 +718,50 @@
event->retcode = event->u.param.param->text_ask(stdin, stderr);
return event;
case BX_SYNC_EVT_LOG_ASK:
- {
- int level = event->u.logmsg.level;
- fprintf(stderr, "========================================================================\n");
- fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level));
- fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix);
- fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg);
- fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
- fprintf(stderr, " cont - continue execution\n");
- fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n");
- fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
- fprintf(stderr, " die - stop execution now\n");
- fprintf(stderr, " abort - dump core %s\n",
- BX_HAVE_ABORT ? "" : "(Disabled)");
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ int level = event->u.logmsg.level;
+ fprintf(stderr, "========================================================================\n");
+ fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level));
+ fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix);
+ fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg);
+ fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
+ fprintf(stderr, " cont - continue execution\n");
+ fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n");
+ fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
+ fprintf(stderr, " die - stop execution now\n");
+ fprintf(stderr, " abort - dump core %s\n",
+ BX_HAVE_ABORT ? "" : "(Disabled)");
#if BX_DEBUGGER
- fprintf(stderr, " debug - continue and return to bochs debugger\n");
+ fprintf(stderr, " debug - continue and return to bochs debugger\n");
#endif
#if BX_GDBSTUB
- fprintf(stderr, " debug - hand control to gdb\n");
+ fprintf(stderr, " debug - hand control to gdb\n");
#endif
- int choice;
+ int choice;
ask:
- if (ask_menu("Choose one of the actions above: [%s] ", "",
- log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
- event->retcode = -1;
- // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
- if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
- fflush(stdout);
- fflush(stderr);
- event->retcode = choice;
- }
- return event;
- case BX_ASYNC_EVT_REFRESH:
- case BX_ASYNC_EVT_DBG_MSG:
- case BX_ASYNC_EVT_LOG_MSG:
- // The text mode interface does not use these events, so just ignore
- // them.
- return event;
- default:
- fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type);
- return event;
+ if (ask_menu("Choose one of the actions above: [%s] ", "",
+ log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
+ event->retcode = -1;
+ // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
+ if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
+ fflush(stdout);
+ fflush(stderr);
+ event->retcode = choice;
+ } else {
+ // warning prompt not implemented
+ event->retcode = 0;
+ }
+ return event;
+ case BX_ASYNC_EVT_REFRESH:
+ case BX_ASYNC_EVT_DBG_MSG:
+ case BX_ASYNC_EVT_LOG_MSG:
+ // The text mode interface does not use these events, so just ignore
+ // them.
+ return event;
+ default:
+ fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type);
+ return event;
}
assert(0); // switch statement should return
}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/win32dialog.cc ./gui/win32dialog.cc
--- /home/volker/bochs/bochs/gui/win32dialog.cc 2014-06-20 11:32:02.034026376 +0200
+++ ./gui/win32dialog.cc 2016-12-28 12:50:14.148888740 +0100
@@ -2,7 +2,7 @@
// $Id: win32dialog.cc 12381 2014-06-20 09:31:56Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2003-2014 The Bochs Project
+// Copyright (C) 2003-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@
#include "win32res.h"
#include "win32paramdlg.h"
-const char log_choices[5][16] = {"ignore", "log", "ask user", "end simulation", "no change"};
+const char log_choices[N_ACT+1][16] = {"ignore", "log", "warn user", "ask user", "end simulation", "no change"};
HWND GetBochsWindow()
{
@@ -97,12 +97,16 @@
SetWindowText(GetDlgItem(hDlg, IDASKMSG), event->u.logmsg.msg);
SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue");
SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and don't ask again");
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
#if BX_DEBUGGER
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
#endif
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
+ } else {
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 0, 0);
+ }
SetFocus(GetDlgItem(hDlg, IDASKLIST));
return FALSE;
case WM_CLOSE:
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.cc ./gui/wxdialog.cc
--- /home/volker/bochs/bochs/gui/wxdialog.cc 2015-01-07 17:17:40.447882000 +0100
+++ ./gui/wxdialog.cc 2016-12-27 20:30:44.997609007 +0100
@@ -2,7 +2,7 @@
// $Id: wxdialog.cc 12594 2015-01-07 16:17:40Z sshwarts $
/////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -208,7 +208,6 @@
: wxDialog(parent, id, wxT(""), wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
- //static int integers[LOG_OPTS_N_CHOICES_NORMAL] = {0, 1, 2, 3};
static wxString names[] = ADVLOG_OPTS_TYPE_NAMES;
SetTitle(ADVLOG_OPTS_TITLE);
vertSizer = new wxBoxSizer(wxVERTICAL);
@@ -1563,7 +1562,7 @@
bool includeNoChange)
{
static wxString choices[] = LOG_OPTS_CHOICES;
- static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4};
+ static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4, 5};
wxChoice *control = new wxChoice(parent, id, wxDefaultPosition, wxDefaultSize);
int lastChoice = 0; // remember index of last choice
int nchoice = includeNoChange? LOG_OPTS_N_CHOICES : LOG_OPTS_N_CHOICES_NORMAL;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.h ./gui/wxdialog.h
--- /home/volker/bochs/bochs/gui/wxdialog.h 2014-12-23 20:30:12.896090221 +0100
+++ ./gui/wxdialog.h 2016-12-27 20:34:28.518389938 +0100
@@ -2,7 +2,7 @@
// $Id: wxdialog.h 12576 2014-12-23 19:30:03Z vruppert $
////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -354,10 +354,10 @@
#define LOG_OPTS_PROMPT wxT("How should Bochs respond to each type of event?")
#define LOG_OPTS_TYPE_NAMES { wxT("Debug events"), wxT("Info events"), wxT("Error events"), wxT("Panic events") }
#define LOG_OPTS_N_TYPES 4
-#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("ask user"), wxT("end simulation"), wxT("no change") }
-#define LOG_OPTS_N_CHOICES_NORMAL 4
-#define LOG_OPTS_N_CHOICES 5 // number of choices, including "no change"
-#define LOG_OPTS_NO_CHANGE 4 // index of "no change"
+#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("warn user"), wxT("ask user"), wxT("end simulation"), wxT("no change") }
+#define LOG_OPTS_N_CHOICES_NORMAL 5
+#define LOG_OPTS_N_CHOICES 6 // number of choices, including "no change"
+#define LOG_OPTS_NO_CHANGE 5 // index of "no change"
#define LOG_OPTS_ADV wxT("For additional control over how each device responds to events, use the menu option \"Log ... By Device\".")
wxFlexGridSizer *gridSizer;
wxChoice *action[LOG_OPTS_N_TYPES];
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxmain.cc ./gui/wxmain.cc
--- /home/volker/bochs/bochs/gui/wxmain.cc 2016-12-26 17:12:57.470174541 +0100
+++ ./gui/wxmain.cc 2016-12-28 12:15:26.035961463 +0100
@@ -2,7 +2,7 @@
// $Id: wxmain.cc 13006 2016-12-26 16:12:54Z vruppert $
/////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -1158,6 +1158,10 @@
#if !BX_DEBUGGER && !BX_GDBSTUB
dlg.EnableButton(dlg.DEBUG, FALSE);
#endif
+ if (be->u.logmsg.flag != BX_LOG_ASK_ASKDLG) {
+ dlg.EnableButton(dlg.DIE, FALSE);
+ dlg.EnableButton(dlg.DUMP, FALSE);
+ }
dlg.SetContext(wxString(be->u.logmsg.prefix, wxConvUTF8));
dlg.SetMessage(wxString(be->u.logmsg.msg, wxConvUTF8));
int n = dlg.ShowModal();
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/x.cc ./gui/x.cc
--- /home/volker/bochs/bochs/gui/x.cc 2016-12-27 17:26:59.622665119 +0100
+++ ./gui/x.cc 2016-12-28 12:03:10.963351647 +0100
@@ -2687,11 +2687,7 @@
} else {
size_x = 30 + maxlen * 6;
}
- if (lines < 3) {
- size_y = 90;
- } else {
- size_y = 60 + lines * 15;
- }
+ size_y = 70 + lines * 15;
x11_dialog_c *xdlg = new x11_dialog_c(name, size_x, size_y,
(mode == XDLG_SIMPLE) ? 1 : 2);
ypos = 34;
@@ -2729,11 +2725,21 @@
bx_param_string_c *sparam;
bx_param_enum_c *eparam;
bx_list_c *list;
+ char message[256];
switch (event->type)
{
case BX_SYNC_EVT_LOG_ASK:
- event->retcode = x11_ask_dialog(event);
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ event->retcode = x11_ask_dialog(event);
+ } else if (event->u.logmsg.flag == BX_LOG_ASK_MSGBOX_WARN) {
+ const char *title = SIM->get_log_level_name(event->u.logmsg.level);
+ sprintf(message, "Device: %s\n\nMessage: %s", event->u.logmsg.prefix,
+ event->u.logmsg.msg);
+ bx_param_bool_c bparam(NULL, "warn", title, message, 1);
+ x11_message_box(&bparam, XDLG_SIMPLE);
+ event->retcode = 0;
+ }
return event;
case BX_SYNC_EVT_ASK_PARAM:
param = event->u.param.param;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/logio.cc ./logio.cc
--- /home/volker/bochs/bochs/logio.cc 2015-05-10 08:55:18.678940963 +0200
+++ ./logio.cc 2016-12-28 00:40:40.395736643 +0100
@@ -2,7 +2,7 @@
// $Id: logio.cc 12759 2015-05-10 06:55:16Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2001-2014 The Bochs Project
+// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -50,11 +50,25 @@
else return "?";
}
+static const char *act_name[N_ACT] = { "ignore", "report", "warn", "ask", "fatal" };
+
const char* iofunctions::getaction(int i) const
{
- static const char *name[] = { "ignore", "report", "ask", "fatal" };
assert (i>=ACT_IGNORE && i<N_ACT);
- return name[i];
+ return act_name[i];
+}
+
+int iofunctions::isaction(const char *val) const
+{
+ int action = -1;
+
+ for (int i = 0; i < N_ACT; i++) {
+ if (!strcmp(val, act_name[i])) {
+ action = ACT_IGNORE + i;
+ break;
+ }
+ }
+ return action;
}
void iofunctions::flush(void)
@@ -414,6 +428,11 @@
logio->out(LOGLEV_ERROR, prefix, fmt, ap);
va_end(ap);
+ if (onoff[LOGLEV_ERROR] == ACT_WARN) {
+ va_start(ap, fmt);
+ warn(LOGLEV_ERROR, prefix, fmt, ap);
+ va_end(ap);
+ }
if (onoff[LOGLEV_ERROR] == ACT_ASK) {
va_start(ap, fmt);
ask(LOGLEV_ERROR, prefix, fmt, ap);
@@ -438,6 +457,11 @@
logio->out(LOGLEV_PANIC, prefix, fmt, ap);
va_end(ap);
+ if (onoff[LOGLEV_PANIC] == ACT_WARN) {
+ va_start(ap, fmt);
+ warn(LOGLEV_PANIC, prefix, fmt, ap);
+ va_end(ap);
+ }
if (onoff[LOGLEV_PANIC] == ACT_ASK) {
va_start(ap, fmt);
ask(LOGLEV_PANIC, prefix, fmt, ap);
@@ -465,6 +489,36 @@
// the actions ask() and fatal() are not supported here
}
+void logfunctions::warn(int level, const char *prefix, const char *fmt, va_list ap)
+{
+ // Guard against reentry on warn() function. The danger is that some
+ // function that's called within warn() could trigger another
+ // BX_ERROR that could call warn() again, leading to infinite
+ // recursion and infinite asks.
+ static char in_warn_already = 0;
+ char buf1[1024];
+ if (in_warn_already) {
+ fprintf(stderr, "logfunctions::warn() should not reenter!!\n");
+ return;
+ }
+ in_warn_already = 1;
+ vsnprintf(buf1, sizeof(buf1), fmt, ap);
+ // FIXME: facility set to 0 because it's unknown.
+
+ // update vga screen. This is useful because sometimes useful messages
+ // are printed on the screen just before a panic. It's also potentially
+ // dangerous if this function calls ask again... That's why I added
+ // the reentry check above.
+ SIM->refresh_vga();
+
+ // ensure the text screen is showing
+ SIM->set_display_mode(DISP_MODE_CONFIG);
+ SIM->log_warn(prefix, level, buf1);
+ // return to simulation mode
+ SIM->set_display_mode(DISP_MODE_SIM);
+ in_warn_already = 0;
+}
+
void logfunctions::ask(int level, const char *prefix, const char *fmt, va_list ap)
{
// Guard against reentry on ask() function. The danger is that some
2016-12-28 18:06:34 +03:00
|
|
|
int bx_real_sim_c::is_action_name(const char *val)
|
|
|
|
{
|
|
|
|
return io->isaction(val);
|
|
|
|
}
|
|
|
|
|
2006-03-07 01:03:16 +03:00
|
|
|
const char *bx_real_sim_c::get_log_level_name(int level)
|
2001-06-08 11:20:07 +04:00
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
return io->getlevel(level);
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
|
|
|
|
2008-09-20 01:31:08 +04:00
|
|
|
void bx_real_sim_c::quit_sim(int code)
|
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
BX_INFO(("quit_sim called with exit code %d", code));
|
2002-12-16 09:43:02 +03:00
|
|
|
exit_code = code;
|
2006-09-09 15:28:52 +04:00
|
|
|
io->exit_log();
|
- 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
|
|
|
// use longjmp to quit cleanly, no matter where in the stack we are.
|
2002-09-07 18:27:50 +04:00
|
|
|
if (quit_context != NULL) {
|
2006-03-07 20:54:27 +03:00
|
|
|
longjmp(*quit_context, 1);
|
|
|
|
BX_PANIC(("in bx_real_sim_c::quit_sim, longjmp should never return"));
|
2002-11-19 12:27:39 +03:00
|
|
|
} else {
|
2006-09-07 22:50:51 +04:00
|
|
|
// use exit() to stop the application.
|
2002-11-19 12:27:39 +03:00
|
|
|
if (!code)
|
2006-03-07 20:54:27 +03:00
|
|
|
BX_PANIC(("Quit simulation command"));
|
2006-03-12 01:40:32 +03:00
|
|
|
::exit(exit_code);
|
2002-11-19 12:27:39 +03:00
|
|
|
}
|
2001-06-08 11:20:07 +04:00
|
|
|
}
|
2001-06-10 00:01:12 +04:00
|
|
|
|
2006-03-07 20:54:27 +03:00
|
|
|
int bx_real_sim_c::get_default_rc(char *path, int len)
|
2001-06-10 00:01:12 +04:00
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
char *rc = bx_find_bochsrc();
|
2001-06-10 00:01:12 +04:00
|
|
|
if (rc == NULL) return -1;
|
2006-03-07 20:54:27 +03:00
|
|
|
strncpy(path, rc, len);
|
2002-10-14 17:31:25 +04:00
|
|
|
path[len-1] = 0;
|
2001-06-10 00:01:12 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-03-13 21:55:53 +03:00
|
|
|
int bx_real_sim_c::read_rc(const char *rc)
|
2001-06-10 00:01:12 +04:00
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
return bx_read_configuration(rc);
|
2001-06-10 00:01:12 +04:00
|
|
|
}
|
|
|
|
|
2001-06-11 10:35:18 +04:00
|
|
|
// return values:
|
|
|
|
// 0: written ok
|
|
|
|
// -1: failed
|
|
|
|
// -2: already exists, and overwrite was off
|
2006-03-13 21:55:53 +03:00
|
|
|
int bx_real_sim_c::write_rc(const char *rc, int overwrite)
|
2001-06-11 10:35:18 +04:00
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
return bx_write_configuration(rc, overwrite);
|
2001-06-11 10:35:18 +04:00
|
|
|
}
|
|
|
|
|
2006-03-07 01:03:16 +03:00
|
|
|
int bx_real_sim_c::get_log_file(char *path, int len)
|
2001-06-10 00:01:12 +04:00
|
|
|
{
|
2006-03-05 13:24:29 +03:00
|
|
|
strncpy(path, SIM->get_param_string(BXPN_LOG_FILENAME)->getptr(), len);
|
2001-06-10 00:01:12 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-08 23:47:03 +03:00
|
|
|
int bx_real_sim_c::set_log_file(const char *path)
|
2001-06-10 00:01:12 +04:00
|
|
|
{
|
2006-03-05 13:24:29 +03:00
|
|
|
SIM->get_param_string(BXPN_LOG_FILENAME)->set(path);
|
2001-06-10 00:01:12 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-03-07 01:03:16 +03:00
|
|
|
int bx_real_sim_c::get_log_prefix(char *prefix, int len)
|
2002-06-26 18:42:35 +04:00
|
|
|
{
|
2006-03-05 13:24:29 +03:00
|
|
|
strncpy(prefix, SIM->get_param_string(BXPN_LOG_PREFIX)->getptr(), len);
|
2002-06-26 18:42:35 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-08 23:47:03 +03:00
|
|
|
int bx_real_sim_c::set_log_prefix(const char *prefix)
|
2002-06-26 18:42:35 +04:00
|
|
|
{
|
2006-03-05 13:24:29 +03:00
|
|
|
SIM->get_param_string(BXPN_LOG_PREFIX)->set(prefix);
|
2002-06-26 18:42:35 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-03-07 01:03:16 +03:00
|
|
|
int bx_real_sim_c::get_debugger_log_file(char *path, int len)
|
2002-12-03 00:26:05 +03:00
|
|
|
{
|
2006-03-05 13:24:29 +03:00
|
|
|
strncpy(path, SIM->get_param_string(BXPN_DEBUGGER_LOG_FILENAME)->getptr(), len);
|
2002-12-03 00:26:05 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-08 23:47:03 +03:00
|
|
|
int bx_real_sim_c::set_debugger_log_file(const char *path)
|
2002-12-03 00:26:05 +03:00
|
|
|
{
|
2006-03-05 13:24:29 +03:00
|
|
|
SIM->get_param_string(BXPN_DEBUGGER_LOG_FILENAME)->set(path);
|
2002-12-03 00:26:05 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-03-23 22:05:16 +03:00
|
|
|
const char *floppy_devtype_names[] = { "none", "5.25\" 360K", "5.25\" 1.2M", "3.5\" 720K", "3.5\" 1.44M", "3.5\" 2.88M", NULL };
|
2007-10-25 03:09:59 +04:00
|
|
|
const char *floppy_type_names[] = { "none", "1.2M", "1.44M", "2.88M", "720K", "360K", "160K", "180K", "320K", "auto", NULL };
|
2005-11-20 20:22:44 +03:00
|
|
|
int floppy_type_n_sectors[] = { -1, 80*2*15, 80*2*18, 80*2*36, 80*2*9, 40*2*9, 40*1*8, 40*1*9, 40*2*8, -1 };
|
2013-01-25 21:56:40 +04:00
|
|
|
const char *media_status_names[] = { "ejected", "inserted", NULL };
|
2007-10-25 03:09:59 +04:00
|
|
|
const char *bochs_bootdisk_names[] = { "none", "floppy", "disk","cdrom", "network", NULL };
|
2003-05-03 20:37:18 +04:00
|
|
|
|
2015-02-22 23:29:58 +03:00
|
|
|
const char *sound_driver_names[] = {
|
|
|
|
"dummy",
|
2015-02-24 00:32:34 +03:00
|
|
|
#if BX_HAVE_SOUND_ALSA
|
2015-02-22 23:29:58 +03:00
|
|
|
"alsa",
|
|
|
|
#endif
|
2015-02-24 00:32:34 +03:00
|
|
|
#if BX_HAVE_SOUND_OSS
|
2015-02-22 23:29:58 +03:00
|
|
|
"oss",
|
|
|
|
#endif
|
2015-02-24 00:32:34 +03:00
|
|
|
#if BX_HAVE_SOUND_OSX
|
2015-02-22 23:29:58 +03:00
|
|
|
"osx",
|
|
|
|
#endif
|
2015-02-24 00:32:34 +03:00
|
|
|
#if BX_HAVE_SOUND_SDL
|
2015-02-22 23:29:58 +03:00
|
|
|
"sdl",
|
|
|
|
#endif
|
2015-02-24 00:32:34 +03:00
|
|
|
#if BX_HAVE_SOUND_WIN
|
2015-02-22 23:29:58 +03:00
|
|
|
"win",
|
|
|
|
#endif
|
|
|
|
"file",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *hdimage_mode_names[] = {
|
2010-02-26 01:04:31 +03:00
|
|
|
"flat",
|
|
|
|
"concat",
|
|
|
|
"external",
|
|
|
|
"dll",
|
|
|
|
"sparse",
|
|
|
|
"vmware3",
|
|
|
|
"vmware4",
|
|
|
|
"undoable",
|
|
|
|
"growing",
|
|
|
|
"volatile",
|
2010-12-23 19:17:12 +03:00
|
|
|
"vvfat",
|
2012-08-05 13:33:33 +04:00
|
|
|
"vpc",
|
2015-03-29 17:27:32 +03:00
|
|
|
"vbox",
|
2010-02-26 01:04:31 +03:00
|
|
|
NULL
|
|
|
|
};
|
2003-08-19 04:10:39 +04:00
|
|
|
|
2010-12-10 20:02:18 +03:00
|
|
|
int bx_real_sim_c::hdimage_get_mode(const char *mode)
|
|
|
|
{
|
2011-09-11 20:27:56 +04:00
|
|
|
for (int i = 0; i <= BX_HDIMAGE_MODE_LAST; i++) {
|
2010-12-10 20:02:18 +03:00
|
|
|
if (!strcmp(mode, hdimage_mode_names[i])) return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-03-07 20:54:27 +03:00
|
|
|
void bx_real_sim_c::set_notify_callback(bxevent_handler func, void *arg)
|
2001-06-11 18:03:35 +04:00
|
|
|
{
|
2002-10-25 01:07:56 +04:00
|
|
|
bxevent_callback = func;
|
|
|
|
bxevent_callback_data = arg;
|
2001-06-11 18:03:35 +04:00
|
|
|
}
|
|
|
|
|
2007-10-14 04:20:30 +04:00
|
|
|
void bx_real_sim_c::get_notify_callback(bxevent_handler *func, void **arg)
|
2002-09-23 20:57:45 +04:00
|
|
|
{
|
2002-10-25 01:07:56 +04:00
|
|
|
*func = bxevent_callback;
|
|
|
|
*arg = bxevent_callback_data;
|
2002-09-23 20:57:45 +04:00
|
|
|
}
|
|
|
|
|
2006-03-07 20:54:27 +03:00
|
|
|
BxEvent *bx_real_sim_c::sim_to_ci_event(BxEvent *event)
|
2001-06-11 18:03:35 +04:00
|
|
|
{
|
2002-10-25 01:07:56 +04:00
|
|
|
if (bxevent_callback == NULL) {
|
2006-03-07 20:54:27 +03:00
|
|
|
BX_ERROR(("notify called, but no bxevent_callback function is registered"));
|
2002-04-18 04:22:20 +04:00
|
|
|
return NULL;
|
2001-06-12 00:51:15 +04:00
|
|
|
} else {
|
2002-10-25 01:07:56 +04:00
|
|
|
return (*bxevent_callback)(bxevent_callback_data, event);
|
2001-06-11 18:03:35 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-29 12:47:07 +03:00
|
|
|
int bx_real_sim_c::log_dlg(const char *prefix, int level, const char *msg, int mode)
|
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/bochs.h ./bochs.h
--- /home/volker/bochs/bochs/bochs.h 2016-08-12 19:06:18.803209189 +0200
+++ ./bochs.h 2016-12-28 00:41:20.000627252 +0100
@@ -2,7 +2,7 @@
// $Id: bochs.h 12935 2016-08-12 17:06:14Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2001-2015 The Bochs Project
+// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -276,8 +276,9 @@
void error(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
void panic(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
void ldebug(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
- void fatal (const char *prefix, const char *fmt, va_list ap, int exit_status);
- void ask (int level, const char *prefix, const char *fmt, va_list ap);
+ void fatal(const char *prefix, const char *fmt, va_list ap, int exit_status);
+ void warn(int level, const char *prefix, const char *fmt, va_list ap);
+ void ask(int level, const char *prefix, const char *fmt, va_list ap);
void put(const char *p);
void put(const char *n, const char *p);
void setio(class iofunctions *);
@@ -334,7 +335,8 @@
void set_log_action(int loglevel, int action);
const char *getlevel(int i) const;
const char *getaction(int i) const;
-
+ int isaction(const char *val) const;
+
protected:
int n_logfn;
#define MAX_LOGFNS 512
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/CHANGES ./CHANGES
--- /home/volker/bochs/bochs/CHANGES 2016-12-26 10:45:44.000000000 +0100
+++ ./CHANGES 2016-12-28 15:54:25.127088081 +0100
@@ -1,5 +1,8 @@
Changes after 2.6.8 release:
+- General
+ - Added new log action "warn", designed to show a message box on error events.
+
- Configure and compile
- Added Android host platform support.
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/config.cc ./config.cc
--- /home/volker/bochs/bochs/config.cc 2016-05-03 21:15:09.158016000 +0200
+++ ./config.cc 2016-12-27 19:53:10.461420368 +0100
@@ -2062,15 +2062,8 @@
actstr = strtok(NULL, "");
if (actstr != NULL) {
def_action = !strcmp(module, "action");
- if (!strcmp(actstr, "fatal"))
- action = ACT_FATAL;
- else if (!strcmp (actstr, "report"))
- action = ACT_REPORT;
- else if (!strcmp (actstr, "ignore"))
- action = ACT_IGNORE;
- else if (!strcmp (actstr, "ask"))
- action = ACT_ASK;
- else {
+ action = SIM->is_action_name(actstr);
+ if (action < ACT_IGNORE) {
PARSE_ERR(("%s: %s directive malformed.", context, params[0]));
free(param);
return -1;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/sdl2.cc ./gui/sdl2.cc
--- /home/volker/bochs/bochs/gui/sdl2.cc 2016-08-12 19:06:18.811209142 +0200
+++ ./gui/sdl2.cc 2016-12-28 12:33:39.534288819 +0100
@@ -2,7 +2,7 @@
// $Id: sdl2.cc 12935 2016-08-12 17:06:14Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2014-2015 The Bochs Project
+// Copyright (C) 2014-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -1478,20 +1478,16 @@
SDL_MessageBoxData msgboxdata;
SDL_MessageBoxButtonData buttondata[4];
int level, retcode;
-#if BX_DEBUGGER || BX_GDBSTUB
- int defbtn = 3;
-#else
- int defbtn = 2;
-#endif
char message[512];
level = event->u.logmsg.level;
- sprintf(message, "%s %s", event->u.logmsg.prefix, event->u.logmsg.msg);
+ sprintf(message, "Device: %s\nMessage: %s", event->u.logmsg.prefix,
+ event->u.logmsg.msg);
msgboxdata.flags = SDL_MESSAGEBOX_ERROR;
msgboxdata.window = window;
msgboxdata.title = SIM->get_log_level_name(level);
msgboxdata.message = message;
- msgboxdata.numbuttons = defbtn + 1;
+ msgboxdata.numbuttons = 2;
msgboxdata.buttons = buttondata;
msgboxdata.colorScheme = NULL;
buttondata[0].flags = 0;
@@ -1500,14 +1496,18 @@
buttondata[1].flags = 0;
buttondata[1].buttonid = BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS;
buttondata[1].text = "Alwayscont";
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ msgboxdata.numbuttons = 3;
+ buttondata[2].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
+ buttondata[2].buttonid = BX_LOG_ASK_CHOICE_DIE;
+ buttondata[2].text = "Quit";
#if BX_DEBUGGER || BX_GDBSTUB
- buttondata[2].flags = 0;
- buttondata[2].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG;
- buttondata[2].text = "Debugger";
-#endif
- buttondata[defbtn].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
- buttondata[defbtn].buttonid = BX_LOG_ASK_CHOICE_DIE;
- buttondata[defbtn].text = "Quit";
+ msgboxdata.numbuttons = 4;
+ buttondata[3].flags = 0;
+ buttondata[3].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG;
+ buttondata[3].text = "Debugger";
+#endif
+ }
if (SDL_ShowMessageBox(&msgboxdata, &retcode) < 0) {
return -1;
} else {
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.cc ./gui/siminterface.cc
--- /home/volker/bochs/bochs/gui/siminterface.cc 2016-12-05 19:56:56.729685000 +0100
+++ ./gui/siminterface.cc 2016-12-28 11:14:02.004075717 +0100
@@ -2,7 +2,7 @@
// $Id: siminterface.cc 12981 2016-12-05 18:56:56Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2015 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -100,6 +100,7 @@
virtual int get_log_action(int mod, int level);
virtual void set_log_action(int mod, int level, int action);
virtual const char *get_action_name(int action);
+ virtual int is_action_name(const char *val);
virtual int get_default_log_action(int level) {
return logfunctions::get_default_action(level);
}
@@ -123,6 +124,7 @@
virtual void set_notify_callback(bxevent_handler func, void *arg);
virtual void get_notify_callback(bxevent_handler *func, void **arg);
virtual BxEvent* sim_to_ci_event(BxEvent *event);
+ virtual int log_warn(const char *prefix, int level, const char *msg);
virtual int log_ask(const char *prefix, int level, const char *msg);
virtual void log_msg(const char *prefix, int level, const char *msg);
virtual void set_log_viewer(bx_bool val) { bx_log_viewer = val; }
@@ -420,6 +422,11 @@
return io->getaction(action);
}
+int bx_real_sim_c::is_action_name(const char *val)
+{
+ return io->isaction(val);
+}
+
const char *bx_real_sim_c::get_log_level_name(int level)
{
return io->getlevel(level);
@@ -575,6 +582,21 @@
}
}
+int bx_real_sim_c::log_warn(const char *prefix, int level, const char *msg)
+{
+ BxEvent be;
+ be.type = BX_SYNC_EVT_LOG_ASK;
+ be.u.logmsg.prefix = prefix;
+ be.u.logmsg.level = level;
+ be.u.logmsg.msg = msg;
+ be.u.logmsg.flag = BX_LOG_ASK_MSGBOX_WARN;
+ // default return value in case something goes wrong.
+ be.retcode = BX_LOG_NOTIFY_FAILED;
+ // calling notify
+ sim_to_ci_event(&be);
+ return be.retcode;
+}
+
// returns 0 for continue, 1 for alwayscontinue, 2 for die.
int bx_real_sim_c::log_ask(const char *prefix, int level, const char *msg)
{
@@ -583,6 +605,7 @@
be.u.logmsg.prefix = prefix;
be.u.logmsg.level = level;
be.u.logmsg.msg = msg;
+ be.u.logmsg.flag = BX_LOG_ASK_ASKDLG;
// default return value in case something goes wrong.
be.retcode = BX_LOG_NOTIFY_FAILED;
// calling notify
@@ -1157,16 +1180,10 @@
} else if (!strncmp(string, "PANIC=", 6)) {
type = LOGLEV_PANIC;
}
- if (!strcmp(string+j, "ignore")) {
- action = ACT_IGNORE;
- } else if (!strcmp(string+j, "report")) {
- action = ACT_REPORT;
- } else if (!strcmp(string+j, "ask")) {
- action = ACT_ASK;
- } else if (!strcmp(string+j, "fatal")) {
- action = ACT_FATAL;
+ action = is_action_name(string+j);
+ if (action >= ACT_IGNORE) {
+ set_log_action(dev, type, action);
}
- set_log_action(dev, type, action);
} else {
if (i == 1) {
BX_ERROR(("restore_logopts(): log module '%s' not found", devname));
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.h ./gui/siminterface.h
--- /home/volker/bochs/bochs/gui/siminterface.h 2016-03-31 19:24:37.451025427 +0200
+++ ./gui/siminterface.h 2016-12-28 11:11:21.036683362 +0100
@@ -168,6 +168,7 @@
typedef enum {
ACT_IGNORE = 0,
ACT_REPORT,
+ ACT_WARN,
ACT_ASK,
ACT_FATAL,
N_ACT
@@ -178,11 +179,11 @@
// normally all action choices are available for all event types. The exclude
// expression allows some choices to be eliminated if they don't make any
// sense. For example, it would be stupid to ignore a panic.
-#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
- /* can't die or ask, on debug or info events */ \
- (type <= LOGLEV_INFO && (choice == ACT_ASK || choice == ACT_FATAL)) \
- /* can't ignore panics */ \
- || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
+#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
+ /* can't die, ask or warn, on debug or info events */ \
+ (type <= LOGLEV_INFO && (choice >= ACT_WARN)) \
+ /* can't ignore panics */ \
+ || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
)
// floppy / cdrom media status
@@ -392,6 +393,7 @@
// synchronizing threads, etc. for each.
typedef struct {
Bit8u level;
+ Bit8u flag;
const char *prefix;
const char *msg;
} BxLogMsgEvent;
@@ -419,6 +421,12 @@
BX_LOG_NOTIFY_FAILED
};
+enum {
+ BX_LOG_ASK_ASKDLG,
+ BX_LOG_ASK_MSGBOX_WARN,
+ BX_LOG_ASK_MSGBOX_QUIT
+};
+
// Event type: BX_SYNC_EVT_GET_DBG_COMMAND
//
// This is a synchronous event sent from the simulator to the debugger
@@ -675,6 +683,7 @@
virtual int get_default_log_action(int level) {return -1;}
virtual void set_default_log_action(int level, int action) {}
virtual const char *get_action_name(int action) {return NULL;}
+ virtual int is_action_name(const char *val) {return -1;}
virtual const char *get_log_level_name(int level) {return NULL;}
virtual int get_max_log_level() {return -1;}
@@ -715,6 +724,9 @@
// send an event from the simulator to the CI.
virtual BxEvent* sim_to_ci_event(BxEvent *event) {return NULL;}
+ // called from simulator when it hits errors, to warn the user
+ // before continuing simulation
+ virtual int log_warn(const char *prefix, int level, const char *msg) {return -1;}
// called from simulator when it hits serious errors, to ask if the user
// wants to continue or not
virtual int log_ask(const char *prefix, int level, const char *msg) {return -1;}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/textconfig.cc ./gui/textconfig.cc
--- /home/volker/bochs/bochs/gui/textconfig.cc 2016-12-05 20:15:59.112637000 +0100
+++ ./gui/textconfig.cc 2016-12-28 12:44:43.079411258 +0100
@@ -2,7 +2,7 @@
// $Id: textconfig.cc 12983 2016-12-05 19:15:59Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2013 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -552,8 +552,8 @@
}
static const char *log_options_prompt1 = "Enter the ID of the device to edit, or -1 to return: [-1] ";
-static const char *log_level_choices[] = { "ignore", "report", "ask", "fatal", "no change" };
-static int log_level_n_choices_normal = 4;
+static const char *log_level_choices[N_ACT+1] = { "ignore", "report", "warn", "ask", "fatal", "no change" };
+static int log_level_n_choices_normal = N_ACT;
void bx_log_options(int individual)
{
@@ -589,7 +589,7 @@
bx_print_log_action_table();
for (int level=0; level<SIM->get_max_log_level(); level++) {
char prompt[1024];
- int action, default_action = 4; // default to no change
+ int action, default_action = N_ACT; // default to no change
sprintf(prompt, "Enter action for %s event on all devices: [no change] ", SIM->get_log_level_name(level));
// do show the no change choice (choices=4)
if (ask_menu(prompt, "", log_level_n_choices_normal+1, log_level_choices, default_action, &action)<0)
@@ -718,47 +718,50 @@
event->retcode = event->u.param.param->text_ask(stdin, stderr);
return event;
case BX_SYNC_EVT_LOG_ASK:
- {
- int level = event->u.logmsg.level;
- fprintf(stderr, "========================================================================\n");
- fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level));
- fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix);
- fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg);
- fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
- fprintf(stderr, " cont - continue execution\n");
- fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n");
- fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
- fprintf(stderr, " die - stop execution now\n");
- fprintf(stderr, " abort - dump core %s\n",
- BX_HAVE_ABORT ? "" : "(Disabled)");
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ int level = event->u.logmsg.level;
+ fprintf(stderr, "========================================================================\n");
+ fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level));
+ fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix);
+ fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg);
+ fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
+ fprintf(stderr, " cont - continue execution\n");
+ fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n");
+ fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
+ fprintf(stderr, " die - stop execution now\n");
+ fprintf(stderr, " abort - dump core %s\n",
+ BX_HAVE_ABORT ? "" : "(Disabled)");
#if BX_DEBUGGER
- fprintf(stderr, " debug - continue and return to bochs debugger\n");
+ fprintf(stderr, " debug - continue and return to bochs debugger\n");
#endif
#if BX_GDBSTUB
- fprintf(stderr, " debug - hand control to gdb\n");
+ fprintf(stderr, " debug - hand control to gdb\n");
#endif
- int choice;
+ int choice;
ask:
- if (ask_menu("Choose one of the actions above: [%s] ", "",
- log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
- event->retcode = -1;
- // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
- if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
- fflush(stdout);
- fflush(stderr);
- event->retcode = choice;
- }
- return event;
- case BX_ASYNC_EVT_REFRESH:
- case BX_ASYNC_EVT_DBG_MSG:
- case BX_ASYNC_EVT_LOG_MSG:
- // The text mode interface does not use these events, so just ignore
- // them.
- return event;
- default:
- fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type);
- return event;
+ if (ask_menu("Choose one of the actions above: [%s] ", "",
+ log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
+ event->retcode = -1;
+ // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
+ if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
+ fflush(stdout);
+ fflush(stderr);
+ event->retcode = choice;
+ } else {
+ // warning prompt not implemented
+ event->retcode = 0;
+ }
+ return event;
+ case BX_ASYNC_EVT_REFRESH:
+ case BX_ASYNC_EVT_DBG_MSG:
+ case BX_ASYNC_EVT_LOG_MSG:
+ // The text mode interface does not use these events, so just ignore
+ // them.
+ return event;
+ default:
+ fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type);
+ return event;
}
assert(0); // switch statement should return
}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/win32dialog.cc ./gui/win32dialog.cc
--- /home/volker/bochs/bochs/gui/win32dialog.cc 2014-06-20 11:32:02.034026376 +0200
+++ ./gui/win32dialog.cc 2016-12-28 12:50:14.148888740 +0100
@@ -2,7 +2,7 @@
// $Id: win32dialog.cc 12381 2014-06-20 09:31:56Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2003-2014 The Bochs Project
+// Copyright (C) 2003-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@
#include "win32res.h"
#include "win32paramdlg.h"
-const char log_choices[5][16] = {"ignore", "log", "ask user", "end simulation", "no change"};
+const char log_choices[N_ACT+1][16] = {"ignore", "log", "warn user", "ask user", "end simulation", "no change"};
HWND GetBochsWindow()
{
@@ -97,12 +97,16 @@
SetWindowText(GetDlgItem(hDlg, IDASKMSG), event->u.logmsg.msg);
SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue");
SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and don't ask again");
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
#if BX_DEBUGGER
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
#endif
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
+ } else {
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 0, 0);
+ }
SetFocus(GetDlgItem(hDlg, IDASKLIST));
return FALSE;
case WM_CLOSE:
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.cc ./gui/wxdialog.cc
--- /home/volker/bochs/bochs/gui/wxdialog.cc 2015-01-07 17:17:40.447882000 +0100
+++ ./gui/wxdialog.cc 2016-12-27 20:30:44.997609007 +0100
@@ -2,7 +2,7 @@
// $Id: wxdialog.cc 12594 2015-01-07 16:17:40Z sshwarts $
/////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -208,7 +208,6 @@
: wxDialog(parent, id, wxT(""), wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
- //static int integers[LOG_OPTS_N_CHOICES_NORMAL] = {0, 1, 2, 3};
static wxString names[] = ADVLOG_OPTS_TYPE_NAMES;
SetTitle(ADVLOG_OPTS_TITLE);
vertSizer = new wxBoxSizer(wxVERTICAL);
@@ -1563,7 +1562,7 @@
bool includeNoChange)
{
static wxString choices[] = LOG_OPTS_CHOICES;
- static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4};
+ static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4, 5};
wxChoice *control = new wxChoice(parent, id, wxDefaultPosition, wxDefaultSize);
int lastChoice = 0; // remember index of last choice
int nchoice = includeNoChange? LOG_OPTS_N_CHOICES : LOG_OPTS_N_CHOICES_NORMAL;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.h ./gui/wxdialog.h
--- /home/volker/bochs/bochs/gui/wxdialog.h 2014-12-23 20:30:12.896090221 +0100
+++ ./gui/wxdialog.h 2016-12-27 20:34:28.518389938 +0100
@@ -2,7 +2,7 @@
// $Id: wxdialog.h 12576 2014-12-23 19:30:03Z vruppert $
////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -354,10 +354,10 @@
#define LOG_OPTS_PROMPT wxT("How should Bochs respond to each type of event?")
#define LOG_OPTS_TYPE_NAMES { wxT("Debug events"), wxT("Info events"), wxT("Error events"), wxT("Panic events") }
#define LOG_OPTS_N_TYPES 4
-#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("ask user"), wxT("end simulation"), wxT("no change") }
-#define LOG_OPTS_N_CHOICES_NORMAL 4
-#define LOG_OPTS_N_CHOICES 5 // number of choices, including "no change"
-#define LOG_OPTS_NO_CHANGE 4 // index of "no change"
+#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("warn user"), wxT("ask user"), wxT("end simulation"), wxT("no change") }
+#define LOG_OPTS_N_CHOICES_NORMAL 5
+#define LOG_OPTS_N_CHOICES 6 // number of choices, including "no change"
+#define LOG_OPTS_NO_CHANGE 5 // index of "no change"
#define LOG_OPTS_ADV wxT("For additional control over how each device responds to events, use the menu option \"Log ... By Device\".")
wxFlexGridSizer *gridSizer;
wxChoice *action[LOG_OPTS_N_TYPES];
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxmain.cc ./gui/wxmain.cc
--- /home/volker/bochs/bochs/gui/wxmain.cc 2016-12-26 17:12:57.470174541 +0100
+++ ./gui/wxmain.cc 2016-12-28 12:15:26.035961463 +0100
@@ -2,7 +2,7 @@
// $Id: wxmain.cc 13006 2016-12-26 16:12:54Z vruppert $
/////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -1158,6 +1158,10 @@
#if !BX_DEBUGGER && !BX_GDBSTUB
dlg.EnableButton(dlg.DEBUG, FALSE);
#endif
+ if (be->u.logmsg.flag != BX_LOG_ASK_ASKDLG) {
+ dlg.EnableButton(dlg.DIE, FALSE);
+ dlg.EnableButton(dlg.DUMP, FALSE);
+ }
dlg.SetContext(wxString(be->u.logmsg.prefix, wxConvUTF8));
dlg.SetMessage(wxString(be->u.logmsg.msg, wxConvUTF8));
int n = dlg.ShowModal();
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/x.cc ./gui/x.cc
--- /home/volker/bochs/bochs/gui/x.cc 2016-12-27 17:26:59.622665119 +0100
+++ ./gui/x.cc 2016-12-28 12:03:10.963351647 +0100
@@ -2687,11 +2687,7 @@
} else {
size_x = 30 + maxlen * 6;
}
- if (lines < 3) {
- size_y = 90;
- } else {
- size_y = 60 + lines * 15;
- }
+ size_y = 70 + lines * 15;
x11_dialog_c *xdlg = new x11_dialog_c(name, size_x, size_y,
(mode == XDLG_SIMPLE) ? 1 : 2);
ypos = 34;
@@ -2729,11 +2725,21 @@
bx_param_string_c *sparam;
bx_param_enum_c *eparam;
bx_list_c *list;
+ char message[256];
switch (event->type)
{
case BX_SYNC_EVT_LOG_ASK:
- event->retcode = x11_ask_dialog(event);
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ event->retcode = x11_ask_dialog(event);
+ } else if (event->u.logmsg.flag == BX_LOG_ASK_MSGBOX_WARN) {
+ const char *title = SIM->get_log_level_name(event->u.logmsg.level);
+ sprintf(message, "Device: %s\n\nMessage: %s", event->u.logmsg.prefix,
+ event->u.logmsg.msg);
+ bx_param_bool_c bparam(NULL, "warn", title, message, 1);
+ x11_message_box(&bparam, XDLG_SIMPLE);
+ event->retcode = 0;
+ }
return event;
case BX_SYNC_EVT_ASK_PARAM:
param = event->u.param.param;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/logio.cc ./logio.cc
--- /home/volker/bochs/bochs/logio.cc 2015-05-10 08:55:18.678940963 +0200
+++ ./logio.cc 2016-12-28 00:40:40.395736643 +0100
@@ -2,7 +2,7 @@
// $Id: logio.cc 12759 2015-05-10 06:55:16Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2001-2014 The Bochs Project
+// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -50,11 +50,25 @@
else return "?";
}
+static const char *act_name[N_ACT] = { "ignore", "report", "warn", "ask", "fatal" };
+
const char* iofunctions::getaction(int i) const
{
- static const char *name[] = { "ignore", "report", "ask", "fatal" };
assert (i>=ACT_IGNORE && i<N_ACT);
- return name[i];
+ return act_name[i];
+}
+
+int iofunctions::isaction(const char *val) const
+{
+ int action = -1;
+
+ for (int i = 0; i < N_ACT; i++) {
+ if (!strcmp(val, act_name[i])) {
+ action = ACT_IGNORE + i;
+ break;
+ }
+ }
+ return action;
}
void iofunctions::flush(void)
@@ -414,6 +428,11 @@
logio->out(LOGLEV_ERROR, prefix, fmt, ap);
va_end(ap);
+ if (onoff[LOGLEV_ERROR] == ACT_WARN) {
+ va_start(ap, fmt);
+ warn(LOGLEV_ERROR, prefix, fmt, ap);
+ va_end(ap);
+ }
if (onoff[LOGLEV_ERROR] == ACT_ASK) {
va_start(ap, fmt);
ask(LOGLEV_ERROR, prefix, fmt, ap);
@@ -438,6 +457,11 @@
logio->out(LOGLEV_PANIC, prefix, fmt, ap);
va_end(ap);
+ if (onoff[LOGLEV_PANIC] == ACT_WARN) {
+ va_start(ap, fmt);
+ warn(LOGLEV_PANIC, prefix, fmt, ap);
+ va_end(ap);
+ }
if (onoff[LOGLEV_PANIC] == ACT_ASK) {
va_start(ap, fmt);
ask(LOGLEV_PANIC, prefix, fmt, ap);
@@ -465,6 +489,36 @@
// the actions ask() and fatal() are not supported here
}
+void logfunctions::warn(int level, const char *prefix, const char *fmt, va_list ap)
+{
+ // Guard against reentry on warn() function. The danger is that some
+ // function that's called within warn() could trigger another
+ // BX_ERROR that could call warn() again, leading to infinite
+ // recursion and infinite asks.
+ static char in_warn_already = 0;
+ char buf1[1024];
+ if (in_warn_already) {
+ fprintf(stderr, "logfunctions::warn() should not reenter!!\n");
+ return;
+ }
+ in_warn_already = 1;
+ vsnprintf(buf1, sizeof(buf1), fmt, ap);
+ // FIXME: facility set to 0 because it's unknown.
+
+ // update vga screen. This is useful because sometimes useful messages
+ // are printed on the screen just before a panic. It's also potentially
+ // dangerous if this function calls ask again... That's why I added
+ // the reentry check above.
+ SIM->refresh_vga();
+
+ // ensure the text screen is showing
+ SIM->set_display_mode(DISP_MODE_CONFIG);
+ SIM->log_warn(prefix, level, buf1);
+ // return to simulation mode
+ SIM->set_display_mode(DISP_MODE_SIM);
+ in_warn_already = 0;
+}
+
void logfunctions::ask(int level, const char *prefix, const char *fmt, va_list ap)
{
// Guard against reentry on ask() function. The danger is that some
2016-12-28 18:06:34 +03:00
|
|
|
{
|
|
|
|
BxEvent be;
|
2016-12-29 12:47:07 +03:00
|
|
|
be.type = BX_SYNC_EVT_LOG_DLG;
|
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/bochs.h ./bochs.h
--- /home/volker/bochs/bochs/bochs.h 2016-08-12 19:06:18.803209189 +0200
+++ ./bochs.h 2016-12-28 00:41:20.000627252 +0100
@@ -2,7 +2,7 @@
// $Id: bochs.h 12935 2016-08-12 17:06:14Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2001-2015 The Bochs Project
+// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -276,8 +276,9 @@
void error(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
void panic(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
void ldebug(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
- void fatal (const char *prefix, const char *fmt, va_list ap, int exit_status);
- void ask (int level, const char *prefix, const char *fmt, va_list ap);
+ void fatal(const char *prefix, const char *fmt, va_list ap, int exit_status);
+ void warn(int level, const char *prefix, const char *fmt, va_list ap);
+ void ask(int level, const char *prefix, const char *fmt, va_list ap);
void put(const char *p);
void put(const char *n, const char *p);
void setio(class iofunctions *);
@@ -334,7 +335,8 @@
void set_log_action(int loglevel, int action);
const char *getlevel(int i) const;
const char *getaction(int i) const;
-
+ int isaction(const char *val) const;
+
protected:
int n_logfn;
#define MAX_LOGFNS 512
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/CHANGES ./CHANGES
--- /home/volker/bochs/bochs/CHANGES 2016-12-26 10:45:44.000000000 +0100
+++ ./CHANGES 2016-12-28 15:54:25.127088081 +0100
@@ -1,5 +1,8 @@
Changes after 2.6.8 release:
+- General
+ - Added new log action "warn", designed to show a message box on error events.
+
- Configure and compile
- Added Android host platform support.
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/config.cc ./config.cc
--- /home/volker/bochs/bochs/config.cc 2016-05-03 21:15:09.158016000 +0200
+++ ./config.cc 2016-12-27 19:53:10.461420368 +0100
@@ -2062,15 +2062,8 @@
actstr = strtok(NULL, "");
if (actstr != NULL) {
def_action = !strcmp(module, "action");
- if (!strcmp(actstr, "fatal"))
- action = ACT_FATAL;
- else if (!strcmp (actstr, "report"))
- action = ACT_REPORT;
- else if (!strcmp (actstr, "ignore"))
- action = ACT_IGNORE;
- else if (!strcmp (actstr, "ask"))
- action = ACT_ASK;
- else {
+ action = SIM->is_action_name(actstr);
+ if (action < ACT_IGNORE) {
PARSE_ERR(("%s: %s directive malformed.", context, params[0]));
free(param);
return -1;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/sdl2.cc ./gui/sdl2.cc
--- /home/volker/bochs/bochs/gui/sdl2.cc 2016-08-12 19:06:18.811209142 +0200
+++ ./gui/sdl2.cc 2016-12-28 12:33:39.534288819 +0100
@@ -2,7 +2,7 @@
// $Id: sdl2.cc 12935 2016-08-12 17:06:14Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2014-2015 The Bochs Project
+// Copyright (C) 2014-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -1478,20 +1478,16 @@
SDL_MessageBoxData msgboxdata;
SDL_MessageBoxButtonData buttondata[4];
int level, retcode;
-#if BX_DEBUGGER || BX_GDBSTUB
- int defbtn = 3;
-#else
- int defbtn = 2;
-#endif
char message[512];
level = event->u.logmsg.level;
- sprintf(message, "%s %s", event->u.logmsg.prefix, event->u.logmsg.msg);
+ sprintf(message, "Device: %s\nMessage: %s", event->u.logmsg.prefix,
+ event->u.logmsg.msg);
msgboxdata.flags = SDL_MESSAGEBOX_ERROR;
msgboxdata.window = window;
msgboxdata.title = SIM->get_log_level_name(level);
msgboxdata.message = message;
- msgboxdata.numbuttons = defbtn + 1;
+ msgboxdata.numbuttons = 2;
msgboxdata.buttons = buttondata;
msgboxdata.colorScheme = NULL;
buttondata[0].flags = 0;
@@ -1500,14 +1496,18 @@
buttondata[1].flags = 0;
buttondata[1].buttonid = BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS;
buttondata[1].text = "Alwayscont";
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ msgboxdata.numbuttons = 3;
+ buttondata[2].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
+ buttondata[2].buttonid = BX_LOG_ASK_CHOICE_DIE;
+ buttondata[2].text = "Quit";
#if BX_DEBUGGER || BX_GDBSTUB
- buttondata[2].flags = 0;
- buttondata[2].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG;
- buttondata[2].text = "Debugger";
-#endif
- buttondata[defbtn].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
- buttondata[defbtn].buttonid = BX_LOG_ASK_CHOICE_DIE;
- buttondata[defbtn].text = "Quit";
+ msgboxdata.numbuttons = 4;
+ buttondata[3].flags = 0;
+ buttondata[3].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG;
+ buttondata[3].text = "Debugger";
+#endif
+ }
if (SDL_ShowMessageBox(&msgboxdata, &retcode) < 0) {
return -1;
} else {
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.cc ./gui/siminterface.cc
--- /home/volker/bochs/bochs/gui/siminterface.cc 2016-12-05 19:56:56.729685000 +0100
+++ ./gui/siminterface.cc 2016-12-28 11:14:02.004075717 +0100
@@ -2,7 +2,7 @@
// $Id: siminterface.cc 12981 2016-12-05 18:56:56Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2015 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -100,6 +100,7 @@
virtual int get_log_action(int mod, int level);
virtual void set_log_action(int mod, int level, int action);
virtual const char *get_action_name(int action);
+ virtual int is_action_name(const char *val);
virtual int get_default_log_action(int level) {
return logfunctions::get_default_action(level);
}
@@ -123,6 +124,7 @@
virtual void set_notify_callback(bxevent_handler func, void *arg);
virtual void get_notify_callback(bxevent_handler *func, void **arg);
virtual BxEvent* sim_to_ci_event(BxEvent *event);
+ virtual int log_warn(const char *prefix, int level, const char *msg);
virtual int log_ask(const char *prefix, int level, const char *msg);
virtual void log_msg(const char *prefix, int level, const char *msg);
virtual void set_log_viewer(bx_bool val) { bx_log_viewer = val; }
@@ -420,6 +422,11 @@
return io->getaction(action);
}
+int bx_real_sim_c::is_action_name(const char *val)
+{
+ return io->isaction(val);
+}
+
const char *bx_real_sim_c::get_log_level_name(int level)
{
return io->getlevel(level);
@@ -575,6 +582,21 @@
}
}
+int bx_real_sim_c::log_warn(const char *prefix, int level, const char *msg)
+{
+ BxEvent be;
+ be.type = BX_SYNC_EVT_LOG_ASK;
+ be.u.logmsg.prefix = prefix;
+ be.u.logmsg.level = level;
+ be.u.logmsg.msg = msg;
+ be.u.logmsg.flag = BX_LOG_ASK_MSGBOX_WARN;
+ // default return value in case something goes wrong.
+ be.retcode = BX_LOG_NOTIFY_FAILED;
+ // calling notify
+ sim_to_ci_event(&be);
+ return be.retcode;
+}
+
// returns 0 for continue, 1 for alwayscontinue, 2 for die.
int bx_real_sim_c::log_ask(const char *prefix, int level, const char *msg)
{
@@ -583,6 +605,7 @@
be.u.logmsg.prefix = prefix;
be.u.logmsg.level = level;
be.u.logmsg.msg = msg;
+ be.u.logmsg.flag = BX_LOG_ASK_ASKDLG;
// default return value in case something goes wrong.
be.retcode = BX_LOG_NOTIFY_FAILED;
// calling notify
@@ -1157,16 +1180,10 @@
} else if (!strncmp(string, "PANIC=", 6)) {
type = LOGLEV_PANIC;
}
- if (!strcmp(string+j, "ignore")) {
- action = ACT_IGNORE;
- } else if (!strcmp(string+j, "report")) {
- action = ACT_REPORT;
- } else if (!strcmp(string+j, "ask")) {
- action = ACT_ASK;
- } else if (!strcmp(string+j, "fatal")) {
- action = ACT_FATAL;
+ action = is_action_name(string+j);
+ if (action >= ACT_IGNORE) {
+ set_log_action(dev, type, action);
}
- set_log_action(dev, type, action);
} else {
if (i == 1) {
BX_ERROR(("restore_logopts(): log module '%s' not found", devname));
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.h ./gui/siminterface.h
--- /home/volker/bochs/bochs/gui/siminterface.h 2016-03-31 19:24:37.451025427 +0200
+++ ./gui/siminterface.h 2016-12-28 11:11:21.036683362 +0100
@@ -168,6 +168,7 @@
typedef enum {
ACT_IGNORE = 0,
ACT_REPORT,
+ ACT_WARN,
ACT_ASK,
ACT_FATAL,
N_ACT
@@ -178,11 +179,11 @@
// normally all action choices are available for all event types. The exclude
// expression allows some choices to be eliminated if they don't make any
// sense. For example, it would be stupid to ignore a panic.
-#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
- /* can't die or ask, on debug or info events */ \
- (type <= LOGLEV_INFO && (choice == ACT_ASK || choice == ACT_FATAL)) \
- /* can't ignore panics */ \
- || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
+#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
+ /* can't die, ask or warn, on debug or info events */ \
+ (type <= LOGLEV_INFO && (choice >= ACT_WARN)) \
+ /* can't ignore panics */ \
+ || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
)
// floppy / cdrom media status
@@ -392,6 +393,7 @@
// synchronizing threads, etc. for each.
typedef struct {
Bit8u level;
+ Bit8u flag;
const char *prefix;
const char *msg;
} BxLogMsgEvent;
@@ -419,6 +421,12 @@
BX_LOG_NOTIFY_FAILED
};
+enum {
+ BX_LOG_ASK_ASKDLG,
+ BX_LOG_ASK_MSGBOX_WARN,
+ BX_LOG_ASK_MSGBOX_QUIT
+};
+
// Event type: BX_SYNC_EVT_GET_DBG_COMMAND
//
// This is a synchronous event sent from the simulator to the debugger
@@ -675,6 +683,7 @@
virtual int get_default_log_action(int level) {return -1;}
virtual void set_default_log_action(int level, int action) {}
virtual const char *get_action_name(int action) {return NULL;}
+ virtual int is_action_name(const char *val) {return -1;}
virtual const char *get_log_level_name(int level) {return NULL;}
virtual int get_max_log_level() {return -1;}
@@ -715,6 +724,9 @@
// send an event from the simulator to the CI.
virtual BxEvent* sim_to_ci_event(BxEvent *event) {return NULL;}
+ // called from simulator when it hits errors, to warn the user
+ // before continuing simulation
+ virtual int log_warn(const char *prefix, int level, const char *msg) {return -1;}
// called from simulator when it hits serious errors, to ask if the user
// wants to continue or not
virtual int log_ask(const char *prefix, int level, const char *msg) {return -1;}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/textconfig.cc ./gui/textconfig.cc
--- /home/volker/bochs/bochs/gui/textconfig.cc 2016-12-05 20:15:59.112637000 +0100
+++ ./gui/textconfig.cc 2016-12-28 12:44:43.079411258 +0100
@@ -2,7 +2,7 @@
// $Id: textconfig.cc 12983 2016-12-05 19:15:59Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2013 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -552,8 +552,8 @@
}
static const char *log_options_prompt1 = "Enter the ID of the device to edit, or -1 to return: [-1] ";
-static const char *log_level_choices[] = { "ignore", "report", "ask", "fatal", "no change" };
-static int log_level_n_choices_normal = 4;
+static const char *log_level_choices[N_ACT+1] = { "ignore", "report", "warn", "ask", "fatal", "no change" };
+static int log_level_n_choices_normal = N_ACT;
void bx_log_options(int individual)
{
@@ -589,7 +589,7 @@
bx_print_log_action_table();
for (int level=0; level<SIM->get_max_log_level(); level++) {
char prompt[1024];
- int action, default_action = 4; // default to no change
+ int action, default_action = N_ACT; // default to no change
sprintf(prompt, "Enter action for %s event on all devices: [no change] ", SIM->get_log_level_name(level));
// do show the no change choice (choices=4)
if (ask_menu(prompt, "", log_level_n_choices_normal+1, log_level_choices, default_action, &action)<0)
@@ -718,47 +718,50 @@
event->retcode = event->u.param.param->text_ask(stdin, stderr);
return event;
case BX_SYNC_EVT_LOG_ASK:
- {
- int level = event->u.logmsg.level;
- fprintf(stderr, "========================================================================\n");
- fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level));
- fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix);
- fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg);
- fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
- fprintf(stderr, " cont - continue execution\n");
- fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n");
- fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
- fprintf(stderr, " die - stop execution now\n");
- fprintf(stderr, " abort - dump core %s\n",
- BX_HAVE_ABORT ? "" : "(Disabled)");
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ int level = event->u.logmsg.level;
+ fprintf(stderr, "========================================================================\n");
+ fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level));
+ fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix);
+ fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg);
+ fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
+ fprintf(stderr, " cont - continue execution\n");
+ fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n");
+ fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
+ fprintf(stderr, " die - stop execution now\n");
+ fprintf(stderr, " abort - dump core %s\n",
+ BX_HAVE_ABORT ? "" : "(Disabled)");
#if BX_DEBUGGER
- fprintf(stderr, " debug - continue and return to bochs debugger\n");
+ fprintf(stderr, " debug - continue and return to bochs debugger\n");
#endif
#if BX_GDBSTUB
- fprintf(stderr, " debug - hand control to gdb\n");
+ fprintf(stderr, " debug - hand control to gdb\n");
#endif
- int choice;
+ int choice;
ask:
- if (ask_menu("Choose one of the actions above: [%s] ", "",
- log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
- event->retcode = -1;
- // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
- if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
- fflush(stdout);
- fflush(stderr);
- event->retcode = choice;
- }
- return event;
- case BX_ASYNC_EVT_REFRESH:
- case BX_ASYNC_EVT_DBG_MSG:
- case BX_ASYNC_EVT_LOG_MSG:
- // The text mode interface does not use these events, so just ignore
- // them.
- return event;
- default:
- fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type);
- return event;
+ if (ask_menu("Choose one of the actions above: [%s] ", "",
+ log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
+ event->retcode = -1;
+ // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
+ if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
+ fflush(stdout);
+ fflush(stderr);
+ event->retcode = choice;
+ } else {
+ // warning prompt not implemented
+ event->retcode = 0;
+ }
+ return event;
+ case BX_ASYNC_EVT_REFRESH:
+ case BX_ASYNC_EVT_DBG_MSG:
+ case BX_ASYNC_EVT_LOG_MSG:
+ // The text mode interface does not use these events, so just ignore
+ // them.
+ return event;
+ default:
+ fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type);
+ return event;
}
assert(0); // switch statement should return
}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/win32dialog.cc ./gui/win32dialog.cc
--- /home/volker/bochs/bochs/gui/win32dialog.cc 2014-06-20 11:32:02.034026376 +0200
+++ ./gui/win32dialog.cc 2016-12-28 12:50:14.148888740 +0100
@@ -2,7 +2,7 @@
// $Id: win32dialog.cc 12381 2014-06-20 09:31:56Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2003-2014 The Bochs Project
+// Copyright (C) 2003-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@
#include "win32res.h"
#include "win32paramdlg.h"
-const char log_choices[5][16] = {"ignore", "log", "ask user", "end simulation", "no change"};
+const char log_choices[N_ACT+1][16] = {"ignore", "log", "warn user", "ask user", "end simulation", "no change"};
HWND GetBochsWindow()
{
@@ -97,12 +97,16 @@
SetWindowText(GetDlgItem(hDlg, IDASKMSG), event->u.logmsg.msg);
SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue");
SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and don't ask again");
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
#if BX_DEBUGGER
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
#endif
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
+ } else {
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 0, 0);
+ }
SetFocus(GetDlgItem(hDlg, IDASKLIST));
return FALSE;
case WM_CLOSE:
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.cc ./gui/wxdialog.cc
--- /home/volker/bochs/bochs/gui/wxdialog.cc 2015-01-07 17:17:40.447882000 +0100
+++ ./gui/wxdialog.cc 2016-12-27 20:30:44.997609007 +0100
@@ -2,7 +2,7 @@
// $Id: wxdialog.cc 12594 2015-01-07 16:17:40Z sshwarts $
/////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -208,7 +208,6 @@
: wxDialog(parent, id, wxT(""), wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
- //static int integers[LOG_OPTS_N_CHOICES_NORMAL] = {0, 1, 2, 3};
static wxString names[] = ADVLOG_OPTS_TYPE_NAMES;
SetTitle(ADVLOG_OPTS_TITLE);
vertSizer = new wxBoxSizer(wxVERTICAL);
@@ -1563,7 +1562,7 @@
bool includeNoChange)
{
static wxString choices[] = LOG_OPTS_CHOICES;
- static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4};
+ static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4, 5};
wxChoice *control = new wxChoice(parent, id, wxDefaultPosition, wxDefaultSize);
int lastChoice = 0; // remember index of last choice
int nchoice = includeNoChange? LOG_OPTS_N_CHOICES : LOG_OPTS_N_CHOICES_NORMAL;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.h ./gui/wxdialog.h
--- /home/volker/bochs/bochs/gui/wxdialog.h 2014-12-23 20:30:12.896090221 +0100
+++ ./gui/wxdialog.h 2016-12-27 20:34:28.518389938 +0100
@@ -2,7 +2,7 @@
// $Id: wxdialog.h 12576 2014-12-23 19:30:03Z vruppert $
////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -354,10 +354,10 @@
#define LOG_OPTS_PROMPT wxT("How should Bochs respond to each type of event?")
#define LOG_OPTS_TYPE_NAMES { wxT("Debug events"), wxT("Info events"), wxT("Error events"), wxT("Panic events") }
#define LOG_OPTS_N_TYPES 4
-#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("ask user"), wxT("end simulation"), wxT("no change") }
-#define LOG_OPTS_N_CHOICES_NORMAL 4
-#define LOG_OPTS_N_CHOICES 5 // number of choices, including "no change"
-#define LOG_OPTS_NO_CHANGE 4 // index of "no change"
+#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("warn user"), wxT("ask user"), wxT("end simulation"), wxT("no change") }
+#define LOG_OPTS_N_CHOICES_NORMAL 5
+#define LOG_OPTS_N_CHOICES 6 // number of choices, including "no change"
+#define LOG_OPTS_NO_CHANGE 5 // index of "no change"
#define LOG_OPTS_ADV wxT("For additional control over how each device responds to events, use the menu option \"Log ... By Device\".")
wxFlexGridSizer *gridSizer;
wxChoice *action[LOG_OPTS_N_TYPES];
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxmain.cc ./gui/wxmain.cc
--- /home/volker/bochs/bochs/gui/wxmain.cc 2016-12-26 17:12:57.470174541 +0100
+++ ./gui/wxmain.cc 2016-12-28 12:15:26.035961463 +0100
@@ -2,7 +2,7 @@
// $Id: wxmain.cc 13006 2016-12-26 16:12:54Z vruppert $
/////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -1158,6 +1158,10 @@
#if !BX_DEBUGGER && !BX_GDBSTUB
dlg.EnableButton(dlg.DEBUG, FALSE);
#endif
+ if (be->u.logmsg.flag != BX_LOG_ASK_ASKDLG) {
+ dlg.EnableButton(dlg.DIE, FALSE);
+ dlg.EnableButton(dlg.DUMP, FALSE);
+ }
dlg.SetContext(wxString(be->u.logmsg.prefix, wxConvUTF8));
dlg.SetMessage(wxString(be->u.logmsg.msg, wxConvUTF8));
int n = dlg.ShowModal();
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/x.cc ./gui/x.cc
--- /home/volker/bochs/bochs/gui/x.cc 2016-12-27 17:26:59.622665119 +0100
+++ ./gui/x.cc 2016-12-28 12:03:10.963351647 +0100
@@ -2687,11 +2687,7 @@
} else {
size_x = 30 + maxlen * 6;
}
- if (lines < 3) {
- size_y = 90;
- } else {
- size_y = 60 + lines * 15;
- }
+ size_y = 70 + lines * 15;
x11_dialog_c *xdlg = new x11_dialog_c(name, size_x, size_y,
(mode == XDLG_SIMPLE) ? 1 : 2);
ypos = 34;
@@ -2729,11 +2725,21 @@
bx_param_string_c *sparam;
bx_param_enum_c *eparam;
bx_list_c *list;
+ char message[256];
switch (event->type)
{
case BX_SYNC_EVT_LOG_ASK:
- event->retcode = x11_ask_dialog(event);
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ event->retcode = x11_ask_dialog(event);
+ } else if (event->u.logmsg.flag == BX_LOG_ASK_MSGBOX_WARN) {
+ const char *title = SIM->get_log_level_name(event->u.logmsg.level);
+ sprintf(message, "Device: %s\n\nMessage: %s", event->u.logmsg.prefix,
+ event->u.logmsg.msg);
+ bx_param_bool_c bparam(NULL, "warn", title, message, 1);
+ x11_message_box(&bparam, XDLG_SIMPLE);
+ event->retcode = 0;
+ }
return event;
case BX_SYNC_EVT_ASK_PARAM:
param = event->u.param.param;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/logio.cc ./logio.cc
--- /home/volker/bochs/bochs/logio.cc 2015-05-10 08:55:18.678940963 +0200
+++ ./logio.cc 2016-12-28 00:40:40.395736643 +0100
@@ -2,7 +2,7 @@
// $Id: logio.cc 12759 2015-05-10 06:55:16Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2001-2014 The Bochs Project
+// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -50,11 +50,25 @@
else return "?";
}
+static const char *act_name[N_ACT] = { "ignore", "report", "warn", "ask", "fatal" };
+
const char* iofunctions::getaction(int i) const
{
- static const char *name[] = { "ignore", "report", "ask", "fatal" };
assert (i>=ACT_IGNORE && i<N_ACT);
- return name[i];
+ return act_name[i];
+}
+
+int iofunctions::isaction(const char *val) const
+{
+ int action = -1;
+
+ for (int i = 0; i < N_ACT; i++) {
+ if (!strcmp(val, act_name[i])) {
+ action = ACT_IGNORE + i;
+ break;
+ }
+ }
+ return action;
}
void iofunctions::flush(void)
@@ -414,6 +428,11 @@
logio->out(LOGLEV_ERROR, prefix, fmt, ap);
va_end(ap);
+ if (onoff[LOGLEV_ERROR] == ACT_WARN) {
+ va_start(ap, fmt);
+ warn(LOGLEV_ERROR, prefix, fmt, ap);
+ va_end(ap);
+ }
if (onoff[LOGLEV_ERROR] == ACT_ASK) {
va_start(ap, fmt);
ask(LOGLEV_ERROR, prefix, fmt, ap);
@@ -438,6 +457,11 @@
logio->out(LOGLEV_PANIC, prefix, fmt, ap);
va_end(ap);
+ if (onoff[LOGLEV_PANIC] == ACT_WARN) {
+ va_start(ap, fmt);
+ warn(LOGLEV_PANIC, prefix, fmt, ap);
+ va_end(ap);
+ }
if (onoff[LOGLEV_PANIC] == ACT_ASK) {
va_start(ap, fmt);
ask(LOGLEV_PANIC, prefix, fmt, ap);
@@ -465,6 +489,36 @@
// the actions ask() and fatal() are not supported here
}
+void logfunctions::warn(int level, const char *prefix, const char *fmt, va_list ap)
+{
+ // Guard against reentry on warn() function. The danger is that some
+ // function that's called within warn() could trigger another
+ // BX_ERROR that could call warn() again, leading to infinite
+ // recursion and infinite asks.
+ static char in_warn_already = 0;
+ char buf1[1024];
+ if (in_warn_already) {
+ fprintf(stderr, "logfunctions::warn() should not reenter!!\n");
+ return;
+ }
+ in_warn_already = 1;
+ vsnprintf(buf1, sizeof(buf1), fmt, ap);
+ // FIXME: facility set to 0 because it's unknown.
+
+ // update vga screen. This is useful because sometimes useful messages
+ // are printed on the screen just before a panic. It's also potentially
+ // dangerous if this function calls ask again... That's why I added
+ // the reentry check above.
+ SIM->refresh_vga();
+
+ // ensure the text screen is showing
+ SIM->set_display_mode(DISP_MODE_CONFIG);
+ SIM->log_warn(prefix, level, buf1);
+ // return to simulation mode
+ SIM->set_display_mode(DISP_MODE_SIM);
+ in_warn_already = 0;
+}
+
void logfunctions::ask(int level, const char *prefix, const char *fmt, va_list ap)
{
// Guard against reentry on ask() function. The danger is that some
2016-12-28 18:06:34 +03:00
|
|
|
be.u.logmsg.prefix = prefix;
|
|
|
|
be.u.logmsg.level = level;
|
|
|
|
be.u.logmsg.msg = msg;
|
2016-12-29 12:47:07 +03:00
|
|
|
be.u.logmsg.mode = mode;
|
2002-10-25 01:07:56 +04:00
|
|
|
// default return value in case something goes wrong.
|
2006-01-31 22:37:56 +03:00
|
|
|
be.retcode = BX_LOG_NOTIFY_FAILED;
|
|
|
|
// calling notify
|
2014-01-12 12:26:04 +04:00
|
|
|
sim_to_ci_event(&be);
|
2002-09-26 02:54:23 +04:00
|
|
|
return be.retcode;
|
2001-06-11 18:03:35 +04:00
|
|
|
}
|
|
|
|
|
2014-01-12 12:26:04 +04:00
|
|
|
void bx_real_sim_c::log_msg(const char *prefix, int level, const char *msg)
|
|
|
|
{
|
|
|
|
if (SIM->has_log_viewer()) {
|
|
|
|
// send message to the log viewer
|
2017-02-18 14:13:56 +03:00
|
|
|
char *logmsg = new char[strlen(prefix) + strlen(msg) + 4];
|
2014-01-13 22:03:40 +04:00
|
|
|
sprintf(logmsg, "%s %s\n", prefix, msg);
|
2014-01-12 12:26:04 +04:00
|
|
|
BxEvent *event = new BxEvent();
|
|
|
|
event->type = BX_ASYNC_EVT_LOG_MSG;
|
2014-01-13 22:03:40 +04:00
|
|
|
event->u.logmsg.prefix = NULL;
|
2014-01-12 12:26:04 +04:00
|
|
|
event->u.logmsg.level = level;
|
2014-01-13 22:03:40 +04:00
|
|
|
event->u.logmsg.msg = logmsg;
|
2014-01-12 12:26:04 +04:00
|
|
|
sim_to_ci_event(event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// Called by simulator whenever it needs the user to choose a new value
|
2008-02-06 01:57:43 +03:00
|
|
|
// for a registered parameter. Create a synchronous ASK_PARAM event,
|
2002-08-29 18:59:37 +04:00
|
|
|
// send it to the CI, and wait for the response. The CI will call the
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// set() method on the parameter if the user changes the value.
|
2006-03-07 01:03:16 +03:00
|
|
|
int bx_real_sim_c::ask_param(bx_param_c *param)
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
{
|
2006-02-27 12:37:58 +03:00
|
|
|
BX_ASSERT(param != NULL);
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// create appropriate event
|
2002-09-26 02:54:23 +04:00
|
|
|
BxEvent event;
|
|
|
|
event.type = BX_SYNC_EVT_ASK_PARAM;
|
2006-02-27 12:37:58 +03:00
|
|
|
event.u.param.param = param;
|
|
|
|
sim_to_ci_event(&event);
|
2002-09-26 02:54:23 +04:00
|
|
|
return event.retcode;
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
}
|
2001-06-16 03:52:34 +04:00
|
|
|
|
2006-03-07 01:03:16 +03:00
|
|
|
int bx_real_sim_c::ask_param(const char *pname)
|
2006-02-22 22:18:29 +03:00
|
|
|
{
|
|
|
|
bx_param_c *paramptr = SIM->get_param(pname);
|
|
|
|
BX_ASSERT(paramptr != NULL);
|
|
|
|
// create appropriate event
|
|
|
|
BxEvent event;
|
|
|
|
event.type = BX_SYNC_EVT_ASK_PARAM;
|
|
|
|
event.u.param.param = paramptr;
|
|
|
|
sim_to_ci_event(&event);
|
|
|
|
return event.retcode;
|
|
|
|
}
|
|
|
|
|
2007-10-25 03:09:59 +04:00
|
|
|
int bx_real_sim_c::ask_filename(const char *filename, int maxlen, const char *prompt, const char *the_default, int flags)
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
{
|
|
|
|
BxEvent event;
|
2011-08-09 13:56:00 +04:00
|
|
|
bx_param_filename_c param(NULL, "filename", prompt, "", the_default, maxlen);
|
|
|
|
param.set_options(param.get_options() | flags);
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
event.type = BX_SYNC_EVT_ASK_PARAM;
|
|
|
|
event.u.param.param = ¶m;
|
2006-06-01 00:12:43 +04:00
|
|
|
sim_to_ci_event(&event);
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
if (event.retcode >= 0)
|
2007-10-25 03:09:59 +04:00
|
|
|
memcpy((char *)filename, param.getptr(), maxlen);
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
return event.retcode;
|
|
|
|
}
|
|
|
|
|
2007-10-25 03:09:59 +04:00
|
|
|
int bx_real_sim_c::ask_yes_no(const char *title, const char *prompt, bx_bool the_default)
|
2006-06-01 00:12:43 +04:00
|
|
|
{
|
|
|
|
BxEvent event;
|
2006-06-04 11:55:34 +04:00
|
|
|
char format[512];
|
|
|
|
|
2006-06-01 00:12:43 +04:00
|
|
|
bx_param_bool_c param(NULL, "yes_no", title, prompt, the_default);
|
2006-06-04 11:55:34 +04:00
|
|
|
sprintf(format, "%s\n\n%s [%%s] ", title, prompt);
|
|
|
|
param.set_ask_format(format);
|
2006-06-01 00:12:43 +04:00
|
|
|
event.type = BX_SYNC_EVT_ASK_PARAM;
|
|
|
|
event.u.param.param = ¶m;
|
|
|
|
sim_to_ci_event(&event);
|
|
|
|
if (event.retcode >= 0) {
|
|
|
|
return param.get();
|
2020-10-18 22:57:05 +03:00
|
|
|
} else {
|
2006-06-01 00:12:43 +04:00
|
|
|
return event.retcode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-18 22:57:05 +03:00
|
|
|
void bx_real_sim_c::message_box(const char *title, const char *message)
|
|
|
|
{
|
|
|
|
BxEvent event;
|
|
|
|
|
|
|
|
event.type = BX_SYNC_EVT_MSG_BOX;
|
|
|
|
event.u.logmsg.prefix = title;
|
|
|
|
event.u.logmsg.msg = message;
|
|
|
|
sim_to_ci_event(&event);
|
|
|
|
}
|
|
|
|
|
2006-03-07 20:54:27 +03:00
|
|
|
void bx_real_sim_c::periodic()
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
{
|
2008-02-06 01:57:43 +03:00
|
|
|
// give the GUI a chance to do periodic things on the bochs thread. in
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
// particular, notice if the thread has been asked to die.
|
2002-09-26 02:54:23 +04:00
|
|
|
BxEvent tick;
|
|
|
|
tick.type = BX_SYNC_EVT_TICK;
|
|
|
|
sim_to_ci_event (&tick);
|
|
|
|
if (tick.retcode < 0) {
|
2006-03-07 20:54:27 +03:00
|
|
|
BX_INFO(("Bochs thread has been asked to quit."));
|
2006-09-04 22:36:47 +04:00
|
|
|
#if !BX_DEBUGGER
|
2006-03-07 20:54:27 +03:00
|
|
|
bx_atexit();
|
|
|
|
quit_sim(0);
|
2006-09-04 22:36:47 +04:00
|
|
|
#else
|
|
|
|
bx_dbg_exit(0);
|
|
|
|
#endif
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
}
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
static int refresh_counter = 0;
|
|
|
|
if (++refresh_counter == 50) {
|
|
|
|
// only ask the CI to refresh every 50 times periodic() is called.
|
|
|
|
// This should obviously be configurable because system speeds and
|
|
|
|
// user preferences vary.
|
2006-03-07 20:54:27 +03:00
|
|
|
refresh_ci();
|
- apply a patch I've been working on
- modified files: config.h.in cpu/init.cc debug/dbg_main.cc gui/control.cc
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h iodev/keyboard.cc
----------------------------------------------------------------------
Patch name: patch.wx-show-cpu2
Author: Bryce Denney
Date: Fri Sep 6 12:13:28 EDT 2002
Description:
Second try at implementing the "Debug:Show Cpu" and "Debug:Show
Keyboard" dialog with values that change as the simulation proceeds.
(Nobody gets to see the first try.) This is the first step toward
making something resembling a wxWindows debugger.
First, variables which are going to be visible in the CI must be
registered as parameters. For some variables, it might be acceptable
to change them from Bit32u into bx_param_num_c and access them only
with set/get methods, but for most variables it would be a horrible
pain and wreck performance.
To deal with this, I introduced the concept of a shadow parameter. A
normal parameter has its value stored inside the struct, but a shadow
parameter has only a pointer to the value. Shadow params allow you to
treat any variable as if it was a parameter, without having to change
its type and access it using get/set methods. Of course, a shadow
param's value is controlled by someone else, so it can change at any
time.
To demonstrate and test the registration of shadow parameters, I
added code in cpu/init.cc to register a few CPU registers and
code in iodev/keyboard.cc to register a few keyboard state values.
Now these parameters are visible in the Debug:Show CPU and
Debug:Show Keyboard dialog boxes.
The Debug:Show* dialog boxes are created by the ParamDialog class,
which already understands how to display each type of parameter,
including the new shadow parameters (because they are just a subclass
of a normal parameter class). I have added a ParamDialog::Refresh()
method, which rereads the value from every parameter that it is
displaying and changes the displayed value. At the moment, in the
Debug:Show CPU dialog, changing the values has no effect. However
this is trivial to add when it's time (just call CommitChanges!). It
wouldn't really make sense to change the values unless you have paused
the simulation, for example when single stepping with the debugger.
The Refresh() method must be called periodically or else the dialog
will show the initial values forever. At the moment, Refresh() is
called when the simulator sends an async event called
BX_ASYNC_EVT_REFRESH, created by a call to SIM->refresh_ci ().
Details:
- implement shadow parameter class for Bit32s, called bx_shadow_num_c.
implement shadow parameter class for Boolean, called bx_shadow_bool_c.
more to follow (I need one for every type!)
- now the simulator thread can request that the config interface refresh
its display. For now, the refresh event causes the CI to check every
parameter it is watching and change the display value. Later, it may
be worth the trouble to keep track of which parameters have actually
changed. Code in the simulator thread calls SIM->refresh_ci(), which
creates an async event called BX_ASYNC_EVT_REFRESH and sends it to
the config interface. When it arrives in the wxWindows gui thread,
it calls RefreshDialogs(), which calls the Refresh() method on any
dialogs that might need it.
- in the debugger, SIM->refresh_ci() is called before every prompt
is printed. Otherwise, the refresh would wait until the next
SIM->periodic(), which might be thousands of cycles. This way,
when you're single stepping, the dialogs update with every step.
- To improve performance, the CI has a flag (MyFrame::WantRefresh())
which tells whether it has any need for refresh events. If no
dialogs are showing that need refresh events, then no event is sent
between threads.
- add a few defaults to the param classes that affect the settings of
newly created parameters. When declaring a lot of params with
similar settings it's more compact to set the default for new params
rather than to change each one separately. default_text_format is
the printf format string for displaying numbers. default_base is
the default base for displaying numbers (0, 16, 2, etc.)
- I added to ParamDialog to make it able to display modeless dialog
boxes such as "Debug:Show CPU". The new Refresh() method queries
all the parameters for their current value and changes the value in
the wxWindows control. The ParamDialog class still needs a little
work; for example, if it's modal it should have Cancel/Ok buttons,
but if it's going to be modeless it should maybe have Apply (commit
any changes) and Close.
2002-09-06 20:43:26 +04:00
|
|
|
refresh_counter = 0;
|
|
|
|
}
|
- I've added lots of comments in siminterface.h, and tried to clean up
the terminology a bit. In particular, the term "gui" has started
to mean different things in different contexts, so I've defined
some more specific names for the parts of the user interface, and
updated comments and some variable names to reflect it. See
siminterface.h for a more complete description of all of these.
VGAW: VGA display window and toolbar buttons, the traditional Bochs
display which is ported to X, win32, MacOS X, etc. Implemented
in gui/gui.* and platform dependent gui/*.cc files.
CI: configuration interface that lets the user change settings such
as floppy disk image, ne2k settings, log options. The CI consists
of two parts: configuration user interface (CUI) which does the
actual rendering to the screen and handles key/mouse/menu events,
and the siminterface object.
CUI: configuration user interface. This handles the user interactions
that allow the user to configure Bochs. To actually change any
values it talks to the siminterface object. One implementation of
the CUI is the text-mode menus in gui/control.cc. Another
implementation is (will be) the wxWindows menus and dialogs in
gui/wxmain.cc.
siminterface: the glue between the CUI and the simulation code,
accessible throughout the code by the global variable
bx_simulator_interface_c *SIM;
Among other things, siminterface methods allow the simulator to ask the
CUI to display things or ask for user input, and allows the CUI
to query and modify variables in the simulation code.
GUI: Literally, "graphical user interface". Until the configuration menus
and wxWindows came along, everyone understood that "gui" referred to the
VGA display window and the toolbar buttons because that's all there
was. Now that we have the wxWindows code, which implements both the VGAW
and the CUI, while all other platforms implement only the VGAW, it's not
so clear. So, I'm trying to use VGAW, CI, and CUI consistently since
they are more specific.
control panel: This has been used as another name for the configuration
interface. "control panel" is also somewhat unspecific and it sounds
like it would be graphical with buttons and sliders, but our text-mode
thing is not graphical at all. I've replaced "control panel" with
"configuration interface" wherever I could find it. In configure script,
the --disable-control-panel option is still supported, but it politely
suggests that you use --disable-config-interface instead.
- clean up comments in siminterface,wx* code
- add comments and examples for bx_param_* and BxEvents
- remove some obsolete stuff: notify_*_args,
bx_simulator_interface_c::[sg]et_enabled() methods
- in siminterface.cc, move a few bx_real_sim_c methods to where they belong,
with the rest of the methods. No changes to the actual methods.
- remove some DOS ^M's which crept in and confused my editor.
2002-08-26 19:31:23 +04:00
|
|
|
}
|
|
|
|
|
2002-08-30 00:13:05 +04:00
|
|
|
// create a disk image file called filename, size=512 bytes * sectors.
|
2006-04-07 00:42:51 +04:00
|
|
|
// If overwrite is 0 and the file exists, returns -1 without changing it.
|
2002-08-30 00:13:05 +04:00
|
|
|
// Otherwise, opens up the image and starts writing. Returns -2 if
|
|
|
|
// the image could not be opened, or -3 if there are failures during
|
|
|
|
// write, e.g. disk full.
|
2008-02-06 01:57:43 +03:00
|
|
|
//
|
2005-01-05 22:54:32 +03:00
|
|
|
// wxWidgets: This may be called from the gui thread.
|
2007-10-14 04:20:30 +04:00
|
|
|
int bx_real_sim_c::create_disk_image(const char *filename, int sectors, bx_bool overwrite)
|
2002-08-30 00:13:05 +04:00
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
if (!overwrite) {
|
|
|
|
// check for existence first
|
2006-03-07 20:54:27 +03:00
|
|
|
fp = fopen(filename, "r");
|
2002-08-30 00:13:05 +04:00
|
|
|
if (fp) {
|
|
|
|
// yes it exists
|
2006-03-07 20:54:27 +03:00
|
|
|
fclose(fp);
|
2002-08-30 00:13:05 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2006-03-07 20:54:27 +03:00
|
|
|
fp = fopen(filename, "w");
|
2002-08-30 00:13:05 +04:00
|
|
|
if (fp == NULL) {
|
|
|
|
#ifdef HAVE_PERROR
|
|
|
|
char buffer[1024];
|
2006-03-07 20:54:27 +03:00
|
|
|
sprintf(buffer, "while opening '%s' for writing", filename);
|
|
|
|
perror(buffer);
|
2002-08-30 00:13:05 +04:00
|
|
|
// not sure how to get this back into the CI
|
|
|
|
#endif
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
int sec = sectors;
|
|
|
|
/*
|
|
|
|
* seek to sec*512-1 and write a single character.
|
|
|
|
* can't just do: fseek(fp, 512*sec-1, SEEK_SET)
|
|
|
|
* because 512*sec may be too large for signed int.
|
|
|
|
*/
|
|
|
|
while (sec > 0)
|
|
|
|
{
|
|
|
|
/* temp <-- min(sec, 4194303)
|
|
|
|
* 4194303 is (int)(0x7FFFFFFF/512)
|
|
|
|
*/
|
|
|
|
int temp = ((sec < 4194303) ? sec : 4194303);
|
|
|
|
fseek(fp, 512*temp, SEEK_CUR);
|
|
|
|
sec -= temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
fseek(fp, -1, SEEK_CUR);
|
|
|
|
if (fputc('\0', fp) == EOF)
|
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
fclose(fp);
|
2002-08-30 00:13:05 +04:00
|
|
|
return -3;
|
|
|
|
}
|
2006-03-07 20:54:27 +03:00
|
|
|
fclose(fp);
|
2002-08-30 00:13:05 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-10-14 04:20:30 +04:00
|
|
|
void bx_real_sim_c::refresh_ci()
|
|
|
|
{
|
2006-11-12 13:07:18 +03:00
|
|
|
if (SIM->has_debug_gui()) {
|
2002-11-19 12:27:39 +03:00
|
|
|
// It's an async event, so allocate a pointer and send it.
|
|
|
|
// The event will be freed by the recipient.
|
2006-11-12 13:07:18 +03:00
|
|
|
BxEvent *event = new BxEvent();
|
2002-11-19 12:27:39 +03:00
|
|
|
event->type = BX_ASYNC_EVT_REFRESH;
|
2006-03-07 20:54:27 +03:00
|
|
|
sim_to_ci_event(event);
|
2002-11-19 12:27:39 +03:00
|
|
|
}
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
}
|
|
|
|
|
2007-10-14 04:20:30 +04:00
|
|
|
bx_param_c *bx_real_sim_c::get_first_atadevice(Bit32u search_type)
|
|
|
|
{
|
2006-02-26 22:11:20 +03:00
|
|
|
char pname[80];
|
2002-09-23 00:56:12 +04:00
|
|
|
for (int channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
|
2006-02-26 22:11:20 +03:00
|
|
|
sprintf(pname, "ata.%d.resources.enabled", channel);
|
|
|
|
if (!SIM->get_param_bool(pname)->get())
|
2002-09-23 00:56:12 +04:00
|
|
|
continue;
|
|
|
|
for (int slave=0; slave<2; slave++) {
|
2006-02-26 22:11:20 +03:00
|
|
|
sprintf(pname, "ata.%d.%s.type", channel, (slave==0)?"master":"slave");
|
|
|
|
Bit32u type = SIM->get_param_enum(pname)->get();
|
2013-01-22 22:26:49 +04:00
|
|
|
if (type == search_type) {
|
2006-02-26 22:11:20 +03:00
|
|
|
sprintf(pname, "ata.%d.%s", channel, (slave==0)?"master":"slave");
|
2012-11-11 16:21:09 +04:00
|
|
|
return SIM->get_param(pname);
|
2002-09-23 00:56:12 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-11-11 16:21:09 +04:00
|
|
|
bx_bool bx_real_sim_c::is_pci_device(const char *name)
|
|
|
|
{
|
|
|
|
#if BX_SUPPORT_PCI
|
2018-02-25 23:59:30 +03:00
|
|
|
unsigned i, max_pci_slots = BX_N_PCI_SLOTS;
|
2012-11-11 16:21:09 +04:00
|
|
|
char devname[80];
|
|
|
|
char *device;
|
|
|
|
|
|
|
|
if (SIM->get_param_bool(BXPN_PCI_ENABLED)->get()) {
|
2018-02-25 23:59:30 +03:00
|
|
|
if (SIM->get_param_enum(BXPN_PCI_CHIPSET)->get() == BX_PCI_CHIPSET_I440BX) {
|
|
|
|
max_pci_slots = 4;
|
|
|
|
}
|
|
|
|
for (i = 0; i < max_pci_slots; i++) {
|
2012-11-11 16:21:09 +04:00
|
|
|
sprintf(devname, "pci.slot.%d", i+1);
|
|
|
|
device = SIM->get_param_string(devname)->getptr();
|
|
|
|
if ((strlen(device) > 0) && (!strcmp(name, device))) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-02-25 23:59:30 +03:00
|
|
|
bx_bool bx_real_sim_c::is_agp_device(const char *name)
|
|
|
|
{
|
|
|
|
#if BX_SUPPORT_PCI
|
|
|
|
if (get_param_bool(BXPN_PCI_ENABLED)->get() &&
|
|
|
|
(SIM->get_param_enum(BXPN_PCI_CHIPSET)->get() == BX_PCI_CHIPSET_I440BX)) {
|
|
|
|
const char *device = SIM->get_param_string("pci.slot.5")->getptr();
|
|
|
|
if ((strlen(device) > 0) && (!strcmp(name, device))) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
#if BX_DEBUGGER
|
|
|
|
|
|
|
|
// this can be safely called from either thread.
|
2006-05-23 01:29:54 +04:00
|
|
|
void bx_real_sim_c::debug_break()
|
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
bx_debug_break();
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// this should only be called from the sim_thread.
|
2006-05-23 01:29:54 +04:00
|
|
|
void bx_real_sim_c::debug_interpret_cmd(char *cmd)
|
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
if (!is_sim_thread()) {
|
|
|
|
fprintf(stderr, "ERROR: debug_interpret_cmd called but not from sim_thread\n");
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
return;
|
|
|
|
}
|
2006-03-07 20:54:27 +03:00
|
|
|
bx_dbg_interpret_line(cmd);
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
}
|
|
|
|
|
2006-03-07 01:03:16 +03:00
|
|
|
char *bx_real_sim_c::debug_get_next_command()
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
{
|
|
|
|
BxEvent event;
|
|
|
|
event.type = BX_SYNC_EVT_GET_DBG_COMMAND;
|
2006-12-10 16:03:25 +03:00
|
|
|
BX_DEBUG(("asking for next debug command"));
|
2002-09-26 02:54:23 +04:00
|
|
|
sim_to_ci_event (&event);
|
2006-12-10 16:03:25 +03:00
|
|
|
BX_DEBUG(("received next debug command: '%s'", event.u.debugcmd.command));
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
if (event.retcode >= 0)
|
|
|
|
return event.u.debugcmd.command;
|
|
|
|
return NULL;
|
|
|
|
}
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
|
2006-03-07 01:03:16 +03:00
|
|
|
void bx_real_sim_c::debug_puts(const char *text)
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
{
|
2006-11-12 13:07:18 +03:00
|
|
|
if (SIM->has_debug_gui()) {
|
2012-07-01 18:37:13 +04:00
|
|
|
// send message to the gui debugger
|
2006-03-07 20:54:27 +03:00
|
|
|
BxEvent *event = new BxEvent();
|
2002-11-19 12:27:39 +03:00
|
|
|
event->type = BX_ASYNC_EVT_DBG_MSG;
|
|
|
|
event->u.logmsg.msg = text;
|
2006-11-12 13:07:18 +03:00
|
|
|
sim_to_ci_event(event);
|
2002-11-19 12:27:39 +03:00
|
|
|
} else {
|
|
|
|
// text mode debugger: just write to console
|
2009-02-12 23:39:38 +03:00
|
|
|
fputs(text, stdout);
|
2002-11-19 12:27:39 +03:00
|
|
|
}
|
- add Debug Log dialog, which shows all the text output that is normally
printed to stderr in the text debugger. Also allows the user to
type (text) debugger commands directly, which also appear in the log.
- all text output in the debugger now passes through dbg_printf()
(used to be fprintf to stderr) so that in wxWindows I can redirect
it all to the wxWindows debug log screen. Added debug_fputs to
siminterface which actually sends the text to the GUI by creating
a BX_ASYNC_EVT_DBG_MSG event.
- changed prefix and msg fields of BxLogMsgEvent to const char *,
and also in args of logmsg method of siminterface.
- don't trap SIGINT in wxWindows. There are other ways to stop execution.
Also, signal handling with multiple threads is very strange and different
on different platforms.
- minor changes to fix gcc -Wall warnings in dbg_main.cc
- add a new boolean parameter BXP_DEBUG_RUNNING that tells if the debugger is
running freely or not. This is used by the wxWindows GUI to enable or
disable certain choices.
- CpuRegistersDialog has continue,stop,step buttons. When the sim is running
freely, I disable continue and step, and enable stop. When the sim stops
to wait for the user, I disable stop and enable continue and step. The
change of enables used to be triggered by actually pressing the button,
but then if you started/stopped the simulation in some other way (typing
in debug log window) the enables were never changed. Now the enables are
controlled by the value of BXP_DEBUG_RUNNING, which is set by the debug code
itself, and the buttons are enabled at the right time.
- ParamDialog::Refresh() is now virtual so that child classes can redefine
its refresh behavior.
- in safeWxStrcpy, force the last element of the array to be a 0, since
I noticed that strncpy is not guaranteed to terminate the string!
- modified: debug/dbg_main.cc debug/debug.h gui/siminterface.cc
gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc
gui/wxmain.h
2002-09-15 15:21:35 +04:00
|
|
|
}
|
- add infrastructure for sending commands from the wxWindows interface to the
Bochs debugger. The Bochs debugger calls SIM->debug_get_next_command() which
does not return until a debugger command is found. The siminterface sends an
synchronous event to the wxWindows thread with a blank to be filled in with a
debugger command. wxWindows fills in the blank and sends the synchronous
event back, and the Bochs debugger interprets it as if it was typed on
the command line. For the long term I haven't decided whether to stick with
sending text strings vs. some other method.
- so far the wxWindows debugger consists of one big dialog box that shows
all the standard registers, and a working Continue, Stop, and Step button.
- modify ParamDialog so that it is more useful as a base class, by moving
some things to protected members&fields, separating out functionality
that is most likely to be replaced into virtual functions, and making it
generally more flexible. The new CpuRegistersDialog is based on
ParamDialog.
- in wxdialog.cc, continue the convention of using wxID_HELP, wxID_OK,
wxID_CANCEL, etc. for the id's of buttons, instead of wxHELP, wxOK, etc.
which are intended to be ORred together in a bit field.
- cpu/init.cc: put ifdefs around DEFPARAMs for flags in configurations
where they don't exist. Add an eflags shadow parameter that represents all
of the bits of eflags at once. There are also boolean shadow params for
each bit.
- modified files: cpu/init.cc debug/dbg_main.cc debug/debug.h
gui/siminterface.cc gui/siminterface.h gui/wxdialog.cc gui/wxdialog.h
gui/wxmain.cc gui/wxmain.h
2002-09-13 23:39:38 +04:00
|
|
|
#endif
|
|
|
|
|
2006-03-07 20:54:27 +03:00
|
|
|
void bx_real_sim_c::register_configuration_interface(
|
2008-02-06 01:57:43 +03:00
|
|
|
const char* name,
|
2002-10-25 01:07:56 +04:00
|
|
|
config_interface_callback_t callback,
|
|
|
|
void *userdata)
|
|
|
|
{
|
|
|
|
ci_callback = callback;
|
|
|
|
ci_callback_data = userdata;
|
|
|
|
registered_ci_name = name;
|
|
|
|
}
|
|
|
|
|
2006-03-07 01:03:16 +03:00
|
|
|
int bx_real_sim_c::configuration_interface(const char *ignore, ci_command_t command)
|
2002-10-25 01:07:56 +04:00
|
|
|
{
|
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:09:59 +04:00
|
|
|
const char *name = ci_param->get_selected();
|
2002-10-25 01:07:56 +04:00
|
|
|
if (!ci_callback) {
|
2006-02-22 00:35:09 +03:00
|
|
|
BX_PANIC(("no configuration interface was loaded"));
|
2002-10-25 01:07:56 +04:00
|
|
|
return -1;
|
|
|
|
}
|
2006-02-22 00:35:09 +03:00
|
|
|
if (strcmp(name, registered_ci_name) != 0) {
|
|
|
|
BX_PANIC(("siminterface does not support loading one configuration interface and then calling another"));
|
2002-10-25 01:07:56 +04:00
|
|
|
return -1;
|
|
|
|
}
|
2008-02-06 01:57:43 +03:00
|
|
|
if (!strcmp(name, "wx"))
|
2012-08-25 17:20:55 +04:00
|
|
|
wxsel = 1;
|
2002-11-19 12:27:39 +03:00
|
|
|
else
|
2012-08-25 17:20:55 +04:00
|
|
|
wxsel = 0;
|
|
|
|
bx_debug_gui = wxsel;
|
2002-12-06 22:34:32 +03:00
|
|
|
// enter configuration mode, just while running the configuration interface
|
2006-02-22 00:35:09 +03:00
|
|
|
set_display_mode(DISP_MODE_CONFIG);
|
2002-12-06 22:34:32 +03:00
|
|
|
int retval = (*ci_callback)(ci_callback_data, command);
|
2006-02-22 00:35:09 +03:00
|
|
|
set_display_mode(DISP_MODE_SIM);
|
2002-12-06 22:34:32 +03:00
|
|
|
return retval;
|
2002-10-25 01:07:56 +04:00
|
|
|
}
|
|
|
|
|
2006-03-07 20:54:27 +03:00
|
|
|
int bx_real_sim_c::begin_simulation(int argc, char *argv[])
|
2002-10-25 01:07:56 +04:00
|
|
|
{
|
2006-03-07 20:54:27 +03:00
|
|
|
return bx_begin_simulation(argc, argv);
|
2002-10-25 01:07:56 +04:00
|
|
|
}
|
|
|
|
|
2015-08-23 10:04:56 +03:00
|
|
|
int bx_real_sim_c::register_runtime_config_handler(void *dev, rt_conf_handler_t handler)
|
2011-06-11 23:38:52 +04:00
|
|
|
{
|
2016-12-05 21:56:56 +03:00
|
|
|
rt_conf_entry_t *rt_conf_entry = new rt_conf_entry_t;
|
|
|
|
rt_conf_entry->id = rt_conf_id;
|
2011-06-11 23:38:52 +04:00
|
|
|
rt_conf_entry->device = dev;
|
|
|
|
rt_conf_entry->handler = handler;
|
|
|
|
rt_conf_entry->next = NULL;
|
|
|
|
|
|
|
|
if (rt_conf_entries == NULL) {
|
|
|
|
rt_conf_entries = rt_conf_entry;
|
|
|
|
} else {
|
|
|
|
rt_conf_entry_t *temp = rt_conf_entries;
|
|
|
|
|
|
|
|
while (temp->next) {
|
|
|
|
temp = temp->next;
|
|
|
|
}
|
|
|
|
temp->next = rt_conf_entry;
|
|
|
|
}
|
2015-08-23 10:04:56 +03:00
|
|
|
return rt_conf_id++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void bx_real_sim_c::unregister_runtime_config_handler(int id)
|
|
|
|
{
|
2015-08-23 19:09:24 +03:00
|
|
|
rt_conf_entry_t *prev = NULL, *curr = rt_conf_entries;
|
2015-08-23 10:04:56 +03:00
|
|
|
|
2015-08-23 19:09:24 +03:00
|
|
|
while (curr != NULL) {
|
|
|
|
if (curr->id == id) {
|
2015-08-23 10:04:56 +03:00
|
|
|
if (prev != NULL) {
|
2015-08-23 19:09:24 +03:00
|
|
|
prev->next = curr->next;
|
2015-08-23 10:04:56 +03:00
|
|
|
} else {
|
2015-08-23 19:09:24 +03:00
|
|
|
rt_conf_entries = curr->next;
|
2015-08-23 10:04:56 +03:00
|
|
|
}
|
2016-12-05 21:56:56 +03:00
|
|
|
delete curr;
|
2015-08-23 10:04:56 +03:00
|
|
|
break;
|
|
|
|
} else {
|
2015-08-23 19:09:24 +03:00
|
|
|
prev = curr;
|
|
|
|
curr = curr->next;
|
2015-08-23 10:04:56 +03:00
|
|
|
}
|
|
|
|
}
|
2011-06-11 23:38:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void bx_real_sim_c::update_runtime_options()
|
|
|
|
{
|
|
|
|
rt_conf_entry_t *temp = rt_conf_entries;
|
|
|
|
|
|
|
|
while (temp != NULL) {
|
|
|
|
temp->handler(temp->device);
|
|
|
|
temp = temp->next;
|
|
|
|
}
|
2011-07-24 18:11:10 +04:00
|
|
|
bx_gui->update_drive_status_buttons();
|
2011-08-15 14:37:41 +04:00
|
|
|
bx_virt_timer.set_realtime_delay();
|
2011-06-11 23:38:52 +04:00
|
|
|
}
|
|
|
|
|
2006-04-07 00:42:51 +04:00
|
|
|
bx_bool bx_real_sim_c::is_sim_thread()
|
2002-10-25 01:07:56 +04:00
|
|
|
{
|
2006-04-07 00:42:51 +04:00
|
|
|
if (is_sim_thread_func == NULL) return 1;
|
2002-10-25 01:07:56 +04:00
|
|
|
return (*is_sim_thread_func)();
|
|
|
|
}
|
|
|
|
|
2002-12-17 08:58:45 +03:00
|
|
|
// check if the text console exists. On some platforms, if Bochs is
|
|
|
|
// started from the "Start Menu" or by double clicking on it on a Mac,
|
|
|
|
// there may be nothing attached to stdin/stdout/stderr. This function
|
2006-04-07 00:42:51 +04:00
|
|
|
// tests if stdin/stdout/stderr are usable and returns 0 if not.
|
|
|
|
bx_bool bx_real_sim_c::test_for_text_console()
|
2002-12-17 08:58:45 +03:00
|
|
|
{
|
|
|
|
#if BX_WITH_CARBON
|
|
|
|
// In a Carbon application, you have a text console if you run the app from
|
|
|
|
// the command line, but if you start it from the finder you don't.
|
2006-04-07 00:42:51 +04:00
|
|
|
if(!isatty(STDIN_FILENO)) return 0;
|
2002-12-17 08:58:45 +03:00
|
|
|
#endif
|
|
|
|
// default: yes
|
2006-04-07 00:42:51 +04:00
|
|
|
return 1;
|
2002-12-17 08:58:45 +03:00
|
|
|
}
|
|
|
|
|
2011-12-23 14:03:10 +04:00
|
|
|
bx_bool bx_real_sim_c::is_addon_option(const char *keyword)
|
2006-03-29 23:27:31 +04:00
|
|
|
{
|
2011-12-23 14:03:10 +04:00
|
|
|
addon_option_t *addon_option;
|
2009-01-06 23:35:39 +03:00
|
|
|
|
2011-12-23 14:03:10 +04:00
|
|
|
for (addon_option = addon_options; addon_option; addon_option = addon_option->next) {
|
|
|
|
if (!strcmp(addon_option->name, keyword)) return 1;
|
2006-04-05 20:05:11 +04:00
|
|
|
}
|
2009-01-06 23:35:39 +03:00
|
|
|
return 0;
|
2006-03-29 23:27:31 +04:00
|
|
|
}
|
|
|
|
|
2011-12-23 14:03:10 +04:00
|
|
|
bx_bool bx_real_sim_c::register_addon_option(const char *keyword, addon_option_parser_t parser,
|
|
|
|
addon_option_save_t save_func)
|
2006-03-29 23:27:31 +04:00
|
|
|
{
|
2016-12-05 21:56:56 +03:00
|
|
|
addon_option_t *addon_option = new addon_option_t;
|
2011-12-23 14:03:10 +04:00
|
|
|
addon_option->name = keyword;
|
|
|
|
addon_option->parser = parser;
|
|
|
|
addon_option->savefn = save_func;
|
|
|
|
addon_option->next = NULL;
|
2009-01-06 23:35:39 +03:00
|
|
|
|
2011-12-23 14:03:10 +04:00
|
|
|
if (addon_options == NULL) {
|
|
|
|
addon_options = addon_option;
|
2006-04-05 20:05:11 +04:00
|
|
|
} else {
|
2011-12-23 14:03:10 +04:00
|
|
|
addon_option_t *temp = addon_options;
|
2009-01-06 23:35:39 +03:00
|
|
|
|
|
|
|
while (temp->next) {
|
|
|
|
if (!strcmp(temp->name, keyword)) {
|
2016-12-05 21:56:56 +03:00
|
|
|
delete addon_option;
|
2009-01-06 23:35:39 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
temp = temp->next;
|
|
|
|
}
|
2011-12-23 14:03:10 +04:00
|
|
|
temp->next = addon_option;
|
2006-04-05 20:05:11 +04:00
|
|
|
}
|
2009-01-06 23:35:39 +03:00
|
|
|
return 1;
|
2006-03-29 23:27:31 +04:00
|
|
|
}
|
|
|
|
|
2011-12-23 14:03:10 +04:00
|
|
|
bx_bool bx_real_sim_c::unregister_addon_option(const char *keyword)
|
2009-01-05 00:46:20 +03:00
|
|
|
{
|
2011-12-23 14:03:10 +04:00
|
|
|
addon_option_t *addon_option, *prev = NULL;
|
2009-01-06 23:35:39 +03:00
|
|
|
|
2011-12-23 14:03:10 +04:00
|
|
|
for (addon_option = addon_options; addon_option; addon_option = addon_option->next) {
|
|
|
|
if (!strcmp(addon_option->name, keyword)) {
|
2009-01-06 23:35:39 +03:00
|
|
|
if (prev == NULL) {
|
2011-12-23 14:03:10 +04:00
|
|
|
addon_options = addon_option->next;
|
2009-01-06 23:35:39 +03:00
|
|
|
} else {
|
2011-12-23 14:03:10 +04:00
|
|
|
prev->next = addon_option->next;
|
2009-01-06 23:35:39 +03:00
|
|
|
}
|
2016-12-05 21:56:56 +03:00
|
|
|
delete addon_option;
|
2009-01-06 23:35:39 +03:00
|
|
|
return 1;
|
|
|
|
} else {
|
2011-12-23 14:03:10 +04:00
|
|
|
prev = addon_option;
|
2009-01-05 00:46:20 +03:00
|
|
|
}
|
|
|
|
}
|
2009-01-06 23:35:39 +03:00
|
|
|
return 0;
|
2009-01-05 00:46:20 +03:00
|
|
|
}
|
|
|
|
|
2011-12-23 14:03:10 +04:00
|
|
|
Bit32s bx_real_sim_c::parse_addon_option(const char *context, int num_params, char *params [])
|
2006-03-29 23:27:31 +04:00
|
|
|
{
|
2016-12-05 21:56:56 +03:00
|
|
|
for (addon_option_t *addon_option = addon_options; addon_option; addon_option = addon_option->next) {
|
2011-12-23 14:03:10 +04:00
|
|
|
if ((!strcmp(addon_option->name, params[0])) &&
|
|
|
|
(addon_option->parser != NULL)) {
|
|
|
|
return (*addon_option->parser)(context, num_params, params);
|
2009-01-06 23:35:39 +03:00
|
|
|
}
|
2006-04-05 20:05:11 +04:00
|
|
|
}
|
2009-01-06 23:35:39 +03:00
|
|
|
return -1;
|
|
|
|
|
2006-04-14 12:07:24 +04:00
|
|
|
}
|
|
|
|
|
2011-12-23 14:03:10 +04:00
|
|
|
Bit32s bx_real_sim_c::save_addon_options(FILE *fp)
|
2006-04-14 12:07:24 +04:00
|
|
|
{
|
2016-12-05 21:56:56 +03:00
|
|
|
for (addon_option_t *addon_option = addon_options; addon_option; addon_option = addon_option->next) {
|
2011-12-23 14:03:10 +04:00
|
|
|
if (addon_option->savefn != NULL) {
|
|
|
|
(*addon_option->savefn)(fp);
|
2006-04-14 12:07:24 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
2006-03-29 23:27:31 +04:00
|
|
|
}
|
|
|
|
|
2014-10-14 19:59:10 +04:00
|
|
|
void bx_real_sim_c::init_statistics()
|
|
|
|
{
|
|
|
|
if (get_statistics_root() == NULL) {
|
|
|
|
new bx_list_c(root_param, "statistics", "statistics");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void bx_real_sim_c::cleanup_statistics()
|
|
|
|
{
|
|
|
|
bx_list_c *list;
|
|
|
|
|
|
|
|
if ((list = get_statistics_root()) != NULL) {
|
|
|
|
list->clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-07 22:50:51 +04:00
|
|
|
void bx_real_sim_c::init_save_restore()
|
2012-02-14 22:13:54 +04:00
|
|
|
{
|
|
|
|
if (get_bochs_root() == NULL) {
|
|
|
|
new bx_list_c(root_param, "bochs", "subtree for save/restore");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void bx_real_sim_c::cleanup_save_restore()
|
2006-09-07 22:50:51 +04:00
|
|
|
{
|
2016-12-05 21:56:56 +03:00
|
|
|
bx_list_c *list = get_bochs_root();
|
2006-09-07 22:50:51 +04:00
|
|
|
|
2016-12-05 21:56:56 +03:00
|
|
|
if (list != NULL) {
|
2006-09-07 22:50:51 +04:00
|
|
|
list->clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-07 16:49:50 +04:00
|
|
|
bx_bool bx_real_sim_c::save_state(const char *checkpoint_path)
|
2006-04-07 00:42:51 +04:00
|
|
|
{
|
2006-04-15 18:05:18 +04:00
|
|
|
char sr_file[BX_PATHNAME_LEN];
|
2014-05-12 21:30:05 +04:00
|
|
|
char devname[20];
|
|
|
|
int dev, ndev = SIM->get_n_log_modules();
|
2006-04-09 13:05:30 +04:00
|
|
|
int type, ntype = SIM->get_max_log_level();
|
2006-04-07 16:49:50 +04:00
|
|
|
|
2012-09-16 23:51:30 +04:00
|
|
|
get_param_string(BXPN_RESTORE_PATH)->set(checkpoint_path);
|
2006-04-15 18:05:18 +04:00
|
|
|
sprintf(sr_file, "%s/config", checkpoint_path);
|
2006-05-28 20:39:25 +04:00
|
|
|
if (write_rc(sr_file, 1) < 0)
|
|
|
|
return 0;
|
2006-04-15 18:05:18 +04:00
|
|
|
sprintf(sr_file, "%s/logopts", checkpoint_path);
|
2007-10-14 04:20:30 +04:00
|
|
|
FILE *fp = fopen(sr_file, "w");
|
2006-04-09 13:05:30 +04:00
|
|
|
if (fp != NULL) {
|
|
|
|
for (dev=0; dev<ndev; dev++) {
|
2014-05-12 21:30:05 +04:00
|
|
|
strcpy(devname, get_logfn_name(dev));
|
|
|
|
if ((strlen(devname) > 0) && (strcmp(devname, "?"))) {
|
|
|
|
fprintf(fp, "%s: ", devname);
|
2006-04-09 13:05:30 +04:00
|
|
|
for (type=0; type<ntype; type++) {
|
|
|
|
if (type > 0) fprintf(fp, ", ");
|
|
|
|
fprintf(fp, "%s=%s", get_log_level_name(type), get_action_name(get_log_action(dev, type)));
|
|
|
|
}
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(fp);
|
2006-05-28 20:39:25 +04:00
|
|
|
} else {
|
|
|
|
return 0;
|
2006-04-09 13:05:30 +04:00
|
|
|
}
|
2007-09-28 23:52:08 +04:00
|
|
|
bx_list_c *sr_list = get_bochs_root();
|
2006-04-15 18:05:18 +04:00
|
|
|
ndev = sr_list->get_size();
|
|
|
|
for (dev=0; dev<ndev; dev++) {
|
|
|
|
sprintf(sr_file, "%s/%s", checkpoint_path, sr_list->get(dev)->get_name());
|
|
|
|
fp = fopen(sr_file, "w");
|
|
|
|
if (fp != NULL) {
|
2006-05-01 22:24:47 +04:00
|
|
|
save_sr_param(fp, sr_list->get(dev), checkpoint_path, 0);
|
2006-04-15 18:05:18 +04:00
|
|
|
fclose(fp);
|
2006-05-28 20:39:25 +04:00
|
|
|
} else {
|
|
|
|
return 0;
|
2006-04-15 18:05:18 +04:00
|
|
|
}
|
|
|
|
}
|
2013-02-09 18:21:58 +04:00
|
|
|
get_param_string(BXPN_RESTORE_PATH)->set("none");
|
2006-05-28 20:39:25 +04:00
|
|
|
return 1;
|
2006-04-07 00:42:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bx_bool bx_real_sim_c::restore_config()
|
|
|
|
{
|
2006-04-07 16:49:50 +04:00
|
|
|
char config[BX_PATHNAME_LEN];
|
|
|
|
sprintf(config, "%s/config", get_param_string(BXPN_RESTORE_PATH)->getptr());
|
|
|
|
BX_INFO(("restoring '%s'", config));
|
2006-05-28 20:39:25 +04:00
|
|
|
return (read_rc(config) >= 0);
|
2006-04-07 00:42:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bx_bool bx_real_sim_c::restore_logopts()
|
|
|
|
{
|
2006-04-09 13:05:30 +04:00
|
|
|
char logopts[BX_PATHNAME_LEN];
|
2014-05-12 21:30:05 +04:00
|
|
|
char line[512], string[512], devname[20];
|
2006-04-09 13:05:30 +04:00
|
|
|
char *ret, *ptr;
|
2014-05-12 21:30:05 +04:00
|
|
|
int i, j, p, dev = 0, type = 0, action = 0;
|
2006-04-15 18:05:18 +04:00
|
|
|
FILE *fp;
|
2006-04-09 13:05:30 +04:00
|
|
|
|
|
|
|
sprintf(logopts, "%s/logopts", get_param_string(BXPN_RESTORE_PATH)->getptr());
|
|
|
|
BX_INFO(("restoring '%s'", logopts));
|
|
|
|
fp = fopen(logopts, "r");
|
|
|
|
if (fp != NULL) {
|
|
|
|
do {
|
|
|
|
ret = fgets(line, sizeof(line)-1, fp);
|
|
|
|
line[sizeof(line) - 1] = '\0';
|
|
|
|
int len = strlen(line);
|
|
|
|
if ((len>0) && (line[len-1] < ' '))
|
|
|
|
line[len-1] = '\0';
|
|
|
|
i = 0;
|
|
|
|
if ((ret != NULL) && strlen(line)) {
|
|
|
|
ptr = strtok(line, ":");
|
|
|
|
while (ptr) {
|
2014-05-12 21:30:05 +04:00
|
|
|
p = 0;
|
|
|
|
while (isspace(ptr[p])) p++;
|
|
|
|
strcpy(string, ptr+p);
|
2006-04-09 13:05:30 +04:00
|
|
|
while (isspace(string[strlen(string)-1])) string[strlen(string)-1] = 0;
|
|
|
|
if (i == 0) {
|
2014-05-12 21:30:05 +04:00
|
|
|
strcpy(devname, string);
|
|
|
|
dev = get_logfn_id(devname);
|
2006-04-09 13:05:30 +04:00
|
|
|
} else if (dev >= 0) {
|
|
|
|
j = 6;
|
|
|
|
if (!strncmp(string, "DEBUG=", 6)) {
|
|
|
|
type = LOGLEV_DEBUG;
|
|
|
|
} else if (!strncmp(string, "INFO=", 5)) {
|
|
|
|
type = LOGLEV_INFO;
|
|
|
|
j = 5;
|
|
|
|
} else if (!strncmp(string, "ERROR=", 6)) {
|
|
|
|
type = LOGLEV_ERROR;
|
|
|
|
} else if (!strncmp(string, "PANIC=", 6)) {
|
|
|
|
type = LOGLEV_PANIC;
|
|
|
|
}
|
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/bochs.h ./bochs.h
--- /home/volker/bochs/bochs/bochs.h 2016-08-12 19:06:18.803209189 +0200
+++ ./bochs.h 2016-12-28 00:41:20.000627252 +0100
@@ -2,7 +2,7 @@
// $Id: bochs.h 12935 2016-08-12 17:06:14Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2001-2015 The Bochs Project
+// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -276,8 +276,9 @@
void error(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
void panic(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
void ldebug(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
- void fatal (const char *prefix, const char *fmt, va_list ap, int exit_status);
- void ask (int level, const char *prefix, const char *fmt, va_list ap);
+ void fatal(const char *prefix, const char *fmt, va_list ap, int exit_status);
+ void warn(int level, const char *prefix, const char *fmt, va_list ap);
+ void ask(int level, const char *prefix, const char *fmt, va_list ap);
void put(const char *p);
void put(const char *n, const char *p);
void setio(class iofunctions *);
@@ -334,7 +335,8 @@
void set_log_action(int loglevel, int action);
const char *getlevel(int i) const;
const char *getaction(int i) const;
-
+ int isaction(const char *val) const;
+
protected:
int n_logfn;
#define MAX_LOGFNS 512
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/CHANGES ./CHANGES
--- /home/volker/bochs/bochs/CHANGES 2016-12-26 10:45:44.000000000 +0100
+++ ./CHANGES 2016-12-28 15:54:25.127088081 +0100
@@ -1,5 +1,8 @@
Changes after 2.6.8 release:
+- General
+ - Added new log action "warn", designed to show a message box on error events.
+
- Configure and compile
- Added Android host platform support.
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/config.cc ./config.cc
--- /home/volker/bochs/bochs/config.cc 2016-05-03 21:15:09.158016000 +0200
+++ ./config.cc 2016-12-27 19:53:10.461420368 +0100
@@ -2062,15 +2062,8 @@
actstr = strtok(NULL, "");
if (actstr != NULL) {
def_action = !strcmp(module, "action");
- if (!strcmp(actstr, "fatal"))
- action = ACT_FATAL;
- else if (!strcmp (actstr, "report"))
- action = ACT_REPORT;
- else if (!strcmp (actstr, "ignore"))
- action = ACT_IGNORE;
- else if (!strcmp (actstr, "ask"))
- action = ACT_ASK;
- else {
+ action = SIM->is_action_name(actstr);
+ if (action < ACT_IGNORE) {
PARSE_ERR(("%s: %s directive malformed.", context, params[0]));
free(param);
return -1;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/sdl2.cc ./gui/sdl2.cc
--- /home/volker/bochs/bochs/gui/sdl2.cc 2016-08-12 19:06:18.811209142 +0200
+++ ./gui/sdl2.cc 2016-12-28 12:33:39.534288819 +0100
@@ -2,7 +2,7 @@
// $Id: sdl2.cc 12935 2016-08-12 17:06:14Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2014-2015 The Bochs Project
+// Copyright (C) 2014-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -1478,20 +1478,16 @@
SDL_MessageBoxData msgboxdata;
SDL_MessageBoxButtonData buttondata[4];
int level, retcode;
-#if BX_DEBUGGER || BX_GDBSTUB
- int defbtn = 3;
-#else
- int defbtn = 2;
-#endif
char message[512];
level = event->u.logmsg.level;
- sprintf(message, "%s %s", event->u.logmsg.prefix, event->u.logmsg.msg);
+ sprintf(message, "Device: %s\nMessage: %s", event->u.logmsg.prefix,
+ event->u.logmsg.msg);
msgboxdata.flags = SDL_MESSAGEBOX_ERROR;
msgboxdata.window = window;
msgboxdata.title = SIM->get_log_level_name(level);
msgboxdata.message = message;
- msgboxdata.numbuttons = defbtn + 1;
+ msgboxdata.numbuttons = 2;
msgboxdata.buttons = buttondata;
msgboxdata.colorScheme = NULL;
buttondata[0].flags = 0;
@@ -1500,14 +1496,18 @@
buttondata[1].flags = 0;
buttondata[1].buttonid = BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS;
buttondata[1].text = "Alwayscont";
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ msgboxdata.numbuttons = 3;
+ buttondata[2].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
+ buttondata[2].buttonid = BX_LOG_ASK_CHOICE_DIE;
+ buttondata[2].text = "Quit";
#if BX_DEBUGGER || BX_GDBSTUB
- buttondata[2].flags = 0;
- buttondata[2].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG;
- buttondata[2].text = "Debugger";
-#endif
- buttondata[defbtn].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
- buttondata[defbtn].buttonid = BX_LOG_ASK_CHOICE_DIE;
- buttondata[defbtn].text = "Quit";
+ msgboxdata.numbuttons = 4;
+ buttondata[3].flags = 0;
+ buttondata[3].buttonid = BX_LOG_ASK_CHOICE_ENTER_DEBUG;
+ buttondata[3].text = "Debugger";
+#endif
+ }
if (SDL_ShowMessageBox(&msgboxdata, &retcode) < 0) {
return -1;
} else {
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.cc ./gui/siminterface.cc
--- /home/volker/bochs/bochs/gui/siminterface.cc 2016-12-05 19:56:56.729685000 +0100
+++ ./gui/siminterface.cc 2016-12-28 11:14:02.004075717 +0100
@@ -2,7 +2,7 @@
// $Id: siminterface.cc 12981 2016-12-05 18:56:56Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2015 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -100,6 +100,7 @@
virtual int get_log_action(int mod, int level);
virtual void set_log_action(int mod, int level, int action);
virtual const char *get_action_name(int action);
+ virtual int is_action_name(const char *val);
virtual int get_default_log_action(int level) {
return logfunctions::get_default_action(level);
}
@@ -123,6 +124,7 @@
virtual void set_notify_callback(bxevent_handler func, void *arg);
virtual void get_notify_callback(bxevent_handler *func, void **arg);
virtual BxEvent* sim_to_ci_event(BxEvent *event);
+ virtual int log_warn(const char *prefix, int level, const char *msg);
virtual int log_ask(const char *prefix, int level, const char *msg);
virtual void log_msg(const char *prefix, int level, const char *msg);
virtual void set_log_viewer(bx_bool val) { bx_log_viewer = val; }
@@ -420,6 +422,11 @@
return io->getaction(action);
}
+int bx_real_sim_c::is_action_name(const char *val)
+{
+ return io->isaction(val);
+}
+
const char *bx_real_sim_c::get_log_level_name(int level)
{
return io->getlevel(level);
@@ -575,6 +582,21 @@
}
}
+int bx_real_sim_c::log_warn(const char *prefix, int level, const char *msg)
+{
+ BxEvent be;
+ be.type = BX_SYNC_EVT_LOG_ASK;
+ be.u.logmsg.prefix = prefix;
+ be.u.logmsg.level = level;
+ be.u.logmsg.msg = msg;
+ be.u.logmsg.flag = BX_LOG_ASK_MSGBOX_WARN;
+ // default return value in case something goes wrong.
+ be.retcode = BX_LOG_NOTIFY_FAILED;
+ // calling notify
+ sim_to_ci_event(&be);
+ return be.retcode;
+}
+
// returns 0 for continue, 1 for alwayscontinue, 2 for die.
int bx_real_sim_c::log_ask(const char *prefix, int level, const char *msg)
{
@@ -583,6 +605,7 @@
be.u.logmsg.prefix = prefix;
be.u.logmsg.level = level;
be.u.logmsg.msg = msg;
+ be.u.logmsg.flag = BX_LOG_ASK_ASKDLG;
// default return value in case something goes wrong.
be.retcode = BX_LOG_NOTIFY_FAILED;
// calling notify
@@ -1157,16 +1180,10 @@
} else if (!strncmp(string, "PANIC=", 6)) {
type = LOGLEV_PANIC;
}
- if (!strcmp(string+j, "ignore")) {
- action = ACT_IGNORE;
- } else if (!strcmp(string+j, "report")) {
- action = ACT_REPORT;
- } else if (!strcmp(string+j, "ask")) {
- action = ACT_ASK;
- } else if (!strcmp(string+j, "fatal")) {
- action = ACT_FATAL;
+ action = is_action_name(string+j);
+ if (action >= ACT_IGNORE) {
+ set_log_action(dev, type, action);
}
- set_log_action(dev, type, action);
} else {
if (i == 1) {
BX_ERROR(("restore_logopts(): log module '%s' not found", devname));
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/siminterface.h ./gui/siminterface.h
--- /home/volker/bochs/bochs/gui/siminterface.h 2016-03-31 19:24:37.451025427 +0200
+++ ./gui/siminterface.h 2016-12-28 11:11:21.036683362 +0100
@@ -168,6 +168,7 @@
typedef enum {
ACT_IGNORE = 0,
ACT_REPORT,
+ ACT_WARN,
ACT_ASK,
ACT_FATAL,
N_ACT
@@ -178,11 +179,11 @@
// normally all action choices are available for all event types. The exclude
// expression allows some choices to be eliminated if they don't make any
// sense. For example, it would be stupid to ignore a panic.
-#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
- /* can't die or ask, on debug or info events */ \
- (type <= LOGLEV_INFO && (choice == ACT_ASK || choice == ACT_FATAL)) \
- /* can't ignore panics */ \
- || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
+#define BX_LOG_OPTS_EXCLUDE(type, choice) ( \
+ /* can't die, ask or warn, on debug or info events */ \
+ (type <= LOGLEV_INFO && (choice >= ACT_WARN)) \
+ /* can't ignore panics */ \
+ || (type == LOGLEV_PANIC && choice == ACT_IGNORE) \
)
// floppy / cdrom media status
@@ -392,6 +393,7 @@
// synchronizing threads, etc. for each.
typedef struct {
Bit8u level;
+ Bit8u flag;
const char *prefix;
const char *msg;
} BxLogMsgEvent;
@@ -419,6 +421,12 @@
BX_LOG_NOTIFY_FAILED
};
+enum {
+ BX_LOG_ASK_ASKDLG,
+ BX_LOG_ASK_MSGBOX_WARN,
+ BX_LOG_ASK_MSGBOX_QUIT
+};
+
// Event type: BX_SYNC_EVT_GET_DBG_COMMAND
//
// This is a synchronous event sent from the simulator to the debugger
@@ -675,6 +683,7 @@
virtual int get_default_log_action(int level) {return -1;}
virtual void set_default_log_action(int level, int action) {}
virtual const char *get_action_name(int action) {return NULL;}
+ virtual int is_action_name(const char *val) {return -1;}
virtual const char *get_log_level_name(int level) {return NULL;}
virtual int get_max_log_level() {return -1;}
@@ -715,6 +724,9 @@
// send an event from the simulator to the CI.
virtual BxEvent* sim_to_ci_event(BxEvent *event) {return NULL;}
+ // called from simulator when it hits errors, to warn the user
+ // before continuing simulation
+ virtual int log_warn(const char *prefix, int level, const char *msg) {return -1;}
// called from simulator when it hits serious errors, to ask if the user
// wants to continue or not
virtual int log_ask(const char *prefix, int level, const char *msg) {return -1;}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/textconfig.cc ./gui/textconfig.cc
--- /home/volker/bochs/bochs/gui/textconfig.cc 2016-12-05 20:15:59.112637000 +0100
+++ ./gui/textconfig.cc 2016-12-28 12:44:43.079411258 +0100
@@ -2,7 +2,7 @@
// $Id: textconfig.cc 12983 2016-12-05 19:15:59Z sshwarts $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2013 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -552,8 +552,8 @@
}
static const char *log_options_prompt1 = "Enter the ID of the device to edit, or -1 to return: [-1] ";
-static const char *log_level_choices[] = { "ignore", "report", "ask", "fatal", "no change" };
-static int log_level_n_choices_normal = 4;
+static const char *log_level_choices[N_ACT+1] = { "ignore", "report", "warn", "ask", "fatal", "no change" };
+static int log_level_n_choices_normal = N_ACT;
void bx_log_options(int individual)
{
@@ -589,7 +589,7 @@
bx_print_log_action_table();
for (int level=0; level<SIM->get_max_log_level(); level++) {
char prompt[1024];
- int action, default_action = 4; // default to no change
+ int action, default_action = N_ACT; // default to no change
sprintf(prompt, "Enter action for %s event on all devices: [no change] ", SIM->get_log_level_name(level));
// do show the no change choice (choices=4)
if (ask_menu(prompt, "", log_level_n_choices_normal+1, log_level_choices, default_action, &action)<0)
@@ -718,47 +718,50 @@
event->retcode = event->u.param.param->text_ask(stdin, stderr);
return event;
case BX_SYNC_EVT_LOG_ASK:
- {
- int level = event->u.logmsg.level;
- fprintf(stderr, "========================================================================\n");
- fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level));
- fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix);
- fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg);
- fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
- fprintf(stderr, " cont - continue execution\n");
- fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n");
- fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
- fprintf(stderr, " die - stop execution now\n");
- fprintf(stderr, " abort - dump core %s\n",
- BX_HAVE_ABORT ? "" : "(Disabled)");
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ int level = event->u.logmsg.level;
+ fprintf(stderr, "========================================================================\n");
+ fprintf(stderr, "Event type: %s\n", SIM->get_log_level_name (level));
+ fprintf(stderr, "Device: %s\n", event->u.logmsg.prefix);
+ fprintf(stderr, "Message: %s\n\n", event->u.logmsg.msg);
+ fprintf(stderr, "A %s has occurred. Do you want to:\n", SIM->get_log_level_name (level));
+ fprintf(stderr, " cont - continue execution\n");
+ fprintf(stderr, " alwayscont - continue execution, and don't ask again.\n");
+ fprintf(stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
+ fprintf(stderr, " die - stop execution now\n");
+ fprintf(stderr, " abort - dump core %s\n",
+ BX_HAVE_ABORT ? "" : "(Disabled)");
#if BX_DEBUGGER
- fprintf(stderr, " debug - continue and return to bochs debugger\n");
+ fprintf(stderr, " debug - continue and return to bochs debugger\n");
#endif
#if BX_GDBSTUB
- fprintf(stderr, " debug - hand control to gdb\n");
+ fprintf(stderr, " debug - hand control to gdb\n");
#endif
- int choice;
+ int choice;
ask:
- if (ask_menu("Choose one of the actions above: [%s] ", "",
- log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
- event->retcode = -1;
- // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
- if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
- fflush(stdout);
- fflush(stderr);
- event->retcode = choice;
- }
- return event;
- case BX_ASYNC_EVT_REFRESH:
- case BX_ASYNC_EVT_DBG_MSG:
- case BX_ASYNC_EVT_LOG_MSG:
- // The text mode interface does not use these events, so just ignore
- // them.
- return event;
- default:
- fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type);
- return event;
+ if (ask_menu("Choose one of the actions above: [%s] ", "",
+ log_action_n_choices, log_action_ask_choices, 2, &choice) < 0)
+ event->retcode = -1;
+ // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
+ if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
+ fflush(stdout);
+ fflush(stderr);
+ event->retcode = choice;
+ } else {
+ // warning prompt not implemented
+ event->retcode = 0;
+ }
+ return event;
+ case BX_ASYNC_EVT_REFRESH:
+ case BX_ASYNC_EVT_DBG_MSG:
+ case BX_ASYNC_EVT_LOG_MSG:
+ // The text mode interface does not use these events, so just ignore
+ // them.
+ return event;
+ default:
+ fprintf(stderr, "textconfig: notify callback called with event type %04x\n", event->type);
+ return event;
}
assert(0); // switch statement should return
}
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/win32dialog.cc ./gui/win32dialog.cc
--- /home/volker/bochs/bochs/gui/win32dialog.cc 2014-06-20 11:32:02.034026376 +0200
+++ ./gui/win32dialog.cc 2016-12-28 12:50:14.148888740 +0100
@@ -2,7 +2,7 @@
// $Id: win32dialog.cc 12381 2014-06-20 09:31:56Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2003-2014 The Bochs Project
+// Copyright (C) 2003-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -27,7 +27,7 @@
#include "win32res.h"
#include "win32paramdlg.h"
-const char log_choices[5][16] = {"ignore", "log", "ask user", "end simulation", "no change"};
+const char log_choices[N_ACT+1][16] = {"ignore", "log", "warn user", "ask user", "end simulation", "no change"};
HWND GetBochsWindow()
{
@@ -97,12 +97,16 @@
SetWindowText(GetDlgItem(hDlg, IDASKMSG), event->u.logmsg.msg);
SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue");
SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and don't ask again");
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Kill simulation");
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Abort (dump core)");
#if BX_DEBUGGER
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_ADDSTRING, 0, (LPARAM)"Continue and return to debugger");
#endif
- SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 2, 0);
+ } else {
+ SendMessage(GetDlgItem(hDlg, IDASKLIST), LB_SETCURSEL, 0, 0);
+ }
SetFocus(GetDlgItem(hDlg, IDASKLIST));
return FALSE;
case WM_CLOSE:
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.cc ./gui/wxdialog.cc
--- /home/volker/bochs/bochs/gui/wxdialog.cc 2015-01-07 17:17:40.447882000 +0100
+++ ./gui/wxdialog.cc 2016-12-27 20:30:44.997609007 +0100
@@ -2,7 +2,7 @@
// $Id: wxdialog.cc 12594 2015-01-07 16:17:40Z sshwarts $
/////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -208,7 +208,6 @@
: wxDialog(parent, id, wxT(""), wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
- //static int integers[LOG_OPTS_N_CHOICES_NORMAL] = {0, 1, 2, 3};
static wxString names[] = ADVLOG_OPTS_TYPE_NAMES;
SetTitle(ADVLOG_OPTS_TITLE);
vertSizer = new wxBoxSizer(wxVERTICAL);
@@ -1563,7 +1562,7 @@
bool includeNoChange)
{
static wxString choices[] = LOG_OPTS_CHOICES;
- static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4};
+ static int integers[LOG_OPTS_N_CHOICES] = {0, 1, 2, 3, 4, 5};
wxChoice *control = new wxChoice(parent, id, wxDefaultPosition, wxDefaultSize);
int lastChoice = 0; // remember index of last choice
int nchoice = includeNoChange? LOG_OPTS_N_CHOICES : LOG_OPTS_N_CHOICES_NORMAL;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxdialog.h ./gui/wxdialog.h
--- /home/volker/bochs/bochs/gui/wxdialog.h 2014-12-23 20:30:12.896090221 +0100
+++ ./gui/wxdialog.h 2016-12-27 20:34:28.518389938 +0100
@@ -2,7 +2,7 @@
// $Id: wxdialog.h 12576 2014-12-23 19:30:03Z vruppert $
////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -354,10 +354,10 @@
#define LOG_OPTS_PROMPT wxT("How should Bochs respond to each type of event?")
#define LOG_OPTS_TYPE_NAMES { wxT("Debug events"), wxT("Info events"), wxT("Error events"), wxT("Panic events") }
#define LOG_OPTS_N_TYPES 4
-#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("ask user"), wxT("end simulation"), wxT("no change") }
-#define LOG_OPTS_N_CHOICES_NORMAL 4
-#define LOG_OPTS_N_CHOICES 5 // number of choices, including "no change"
-#define LOG_OPTS_NO_CHANGE 4 // index of "no change"
+#define LOG_OPTS_CHOICES { wxT("ignore"), wxT("log"), wxT("warn user"), wxT("ask user"), wxT("end simulation"), wxT("no change") }
+#define LOG_OPTS_N_CHOICES_NORMAL 5
+#define LOG_OPTS_N_CHOICES 6 // number of choices, including "no change"
+#define LOG_OPTS_NO_CHANGE 5 // index of "no change"
#define LOG_OPTS_ADV wxT("For additional control over how each device responds to events, use the menu option \"Log ... By Device\".")
wxFlexGridSizer *gridSizer;
wxChoice *action[LOG_OPTS_N_TYPES];
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/wxmain.cc ./gui/wxmain.cc
--- /home/volker/bochs/bochs/gui/wxmain.cc 2016-12-26 17:12:57.470174541 +0100
+++ ./gui/wxmain.cc 2016-12-28 12:15:26.035961463 +0100
@@ -2,7 +2,7 @@
// $Id: wxmain.cc 13006 2016-12-26 16:12:54Z vruppert $
/////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2002-2014 The Bochs Project
+// Copyright (C) 2002-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -1158,6 +1158,10 @@
#if !BX_DEBUGGER && !BX_GDBSTUB
dlg.EnableButton(dlg.DEBUG, FALSE);
#endif
+ if (be->u.logmsg.flag != BX_LOG_ASK_ASKDLG) {
+ dlg.EnableButton(dlg.DIE, FALSE);
+ dlg.EnableButton(dlg.DUMP, FALSE);
+ }
dlg.SetContext(wxString(be->u.logmsg.prefix, wxConvUTF8));
dlg.SetMessage(wxString(be->u.logmsg.msg, wxConvUTF8));
int n = dlg.ShowModal();
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/gui/x.cc ./gui/x.cc
--- /home/volker/bochs/bochs/gui/x.cc 2016-12-27 17:26:59.622665119 +0100
+++ ./gui/x.cc 2016-12-28 12:03:10.963351647 +0100
@@ -2687,11 +2687,7 @@
} else {
size_x = 30 + maxlen * 6;
}
- if (lines < 3) {
- size_y = 90;
- } else {
- size_y = 60 + lines * 15;
- }
+ size_y = 70 + lines * 15;
x11_dialog_c *xdlg = new x11_dialog_c(name, size_x, size_y,
(mode == XDLG_SIMPLE) ? 1 : 2);
ypos = 34;
@@ -2729,11 +2725,21 @@
bx_param_string_c *sparam;
bx_param_enum_c *eparam;
bx_list_c *list;
+ char message[256];
switch (event->type)
{
case BX_SYNC_EVT_LOG_ASK:
- event->retcode = x11_ask_dialog(event);
+ if (event->u.logmsg.flag == BX_LOG_ASK_ASKDLG) {
+ event->retcode = x11_ask_dialog(event);
+ } else if (event->u.logmsg.flag == BX_LOG_ASK_MSGBOX_WARN) {
+ const char *title = SIM->get_log_level_name(event->u.logmsg.level);
+ sprintf(message, "Device: %s\n\nMessage: %s", event->u.logmsg.prefix,
+ event->u.logmsg.msg);
+ bx_param_bool_c bparam(NULL, "warn", title, message, 1);
+ x11_message_box(&bparam, XDLG_SIMPLE);
+ event->retcode = 0;
+ }
return event;
case BX_SYNC_EVT_ASK_PARAM:
param = event->u.param.param;
diff -urNX /home/volker/exclude-bochs /home/volker/bochs/bochs/logio.cc ./logio.cc
--- /home/volker/bochs/bochs/logio.cc 2015-05-10 08:55:18.678940963 +0200
+++ ./logio.cc 2016-12-28 00:40:40.395736643 +0100
@@ -2,7 +2,7 @@
// $Id: logio.cc 12759 2015-05-10 06:55:16Z vruppert $
/////////////////////////////////////////////////////////////////////////
//
-// Copyright (C) 2001-2014 The Bochs Project
+// Copyright (C) 2001-2016 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -50,11 +50,25 @@
else return "?";
}
+static const char *act_name[N_ACT] = { "ignore", "report", "warn", "ask", "fatal" };
+
const char* iofunctions::getaction(int i) const
{
- static const char *name[] = { "ignore", "report", "ask", "fatal" };
assert (i>=ACT_IGNORE && i<N_ACT);
- return name[i];
+ return act_name[i];
+}
+
+int iofunctions::isaction(const char *val) const
+{
+ int action = -1;
+
+ for (int i = 0; i < N_ACT; i++) {
+ if (!strcmp(val, act_name[i])) {
+ action = ACT_IGNORE + i;
+ break;
+ }
+ }
+ return action;
}
void iofunctions::flush(void)
@@ -414,6 +428,11 @@
logio->out(LOGLEV_ERROR, prefix, fmt, ap);
va_end(ap);
+ if (onoff[LOGLEV_ERROR] == ACT_WARN) {
+ va_start(ap, fmt);
+ warn(LOGLEV_ERROR, prefix, fmt, ap);
+ va_end(ap);
+ }
if (onoff[LOGLEV_ERROR] == ACT_ASK) {
va_start(ap, fmt);
ask(LOGLEV_ERROR, prefix, fmt, ap);
@@ -438,6 +457,11 @@
logio->out(LOGLEV_PANIC, prefix, fmt, ap);
va_end(ap);
+ if (onoff[LOGLEV_PANIC] == ACT_WARN) {
+ va_start(ap, fmt);
+ warn(LOGLEV_PANIC, prefix, fmt, ap);
+ va_end(ap);
+ }
if (onoff[LOGLEV_PANIC] == ACT_ASK) {
va_start(ap, fmt);
ask(LOGLEV_PANIC, prefix, fmt, ap);
@@ -465,6 +489,36 @@
// the actions ask() and fatal() are not supported here
}
+void logfunctions::warn(int level, const char *prefix, const char *fmt, va_list ap)
+{
+ // Guard against reentry on warn() function. The danger is that some
+ // function that's called within warn() could trigger another
+ // BX_ERROR that could call warn() again, leading to infinite
+ // recursion and infinite asks.
+ static char in_warn_already = 0;
+ char buf1[1024];
+ if (in_warn_already) {
+ fprintf(stderr, "logfunctions::warn() should not reenter!!\n");
+ return;
+ }
+ in_warn_already = 1;
+ vsnprintf(buf1, sizeof(buf1), fmt, ap);
+ // FIXME: facility set to 0 because it's unknown.
+
+ // update vga screen. This is useful because sometimes useful messages
+ // are printed on the screen just before a panic. It's also potentially
+ // dangerous if this function calls ask again... That's why I added
+ // the reentry check above.
+ SIM->refresh_vga();
+
+ // ensure the text screen is showing
+ SIM->set_display_mode(DISP_MODE_CONFIG);
+ SIM->log_warn(prefix, level, buf1);
+ // return to simulation mode
+ SIM->set_display_mode(DISP_MODE_SIM);
+ in_warn_already = 0;
+}
+
void logfunctions::ask(int level, const char *prefix, const char *fmt, va_list ap)
{
// Guard against reentry on ask() function. The danger is that some
2016-12-28 18:06:34 +03:00
|
|
|
action = is_action_name(string+j);
|
|
|
|
if (action >= ACT_IGNORE) {
|
|
|
|
set_log_action(dev, type, action);
|
2006-04-09 13:05:30 +04:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (i == 1) {
|
2014-05-12 21:30:05 +04:00
|
|
|
BX_ERROR(("restore_logopts(): log module '%s' not found", devname));
|
2006-04-09 13:05:30 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
ptr = strtok(NULL, ",");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (!feof(fp));
|
|
|
|
fclose(fp);
|
2006-05-28 20:39:25 +04:00
|
|
|
} else {
|
|
|
|
return 0;
|
2006-04-09 13:05:30 +04:00
|
|
|
}
|
2006-05-28 20:39:25 +04:00
|
|
|
return 1;
|
2006-04-07 00:42:51 +04:00
|
|
|
}
|
|
|
|
|
2015-10-05 21:09:58 +03:00
|
|
|
static int bx_restore_getline(FILE *fp, char *line, int maxlen)
|
|
|
|
{
|
|
|
|
char *ret = fgets(line, maxlen - 1, fp);
|
|
|
|
line[maxlen - 1] = '\0';
|
|
|
|
int len = strlen(line);
|
|
|
|
if ((len > 0) && (line[len - 1] < ' '))
|
|
|
|
line[len - 1] = '\0';
|
|
|
|
return (ret != NULL) ? len : 0;
|
|
|
|
}
|
|
|
|
|
2007-10-14 23:04:51 +04:00
|
|
|
bx_bool bx_real_sim_c::restore_bochs_param(bx_list_c *root, const char *sr_path, const char *restore_name)
|
2006-04-07 00:42:51 +04:00
|
|
|
{
|
2006-04-15 18:05:18 +04:00
|
|
|
char devstate[BX_PATHNAME_LEN], devdata[BX_PATHNAME_LEN];
|
2019-11-23 18:15:50 +03:00
|
|
|
char line[512], buf[512];
|
|
|
|
char pname[81]; // take extra 81st character for /0
|
2015-10-05 21:09:58 +03:00
|
|
|
char *ptr;
|
2018-02-05 01:20:46 +03:00
|
|
|
int i;
|
2007-10-14 04:20:30 +04:00
|
|
|
unsigned n;
|
2006-04-15 18:05:18 +04:00
|
|
|
bx_param_c *param = NULL;
|
|
|
|
FILE *fp, *fp2;
|
|
|
|
|
2007-10-14 23:04:51 +04:00
|
|
|
if (root->get_by_name(restore_name) == NULL) {
|
|
|
|
BX_ERROR(("restore_bochs_param(): unknown parameter to restore"));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-10-14 04:20:30 +04:00
|
|
|
sprintf(devstate, "%s/%s", sr_path, restore_name);
|
|
|
|
BX_INFO(("restoring '%s'", devstate));
|
|
|
|
bx_list_c *base = root;
|
|
|
|
fp = fopen(devstate, "r");
|
|
|
|
if (fp != NULL) {
|
|
|
|
do {
|
2015-10-05 21:09:58 +03:00
|
|
|
int len = bx_restore_getline(fp, line, BX_PATHNAME_LEN);
|
2007-10-14 04:20:30 +04:00
|
|
|
i = 0;
|
2015-10-05 21:09:58 +03:00
|
|
|
if (len > 0) {
|
2007-10-14 04:20:30 +04:00
|
|
|
ptr = strtok(line, " ");
|
|
|
|
while (ptr) {
|
|
|
|
if (i == 0) {
|
|
|
|
if (!strcmp(ptr, "}")) {
|
2015-08-28 20:37:38 +03:00
|
|
|
base->restore();
|
2007-10-14 04:20:30 +04:00
|
|
|
base = (bx_list_c*)base->get_parent();
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
param = get_param(ptr, base);
|
2015-08-28 20:37:38 +03:00
|
|
|
strncpy(pname, ptr, 80);
|
2007-10-14 04:20:30 +04:00
|
|
|
}
|
|
|
|
} else if (i == 2) {
|
2008-12-28 23:30:48 +03:00
|
|
|
if (param == NULL) {
|
2015-08-28 20:37:38 +03:00
|
|
|
BX_PANIC(("cannot find param '%s'!", pname));
|
2007-10-14 04:20:30 +04:00
|
|
|
}
|
2008-12-28 23:30:48 +03:00
|
|
|
else {
|
|
|
|
if (param->get_type() != BXT_LIST) {
|
|
|
|
param->get_param_path(pname, 80);
|
|
|
|
BX_DEBUG(("restoring parameter '%s'", pname));
|
|
|
|
}
|
|
|
|
switch (param->get_type()) {
|
|
|
|
case BXT_PARAM_NUM:
|
|
|
|
case BXT_PARAM_BOOL:
|
|
|
|
case BXT_PARAM_ENUM:
|
2018-01-19 23:27:04 +03:00
|
|
|
case BXT_PARAM_STRING:
|
|
|
|
case BXT_PARAM_BYTESTRING:
|
2018-02-05 01:20:46 +03:00
|
|
|
param->parse_param(ptr);
|
2008-12-28 23:30:48 +03:00
|
|
|
break;
|
|
|
|
case BXT_PARAM_DATA:
|
2015-10-05 21:09:58 +03:00
|
|
|
{
|
|
|
|
bx_shadow_data_c *dparam = (bx_shadow_data_c*)param;
|
2018-01-20 00:21:09 +03:00
|
|
|
if (!dparam->is_text_format()) {
|
2015-10-05 21:09:58 +03:00
|
|
|
sprintf(devdata, "%s/%s", sr_path, ptr);
|
|
|
|
fp2 = fopen(devdata, "rb");
|
|
|
|
if (fp2 != NULL) {
|
|
|
|
fread(dparam->getptr(), 1, dparam->get_size(), fp2);
|
|
|
|
fclose(fp2);
|
|
|
|
}
|
2018-01-26 23:02:28 +03:00
|
|
|
} else if (!strcmp(ptr, "[")) {
|
2015-10-05 21:09:58 +03:00
|
|
|
i = 0;
|
|
|
|
do {
|
|
|
|
bx_restore_getline(fp, buf, BX_PATHNAME_LEN);
|
|
|
|
ptr = strtok(buf, " ");
|
|
|
|
while (ptr) {
|
2018-01-26 23:02:28 +03:00
|
|
|
if (!strcmp(ptr, "]")) {
|
2015-10-05 21:09:58 +03:00
|
|
|
i = 0;
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
if (sscanf(ptr, "0x%02x", &n) == 1) {
|
|
|
|
dparam->set(i++, (Bit8u)n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ptr = strtok(NULL, " ");
|
|
|
|
}
|
|
|
|
} while (i > 0);
|
|
|
|
}
|
2008-12-28 23:30:48 +03:00
|
|
|
}
|
|
|
|
break;
|
2011-07-22 21:46:06 +04:00
|
|
|
case BXT_PARAM_FILEDATA:
|
|
|
|
sprintf(devdata, "%s/%s", sr_path, ptr);
|
|
|
|
fp2 = fopen(devdata, "rb");
|
|
|
|
if (fp2 != NULL) {
|
|
|
|
FILE **fpp = ((bx_shadow_filedata_c*)param)->get_fpp();
|
|
|
|
// If the temporary backing store file wasn't created, do it now.
|
|
|
|
if (*fpp == NULL)
|
|
|
|
*fpp = tmpfile();
|
|
|
|
if (*fpp != NULL) {
|
|
|
|
while (!feof(fp2)) {
|
|
|
|
char buffer[64];
|
|
|
|
size_t chars = fread(buffer, 1, sizeof(buffer), fp2);
|
|
|
|
fwrite(buffer, 1, chars, *fpp);
|
|
|
|
}
|
|
|
|
fflush(*fpp);
|
|
|
|
}
|
|
|
|
((bx_shadow_filedata_c*)param)->restore(fp2);
|
|
|
|
fclose(fp2);
|
|
|
|
}
|
|
|
|
break;
|
2008-12-28 23:30:48 +03:00
|
|
|
case BXT_LIST:
|
|
|
|
base = (bx_list_c*)param;
|
|
|
|
break;
|
|
|
|
default:
|
2014-05-14 01:10:31 +04:00
|
|
|
BX_ERROR(("restore_bochs_param(): unknown parameter type"));
|
2008-12-28 23:30:48 +03:00
|
|
|
}
|
2006-04-15 18:05:18 +04:00
|
|
|
}
|
|
|
|
}
|
2007-10-14 04:20:30 +04:00
|
|
|
i++;
|
|
|
|
ptr = strtok(NULL, " ");
|
2006-04-15 18:05:18 +04:00
|
|
|
}
|
2007-10-14 04:20:30 +04:00
|
|
|
}
|
|
|
|
} while (!feof(fp));
|
|
|
|
fclose(fp);
|
|
|
|
} else {
|
2007-10-14 23:04:51 +04:00
|
|
|
BX_ERROR(("restore_bochs_param(): error in file open"));
|
2007-10-14 04:20:30 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bx_bool bx_real_sim_c::restore_hardware()
|
|
|
|
{
|
|
|
|
bx_list_c *sr_list = get_bochs_root();
|
|
|
|
int ndev = sr_list->get_size();
|
|
|
|
for (int dev=0; dev<ndev; dev++) {
|
2007-10-14 23:04:51 +04:00
|
|
|
if (!restore_bochs_param(sr_list, get_param_string(BXPN_RESTORE_PATH)->getptr(), sr_list->get(dev)->get_name()))
|
2006-05-28 20:39:25 +04:00
|
|
|
return 0;
|
2006-04-15 18:05:18 +04:00
|
|
|
}
|
2006-05-28 20:39:25 +04:00
|
|
|
return 1;
|
2006-04-07 00:42:51 +04:00
|
|
|
}
|
2006-04-15 18:05:18 +04:00
|
|
|
|
2007-10-14 04:20:30 +04:00
|
|
|
bx_bool bx_real_sim_c::save_sr_param(FILE *fp, bx_param_c *node, const char *sr_path, int level)
|
2006-04-15 18:05:18 +04:00
|
|
|
{
|
2015-10-05 21:09:58 +03:00
|
|
|
int i, j;
|
2020-08-06 23:21:14 +03:00
|
|
|
char pname[BX_PATHNAME_LEN], tmpstr[BX_PATHNAME_LEN+1];
|
2006-04-15 18:05:18 +04:00
|
|
|
FILE *fp2;
|
|
|
|
|
2006-05-01 22:24:47 +04:00
|
|
|
for (i=0; i<level; i++)
|
|
|
|
fprintf(fp, " ");
|
2006-04-15 18:05:18 +04:00
|
|
|
if (node == NULL) {
|
|
|
|
BX_ERROR(("NULL pointer"));
|
2007-10-14 04:20:30 +04:00
|
|
|
return 0;
|
2006-04-15 18:05:18 +04:00
|
|
|
}
|
2006-05-01 22:24:47 +04:00
|
|
|
fprintf(fp, "%s = ", node->get_name());
|
2006-04-15 18:05:18 +04:00
|
|
|
switch (node->get_type()) {
|
|
|
|
case BXT_PARAM_NUM:
|
|
|
|
case BXT_PARAM_BOOL:
|
|
|
|
case BXT_PARAM_ENUM:
|
|
|
|
case BXT_PARAM_STRING:
|
2018-01-19 23:27:04 +03:00
|
|
|
case BXT_PARAM_BYTESTRING:
|
2018-01-10 22:10:19 +03:00
|
|
|
node->dump_param(fp);
|
|
|
|
fprintf(fp, "\n");
|
2006-04-15 18:05:18 +04:00
|
|
|
break;
|
|
|
|
case BXT_PARAM_DATA:
|
2015-10-05 21:09:58 +03:00
|
|
|
{
|
|
|
|
bx_shadow_data_c *dparam = (bx_shadow_data_c*)node;
|
2018-01-26 23:02:28 +03:00
|
|
|
if (!dparam->is_text_format()) {
|
2015-10-05 21:09:58 +03:00
|
|
|
node->get_param_path(pname, BX_PATHNAME_LEN);
|
|
|
|
if (!strncmp(pname, "bochs.", 6)) {
|
|
|
|
strcpy(pname, pname+6);
|
|
|
|
}
|
|
|
|
fprintf(fp, "%s\n", pname);
|
|
|
|
if (sr_path)
|
|
|
|
sprintf(tmpstr, "%s/%s", sr_path, pname);
|
|
|
|
else
|
|
|
|
strcpy(tmpstr, pname);
|
|
|
|
fp2 = fopen(tmpstr, "wb");
|
|
|
|
if (fp2 != NULL) {
|
|
|
|
fwrite(dparam->getptr(), 1, dparam->get_size(), fp2);
|
|
|
|
fclose(fp2);
|
|
|
|
}
|
|
|
|
} else {
|
2018-01-26 23:02:28 +03:00
|
|
|
fprintf(fp, "[\n");
|
2015-10-05 21:09:58 +03:00
|
|
|
for (i=0; i < (int)dparam->get_size(); i++) {
|
|
|
|
if ((i % 16) == 0) {
|
|
|
|
for (j=0; j<(level+1); j++)
|
|
|
|
fprintf(fp, " ");
|
|
|
|
} else {
|
|
|
|
fprintf(fp, ", ");
|
|
|
|
}
|
|
|
|
fprintf(fp, "0x%02x", dparam->get(i));
|
|
|
|
if (i == (int)(dparam->get_size() - 1)) {
|
|
|
|
fprintf(fp, "\n");
|
|
|
|
} else if ((i % 16) == 15) {
|
|
|
|
fprintf(fp, ",\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i=0; i<level; i++)
|
|
|
|
fprintf(fp, " ");
|
2018-01-26 23:02:28 +03:00
|
|
|
fprintf(fp, "]\n");
|
2015-10-05 21:09:58 +03:00
|
|
|
}
|
2006-04-15 18:05:18 +04:00
|
|
|
}
|
|
|
|
break;
|
2011-07-22 21:46:06 +04:00
|
|
|
case BXT_PARAM_FILEDATA:
|
|
|
|
fprintf(fp, "%s.%s\n", node->get_parent()->get_name(), node->get_name());
|
|
|
|
if (sr_path)
|
|
|
|
sprintf(tmpstr, "%s/%s.%s", sr_path, node->get_parent()->get_name(), node->get_name());
|
|
|
|
else
|
|
|
|
sprintf(tmpstr, "%s.%s", node->get_parent()->get_name(), node->get_name());
|
|
|
|
fp2 = fopen(tmpstr, "wb");
|
|
|
|
if (fp2 != NULL) {
|
|
|
|
FILE **fpp = ((bx_shadow_filedata_c*)node)->get_fpp();
|
|
|
|
// If the backing store hasn't been created, just save an empty 0 byte placeholder file.
|
|
|
|
if (*fpp != NULL) {
|
|
|
|
while (!feof(*fpp)) {
|
|
|
|
char buffer[64];
|
|
|
|
size_t chars = fread (buffer, 1, sizeof(buffer), *fpp);
|
|
|
|
fwrite(buffer, 1, chars, fp2);
|
|
|
|
}
|
|
|
|
fflush(*fpp);
|
|
|
|
}
|
|
|
|
((bx_shadow_filedata_c*)node)->save(fp2);
|
|
|
|
fclose(fp2);
|
|
|
|
}
|
|
|
|
break;
|
2006-04-15 18:05:18 +04:00
|
|
|
case BXT_LIST:
|
|
|
|
{
|
2006-05-01 22:24:47 +04:00
|
|
|
fprintf(fp, "{\n");
|
2006-04-15 18:05:18 +04:00
|
|
|
bx_list_c *list = (bx_list_c*)node;
|
|
|
|
for (i=0; i < list->get_size(); i++) {
|
2006-05-01 22:24:47 +04:00
|
|
|
save_sr_param(fp, list->get(i), sr_path, level+1);
|
2006-04-15 18:05:18 +04:00
|
|
|
}
|
2006-05-01 22:24:47 +04:00
|
|
|
for (i=0; i<level; i++)
|
|
|
|
fprintf(fp, " ");
|
|
|
|
fprintf(fp, "}\n");
|
2006-04-15 18:05:18 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
BX_ERROR(("save_sr_param(): unknown parameter type"));
|
2007-10-14 04:20:30 +04:00
|
|
|
return 0;
|
2006-04-15 18:05:18 +04:00
|
|
|
}
|
2007-10-14 04:20:30 +04:00
|
|
|
|
|
|
|
return 1;
|
2006-04-15 18:05:18 +04:00
|
|
|
}
|
2012-01-16 21:11:16 +04:00
|
|
|
|
2012-02-16 22:06:03 +04:00
|
|
|
bx_bool bx_real_sim_c::opt_plugin_ctrl(const char *plugname, bx_bool load)
|
|
|
|
{
|
2012-07-06 21:19:32 +04:00
|
|
|
bx_list_c *plugin_ctrl = (bx_list_c*)SIM->get_param(BXPN_PLUGIN_CTRL);
|
|
|
|
if (!strcmp(plugname, "*")) {
|
|
|
|
// verify optional plugin configuration and load/unload plugins if necessary
|
|
|
|
int i = 0;
|
|
|
|
while (i < plugin_ctrl->get_size()) {
|
|
|
|
bx_param_bool_c *plugin = (bx_param_bool_c*)plugin_ctrl->get(i);
|
|
|
|
if (load == (bx_bool)plugin->get()) {
|
|
|
|
opt_plugin_ctrl(plugin->get_name(), load);
|
|
|
|
if (load) i++;
|
|
|
|
} else {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
2012-02-16 22:06:03 +04:00
|
|
|
if (load != PLUG_device_present(plugname)) {
|
|
|
|
if (load) {
|
|
|
|
if (PLUG_load_opt_plugin(plugname)) {
|
2012-07-06 21:19:32 +04:00
|
|
|
if (plugin_ctrl->get_by_name(plugname) == NULL) {
|
|
|
|
new bx_param_bool_c(plugin_ctrl, plugname, "", "", 1);
|
2012-02-24 01:26:13 +04:00
|
|
|
}
|
2012-02-16 22:06:03 +04:00
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
BX_PANIC(("optional plugin '%s' not found", plugname));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
PLUG_unload_opt_plugin(plugname);
|
2012-07-06 21:19:32 +04:00
|
|
|
plugin_ctrl->remove(plugname);
|
2012-02-16 22:06:03 +04:00
|
|
|
return 1;
|
|
|
|
}
|
2013-02-17 12:27:43 +04:00
|
|
|
} else if (!load && !PLUG_device_present(plugname)) {
|
|
|
|
plugin_ctrl->remove(plugname);
|
2012-02-16 22:06:03 +04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-01-16 21:11:16 +04:00
|
|
|
void bx_real_sim_c::init_std_nic_options(const char *name, bx_list_c *menu)
|
|
|
|
{
|
|
|
|
bx_init_std_nic_options(name, menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
void bx_real_sim_c::init_usb_options(const char *usb_name, const char *pname, int maxports)
|
|
|
|
{
|
|
|
|
bx_init_usb_options(usb_name, pname, maxports);
|
|
|
|
}
|
|
|
|
|
2013-01-26 22:17:23 +04:00
|
|
|
int bx_real_sim_c::parse_param_from_list(const char *context, const char *param, bx_list_c *base)
|
|
|
|
{
|
|
|
|
return bx_parse_param_from_list(context, param, base);
|
|
|
|
}
|
|
|
|
|
2012-01-16 21:11:16 +04:00
|
|
|
int bx_real_sim_c::parse_nic_params(const char *context, const char *param, bx_list_c *base)
|
|
|
|
{
|
|
|
|
return bx_parse_nic_params(context, param, base);
|
|
|
|
}
|
|
|
|
|
|
|
|
int bx_real_sim_c::parse_usb_port_params(const char *context, bx_bool devopt,
|
|
|
|
const char *param, int maxports, bx_list_c *base)
|
|
|
|
{
|
|
|
|
return bx_parse_usb_port_params(context, devopt, param, maxports, base);
|
|
|
|
}
|
|
|
|
|
2020-12-05 00:09:18 +03:00
|
|
|
int bx_real_sim_c::split_option_list(const char *msg, const char *rawopt,
|
|
|
|
char **argv, int max_argv)
|
|
|
|
{
|
|
|
|
return bx_split_option_list(msg, rawopt, argv, max_argv);
|
|
|
|
}
|
|
|
|
|
2013-01-20 02:37:15 +04:00
|
|
|
int bx_real_sim_c::write_param_list(FILE *fp, bx_list_c *base, const char *optname, bx_bool multiline)
|
2012-01-16 21:11:16 +04:00
|
|
|
{
|
2013-01-20 02:37:15 +04:00
|
|
|
return bx_write_param_list(fp, base, optname, multiline);
|
2012-01-16 21:11:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
int bx_real_sim_c::write_usb_options(FILE *fp, int maxports, bx_list_c *base)
|
|
|
|
{
|
|
|
|
return bx_write_usb_options(fp, maxports, base);
|
|
|
|
}
|
2017-01-01 20:45:06 +03:00
|
|
|
|
2017-01-13 18:57:36 +03:00
|
|
|
#if BX_USE_GUI_CONSOLE
|
2017-01-01 20:45:06 +03:00
|
|
|
int bx_real_sim_c::bx_printf(const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
char buf[1025];
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vsnprintf(buf, 1024, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
if (get_init_done()) {
|
|
|
|
if (bx_gui->has_gui_console()) {
|
|
|
|
return bx_gui->bx_printf(buf);
|
|
|
|
}
|
|
|
|
}
|
2019-12-09 18:18:47 +03:00
|
|
|
return printf("%s", buf);
|
2017-01-01 20:45:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
char* bx_real_sim_c::bx_gets(char *s, int size, FILE *stream)
|
|
|
|
{
|
|
|
|
if (get_init_done()) {
|
|
|
|
if (bx_gui->has_gui_console()) {
|
|
|
|
return bx_gui->bx_gets(s, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fgets(s, size, stream);
|
|
|
|
}
|
|
|
|
#endif
|