- devices 'pcidev' and 'pcipnic': moved config parameter creation and bochsrc

option parsing to the plugin device code
This commit is contained in:
Volker Ruppert 2012-01-09 17:15:03 +00:00
parent 2900956327
commit db4520f778
6 changed files with 178 additions and 116 deletions

View File

@ -8,8 +8,8 @@
# 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: 'biosdev', 'e1000', 'es1370',
# 'extfpuirq', 'gameport', 'iodebug', 'speaker', 'unmapped', 'usb_ohci',
# 'usb_uhci' and 'usb_xhci'.
# 'extfpuirq', 'gameport', 'iodebug', 'pcidev', 'pcipnic', 'speaker',
# 'unmapped', 'usb_ohci', 'usb_uhci' and 'usb_xhci'.
#=======================================================================
#plugin_ctrl: unmapped=1, biosdev=1, speaker=1, e1000=1
@ -885,7 +885,8 @@ private_colormap: enabled=0
#
# The pseudo-NIC 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.
# In addition to this, it must be loaded with 'plugin_ctrl' and assigned
# to a PCI slot.
#=======================================================================
#pnic: enabled=1, mac=b0:c4:20:00:00:00, ethmod=vnet

View File

@ -755,8 +755,7 @@ void bx_init_options()
bx_list_c *pci = new bx_list_c(root_param, "pci", "PCI Options");
// pci options
bx_param_c *pci_deps_list[3+BX_N_PCI_SLOTS+2*BX_SUPPORT_PCIDEV];
bx_param_c **pci_deps_ptr = &pci_deps_list[0];
deplist = new bx_list_c(NULL, 2+BX_N_PCI_SLOTS+2*BX_SUPPORT_PCIDEV);
bx_param_bool_c *i440fx_support = new bx_param_bool_c(pci,
"i440fx_support",
@ -765,7 +764,7 @@ void bx_init_options()
BX_SUPPORT_PCI);
// pci slots
bx_list_c *slot = new bx_list_c(pci, "slot", "PCI Slots");
*pci_deps_ptr++ = slot;
deplist->add(slot);
for (i=0; i<BX_N_PCI_SLOTS; i++) {
sprintf(name, "%d", i+1);
sprintf (descr, "Name of the device connected to PCI slot #%d", i+1);
@ -775,46 +774,11 @@ void bx_init_options()
label,
descr,
"", BX_PATHNAME_LEN);
// add to deplist
*pci_deps_ptr++ = devname;
deplist->add(devname);
}
// pcidev options
bx_list_c *pcidev = new bx_list_c(pci, "pcidev", "Host PCI Device Mapping");
*pci_deps_ptr++ = pcidev;
bx_param_num_c *pcivid = new bx_param_num_c(pcidev,
"vendor",
"PCI Vendor ID",
"The vendor ID of the host PCI device to map",
0, 0xffff,
0xffff); // vendor id 0xffff = no pci device present
pcivid->set_base(16);
pcivid->set_format("0x%04x");
pcivid->set_long_format("PCI Vendor ID: 0x%04x");
#if BX_SUPPORT_PCIDEV
*pci_deps_ptr++ = pcivid;
#else
pcivid->set_enabled(0);
#endif
bx_param_num_c *pcidid = new bx_param_num_c(pcidev,
"device",
"PCI Device ID",
"The device ID of the host PCI device to map",
0, 0xffff,
0x0);
pcidid->set_base(16);
pcidid->set_format("0x%04x");
pcidid->set_long_format("PCI Device ID: 0x%04x");
#if BX_SUPPORT_PCIDEV
*pci_deps_ptr++ = pcidid;
#else
pcidid->set_enabled(0);
#endif
// add final NULL at the end, and build the menu
*pci_deps_ptr = NULL;
i440fx_support->set_dependent_list(new bx_list_c(NULL, "", "", pci_deps_list));
i440fx_support->set_dependent_list(deplist);
pci->set_options(pci->SHOW_PARENT);
slot->set_options(slot->SHOW_PARENT);
pcidev->set_options(pcidev->SHOW_PARENT | pcidev->USE_BOX_TITLE);
// display subtree
bx_list_c *display = new bx_list_c(root_param, "display", "Bochs Display & Interface Options", 7);
@ -1525,18 +1489,6 @@ void bx_init_options()
irq->set_options(irq->USE_SPIN_CONTROL);
bx_init_std_nic_options("NE2K", menu);
enabled->set_dependent_list(menu->clone());
// pnic options
menu = new bx_list_c(network, "pnic", "PCI Pseudo NIC");
menu->set_options(menu->SHOW_PARENT);
menu->set_enabled(BX_SUPPORT_PCIPNIC);
enabled = new bx_param_bool_c(menu,
"enabled",
"Enable Pseudo NIC emulation",
"Enables the Pseudo NIC emulation",
0);
enabled->set_enabled(BX_SUPPORT_PCIPNIC);
bx_init_std_nic_options("Pseudo NIC", menu);
enabled->set_dependent_list(menu->clone());
// sound subtree
bx_list_c *sound = new bx_list_c(root_param, "sound", "Sound Configuration");
@ -2260,6 +2212,12 @@ bx_bool is_optplugin_option(const char *param)
#if BX_SUPPORT_ES1370
"es1370",
#endif
#if BX_SUPPORT_PCIDEV
"pcidev",
#endif
#if BX_SUPPORT_PCIPNIC
"pnic",
#endif
#if BX_SUPPORT_USB_OHCI
"usb_ohci",
#endif
@ -3120,27 +3078,6 @@ static int parse_line_formatted(const char *context, int num_params, char *param
PARSE_ERR(("%s: pci: chipset not specified", context));
}
}
} else if (!strcmp(params[0], "pcidev")) {
if (num_params != 3) {
PARSE_ERR(("%s: pcidev directive malformed.", context));
}
for (i=1; i<num_params; i++) {
if (!strncmp(params[i], "vendor=", 7)) {
if ((params[i][7] == '0') && (toupper(params[i][8]) == 'X'))
SIM->get_param_num(BXPN_PCIDEV_VENDOR)->set(strtoul(&params[i][7], NULL, 16));
else
SIM->get_param_num(BXPN_PCIDEV_VENDOR)->set(strtoul(&params[i][7], NULL, 10));
}
else if (!strncmp(params[i], "device=", 7)) {
if ((params[i][7] == '0') && (toupper(params[i][8]) == 'X'))
SIM->get_param_num(BXPN_PCIDEV_DEVICE)->set(strtoul(&params[i][7], NULL, 16));
else
SIM->get_param_num(BXPN_PCIDEV_DEVICE)->set(strtoul(&params[i][7], NULL, 10));
}
else {
BX_ERROR(("%s: unknown parameter for pcidev ignored.", context));
}
}
} else if (!strcmp(params[0], "cmosimage")) {
for (i=1; i<num_params; i++) {
if (!strncmp(params[i], "file=", 5)) {
@ -3317,29 +3254,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], "pnic")) {
int ret, valid = 0;
base = (bx_list_c*) SIM->get_param(BXPN_PNIC);
if (!SIM->get_param_bool("enabled", base)->get()) {
SIM->get_param_enum("ethmod", base)->set_by_name("null");
}
for (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) {
PARSE_ERR(("%s: 'pnic' 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));
@ -3922,11 +3836,6 @@ int bx_write_configuration(const char *rc, int overwrite)
}
}
fprintf(fp, "\n");
if (SIM->get_param_num(BXPN_PCIDEV_VENDOR)->get() != 0xffff) {
fprintf(fp, "pcidev: vendor=0x%04x, device=0x%04x\n",
SIM->get_param_num(BXPN_PCIDEV_VENDOR)->get(),
SIM->get_param_num(BXPN_PCIDEV_DEVICE)->get());
}
fprintf(fp, "vga: extension=%s, update_freq=%u\n",
SIM->get_param_string(BXPN_VGA_EXTENSION)->getptr(),
SIM->get_param_num(BXPN_VGA_UPDATE_FREQUENCY)->get());
@ -4021,7 +3930,6 @@ int bx_write_configuration(const char *rc, int overwrite)
#endif
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_sound_options(fp, (bx_list_c*) SIM->get_param(BXPN_SOUND_SB16));
bx_write_loader_options(fp);
bx_write_log_options(fp, (bx_list_c*) SIM->get_param("log"));

View File

@ -218,16 +218,6 @@ void bx_devices_c::init(BX_MEM_C *newmem)
((!strlen(vga_ext)) || (!strcmp(vga_ext, "none")) || (!strcmp(vga_ext, "vbe")))) {
PLUG_load_plugin(pcivga, PLUGTYPE_OPTIONAL);
}
#if BX_SUPPORT_PCIDEV
if (SIM->get_param_num(BXPN_PCIDEV_VENDOR)->get() != 0xffff) {
PLUG_load_plugin(pcidev, PLUGTYPE_OPTIONAL);
}
#endif
#if BX_SUPPORT_PCIPNIC
if (SIM->get_param_bool(BXPN_PNIC_ENABLED)->get()) {
PLUG_load_plugin(pcipnic, PLUGTYPE_OPTIONAL);
}
#endif
}
#endif

