- rewrite of the optional plugin control feature. Now the plugins are loaded

directly while parsing the bochsrc or command line. If plugin support is enabled,
  the option could load all optional plugins, not only the ones supported before.
  NOTE #1: The old option had all plugins enabled by default and gave the user
           a chance to diable them. Now the plugins are only loaded if they
           appear in the config line and they are set to "1".
  NOTE #2: Loading a plugin that is controlled by a bochsrc option is possible,
           but it currently leads to a panic, since the load command is still
           present in devices.cc.
  NOTE #3: The plugin init code creates the device object and registers the
           optional plugin device. As an option, it can create config parameters
           and register an option parser. The device init, register state and
           reset is still handled in devices.cc, but in the order the devices
           have been loaded with the plugin control.
  NOTE #4: If plugin support is disabled, the plugin control only accepts the
           devices listed in plugin.cc.
- plugin init of core plugins now fails if they are not loaded with the expected
  type. For core plugins the load order is important and they cannot be handled
  with the chained devices list (used for optional and user plugins).
- some additions for calling config.cc functions from a plugin device
This commit is contained in:
Volker Ruppert 2011-12-25 08:52:34 +00:00
parent c4952b4c84
commit aad2d89c83
19 changed files with 163 additions and 116 deletions

View File

@ -111,12 +111,15 @@ extern "C" {
#endif
// prototypes
int bx_begin_simulation(int argc, char *argv[]);
int bx_begin_simulation(int argc, char *argv[]);
void bx_stop_simulation();
char *bx_find_bochsrc(void);
int bx_parse_cmdline(int arg, int argc, char *argv[]);
int bx_read_configuration(const char *rcfile);
int bx_write_configuration(const char *rcfile, int overwrite);
int bx_parse_cmdline(int arg, int argc, char *argv[]);
int bx_read_configuration(const char *rcfile);
int bx_write_configuration(const char *rcfile, int overwrite);
void bx_init_std_nic_options(const char *name, bx_list_c *menu);
int bx_write_pci_nic_options(FILE *fp, bx_list_c *base);
int bx_parse_nic_params(const char *context, const char *param, bx_list_c *base);
void bx_reset_options(void);
Bit32u crc32(const Bit8u *buf, int len);
// for param-tree testing only

View File

@ -276,6 +276,9 @@ void bx_init_options()
"set benchmark mode",
0, BX_MAX_BIT32U, 0);
// optional plugin control (empty list)
menu = new bx_list_c(menu, "plugin_ctrl", "Optional Plugin Control", 16);
// subtree for special menus
bx_list_c *special_menus = new bx_list_c(root_param, "menu", "");
@ -1722,26 +1725,6 @@ void bx_init_options()
0);
enabled->set_dependent_list(menu->clone());
// optional plugin control
menu = new bx_list_c(misc, "plugin_ctrl", "Optional Plugin Control", 8);
menu->set_options(menu->SHOW_PARENT | menu->USE_BOX_TITLE);
new bx_param_bool_c(menu, "unmapped", "Enable 'unmapped'", "", 1);
new bx_param_bool_c(menu, "biosdev", "Enable 'biosdev'", "", 1);
new bx_param_bool_c(menu, "speaker", "Enable 'speaker'", "", 1);
new bx_param_bool_c(menu, "extfpuirq", "Enable 'extfpuirq'", "", 1);
#if BX_SUPPORT_GAMEPORT
new bx_param_bool_c(menu, "gameport", "Enable 'gameport'", "", 1);
#endif
#if BX_SUPPORT_IODEBUG
new bx_param_bool_c(menu, "iodebug", "Enable 'iodebug'", "", 1);
#endif
#if BX_SUPPORT_PCI
new bx_param_bool_c(menu, "acpi", "Enable 'acpi'", "", 1);
#endif
#if BX_SUPPORT_APIC
new bx_param_bool_c(menu, "ioapic", "Enable 'ioapic'", "", 1);
#endif
#if BX_PLUGINS
// user plugin options
menu = new bx_list_c(misc, "user_plugin", "User Plugin Options", BX_N_USER_PLUGINS);
@ -2263,7 +2246,7 @@ static int parse_usb_port_params(const char *context, bx_bool devopt, const char
return 0;
}
int parse_nic_params(const char *context, const char *param, bx_list_c *base)
int bx_parse_nic_params(const char *context, const char *param, bx_list_c *base)
{
int tmp[6];
char tmpchar[6];
@ -3372,7 +3355,7 @@ static int parse_line_formatted(const char *context, int num_params, char *param
SIM->get_param_num("irq", base)->set(atol(&params[i][4]));
valid |= 0x02;
} else {
ret = parse_nic_params(context, params[i], base);
ret = bx_parse_nic_params(context, params[i], base);
if (ret > 0) {
valid |= ret;
}
@ -3401,7 +3384,7 @@ static int parse_line_formatted(const char *context, int num_params, char *param
SIM->get_param_enum("ethmod", base)->set_by_name("null");
}
for (i=1; i<num_params; i++) {
ret = parse_nic_params(context, params[i], base);
ret = bx_parse_nic_params(context, params[i], base);
if (ret > 0) {
valid |= ret;
}
@ -3424,7 +3407,7 @@ static int parse_line_formatted(const char *context, int num_params, char *param
SIM->get_param_enum("ethmod", base)->set_by_name("null");
}
for (i=1; i<num_params; i++) {
ret = parse_nic_params(context, params[i], base);
ret = bx_parse_nic_params(context, params[i], base);
if (ret > 0) {
valid |= ret;
}
@ -3541,18 +3524,35 @@ static int parse_line_formatted(const char *context, int num_params, char *param
}
#endif
else if (!strcmp(params[0], "plugin_ctrl")) {
char *pname, *val;
char *param, *pname, *val;
bx_param_bool_c *plugin;
for (i=1; i<num_params; i++) {
pname = strtok(params[i], "=");
param = strdup(params[i]);
pname = strtok(param, "=");
val = strtok(NULL, "");
base = (bx_list_c*)SIM->get_param(BXPN_PLUGIN_CTRL);
plugin = (bx_param_bool_c*)base->get_by_name(pname);
if (plugin != NULL) {
plugin->set(atoi(val));
if (val != NULL) {
if (isdigit(val[0])) {
bx_bool load = atoi(val);
base = (bx_list_c*)SIM->get_param(BXPN_PLUGIN_CTRL);
if (load != PLUG_device_present(pname)) {
if (load) {
if (PLUG_load_opt_plugin(pname)) {
plugin = new bx_param_bool_c(base, pname, "", "", 1);
} else {
BX_PANIC(("optional plugin '%s' not found", pname));
}
} else {
PLUG_unload_opt_plugin(pname);
base->remove(pname);
}
}
} else {
PARSE_ERR(("%s: plugin_ctrl directive malformed", context));
}
} else {
PARSE_ERR(("%s: unknown optional plugin '%s'", context, pname));
PARSE_ERR(("%s: plugin_ctrl directive malformed", context));
}
free(param);
}
}
// user-defined options handled by registered functions
@ -3895,6 +3895,16 @@ int bx_write_configuration(const char *rc, int overwrite)
if (fp == NULL) return -1;
// finally it's open and we can start writing.
fprintf(fp, "# configuration file generated by Bochs\n");
base = (bx_list_c*) SIM->get_param(BXPN_PLUGIN_CTRL);
if (base->get_size() > 0) {
fprintf(fp, "plugin_ctrl: ");
for (i = 0; i < base->get_size(); i++) {
if (i > 0) fprintf(fp, ", ");
bx_param_bool_c *plugin = (bx_param_bool_c*)(base->get(i));
fprintf(fp, "%s=1", plugin->get_name());
}
fprintf(fp, "\n");
}
#if BX_PLUGINS
// user plugins
for (i=0; i<BX_N_USER_PLUGINS; i++) {
@ -3905,15 +3915,6 @@ int bx_write_configuration(const char *rc, int overwrite)
}
}
#endif
fprintf(fp, "plugin_ctrl: ");
base = (bx_list_c*) SIM->get_param(BXPN_PLUGIN_CTRL);
for (i=0; i<base->get_size(); i++) {
if (i > 0) fprintf(fp, ", ");
bx_param_bool_c *plugin = (bx_param_bool_c*)(base->get(i));
fprintf(fp, "%s=%d", plugin->get_name(), plugin->get());
}
fprintf(fp, "\n");
fprintf(fp, "config_interface: %s\n", SIM->get_param_enum(BXPN_SEL_CONFIG_INTERFACE)->get_selected());
fprintf(fp, "display_library: %s", SIM->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY)->get_selected());
strptr = SIM->get_param_string(BXPN_DISPLAYLIB_OPTIONS)->getptr();

View File

@ -101,15 +101,20 @@ Bit8u bin_to_bcd(Bit8u value, bx_bool is_binary)
int libcmos_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
theCmosDevice = new bx_cmos_c();
bx_devices.pluginCmosDevice = theCmosDevice;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theCmosDevice, BX_PLUGIN_CMOS);
return(0); // Success
if (type == PLUGTYPE_CORE) {
theCmosDevice = new bx_cmos_c();
bx_devices.pluginCmosDevice = theCmosDevice;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theCmosDevice, BX_PLUGIN_CMOS);
return 0; // Success
} else {
return -1;
}
}
void libcmos_LTX_plugin_fini(void)
{ if (theCmosDevice != NULL)
{ delete theCmosDevice;
{
if (theCmosDevice != NULL) {
delete theCmosDevice;
theCmosDevice = NULL;
}
}

View File

@ -106,8 +106,6 @@ void bx_devices_c::init(BX_MEM_C *newmem)
unsigned i;
const char def_name[] = "Default";
const char *vga_ext;
bx_list_c *plugin_ctrl;
bx_param_bool_c *plugin;
BX_DEBUG(("Init $Id$"));
mem = newmem;
@ -185,22 +183,9 @@ void bx_devices_c::init(BX_MEM_C *newmem)
#if BX_SUPPORT_PCIUSB
PLUG_load_plugin(usb_common, PLUGTYPE_CORE);
#endif
} else {
plugin_ctrl = (bx_list_c*)SIM->get_param(BXPN_PLUGIN_CTRL);
SIM->get_param_bool(BX_PLUGIN_ACPI, plugin_ctrl)->set(0);
}
#else
BX_ERROR(("Bochs is not compiled with PCI support"));
}
#endif
// optional plugins not controlled by separate option
plugin_ctrl = (bx_list_c*)SIM->get_param(BXPN_PLUGIN_CTRL);
for (i = 0; i < (unsigned)plugin_ctrl->get_size(); i++) {
plugin = (bx_param_bool_c*)(plugin_ctrl->get(i));
if (plugin->get()) {
PLUG_load_opt_plugin(plugin->get_name());
}
}
PLUG_load_plugin(keyboard, PLUGTYPE_OPTIONAL);

