diff --git a/bochs/.bochsrc b/bochs/.bochsrc index 1fcd94f3c..0149f73e8 100644 --- a/bochs/.bochsrc +++ b/bochs/.bochsrc @@ -1,6 +1,17 @@ # You may now use double quotes around pathnames, in case # your pathname includes spaces. +#======================================================================= +# PLUGIN_CTRL: +# Controls the presence of optional device plugins. These plugins are loaded +# directly with this option and some of them install a config option that is +# only available when the plugin device is loaded. The value "1" means to load +# the plugin and "0" will unload it (if loaded before). +# These plugins are currently supported: 'acpi', 'biosdev', 'e1000', 'es1370', +# 'extfpuirq', 'gameport', 'iodebug', 'speaker' and 'unmapped'. +#======================================================================= +#plugin_ctrl: unmapped=1, biosdev=1, speaker=1, e1000=1 + #======================================================================= # CONFIG_INTERFACE # @@ -706,10 +717,10 @@ parport1: enabled=1, file="parport.out" #======================================================================= # ES1370: # This defines the ES1370 sound emulation. The parameter 'enabled' controls the -# presence of the device. In addition to this, it must be assigned to a PCI -# slot. The 'wavedev' parameter is similar to the 'wave' parameter of the SB16 -# soundcard. The emulation supports recording and playback (except DAC1+DAC2 -# output at the same time). +# presence of the device. In addition to this, it must be loaded with 'plugin_ctrl' +# and assigned to a PCI slot. The 'wavedev' parameter is similar to the 'wave' +# parameter of the SB16 soundcard. The emulation supports recording and playback +# (except DAC1+DAC2 output at the same time). # # Examples: # es1370: enabled=1, wavedev="" # win32 @@ -879,7 +890,7 @@ private_colormap: enabled=0 # # The E1000 accepts the same syntax (for mac, ethmod, ethdev, script, bootrom) # and supports the same networking modules as the NE2000 adapter. In addition -# to this, it must be assigned to a PCI slot. +# to this, it must be loaded with 'plugin_ctrl' and assigned to a PCI slot. #======================================================================= #e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=slirp, script=/usr/local/bin/slirp @@ -1062,15 +1073,6 @@ pci: enabled=1, chipset=i440fx #======================================================================= #gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0 -#======================================================================= -# PLUGIN_CTRL: -# Controls the presence of optional plugins without a separate option. -# By default all existing plugins are enabled. These plugins are currently -# supported: 'acpi', 'biosdev', 'extfpuirq', 'gameport', 'iodebug', -# 'pci_ide', 'speaker' and 'unmapped'. -#======================================================================= -#plugin_ctrl: biosdev=0, speaker=0 - #======================================================================= # USER_PLUGIN: # Load user-defined plugin. This option is available only if Bochs is diff --git a/bochs/config.cc b/bochs/config.cc index 9b7d065a7..f787b9bf3 100644 --- a/bochs/config.cc +++ b/bochs/config.cc @@ -1574,18 +1574,6 @@ void bx_init_options() enabled->set_enabled(BX_SUPPORT_PCIPNIC); bx_init_std_nic_options("Pseudo NIC", menu); enabled->set_dependent_list(menu->clone()); - // e1000 options - menu = new bx_list_c(network, "e1000", "Intel(R) Gigabit Ethernet"); - menu->set_options(menu->SHOW_PARENT); - menu->set_enabled(BX_SUPPORT_E1000); - enabled = new bx_param_bool_c(menu, - "enabled", - "Enable Intel(R) Gigabit Ethernet emulation", - "Enables the Intel(R) Gigabit Ethernet emulation", - 0); - enabled->set_enabled(BX_SUPPORT_E1000); - bx_init_std_nic_options("Intel(R) Gigabit Ethernet", menu); - enabled->set_dependent_list(menu->clone()); // sound subtree bx_list_c *sound = new bx_list_c(root_param, "sound", "Sound Configuration"); @@ -1663,27 +1651,6 @@ void bx_init_options() deplist->add(logfile); loglevel->set_dependent_list(deplist); - menu = new bx_list_c(sound, "es1370", "ES1370 Configuration", 8); - menu->set_options(menu->SHOW_PARENT); - menu->set_enabled(BX_SUPPORT_ES1370); - - // ES1370 options - enabled = new bx_param_bool_c(menu, - "enabled", - "Enable ES1370 emulation", - "Enables the ES1370 emulation", - 0); - enabled->set_enabled(BX_SUPPORT_ES1370); - - bx_param_filename_c *wavedev = new bx_param_filename_c(menu, - "wavedev", - "Wave device", - "This is the device where the wave output is sent to", - "", BX_PATHNAME_LEN); - deplist = new bx_list_c(NULL, 1); - deplist->add(wavedev); - enabled->set_dependent_list(deplist); - // misc options subtree bx_list_c *misc = new bx_list_c(root_param, "misc", "Configure Everything Else"); misc->set_options(misc->SHOW_PARENT); @@ -1837,7 +1804,7 @@ void bx_reset_options() // network devices SIM->get_param("network")->reset(); - // SB16 & ES1370 + // sound devices SIM->get_param("sound")->reset(); // misc @@ -3037,17 +3004,6 @@ static int parse_line_formatted(const char *context, int num_params, char *param SIM->get_param_bool("enabled", base)->set(1); else SIM->get_param_bool("enabled", base)->set(0); - } else if (!strcmp(params[0], "es1370")) { - base = (bx_list_c*) SIM->get_param(BXPN_SOUND_ES1370); - for (i=1; iset(atol(¶ms[i][8])); - } else if (!strncmp(params[i], "wavedev=", 8)) { - SIM->get_param_string("wavedev", base)->set(¶ms[i][8]); - } else { - BX_ERROR(("%s: unknown parameter for es1370 ignored.", context)); - } - } } else if ((!strncmp(params[0], "com", 3)) && (strlen(params[0]) == 4)) { char tmpname[80]; idx = params[0][3]; @@ -3412,29 +3368,6 @@ static int parse_line_formatted(const char *context, int num_params, char *param SIM->get_param_bool("enabled", base)->set(0); } } - } else if (!strcmp(params[0], "e1000")) { - int ret, valid = 0; - base = (bx_list_c*) SIM->get_param(BXPN_E1000); - if (!SIM->get_param_bool("enabled", base)->get()) { - SIM->get_param_enum("ethmod", base)->set_by_name("null"); - } - for (i=1; i 0) { - valid |= ret; - } - } - if (!SIM->get_param_bool("enabled", base)->get()) { - if (valid == 0x04) { - SIM->get_param_bool("enabled", base)->set(1); - } else if (valid < 0x80) { - PARSE_ERR(("%s: 'e1000' directive incomplete (mac is required)", context)); - } - } else { - if (valid & 0x80) { - SIM->get_param_bool("enabled", base)->set(0); - } - } } else if (!strcmp(params[0], "load32bitOSImage")) { if ((num_params!=4) && (num_params!=5)) { PARSE_ERR(("%s: load32bitOSImage directive: wrong # args.", context)); @@ -3771,8 +3704,6 @@ int bx_write_sound_options(FILE *fp, bx_list_c *base) SIM->get_param_num("loglevel", base)->get(), SIM->get_param_string("logfile", base)->getptr(), SIM->get_param_num("dmatimer", base)->get()); - } else if (!strcmp(base->get_name(), "es1370")) { - fprintf(fp, ", wavedev=%s", SIM->get_param_string("wavedev", base)->getptr()); } } fprintf(fp, "\n"); @@ -4121,9 +4052,7 @@ int bx_write_configuration(const char *rc, int overwrite) bx_write_clock_cmos_options(fp); bx_write_ne2k_options(fp, (bx_list_c*) SIM->get_param(BXPN_NE2K)); bx_write_pci_nic_options(fp, (bx_list_c*) SIM->get_param(BXPN_PNIC)); - bx_write_pci_nic_options(fp, (bx_list_c*) SIM->get_param(BXPN_E1000)); bx_write_sound_options(fp, (bx_list_c*) SIM->get_param(BXPN_SOUND_SB16)); - bx_write_sound_options(fp, (bx_list_c*) SIM->get_param(BXPN_SOUND_ES1370)); bx_write_loader_options(fp); bx_write_log_options(fp, (bx_list_c*) SIM->get_param("log")); bx_write_keyboard_options(fp); diff --git a/bochs/iodev/devices.cc b/bochs/iodev/devices.cc index d8ba1173b..edc2ee7a3 100644 --- a/bochs/iodev/devices.cc +++ b/bochs/iodev/devices.cc @@ -238,11 +238,6 @@ void bx_devices_c::init(BX_MEM_C *newmem) if (SIM->get_param_bool(BXPN_PNIC_ENABLED)->get()) { PLUG_load_plugin(pcipnic, PLUGTYPE_OPTIONAL); } -#endif -#if BX_SUPPORT_E1000 - if (SIM->get_param_bool(BXPN_E1000_ENABLED)->get()) { - PLUG_load_plugin(e1000, PLUGTYPE_OPTIONAL); - } #endif } #endif @@ -264,13 +259,6 @@ void bx_devices_c::init(BX_MEM_C *newmem) BX_ERROR(("Bochs is not compiled with SB16 support")); #endif } - if (SIM->get_param_bool(BXPN_ES1370_ENABLED)->get()) { -#if BX_SUPPORT_ES1370 - PLUG_load_plugin(es1370, PLUGTYPE_OPTIONAL); -#else - BX_ERROR(("Bochs is not compiled with ES1370 support")); -#endif - } // CMOS RAM & RTC pluginCmosDevice->init(); diff --git a/bochs/iodev/e1000.cc b/bochs/iodev/e1000.cc index 1a69c8ecc..a1a0df9ab 100644 --- a/bochs/iodev/e1000.cc +++ b/bochs/iodev/e1000.cc @@ -277,15 +277,78 @@ static const Bit16u e1000_eeprom_template[64] = { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, }; +// builtin configuration handling functions + +void e1000_init_options(void) +{ + bx_param_c *network = SIM->get_param("network"); + bx_list_c *menu = new bx_list_c(network, "e1000", "Intel(R) Gigabit Ethernet"); + menu->set_options(menu->SHOW_PARENT); + bx_param_bool_c *enabled = new bx_param_bool_c(menu, + "enabled", + "Enable Intel(R) Gigabit Ethernet emulation", + "Enables the Intel(R) Gigabit Ethernet emulation", + 0); + bx_init_std_nic_options("Intel(R) Gigabit Ethernet", menu); + enabled->set_dependent_list(menu->clone()); +} + +Bit32s e1000_options_parser(const char *context, int num_params, char *params[]) +{ + int ret, valid = 0; + + if (!strcmp(params[0], "e1000")) { + bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_E1000); + if (!SIM->get_param_bool("enabled", base)->get()) { + SIM->get_param_enum("ethmod", base)->set_by_name("null"); + } + for (int i = 1; i < num_params; i++) { + ret = bx_parse_nic_params(context, params[i], base); + if (ret > 0) { + valid |= ret; + } + } + if (!SIM->get_param_bool("enabled", base)->get()) { + if (valid == 0x04) { + SIM->get_param_bool("enabled", base)->set(1); + } else if (valid < 0x80) { + BX_PANIC(("%s: 'e1000' directive incomplete (mac is required)", context)); + } + } else { + if (valid & 0x80) { + SIM->get_param_bool("enabled", base)->set(0); + } + } + } else { + BX_PANIC(("%s: unknown directive '%s'", context, params[0])); + } + return 0; +} + +Bit32s e1000_options_save(FILE *fp) +{ + bx_write_pci_nic_options(fp, (bx_list_c*) SIM->get_param(BXPN_E1000)); + return 0; +} + +// device plugin entry points + int libe1000_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[]) { theE1000Device = new bx_e1000_c(); BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theE1000Device, BX_PLUGIN_E1000); + // add new configuration parameter for the config interface + e1000_init_options(); + // register add-on option for bochsrc and command line + SIM->register_addon_option("e1000", e1000_options_parser, e1000_options_save); return 0; // Success } void libe1000_LTX_plugin_fini(void) { + SIM->unregister_addon_option("e1000"); + bx_list_c *menu = (bx_list_c*)SIM->get_param("network"); + menu->remove("e1000"); delete theE1000Device; } @@ -342,6 +405,8 @@ Bit16u net_checksum_finish(Bit32u sum) } +// the device object + bx_e1000_c::bx_e1000_c() { put("E1000"); @@ -366,14 +431,19 @@ bx_e1000_c::~bx_e1000_c() void bx_e1000_c::init(void) { - bx_list_c *base; Bit8u macaddr[6]; int i; Bit16u checksum = 0; const char *bootrom; // Read in values from config interface - base = (bx_list_c*) SIM->get_param(BXPN_E1000); + bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_E1000); + // Check if the device is disabled or not configured + if (!SIM->get_param_bool("enabled", base)->get()) { + BX_INFO(("E1000 disabled")); + BX_UNREGISTER_DEVICE_DEVMODEL("e1000"); + return; + } memcpy(macaddr, SIM->get_param_string("macaddr", base)->getptr(), 6); memcpy(BX_E1000_THIS s.eeprom_data, e1000_eeprom_template, diff --git a/bochs/iodev/es1370.cc b/bochs/iodev/es1370.cc index 264ab63b2..b0b88aa4d 100644 --- a/bochs/iodev/es1370.cc +++ b/bochs/iodev/es1370.cc @@ -86,18 +86,85 @@ const Bit16u ctl_ch_en[3] = {0x0040, 0x0020, 0x0010}; const Bit16u sctl_ch_pause[3] = {0x0800, 0x1000, 0x0000}; const Bit16u sctl_loop_sel[3] = {0x2000, 0x4000, 0x8000}; +// builtin configuration handling functions + +void es1370_init_options(void) +{ + bx_param_c *sound = SIM->get_param("sound"); + bx_list_c *menu = new bx_list_c(sound, "es1370", "ES1370 Configuration", 8); + menu->set_options(menu->SHOW_PARENT); + menu->set_enabled(BX_SUPPORT_ES1370); + + bx_param_bool_c *enabled = new bx_param_bool_c(menu, + "enabled", + "Enable ES1370 emulation", + "Enables the ES1370 emulation", + 0); + enabled->set_enabled(BX_SUPPORT_ES1370); + + bx_param_filename_c *wavedev = new bx_param_filename_c(menu, + "wavedev", + "Wave device", + "This is the device where the wave output is sent to", + "", BX_PATHNAME_LEN); + bx_list_c *deplist = new bx_list_c(NULL, 1); + deplist->add(wavedev); + enabled->set_dependent_list(deplist); +} + +Bit32s es1370_options_parser(const char *context, int num_params, char *params[]) +{ + if (!strcmp(params[0], "es1370")) { + bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_ES1370); + for (int i = 1; i < num_params; i++) { + if (!strncmp(params[i], "enabled=", 8)) { + SIM->get_param_bool("enabled", base)->set(atol(¶ms[i][8])); + } else if (!strncmp(params[i], "wavedev=", 8)) { + SIM->get_param_string("wavedev", base)->set(¶ms[i][8]); + } else { + BX_ERROR(("%s: unknown parameter for es1370 ignored.", context)); + } + } + } else { + BX_PANIC(("%s: unknown directive '%s'", context, params[0])); + } + return 0; +} + +Bit32s es1370_options_save(FILE *fp) +{ + bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_ES1370); + fprintf(fp, "es1370: enabled=%d", SIM->get_param_bool("enabled", base)->get()); + if (SIM->get_param_bool("enabled", base)->get()) { + fprintf(fp, ", wavedev=%s", SIM->get_param_string("wavedev", base)->getptr()); + } + fprintf(fp, "\n"); + return 0; +} + +// device plugin entry points + int libes1370_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[]) { theES1370Device = new bx_es1370_c(); BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theES1370Device, BX_PLUGIN_ES1370); + // add new configuration parameter for the config interface + es1370_init_options(); + // register add-on option for bochsrc and command line + SIM->register_addon_option("es1370", es1370_options_parser, es1370_options_save); return 0; // Success } void libes1370_LTX_plugin_fini(void) { + SIM->unregister_addon_option("es1370"); + bx_list_c *menu = (bx_list_c*)SIM->get_param("sound"); + menu->remove("es1370"); delete theES1370Device; } +// the device object + bx_es1370_c::bx_es1370_c() { put("E1370"); @@ -121,6 +188,14 @@ bx_es1370_c::~bx_es1370_c() void bx_es1370_c::init(void) { + // Read in values from config interface + bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_ES1370); + // Check if the device is disabled or not configured + if (!SIM->get_param_bool("enabled", base)->get()) { + BX_INFO(("ES1370 disabled")); + BX_UNREGISTER_DEVICE_DEVMODEL("es1370"); + return; + } BX_ES1370_THIS s.devfunc = 0x00; DEV_register_pci_handlers(this, &BX_ES1370_THIS s.devfunc, BX_PLUGIN_ES1370, "Experimental ES1370 soundcard"); diff --git a/bochs/plugin.cc b/bochs/plugin.cc index 80fb71589..6a1bb0d4a 100644 --- a/bochs/plugin.cc +++ b/bochs/plugin.cc @@ -836,6 +836,12 @@ static builtin_plugin_t builtin_opt_plugins[] = { #endif #if BX_SUPPORT_APIC BUILTIN_PLUGIN_ENTRY(ioapic), +#endif +#if BX_SUPPORT_E1000 + BUILTIN_PLUGIN_ENTRY(e1000), +#endif +#if BX_SUPPORT_ES1370 + BUILTIN_PLUGIN_ENTRY(es1370), #endif {"NULL", NULL, NULL, 0} };