diff --git a/bochs/bochs.h b/bochs/bochs.h index 7c393eaf2..c7893a05c 100644 --- a/bochs/bochs.h +++ b/bochs/bochs.h @@ -245,8 +245,9 @@ typedef class logfunctions { // values of onoff: 0=ignore, 1=report, 2=fatal #define ACT_IGNORE 0 #define ACT_REPORT 1 -#define ACT_FATAL 2 -#define N_ACT 3 +#define ACT_ASK 2 +#define ACT_FATAL 3 +#define N_ACT 4 int onoff[N_LOGLEV]; class iofunctions *logio; public: @@ -259,6 +260,7 @@ public: void panic(char *fmt, ...); void ldebug(char *fmt, ...); void fatal (char *prefix, char *fmt, va_list ap); + void ask (int level, char *prefix, char *fmt, va_list ap); void setprefix(char *); void settype(int); void setio(class iofunctions *); @@ -398,8 +400,8 @@ public: return loglevel[i]; } char *getaction(int i) { - static char *name[] = { "ignore", "report", "fatal" }; - assert (i>=ACT_IGNORE && i<=ACT_FATAL); + static char *name[] = { "ignore", "report", "ask", "fatal" }; + assert (i>=ACT_IGNORE && ilog_msg_2 (prefix, &level, msg, sizeof(msg)) >= 0); + fprintf (stderr, "========================================================================\n"); + fprintf (stderr, "Event type: %s\n", SIM->get_log_level_name (level)); + fprintf (stderr, "Device: %s\n", prefix); + fprintf (stderr, "Message: %s\n\n", msg); + fprintf (stderr, "A panic has occurred. Do you want to:\n"); + 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), prefix); + fprintf (stderr, " die - stop execution now\n"); + int choice; + if (ask_menu ("Choose cont, alwayscont, or die. [%s] ", 3, + log_action_ask_choices, 2, &choice) < 0) + return SIM->notify_return(-1); + // return 0 for continue, 1 for alwayscontinue, 2 for die. + SIM->notify_return(choice); + } + break; + default: + fprintf (stderr, "Control panel: notify callback called with unknown code %04x\n", code); + } +} + +void bx_control_panel_init () { + //fprintf (stderr, "bx_control_panel_init()\n"); + SIM->set_notify_callback (control_panel_notify_callback); +} + #endif diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc index 21ef41f3f..7b923609e 100644 --- a/bochs/gui/siminterface.cc +++ b/bochs/gui/siminterface.cc @@ -1,6 +1,6 @@ /* * gui/siminterface.cc - * $Id: siminterface.cc,v 1.9 2001-06-11 06:48:37 bdenney Exp $ + * $Id: siminterface.cc,v 1.10 2001-06-11 14:03:35 bdenney Exp $ * * Defines the actual link between bx_simulator_interface_c methods * and the simulator. This file includes bochs.h because it needs @@ -17,6 +17,14 @@ logfunctions *siminterface_log = NULL; #define LOG_THIS siminterface_log-> class bx_real_sim_c : public bx_simulator_interface_c { + sim_interface_callback_t callback; + int notify_return_val; + int notify_int_args[10]; + char *notify_string_args[10]; +#define NOTIFY_TYPE_INT +#define NOTIFY_TYPE_STRING +public: + bx_real_sim_c (); virtual int getips (); virtual void setips (int ips); virtual int get_vga_update_interval (); @@ -57,6 +65,11 @@ class bx_real_sim_c : public bx_simulator_interface_c { virtual int set_rom_address (int addr); virtual int get_private_colormap (); virtual void set_private_colormap (int en); + virtual void set_notify_callback (sim_interface_callback_t func); + virtual int notify_return (int retcode); + virtual int LOCAL_notify (int code); + virtual int LOCAL_log_msg (char *prefix, int level, char *msg); + virtual int log_msg_2 (char *prefix, int *level, char *msg, int len); }; void init_siminterface () @@ -73,6 +86,11 @@ bx_simulator_interface_c::bx_simulator_interface_c () init_done = 0; } +bx_real_sim_c::bx_real_sim_c () +{ + callback = NULL; +} + int bx_real_sim_c::getips () { @@ -364,4 +382,54 @@ bx_real_sim_c::set_private_colormap (int en) bx_options.private_colormap = en; } +void +bx_real_sim_c::set_notify_callback (sim_interface_callback_t func) +{ + callback = func; +} + +int +bx_real_sim_c::notify_return (int retcode) +{ + notify_return_val = retcode; + return 0; +} + +int +bx_real_sim_c::LOCAL_notify (int code) +{ + if (callback == NULL) + BX_ERROR (("notify called, but no callback function is registered")); + else { + notify_return_val = -999; + (*callback)(code); + if (notify_return_val == -999) + BX_ERROR (("notify callback returned without setting the return value")); + return notify_return_val; + } +} + +// returns 0 for continue, 1 for alwayscontinue, 2 for die. +int +bx_real_sim_c::LOCAL_log_msg (char *prefix, int level, char *msg) +{ + //fprintf (stderr, "calling notify.\n"); + notify_string_args[0] = prefix; + notify_int_args[1] = level; + notify_string_args[2] = msg; + int val = LOCAL_notify (NOTIFY_CODE_LOGMSG); + //fprintf (stderr, "notify returned %d\n", val); + return val; +} + +// called by control.cc +int +bx_real_sim_c::log_msg_2 (char *prefix, int *level, char *msg, int len) +{ + strncpy (prefix, notify_string_args[0], len); + *level= notify_int_args[1]; + strncpy (msg, notify_string_args[2], len); + return 0; +} + #endif // if BX_USE_CONTROL_PANEL==1 diff --git a/bochs/gui/siminterface.h b/bochs/gui/siminterface.h index 758c2c985..9fc7a6def 100644 --- a/bochs/gui/siminterface.h +++ b/bochs/gui/siminterface.h @@ -1,6 +1,6 @@ /* * gui/siminterface.h - * $Id: siminterface.h,v 1.5 2001-06-11 06:35:18 bdenney Exp $ + * $Id: siminterface.h,v 1.6 2001-06-11 14:03:35 bdenney Exp $ * * Interface to the simulator, currently only used by control.cc. * The base class bx_simulator_interface_c, contains only virtual functions @@ -98,6 +98,15 @@ public: virtual int set_rom_address (int addr) {return -1;} virtual int get_private_colormap () { return -1; } virtual void set_private_colormap (int en) {} + typedef int (*sim_interface_callback_t)(int code); + virtual void set_notify_callback (sim_interface_callback_t func) {} + virtual int notify_return (int retcode) {return -1;} + // methods marked LOCAL should only be called by the simulator, not + // from the control panel. +#define NOTIFY_CODE_LOGMSG 0x101 + virtual int LOCAL_notify (int code) {} + virtual int LOCAL_log_msg (char *prefix, int level, char *msg) {return -1;} + virtual int log_msg_2 (char *prefix, int *level, char *msg, int len) {return -1;} }; extern bx_simulator_interface_c *SIM; diff --git a/bochs/main.cc b/bochs/main.cc index ab997908b..96735f81c 100644 --- a/bochs/main.cc +++ b/bochs/main.cc @@ -84,7 +84,7 @@ bx_options_t bx_options = { 1, // newHardDriveSupport { 0, NULL, NULL, NULL }, // load32bitOSImage hack stuff // log options: ignore debug, report info and error, crash on panic. - { "-", { ACT_IGNORE, ACT_REPORT, ACT_REPORT, ACT_FATAL } }, + { "-", { ACT_IGNORE, ACT_REPORT, ACT_REPORT, ACT_ASK } }, }; static void parse_line_unformatted(char *context, char *line); @@ -309,7 +309,10 @@ logfunctions::info(char *fmt, ...) va_start(ap, fmt); this->logio->out(this->type,LOGLEV_INFO,this->prefix, fmt, ap); - if (onoff[LOGLEV_INFO] == ACT_FATAL) fatal (this->prefix, fmt, ap); + if (onoff[LOGLEV_INFO] == ACT_ASK) + ask (LOGLEV_INFO, this->prefix, fmt, ap); + if (onoff[LOGLEV_INFO] == ACT_FATAL) + fatal (this->prefix, fmt, ap); va_end(ap); } @@ -327,7 +330,10 @@ logfunctions::error(char *fmt, ...) va_start(ap, fmt); this->logio->out(this->type,LOGLEV_ERROR,this->prefix, fmt, ap); - if (onoff[LOGLEV_ERROR] == ACT_FATAL) fatal (this->prefix, fmt, ap); + if (onoff[LOGLEV_ERROR] == ACT_ASK) + ask (LOGLEV_ERROR, this->prefix, fmt, ap); + if (onoff[LOGLEV_ERROR] == ACT_FATAL) + fatal (this->prefix, fmt, ap); va_end(ap); } @@ -344,7 +350,10 @@ logfunctions::panic(char *fmt, ...) va_start(ap, fmt); this->logio->out(this->type,LOGLEV_PANIC,this->prefix, fmt, ap); - if (onoff[LOGLEV_PANIC] == ACT_FATAL) fatal (this->prefix, fmt, ap); + if (onoff[LOGLEV_PANIC] == ACT_ASK) + ask (LOGLEV_PANIC, this->prefix, fmt, ap); + if (onoff[LOGLEV_PANIC] == ACT_FATAL) + fatal (this->prefix, fmt, ap); va_end(ap); } @@ -361,10 +370,35 @@ logfunctions::ldebug(char *fmt, ...) va_start(ap, fmt); this->logio->out(this->type,LOGLEV_DEBUG,this->prefix, fmt, ap); - if (onoff[LOGLEV_DEBUG] == ACT_FATAL) fatal (this->prefix, fmt, ap); + if (onoff[LOGLEV_DEBUG] == ACT_ASK) + ask (LOGLEV_DEBUG, this->prefix, fmt, ap); + if (onoff[LOGLEV_DEBUG] == ACT_FATAL) + fatal (this->prefix, fmt, ap); va_end(ap); } +void +logfunctions::ask (int level, char *prefix, char *fmt, va_list ap) +{ +#if BX_USE_CONTROL_PANEL + char buf1[1024], buf2[1024]; + vsprintf (buf1, fmt, ap); + sprintf (buf2, "%s %s", prefix, buf1); + // FIXME: facility set to 0 because it's unknown. + int val = SIM->LOCAL_log_msg (prefix, level, buf2); + switch (val) + { + case 0: // user chose continue + break; + case 1: // user said continue, and don't ask for this facility again. + setonoff (level, ACT_REPORT); + break; + case 2: // user chose die + fatal (prefix, fmt, ap); + } +#endif +} + void logfunctions::fatal (char *prefix, char *fmt, va_list ap) { @@ -922,6 +956,8 @@ parse_line_formatted(char *context, int num_params, char *params[]) bx_options.log.actions[LOGLEV_PANIC] = ACT_REPORT; else if (!strcmp (action, "ignore")) bx_options.log.actions[LOGLEV_PANIC] = ACT_IGNORE; + else if (!strcmp (action, "ask")) + bx_options.log.actions[LOGLEV_PANIC] = ACT_ASK; else { BX_PANIC(("%s: panic directive malformed.", context)); } @@ -940,6 +976,8 @@ parse_line_formatted(char *context, int num_params, char *params[]) bx_options.log.actions[LOGLEV_ERROR] = ACT_REPORT; else if (!strcmp (action, "ignore")) bx_options.log.actions[LOGLEV_ERROR] = ACT_IGNORE; + else if (!strcmp (action, "ask")) + bx_options.log.actions[LOGLEV_PANIC] = ACT_ASK; else { BX_PANIC(("%s: error directive malformed.", context)); } @@ -958,6 +996,8 @@ parse_line_formatted(char *context, int num_params, char *params[]) bx_options.log.actions[LOGLEV_INFO] = ACT_REPORT; else if (!strcmp (action, "ignore")) bx_options.log.actions[LOGLEV_INFO] = ACT_IGNORE; + else if (!strcmp (action, "ask")) + bx_options.log.actions[LOGLEV_PANIC] = ACT_ASK; else { BX_PANIC(("%s: info directive malformed.", context)); } @@ -976,6 +1016,8 @@ parse_line_formatted(char *context, int num_params, char *params[]) bx_options.log.actions[LOGLEV_DEBUG] = ACT_REPORT; else if (!strcmp (action, "ignore")) bx_options.log.actions[LOGLEV_DEBUG] = ACT_IGNORE; + else if (!strcmp (action, "ask")) + bx_options.log.actions[LOGLEV_PANIC] = ACT_ASK; else { BX_PANIC(("%s: debug directive malformed.", context)); }