View File

@ -39,10 +39,14 @@ bx_dma_c *theDmaDevice = NULL;
int libdma_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
theDmaDevice = new bx_dma_c ();
bx_devices.pluginDmaDevice = theDmaDevice;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theDmaDevice, BX_PLUGIN_DMA);
return(0); // Success
if (type == PLUGTYPE_CORE) {
theDmaDevice = new bx_dma_c ();
bx_devices.pluginDmaDevice = theDmaDevice;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theDmaDevice, BX_PLUGIN_DMA);
return 0; // Success
} else {
return -1;
}
}
void libdma_LTX_plugin_fini(void)

View File

@ -110,10 +110,14 @@ static Bit16u drate_in_k[4] = {
int libfloppy_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
theFloppyController = new bx_floppy_ctrl_c();
bx_devices.pluginFloppyDevice = theFloppyController;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theFloppyController, BX_PLUGIN_FLOPPY);
return(0); // Success
if (type == PLUGTYPE_CORE) {
theFloppyController = new bx_floppy_ctrl_c();
bx_devices.pluginFloppyDevice = theFloppyController;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theFloppyController, BX_PLUGIN_FLOPPY);
return 0; // Success
} else {
return -1;
}
}
void libfloppy_LTX_plugin_fini(void)

View File

@ -45,9 +45,13 @@ bx_hdimage_ctl_c* theHDImageCtl = NULL;
int libhdimage_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
theHDImageCtl = new bx_hdimage_ctl_c;
bx_devices.pluginHDImageCtl = theHDImageCtl;
return(0); // Success
if (type == PLUGTYPE_CORE) {
theHDImageCtl = new bx_hdimage_ctl_c;
bx_devices.pluginHDImageCtl = theHDImageCtl;
return 0; // Success
} else {
return -1;
}
}
void libhdimage_LTX_plugin_fini(void)

