diff --git a/bochs/bochs.h b/bochs/bochs.h index f98bad9e5..8bcb6f2eb 100644 --- a/bochs/bochs.h +++ b/bochs/bochs.h @@ -82,6 +82,8 @@ extern "C" { #include "debug/debug.h" #include "bxversion.h" +#include "gui/siminterface.h" + // // some macros to interface the CPU and memory to external environment // so that these functions can be redirected to the debugger when @@ -316,6 +318,7 @@ class iofunctions { #define CPU13LOG 38 #define CPU14LOG 39 #define CPU15LOG 40 +#define CTRLLOG 41 public: @@ -377,6 +380,7 @@ public: "CPUd", "CPUe", "CPUf", + "CTRL" }; return logclass[i]; } @@ -551,16 +555,17 @@ extern bx_devices_c bx_devices; #define BX_RESET_SOFTWARE 10 #define BX_RESET_HARDWARE 11 +#define BX_PATHNAME_LEN 512 typedef struct { - char path[512]; + char path[BX_PATHNAME_LEN]; unsigned type; unsigned initial_status; } bx_floppy_options; typedef struct { Boolean present; - char path[512]; + char path[BX_PATHNAME_LEN]; unsigned int cylinders; unsigned int heads; unsigned int spt; @@ -569,7 +574,7 @@ typedef struct { struct bx_cdrom_options { Boolean present; - char dev[512]; + char dev[BX_PATHNAME_LEN]; Boolean inserted; }; diff --git a/bochs/gui/Makefile.in b/bochs/gui/Makefile.in index 1871b6efa..7ba650683 100644 --- a/bochs/gui/Makefile.in +++ b/bochs/gui/Makefile.in @@ -47,7 +47,7 @@ GUI_OBJS_MACOS = macintosh.o GUI_OBJS_NOGUI = nogui.o GUI_OBJS_TERM = term.o GUI_OBJS_RFB = rfb.o -GUI_OBJS = gui.o control.o @GUI_OBJS@ +GUI_OBJS = gui.o control.o siminterface.o @GUI_OBJS@ BX_INCDIRS = -I.. -I../iodev -I../@INSTRUMENT_DIR@ LOCAL_CXXFLAGS = @@ -59,7 +59,7 @@ LOCAL_CXXFLAGS = BX_GUI_OBJS = $(GUI_OBJS) -BX_INCLUDES = iodev.h control.h +BX_INCLUDES = iodev.h control.h siminterface.h .@CPP_SUFFIX@.o: $(CXX) @DASH@c $(CXXFLAGS) $(LOCAL_CXXFLAGS) $(BX_INCDIRS) @CXXFP@$< @OFP@$@ diff --git a/bochs/gui/control.cc b/bochs/gui/control.cc index 067c330d4..04f0275f3 100644 --- a/bochs/gui/control.cc +++ b/bochs/gui/control.cc @@ -1,13 +1,72 @@ -#include "bochs.h" +/* + * gui/control.cc + * $Id: control.cc,v 1.2 2001-06-08 07:20:07 bdenney Exp $ + * + * This is code for a text-mode control panel. Note that this file + * does NOT include bochs.h. Instead, it does all of its contact with + * the simulator through an object called SIM, defined in siminterface.cc + * and siminterface.h. This separation adds an extra layer of method + * calls before any work can be done, but the benefit is that the compiler + * enforces the rules. I can guarantee that control.cc doesn't call any + * I/O device objects directly, for example, because the bx_devices symbol + * isn't even defined in this context. + * -#define LOG_THIS genlog-> +Musings by Bryce: +Now that there are some capabilities here, start moving toward the desired +model of separation of gui and simulator. Design a method-call interface +between objects which could later be turned into a network protocol. -void bx_control_panel_entry () -{ - bx_control_panel_main (); +Most messages go from the control panel to bochs, with bochs sending a response +back. Examples: turn on debug event logging for the PIC, or set IPS to +1.5million. Others kinds of messages go from bochs to the control panel. +Example: errors such as "disk image not found", status information such as the +current CPU state. + +But because of the nature of a control panel, most information flows from +the control panel to Bochs. I think we can take advantage of this to +simplify the protocol. The GUI can ask bochs to do things and get a +response back. Bochs can tell the GUI something, but will not get a +response back. + +The control panel should exist before the Bochs simulator starts, so that the +user can get their settings right before booting up a simulator. Once +bochs has begun, some settings can no longer be changed, such as how much +memory there is. Others can be changed at any time, like the value of IPS +or the name of the floppy disk images. If you had the bochs simulator +as a shared library, the GUI could let you choose which version of the +simulator library to load (one with debugging or SMP support or not, +for example). + +When the control panel connects to Bochs, each needs to learn what the other +can do. Some versions of Bochs will have cdrom support, others will not. +Design a simple and general way for the two parties to describe what they +can do, so that the GUI can grey-out some menu choices, and Bochs knows +what the GUI can handle. I think Bochs should provide a list of +capabilities in something like the form of: + typedef struct { Bit16u id; String name; } bx_capability_t; +Only the negotiation of capabilities uses the string name, and for everything +else the 16-bit id is used (use htons() if sending over network). Each +capability is like a function that can be called on the remote object, +and each function needs an input list and a return value. + +Hmm.... This sounds like reinventing function calls. Next I'm going to +say we need to implement prototypes and type checking. +*/ + +extern "C" { +#include +#include +#include } +#include "siminterface.h" +#define BX_PANIC(x) printf x + +void bx_floppy_change (); +void bx_ips_change (); +void bx_log_options (); /******************************************************************/ /* lots of code stolen from bximage.c */ @@ -190,8 +249,8 @@ void bx_control_panel_main () fprintf (stderr, "Continuing simulation\n"); return; case 11: - BX_PANIC(("You chose quit on the control panel")); - exit(1); + fprintf (stderr, "You chose quit on the control panel.\n"); + SIM->quit_sim (); break; default: fprintf (stderr, "Menu choice %d not implemented.\n", choice); @@ -202,31 +261,29 @@ void bx_control_panel_main () void bx_floppy_change () { - int which; - if (ask_int ("Change floppy 0 or 1? [0] ", 0, 1, 0, &which) < 0) + int drive; + if (ask_int ("Change floppy 0 or 1? [0] ", 0, 1, 0, &drive) < 0) return; char oldpath[1024], newpath[1024]; - strcpy (oldpath, (which)? bx_options.floppyb.path : bx_options.floppya.path); + SIM->get_floppy_path (drive, oldpath, 1024); char prompt[1024]; sprintf (prompt, "Enter new pathname: [%s] ", oldpath); if (ask_string (prompt, oldpath, newpath) < 0) return; - fprintf (stderr, "Changing floppy %d to new path %s\n", which, newpath); - strcpy ((which)? bx_options.floppyb.path : bx_options.floppya.path, newpath); - - // notify - bx_devices.floppy->set_media_status (which, 0); - bx_devices.floppy->set_media_status (which, 1); + fprintf (stderr, "Changing floppy %d to new path %s\n", drive, newpath); + SIM->set_floppy_options (drive, 0, newpath); + SIM->set_floppy_options (drive, 1, newpath); } void bx_ips_change () { char prompt[1024]; - sprintf (prompt, "Type a new value for ips: [%d] ", bx_options.ips); + int oldips = SIM->getips (); + sprintf (prompt, "Type a new value for ips: [%d] ", oldips); int newips; - if (ask_int (prompt, 1, 1<<30, bx_options.ips, &newips) < 0) + if (ask_int (prompt, 1, 1<<30, oldips, &newips) < 0) return; - bx_options.ips = newips; + SIM->setips (newips); } static void bx_print_log_action_table () @@ -235,11 +292,11 @@ static void bx_print_log_action_table () fprintf (stderr, "Current log settings:\n"); fprintf (stderr, " Debug Info Error Panic\n"); fprintf (stderr, "ID Device Action Action Action Action\n"); - for (int i=0; iget_n_logfns (); i++) { - logfunc_t *logfn = io->get_logfn (i); - fprintf (stderr, "%3d. %s ", i, logfn->getprefix ()); - for (int j=0; jgetaction (logfn->getonoff(j))); + int i, imax=SIM->get_n_log_modules (); + for (int i=0; iget_prefix (i)); + for (int j=0; jget_max_log_level (); j++) { + fprintf (stderr, "%10s ", SIM->get_action_name (SIM->get_log_action (i, j))); } fprintf (stderr, "\n"); } @@ -254,19 +311,18 @@ void bx_log_options () while (!done) { bx_print_log_action_table (); int id, level, action; - int maxid = io->get_n_logfns (); + int maxid = SIM->get_n_log_modules (); if (ask_int (log_options_prompt1, -1, maxid-1, -1, &id) < 0) return; if (id < 0) return; - logfunc_t *logfn = io->get_logfn (id); - fprintf (stderr, "Editing log options for the device %s\n", logfn->getprefix ()); - for (level=0; levelget_prefix (id)); + for (level=0; levelget_max_log_level (); level++) { char prompt[1024]; - int default_action = logfn->getonoff (level); - sprintf (prompt, "Enter action for %s event: [%s] ", io->getlevel(level), io->getaction (default_action)); + int default_action = SIM->get_log_action (id, level); + sprintf (prompt, "Enter action for %s event: [%s] ", SIM->get_log_level_name (level), SIM->get_action_name(default_action)); if (ask_menu (prompt, 3, log_level_choices, default_action, &action)<0) return; - logfn->setonoff (level, action); + SIM->set_log_action (id, level, action); } } } diff --git a/bochs/gui/control.h b/bochs/gui/control.h index e9fe63042..15ef378f9 100644 --- a/bochs/gui/control.h +++ b/bochs/gui/control.h @@ -1,5 +1 @@ -void bx_control_panel_entry (); void bx_control_panel_main (); -void bx_floppy_change (); -void bx_ips_change (); -void bx_log_options (); diff --git a/bochs/gui/gui.cc b/bochs/gui/gui.cc index 162af2fbd..2f3e8f3e4 100644 --- a/bochs/gui/gui.cc +++ b/bochs/gui/gui.cc @@ -51,6 +51,7 @@ bx_gui_c::bx_gui_c(void) bx_gui_c::init(int argc, char **argv, unsigned tilewidth, unsigned tileheight) { specific_init(&bx_gui, argc, argv, tilewidth, tileheight, BX_HEADER_BAR_Y); + init_siminterface (); // Define some bitmaps to use in the headerbar BX_GUI_THIS floppyA_bmap_id = create_bitmap(bx_floppya_bmap, @@ -175,8 +176,7 @@ bx_gui_c::power_handler(void) void bx_gui_c::snapshot_handler(void) { - BX_INFO(( "# SNAPSHOT callback (unimplemented)." )); - bx_control_panel_entry (); + bx_control_panel_main (); } void diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc new file mode 100644 index 000000000..5f03be549 --- /dev/null +++ b/bochs/gui/siminterface.cc @@ -0,0 +1,140 @@ +/* + * gui/siminterface.cc + * $Id: siminterface.cc,v 1.1 2001-06-08 07:20:07 bdenney Exp $ + * + * Defines the actual link between bx_simulator_interface_c methods + * and the simulator. This file includes bochs.h because it needs + * access to bx_options and other simulator objecst and methods. + * + */ + +#include "bochs.h" + +// this dummy only exists for purposes of log functions. It would be +// lovely to get rid of it. +class siminterface_dummy_c : public logfunctions { + dummy () { + setprefix("[CTRL]"); // control panel + settype(CTRLLOG); + } +}; +siminterface_dummy_c siminterface_dummy; + +bx_simulator_interface_c *SIM = NULL; +#define LOG_THIS siminterface_dummy. + +class bx_real_sim_c : public bx_simulator_interface_c { + void get_floppy_path (int drive, char *buffer, int size); + int get_floppy_present (int drive); + void set_floppy_options (int drive, int present, char *path); + int getips (); + void setips (int ips); + int get_n_log_modules (); + char *get_prefix (int mod); + int get_log_action (int mod, int level); + void set_log_action (int mod, int level, int action); + char *get_action_name (int action); + char *get_log_level_name (int level); + int get_max_log_level (); + void quit_sim (); +}; + +void init_siminterface () +{ + fprintf (stderr, "INIT Interface\n"); + if (SIM == NULL) { + BX_INFO (("init_siminterface")); + SIM = new bx_real_sim_c(); + } +} + +bx_simulator_interface_c::bx_simulator_interface_c () +{ +} + +void +bx_real_sim_c::get_floppy_path (int drive, char *buffer, int size) +{ + strncpy (buffer, + (drive==0)? bx_options.floppya.path : bx_options.floppyb.path, + size); +} + +int +bx_real_sim_c::get_floppy_present (int drive) +{ + BX_ASSERT(0); +} + +void +bx_real_sim_c::set_floppy_options (int drive, int present, char *path) +{ + bx_devices.floppy->set_media_status (drive, present); + strncpy ( + (drive==0)? bx_options.floppya.path : bx_options.floppyb.path, + path, + BX_PATHNAME_LEN); +} + +int +bx_real_sim_c::getips () +{ + return bx_options.ips; +} + +void +bx_real_sim_c::setips (int ips) +{ + bx_options.ips = ips; +} + +int +bx_real_sim_c::get_n_log_modules () +{ + return io->get_n_logfns (); +} + +char * +bx_real_sim_c::get_prefix (int mod) +{ + logfunc_t *logfn = io->get_logfn (mod); + return logfn->getprefix (); +} + +int +bx_real_sim_c::get_log_action (int mod, int level) +{ + logfunc_t *logfn = io->get_logfn (mod); + return logfn->getonoff (level); +} + +void +bx_real_sim_c::set_log_action (int mod, int level, int action) +{ + logfunc_t *logfn = io->get_logfn (mod); + return logfn->setonoff (level, action); +} + +char * +bx_real_sim_c::get_action_name (int action) +{ + return io->getaction (action); +} + +char * +bx_real_sim_c::get_log_level_name (int level) +{ + return io->getlevel (level); +} + +int +bx_real_sim_c::get_max_log_level () +{ + return MAX_LOGLEV; +} + +void +bx_real_sim_c::quit_sim () { + BX_PANIC (("Quit simulation command")); + ::exit (0); +} diff --git a/bochs/gui/siminterface.h b/bochs/gui/siminterface.h new file mode 100644 index 000000000..2a2731e8a --- /dev/null +++ b/bochs/gui/siminterface.h @@ -0,0 +1,37 @@ +/* + * gui/siminterface.h + * $Id: siminterface.h,v 1.1 2001-06-08 07:20:07 bdenney Exp $ + * + * Interface to the simulator, currently only used by control.cc. + * The base class bx_simulator_interface_c, contains only virtual functions + * and it defines the interface that control.cc is allowed to use. + * In siminterface.cc, a class called bx_real_sim_c is defined with + * bx_simulator_interface_c as its parent class. Bx_real_sim_c + * implements each of the functions. The separation into parent class + * and child class leaves the possibility of making a different child + * class that talks to the simulator in a different way (networking + * for example). + * + */ + +class bx_simulator_interface_c { +public: + bx_simulator_interface_c (); + virtual void get_floppy_path (int drive, char *buffer, int size) {} + virtual int get_floppy_present (int drive) {return -1;} + virtual void set_floppy_options (int drive, int present, char *path) {} + virtual int getips () {return -1;} + virtual void setips (int ips) {} + virtual int get_n_log_modules () {return -1;} + virtual char *get_prefix (int mod) {return 0;} + virtual int get_log_action (int mod, int level) {return -1;} + virtual void set_log_action (int mod, int level, int action) {} + virtual char *get_action_name (int action) {return 0;} + virtual char *get_log_level_name (int level) {return 0;} + virtual int get_max_log_level () {return -1;} + virtual void quit_sim () {} +}; + +extern bx_simulator_interface_c *SIM; + +extern void init_siminterface ();