View File

@ -44,18 +44,97 @@
bx_pcidev_c* thePciDevAdapter = NULL;
// builtin configuration handling functions
void pcidev_init_options(void)
{
bx_param_c *pci = SIM->get_param("pci");
bx_list_c *pcidev = new bx_list_c(pci, "pcidev", "Host PCI Device Mapping");
bx_param_num_c *pcivid = new bx_param_num_c(pcidev,
"vendor",
"PCI Vendor ID",
"The vendor ID of the host PCI device to map",
0, 0xffff,
0xffff); // vendor id 0xffff = no pci device present
pcivid->set_base(16);
pcivid->set_format("0x%04x");
pcivid->set_long_format("PCI Vendor ID: 0x%04x");
bx_param_num_c *pcidid = new bx_param_num_c(pcidev,
"device",
"PCI Device ID",
"The device ID of the host PCI device to map",
0, 0xffff,
0x0);
pcidid->set_base(16);
pcidid->set_format("0x%04x");
pcidid->set_long_format("PCI Device ID: 0x%04x");
pcidev->set_options(pcidev->SHOW_PARENT | pcidev->USE_BOX_TITLE);
bx_list_c *deplist = ((bx_param_bool_c*)SIM->get_param(BXPN_I440FX_SUPPORT))->get_dependent_list();
deplist->add(pcidev);
deplist->add(pcivid);
deplist->add(pcidid);
}
Bit32s pcidev_options_parser(const char *context, int num_params, char *params[])
{
if (!strcmp(params[0], "pcidev")) {
if (num_params != 3) {
BX_PANIC(("%s: pcidev directive malformed.", context));
}
for (int i = 1; i < num_params; i++) {
if (!strncmp(params[i], "vendor=", 7)) {
if ((params[i][7] == '0') && (toupper(params[i][8]) == 'X'))
SIM->get_param_num(BXPN_PCIDEV_VENDOR)->set(strtoul(&params[i][7], NULL, 16));
else
SIM->get_param_num(BXPN_PCIDEV_VENDOR)->set(strtoul(&params[i][7], NULL, 10));
} else if (!strncmp(params[i], "device=", 7)) {
if ((params[i][7] == '0') && (toupper(params[i][8]) == 'X'))
SIM->get_param_num(BXPN_PCIDEV_DEVICE)->set(strtoul(&params[i][7], NULL, 16));
else
SIM->get_param_num(BXPN_PCIDEV_DEVICE)->set(strtoul(&params[i][7], NULL, 10));
} else {
BX_ERROR(("%s: unknown parameter for pcidev ignored.", context));
}
}
} else {
BX_PANIC(("%s: unknown directive '%s'", context, params[0]));
}
return 0;
}
Bit32s pcidev_options_save(FILE *fp)
{
if (SIM->get_param_num(BXPN_PCIDEV_VENDOR)->get() != 0xffff) {
fprintf(fp, "pcidev: vendor=0x%04x, device=0x%04x\n",
SIM->get_param_num(BXPN_PCIDEV_VENDOR)->get(),
SIM->get_param_num(BXPN_PCIDEV_DEVICE)->get());
}
return 0;
}
// device plugin entry points
int libpcidev_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
thePciDevAdapter = new bx_pcidev_c();
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePciDevAdapter, BX_PLUGIN_PCIDEV);
// add new configuration parameter for the config interface
pcidev_init_options();
// register add-on option for bochsrc and command line
SIM->register_addon_option("pcidev", pcidev_options_parser, pcidev_options_save);
return 0; // Success
}
void libpcidev_LTX_plugin_fini(void)
{
SIM->unregister_addon_option("pcidev");
bx_list_c *menu = (bx_list_c*)SIM->get_param("network");
menu->remove("pcidev");
delete thePciDevAdapter;
}
// the device object
bx_pcidev_c::bx_pcidev_c()
{
put("pcidev", "PCI2H");
@ -156,7 +235,13 @@ static const char * const pcidev_name = "Experimental PCI 2 host PCI";
void bx_pcidev_c::init(void)
{
// called once when bochs initializes
// Check if the device is disabled or not configured
if (SIM->get_param_num(BXPN_PCIDEV_VENDOR)->get() == 0xffff) {
BX_INFO(("Host PCI device mapping disabled"));
BX_UNREGISTER_DEVICE_DEVMODEL("pcidev");
return;
}
BX_PCIDEV_THIS pcidev_fd = -1;
int fd;
fd = open("/dev/pcidev", O_RDWR);

View File

@ -39,18 +39,83 @@ bx_pcipnic_c* thePNICDevice = NULL;
const Bit8u pnic_iomask[16] = {2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// builtin configuration handling functions
void pnic_init_options(void)
{
bx_param_c *network = SIM->get_param("network");
bx_list_c *menu = new bx_list_c(network, "pnic", "PCI Pseudo NIC");
menu->set_options(menu->SHOW_PARENT);
bx_param_bool_c *enabled = new bx_param_bool_c(menu,
"enabled",
"Enable Pseudo NIC emulation",
"Enables the Pseudo NIC emulation",
0);
bx_init_std_nic_options("Pseudo NIC", menu);
enabled->set_dependent_list(menu->clone());
}
Bit32s pnic_options_parser(const char *context, int num_params, char *params[])
{
int ret, valid = 0;
if (!strcmp(params[0], "pnic")) {
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_PNIC);
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: 'pnic' 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 pnic_options_save(FILE *fp)
{
bx_write_pci_nic_options(fp, (bx_list_c*) SIM->get_param(BXPN_PNIC));
return 0;
}
// device plugin entry points
int libpcipnic_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
{
thePNICDevice = new bx_pcipnic_c();
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePNICDevice, BX_PLUGIN_PCIPNIC);
// add new configuration parameter for the config interface
pnic_init_options();
// register add-on option for bochsrc and command line
SIM->register_addon_option("pnic", pnic_options_parser, pnic_options_save);
return 0; // Success
}
void libpcipnic_LTX_plugin_fini(void)
{
SIM->unregister_addon_option("pnic");
bx_list_c *menu = (bx_list_c*)SIM->get_param("network");
menu->remove("pnic");
delete thePNICDevice;
}
// the device object
bx_pcipnic_c::bx_pcipnic_c()
{
put("pcipnic", "PNIC");
@ -68,6 +133,13 @@ void bx_pcipnic_c::init(void)
// Read in values from config interface
base = (bx_list_c*) SIM->get_param(BXPN_PNIC);
// Check if the device is disabled or not configured
if (!SIM->get_param_bool("enabled", base)->get()) {
BX_INFO(("PCI Pseudo NIC disabled"));
BX_UNREGISTER_DEVICE_DEVMODEL("pcipnic");
return;
}
memcpy(BX_PNIC_THIS s.macaddr, SIM->get_param_string("macaddr", base)->getptr(), 6);
BX_PNIC_THIS s.devfunc = 0x00;

View File

@ -836,6 +836,12 @@ static builtin_plugin_t builtin_opt_plugins[] = {
#if BX_SUPPORT_ES1370
BUILTIN_PLUGIN_ENTRY(es1370),
#endif
#if BX_SUPPORT_PCIDEV
BUILTIN_PLUGIN_ENTRY(pcidev),
#endif
#if BX_SUPPORT_PCIPNIC
BUILTIN_PLUGIN_ENTRY(pcipnic),
#endif
#if BX_SUPPORT_USB_OHCI
BUILTIN_PLUGIN_ENTRY(usb_ohci),
#endif