View File

@ -41,9 +41,13 @@ bx_netmod_ctl_c* theNetModCtl = NULL;
int libnetmod_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
theNetModCtl = new bx_netmod_ctl_c;
bx_devices.pluginNetModCtl = theNetModCtl;
return(0); // Success
if (type == PLUGTYPE_CORE) {
theNetModCtl = new bx_netmod_ctl_c;
bx_devices.pluginNetModCtl = theNetModCtl;
return 0; // Success
} else {
return -1;
}
}
void libnetmod_LTX_plugin_fini(void)

View File

@ -39,10 +39,14 @@ bx_pci_bridge_c *thePciBridge = NULL;
int libpci_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
thePciBridge = new bx_pci_bridge_c();
bx_devices.pluginPciBridge = thePciBridge;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePciBridge, BX_PLUGIN_PCI);
return(0); // Success
if (type == PLUGTYPE_CORE) {
thePciBridge = new bx_pci_bridge_c();
bx_devices.pluginPciBridge = thePciBridge;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePciBridge, BX_PLUGIN_PCI);
return 0; // Success
} else {
return -1;
}
}
void libpci_LTX_plugin_fini(void)

View File

@ -40,10 +40,14 @@ bx_piix3_c *thePci2IsaBridge = NULL;
int libpci2isa_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
thePci2IsaBridge = new bx_piix3_c();
bx_devices.pluginPci2IsaBridge = thePci2IsaBridge;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePci2IsaBridge, BX_PLUGIN_PCI2ISA);
return(0); // Success
if (type == PLUGTYPE_CORE) {
thePci2IsaBridge = new bx_piix3_c();
bx_devices.pluginPci2IsaBridge = thePci2IsaBridge;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePci2IsaBridge, BX_PLUGIN_PCI2ISA);
return 0; // Success
} else {
return -1;
}
}
void libpci2isa_LTX_plugin_fini(void)

View File

@ -33,10 +33,14 @@ bx_pic_c *thePic = NULL;
int libpic_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
thePic = new bx_pic_c();
bx_devices.pluginPicDevice = thePic;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePic, BX_PLUGIN_PIC);
return(0); // Success
if (type == PLUGTYPE_CORE) {
thePic = new bx_pic_c();
bx_devices.pluginPicDevice = thePic;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePic, BX_PLUGIN_PIC);
return 0; // Success
} else {
return -1;
}
}
void libpic_LTX_plugin_fini(void)

View File

@ -35,10 +35,14 @@ bx_pit_c *thePit = NULL;
int libpit_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
thePit = new bx_pit_c();
bx_devices.pluginPitDevice = thePit;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePit, BX_PLUGIN_PIT);
return(0); // Success
if (type == PLUGTYPE_CORE) {
thePit = new bx_pit_c();
bx_devices.pluginPitDevice = thePit;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePit, BX_PLUGIN_PIT);
return 0; // Success
} else {
return -1;
}
}
void libpit_LTX_plugin_fini(void)

View File

@ -40,9 +40,13 @@ bx_soundmod_ctl_c* theSoundModCtl = NULL;
int libsoundmod_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
theSoundModCtl = new bx_soundmod_ctl_c;
bx_devices.pluginSoundModCtl = theSoundModCtl;
return(0); // Success
if (type == PLUGTYPE_CORE) {
theSoundModCtl = new bx_soundmod_ctl_c;
bx_devices.pluginSoundModCtl = theSoundModCtl;
return 0; // Success
} else {
return -1;
}
}
void libsoundmod_LTX_plugin_fini(void)

View File

@ -224,11 +224,15 @@ static bx_svga_cirrus_c *theSvga = NULL;
int libvga_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
theSvga = new bx_svga_cirrus_c();
bx_vga_set_smf_pointer(theSvga);
bx_devices.pluginVgaDevice = theSvga;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theSvga, BX_PLUGIN_VGA);
return(0); // Success
if (type == PLUGTYPE_CORE) {
theSvga = new bx_svga_cirrus_c();
bx_vga_set_smf_pointer(theSvga);
bx_devices.pluginVgaDevice = theSvga;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theSvga, BX_PLUGIN_VGA);
return 0; // Success
} else {
return -1;
}
}
void libvga_LTX_plugin_fini(void)

View File

@ -60,9 +60,13 @@ bx_usb_devctl_c* theUsbDevCtl = NULL;
int libusb_common_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
theUsbDevCtl = new bx_usb_devctl_c;
bx_devices.pluginUsbDevCtl = theUsbDevCtl;
return(0); // Success
if (type == PLUGTYPE_CORE) {
theUsbDevCtl = new bx_usb_devctl_c;
bx_devices.pluginUsbDevCtl = theUsbDevCtl;
return 0; // Success
} else {
return -1;
}
}
void libusb_common_LTX_plugin_fini(void)

View File

@ -85,10 +85,14 @@ void bx_vga_set_smf_pointer(bx_vga_c *theVga_ptr)
#else // BX_SUPPORT_CLGD54XX
int libvga_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
theVga = new bx_vga_c();
bx_devices.pluginVgaDevice = theVga;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theVga, BX_PLUGIN_VGA);
return(0); // Success
if (type == PLUGTYPE_CORE) {
theVga = new bx_vga_c();
bx_devices.pluginVgaDevice = theVga;
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theVga, BX_PLUGIN_VGA);
return 0; // Success
} else {
return -1;
}
}
void libvga_LTX_plugin_fini(void)

View File

@ -32,6 +32,7 @@
#define BXPN_RESTORE_FLAG "general.restore"
#define BXPN_RESTORE_PATH "general.restore_path"
#define BXPN_DEBUG_RUNNING "general.debug_running"
#define BXPN_PLUGIN_CTRL "general.plugin_ctrl"
#define BXPN_CPU_NPROCESSORS "cpu.n_processors"
#define BXPN_CPU_NCORES "cpu.n_cores"
#define BXPN_CPU_NTHREADS "cpu.n_threads"
@ -173,7 +174,6 @@
#define BXPN_ES1370_WAVEDEV "sound.es1370.wavedev"
#define BXPN_PORT_E9_HACK "misc.port_e9_hack"
#define BXPN_GDBSTUB "misc.gdbstub"
#define BXPN_PLUGIN_CTRL "misc.plugin_ctrl"
#define BXPN_LOG_FILENAME "log.filename"
#define BXPN_LOG_PREFIX "log.prefix"
#define BXPN_DEBUGGER_LOG_FILENAME "log.debugger_filename"

View File

@ -739,7 +739,7 @@ void bx_unload_plugins()
#endif
} else {
#if !BX_PLUGINS
if (!bx_unload_opt_plugin(device->name)) {
if (!bx_unload_opt_plugin(device->name, 0)) {
delete device->devmodel;
}
#endif
@ -856,12 +856,15 @@ int bx_load_opt_plugin(const char *name)
return 0;
}
int bx_unload_opt_plugin(const char *name)
int bx_unload_opt_plugin(const char *name, bx_bool devflag)
{
int i = 0;
while (strcmp(builtin_opt_plugins[i].name, "NULL")) {
if (!strcmp(name, builtin_opt_plugins[i].name)) {
if (builtin_opt_plugins[i].status == 1) {
if (devflag) {
pluginUnregisterDeviceDevmodel(builtin_opt_plugins[i].name);
}
builtin_opt_plugins[i].plugin_fini();
builtin_opt_plugins[i].status = 0;
}

View File

@ -79,6 +79,7 @@ extern "C" {
#define BX_REGISTER_DEVICE_DEVMODEL(a,b,c,d) pluginRegisterDeviceDevmodel(a,b,c,d)
#define BX_UNREGISTER_DEVICE_DEVMODEL(a) pluginUnregisterDeviceDevmodel(a)
#define PLUG_device_present(a) pluginDevicePresent(a)
#if BX_PLUGINS
@ -86,6 +87,7 @@ extern "C" {
#define PLUG_load_opt_plugin(name) bx_load_plugin(name,PLUGTYPE_OPTIONAL)
#define PLUG_load_user_plugin(name) {bx_load_plugin(name,PLUGTYPE_USER);}
#define PLUG_unload_plugin(name) {bx_unload_plugin(#name,1);}
#define PLUG_unload_opt_plugin(name) bx_unload_plugin(name,1)
#define PLUG_unload_user_plugin(name) {bx_unload_plugin(name,1);}
#define DEV_register_ioread_handler(b,c,d,e,f) pluginRegisterIOReadHandler(b,c,d,e,f)
@ -107,9 +109,9 @@ extern "C" {
// When plugins are off, PLUG_load_plugin will call the plugin_init function
// directly.
#define PLUG_load_plugin(name,type) {lib##name##_LTX_plugin_init(NULL,type,0,NULL);}
#define PLUG_unload_plugin(name) {lib##name##_LTX_plugin_fini();}
#define PLUG_load_opt_plugin(name) bx_load_opt_plugin(name)
#define PLUG_unload_opt_plugin(name) bx_unload_opt_plugin(name);
#define PLUG_unload_plugin(name) {lib##name##_LTX_plugin_fini();}
#define PLUG_unload_opt_plugin(name) bx_unload_opt_plugin(name,1);
#define DEV_register_ioread_handler(b,c,d,e,f) bx_devices.register_io_read_handler(b,c,d,e,f)
#define DEV_register_iowrite_handler(b,c,d,e,f) bx_devices.register_io_write_handler(b,c,d,e,f)
#define DEV_unregister_ioread_handler(b,c,d,e) bx_devices.unregister_io_read_handler(b,c,d,e)
@ -384,7 +386,7 @@ extern void bx_plugins_after_restore_state(void);
#if !BX_PLUGINS
int bx_load_opt_plugin(const char *name);
int bx_unload_opt_plugin(const char *name);
int bx_unload_opt_plugin(const char *name, bx_bool devflag);
#endif
// every plugin must define these, within the extern"C" block, so that