- rewrite of the USB runtime configuration code (for textconfig only)

* USB runtime options moved to a new dynamic menu
  * USB host controllers create own submenus in init()
  * USB runtime parameter handlers simplified
  * TODO: related changes in the wx and win32dialog code
This commit is contained in:
Volker Ruppert 2009-03-04 18:20:50 +00:00
parent 7a1236636a
commit de9f1dcce9
8 changed files with 118 additions and 129 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: config.cc,v 1.158 2009-02-22 17:05:40 vruppert Exp $
// $Id: config.cc,v 1.159 2009-03-04 18:20:32 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -1731,7 +1731,10 @@ void bx_init_options()
path->set_ask_format("Enter debugger log filename: [%s] ");
path->set_enabled(BX_DEBUGGER);
// runtime options
// USB runtime options
usb = new bx_list_c(special_menus, "usb_runtime", "USB runtime options", 10);
usb->get_options()->set(bx_list_c::SHOW_PARENT);
// misc runtime options
bx_param_c *runtime_init_list[] = {
SIM->get_param_num(BXPN_VGA_UPDATE_INTERVAL),
SIM->get_param_bool(BXPN_MOUSE_ENABLED),
@ -1739,10 +1742,6 @@ void bx_init_options()
SIM->get_param_string(BXPN_USER_SHORTCUT),
SIM->get_param_num(BXPN_SB16_DMATIMER),
SIM->get_param_num(BXPN_SB16_LOGLEVEL),
SIM->get_param_string(BXPN_UHCI_PORT1),
SIM->get_param_string(BXPN_UHCI_PORT2),
SIM->get_param_string(BXPN_OHCI_PORT1),
SIM->get_param_string(BXPN_OHCI_PORT2),
NULL
};
menu = new bx_list_c(special_menus, "runtime", "Misc runtime options", runtime_init_list);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: siminterface.h,v 1.230 2009-02-21 11:43:18 vruppert Exp $
// $Id: siminterface.h,v 1.231 2009-03-04 18:20:39 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2009 The Bochs Project
@ -229,9 +229,11 @@ typedef enum {
#define BXPN_ATA1_SLAVE "ata.1.slave"
#define BXPN_ATA2_SLAVE "ata.2.slave"
#define BXPN_ATA3_SLAVE "ata.3.slave"
#define BXPN_USB_UHCI "ports.usb.uhci"
#define BXPN_UHCI_ENABLED "ports.usb.uhci.enabled"
#define BXPN_UHCI_PORT1 "ports.usb.uhci.port1"
#define BXPN_UHCI_PORT2 "ports.usb.uhci.port2"
#define BXPN_USB_OHCI "ports.usb.ohci"
#define BXPN_OHCI_ENABLED "ports.usb.ohci.enabled"
#define BXPN_OHCI_PORT1 "ports.usb.ohci.port1"
#define BXPN_OHCI_PORT2 "ports.usb.ohci.port2"
@ -254,6 +256,7 @@ typedef enum {
#define BXPN_MENU_DISK "menu.disk"
#define BXPN_MENU_MEMORY "menu.memory"
#define BXPN_MENU_RUNTIME "menu.runtime"
#define BXPN_MENU_RUNTIME_USB "menu.usb_runtime"
#define BXPN_WX_KBD_STATE "wxdebug.keyboard"
#define BXPN_WX_CPU_STATE "wxdebug.cpu"
#define BXPN_WX_CPU0_STATE "wxdebug.cpu.0"

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: textconfig.cc,v 1.73 2009-02-08 09:05:52 vruppert Exp $
// $Id: textconfig.cc,v 1.74 2009-03-04 18:20:40 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2009 The Bochs Project
@ -320,11 +320,12 @@ static const char *runtime_menu_prompt =
"8. Log options for all devices\n"
"9. Log options for individual devices\n"
"10. Instruction tracing: off (doesn't exist yet)\n"
"11. Misc runtime options\n"
"12. Continue simulation\n"
"13. Quit now\n"
"11. USB runtime options\n"
"12. Misc runtime options\n"
"13. Continue simulation\n"
"14. Quit now\n"
"\n"
"Please choose one: [12] ";
"Please choose one: [13] ";
#endif
#define NOT_IMPLEMENTED(choice) \
@ -527,6 +528,7 @@ int bx_config_interface(int menu)
case BX_CI_RT_LOGOPTS1: bx_log_options(0); break;
case BX_CI_RT_LOGOPTS2: bx_log_options(1); break;
case BX_CI_RT_INST_TR: NOT_IMPLEMENTED(choice); break;
case BX_CI_RT_USB: do_menu(BXPN_MENU_RUNTIME_USB); break;
case BX_CI_RT_MISC: do_menu(BXPN_MENU_RUNTIME); break;
case BX_CI_RT_CONT: fprintf(stderr, "Continuing simulation\n"); return 0;
case BX_CI_RT_QUIT:

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: textconfig.h,v 1.9 2009-02-08 09:05:52 vruppert Exp $
// $Id: textconfig.h,v 1.10 2009-03-04 18:20:44 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2009 The Bochs Project
@ -47,6 +47,7 @@ enum {
BX_CI_RT_LOGOPTS1,
BX_CI_RT_LOGOPTS2,
BX_CI_RT_INST_TR,
BX_CI_RT_USB,
BX_CI_RT_MISC,
BX_CI_RT_CONT,
BX_CI_RT_QUIT

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: usb_ohci.cc,v 1.14 2009-03-03 18:29:51 vruppert Exp $
// $Id: usb_ohci.cc,v 1.15 2009-03-04 18:20:44 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2009 Benjamin D Lunt (fys at frontiernet net)
@ -99,22 +99,25 @@ bx_usb_ohci_c::bx_usb_ohci_c()
bx_usb_ohci_c::~bx_usb_ohci_c()
{
char pname[6];
if (BX_OHCI_THIS device_buffer != NULL)
delete [] BX_OHCI_THIS device_buffer;
for (int i=0; i<USB_NUM_PORTS; i++) {
for (int i=0; i<USB_OHCI_NUM_PORTS; i++) {
sprintf(pname, "port%d", i+1);
SIM->get_param_string(pname, SIM->get_param(BXPN_USB_OHCI))->set_handler(NULL);
remove_device(i);
}
SIM->get_param_string(BXPN_OHCI_PORT1)->set_handler(NULL);
SIM->get_param_string(BXPN_OHCI_PORT2)->set_handler(NULL);
BX_DEBUG(("Exit"));
}
void bx_usb_ohci_c::init(void)
{
unsigned i;
char pname[6];
bx_param_string_c *port;
BX_OHCI_THIS device_buffer = new Bit8u[65536];
@ -143,12 +146,15 @@ void bx_usb_ohci_c::init(void)
//FIXME: for now, we want a status bar // hub zero, port zero
BX_OHCI_THIS hub.statusbar_id[0] = bx_gui->register_statusitem("OHCI");
SIM->get_param_string(BXPN_OHCI_PORT1)->set_handler(usb_param_handler);
SIM->get_param_string(BXPN_OHCI_PORT1)->set_runtime_param(1);
SIM->get_param_string(BXPN_OHCI_PORT2)->set_handler(usb_param_handler);
SIM->get_param_string(BXPN_OHCI_PORT2)->set_runtime_param(1);
for (i=0; i<USB_NUM_PORTS; i++) {
bx_list_c *usb_rt = (bx_list_c*)SIM->get_param(BXPN_MENU_RUNTIME_USB);
bx_list_c *ohci = new bx_list_c(usb_rt, "ohci", "OHCI Configuration");
ohci->get_options()->set(bx_list_c::SHOW_PARENT);
for (i=0; i<USB_OHCI_NUM_PORTS; i++) {
sprintf(pname, "port%d", i+1);
port = SIM->get_param_string(pname, SIM->get_param(BXPN_USB_OHCI));
ohci->add(port);
port->set_handler(usb_param_handler);
port->set_runtime_param(1);
BX_OHCI_THIS hub.usb_port[i].device = NULL;
}
@ -208,18 +214,12 @@ void bx_usb_ohci_c::reset(unsigned type)
}
BX_OHCI_THIS reset_hc();
if (BX_OHCI_THIS hub.usb_port[0].device == NULL) {
init_device(0, SIM->get_param_string(BXPN_OHCI_PORT1)->getptr());
}
if (BX_OHCI_THIS hub.usb_port[1].device == NULL) {
init_device(1, SIM->get_param_string(BXPN_OHCI_PORT2)->getptr());
}
}
void bx_usb_ohci_c::reset_hc()
{
int i;
char pname[6];
// reset locals
BX_OHCI_THIS hub.ohci_done_count = 7;
@ -303,10 +303,10 @@ void bx_usb_ohci_c::reset_hc()
BX_OHCI_THIS hub.op_regs.HcRhDescriptorA.dt = 0;
BX_OHCI_THIS hub.op_regs.HcRhDescriptorA.nps = 0;
BX_OHCI_THIS hub.op_regs.HcRhDescriptorA.psm = 1;
BX_OHCI_THIS hub.op_regs.HcRhDescriptorA.ndp = USB_NUM_PORTS;
BX_OHCI_THIS hub.op_regs.HcRhDescriptorA.ndp = USB_OHCI_NUM_PORTS;
// HcRhDescriptorB
BX_OHCI_THIS hub.op_regs.HcRhDescriptorB.ppcm = 0x0000 | ((USB_NUM_PORTS == 1) ? 2 : 0) | ((USB_NUM_PORTS == 2) ? 4 : 0);
BX_OHCI_THIS hub.op_regs.HcRhDescriptorB.ppcm = 0x0000 | ((USB_OHCI_NUM_PORTS == 1) ? 2 : 0) | ((USB_OHCI_NUM_PORTS == 2) ? 4 : 0);
BX_OHCI_THIS hub.op_regs.HcRhDescriptorB.dr = 0x0000;
// HcRhStatus
@ -320,9 +320,12 @@ void bx_usb_ohci_c::reset_hc()
BX_OHCI_THIS hub.op_regs.HcRhStatus.lps = 0;
// HcRhPortStatus[x]
for (i=0; i<USB_NUM_PORTS; i++) {
for (i=0; i<USB_OHCI_NUM_PORTS; i++) {
reset_port(i);
if (BX_OHCI_THIS hub.usb_port[i].device != NULL) {
if (BX_OHCI_THIS hub.usb_port[i].device == NULL) {
sprintf(pname, "port%d", i+1);
init_device(i, SIM->get_param_string(pname, SIM->get_param(BXPN_USB_OHCI))->getptr());
} else {
usb_set_connect_status(i, BX_OHCI_THIS hub.usb_port[i].device->get_type(), 1);
}
}
@ -407,7 +410,7 @@ void bx_usb_ohci_c::register_state(void)
new bx_shadow_bool_c(reg, "drwe", &BX_OHCI_THIS hub.op_regs.HcRhStatus.drwe);
new bx_shadow_bool_c(reg, "oci", &BX_OHCI_THIS hub.op_regs.HcRhStatus.oci);
new bx_shadow_bool_c(reg, "lps", &BX_OHCI_THIS hub.op_regs.HcRhStatus.lps);
for (i=0; i<USB_NUM_PORTS; i++) {
for (i=0; i<USB_OHCI_NUM_PORTS; i++) {
sprintf(portnum, "port%d", i+1);
port = new bx_list_c(hub, portnum, 2);
reg = new bx_list_c(port, "HcRhPortStatus", 12);
@ -440,7 +443,7 @@ void bx_usb_ohci_c::after_restore_state(void)
4096)) {
BX_INFO(("new base address: 0x%04x", BX_OHCI_THIS hub.base_addr));
}
for (int j=0; j<USB_NUM_PORTS; j++) {
for (int j=0; j<USB_OHCI_NUM_PORTS; j++) {
if (BX_OHCI_THIS hub.usb_port[j].device != NULL) {
BX_OHCI_THIS hub.usb_port[j].device->after_restore_state();
}
@ -650,17 +653,17 @@ bx_bool bx_usb_ohci_c::read_handler(bx_phy_address addr, unsigned len, void *dat
break;
case 0x60: // HcRhPortStatus[3]
#if (USB_NUM_PORTS < 4)
#if (USB_OHCI_NUM_PORTS < 4)
val = 0;
break;
#endif
case 0x5C: // HcRhPortStatus[2]
#if (USB_NUM_PORTS < 3)
#if (USB_OHCI_NUM_PORTS < 3)
val = 0;
break;
#endif
case 0x58: // HcRhPortStatus[1]
#if (USB_NUM_PORTS < 2)
#if (USB_OHCI_NUM_PORTS < 2)
val = 0;
break;
#endif
@ -758,7 +761,7 @@ bx_bool bx_usb_ohci_c::write_handler(bx_phy_address addr, unsigned len, void *da
BX_OHCI_THIS hub.op_regs.HcCommandStatus.hcr = 1;
BX_OHCI_THIS reset_hc();
BX_OHCI_THIS hub.op_regs.HcControl.hcfs = 3; // suspend state
for (unsigned i=0; i<USB_NUM_PORTS; i++)
for (unsigned i=0; i<USB_OHCI_NUM_PORTS; i++)
if (BX_OHCI_THIS hub.usb_port[i].HcRhPortStatus.ccs && (BX_OHCI_THIS hub.usb_port[i].device != NULL))
BX_OHCI_THIS hub.usb_port[i].device->usb_send_msg(USB_MSG_RESET);
}
@ -896,20 +899,20 @@ bx_bool bx_usb_ohci_c::write_handler(bx_phy_address addr, unsigned len, void *da
if (value & (1<<17)) BX_OHCI_THIS hub.op_regs.HcRhStatus.ocic = 1;
if (value & (1<<16)) {
if (BX_OHCI_THIS hub.op_regs.HcRhDescriptorA.psm == 0) {
for (p=0; p<USB_NUM_PORTS; p++)
for (p=0; p<USB_OHCI_NUM_PORTS; p++)
BX_OHCI_THIS hub.usb_port[p].HcRhPortStatus.pps = 1;
} else {
for (p=0; p<USB_NUM_PORTS; p++)
for (p=0; p<USB_OHCI_NUM_PORTS; p++)
if ((BX_OHCI_THIS hub.op_regs.HcRhDescriptorB.ppcm & (1<<p)) == 0)
BX_OHCI_THIS hub.usb_port[p].HcRhPortStatus.pps = 1;
}
}
if (value & (1<<0)) {
if (BX_OHCI_THIS hub.op_regs.HcRhDescriptorA.psm == 0) {
for (p=0; p<USB_NUM_PORTS; p++)
for (p=0; p<USB_OHCI_NUM_PORTS; p++)
BX_OHCI_THIS hub.usb_port[p].HcRhPortStatus.pps = 0;
} else {
for (p=0; p<USB_NUM_PORTS; p++)
for (p=0; p<USB_OHCI_NUM_PORTS; p++)
if (!(BX_OHCI_THIS hub.op_regs.HcRhDescriptorB.ppcm & (1<<p)))
BX_OHCI_THIS hub.usb_port[p].HcRhPortStatus.pps = 0;
}
@ -918,15 +921,15 @@ bx_bool bx_usb_ohci_c::write_handler(bx_phy_address addr, unsigned len, void *da
}
case 0x60: // HcRhPortStatus[3]
#if (USB_NUM_PORTS < 4)
#if (USB_OHCI_NUM_PORTS < 4)
break;
#endif
case 0x5C: // HcRhPortStatus[2]
#if (USB_NUM_PORTS < 3)
#if (USB_OHCI_NUM_PORTS < 3)
break;
#endif
case 0x58: // HcRhPortStatus[1]
#if (USB_NUM_PORTS < 2)
#if (USB_OHCI_NUM_PORTS < 2)
break;
#endif
case 0x54: { // HcRhPortStatus[0]
@ -1188,7 +1191,7 @@ bx_bool bx_usb_ohci_c::process_td(struct OHCI_TD *td, struct OHCI_ED *ed)
}
// find the device
for (i=0; i<USB_NUM_PORTS; i++) {
for (i=0; i<USB_OHCI_NUM_PORTS; i++) {
if (BX_OHCI_THIS hub.usb_port[i].device != NULL) {
if (BX_OHCI_THIS hub.usb_port[i].device->get_connected()) {
if (BX_OHCI_THIS hub.usb_port[i].device->get_address() == ED_GET_FA(ed)) {
@ -1494,33 +1497,22 @@ const char *bx_usb_ohci_c::usb_param_handler(bx_param_string_c *param, int set,
const char *oldval, const char *val, int maxlen)
{
usbdev_type type = USB_DEV_TYPE_NONE;
int portnum;
// handler for USB runtime parameters
if (set) {
char pname[BX_PATHNAME_LEN];
param->get_param_path(pname, BX_PATHNAME_LEN);
if (!strcmp(pname, BXPN_OHCI_PORT1)) {
BX_INFO(("USB port #1 experimental device change"));
if (!strcmp(val, "none") && BX_OHCI_THIS hub.usb_port[0].HcRhPortStatus.ccs) {
if (BX_OHCI_THIS hub.usb_port[0].device != NULL) {
type = BX_OHCI_THIS hub.usb_port[0].device->get_type();
portnum = atoi(param->get_name()+4) - 1;
if ((portnum >= 0) && (portnum < USB_OHCI_NUM_PORTS)) {
BX_INFO(("USB port #%d experimental device change", portnum+1));
if (!strcmp(val, "none") && BX_OHCI_THIS hub.usb_port[portnum].HcRhPortStatus.ccs) {
if (BX_OHCI_THIS hub.usb_port[portnum].device != NULL) {
type = BX_OHCI_THIS hub.usb_port[portnum].device->get_type();
}
usb_set_connect_status(0, type, 0);
} else if (strcmp(val, "none") && !BX_OHCI_THIS hub.usb_port[0].HcRhPortStatus.ccs) {
init_device(0, val);
}
} else if (!strcmp(pname, BXPN_OHCI_PORT2)) {
BX_INFO(("USB port #2 experimental device change"));
if (!strcmp(val, "none") && BX_OHCI_THIS hub.usb_port[1].HcRhPortStatus.ccs) {
if (BX_OHCI_THIS hub.usb_port[1].device != NULL) {
type = BX_OHCI_THIS hub.usb_port[1].device->get_type();
}
usb_set_connect_status(1, type, 0);
} else if (strcmp(val, "none") && !BX_OHCI_THIS hub.usb_port[1].HcRhPortStatus.ccs) {
init_device(1, val);
usb_set_connect_status(portnum, type, 0);
} else if (strcmp(val, "none") && !BX_OHCI_THIS hub.usb_port[portnum].HcRhPortStatus.ccs) {
init_device(portnum, val);
}
} else {
BX_PANIC(("usb_param_handler called with unexpected parameter '%s'", pname));
BX_PANIC(("usb_param_handler called with unexpected parameter '%s'", param->get_name()));
}
}
return val;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: usb_ohci.h,v 1.10 2009-03-03 18:29:51 vruppert Exp $
// $Id: usb_ohci.h,v 1.11 2009-03-04 18:20:46 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2009 Benjamin D Lunt (fys at frontiernet net)
@ -30,7 +30,7 @@
# define BX_OHCI_THIS_PTR this
#endif
#define USB_NUM_PORTS 2
#define USB_OHCI_NUM_PORTS 2
#define OHCI_INTR_SO (1<<0) // Scheduling overrun
#define OHCI_INTR_WD (1<<1) // HcDoneHead writeback
@ -234,7 +234,7 @@ typedef struct {
bx_bool pes; // 1 bit PortEnableStatus = 0b RW RW
bx_bool ccs; // 1 bit CurrentConnectStatus = 0b RW RW
} HcRhPortStatus;
} usb_port[USB_NUM_PORTS];
} usb_port[USB_OHCI_NUM_PORTS];
Bit8u pci_conf[256];
Bit8u devfunc;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: usb_uhci.cc,v 1.12 2009-03-03 18:29:51 vruppert Exp $
// $Id: usb_uhci.cc,v 1.13 2009-03-04 18:20:46 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2009 Benjamin D Lunt (fys at frontiernet net)
@ -66,22 +66,25 @@ bx_usb_uhci_c::bx_usb_uhci_c()
bx_usb_uhci_c::~bx_usb_uhci_c()
{
char pname[6];
if (BX_UHCI_THIS device_buffer != NULL)
delete [] BX_UHCI_THIS device_buffer;
for (int i=0; i<USB_NUM_PORTS; i++) {
for (int i=0; i<USB_UHCI_NUM_PORTS; i++) {
sprintf(pname, "port%d", i+1);
SIM->get_param_string(pname, SIM->get_param(BXPN_USB_UHCI))->set_handler(NULL);
remove_device(i);
}
SIM->get_param_string(BXPN_UHCI_PORT1)->set_handler(NULL);
SIM->get_param_string(BXPN_UHCI_PORT2)->set_handler(NULL);
BX_DEBUG(("Exit"));
}
void bx_usb_uhci_c::init(void)
{
unsigned i;
char pname[6];
bx_param_string_c *port;
BX_UHCI_THIS device_buffer = new Bit8u[65536];
@ -107,12 +110,15 @@ void bx_usb_uhci_c::init(void)
//FIXME: for now, we want a status bar // hub zero, port zero
BX_UHCI_THIS hub.statusbar_id[0] = bx_gui->register_statusitem("UHCI");
SIM->get_param_string(BXPN_UHCI_PORT1)->set_handler(usb_param_handler);
SIM->get_param_string(BXPN_UHCI_PORT1)->set_runtime_param(1);
SIM->get_param_string(BXPN_UHCI_PORT2)->set_handler(usb_param_handler);
SIM->get_param_string(BXPN_UHCI_PORT2)->set_runtime_param(1);
for (i=0; i<USB_NUM_PORTS; i++) {
bx_list_c *usb_rt = (bx_list_c*)SIM->get_param(BXPN_MENU_RUNTIME_USB);
bx_list_c *uhci = new bx_list_c(usb_rt, "uhci", "UHCI Configuration");
uhci->get_options()->set(bx_list_c::SHOW_PARENT);
for (i=0; i<USB_UHCI_NUM_PORTS; i++) {
sprintf(pname, "port%d", i+1);
port = SIM->get_param_string(pname, SIM->get_param(BXPN_USB_UHCI));
uhci->add(port);
port->set_handler(usb_param_handler);
port->set_runtime_param(1);
BX_UHCI_THIS hub.usb_port[i].device = NULL;
}
@ -125,6 +131,7 @@ void bx_usb_uhci_c::init(void)
void bx_usb_uhci_c::reset(unsigned type)
{
unsigned i, j;
char pname[6];
if (type == BX_RESET_HARDWARE) {
static const struct reset_vals_t {
@ -182,7 +189,7 @@ void bx_usb_uhci_c::reset(unsigned type)
BX_UHCI_THIS hub.usb_frame_num.frame_num = 0x0000;
BX_UHCI_THIS hub.usb_frame_base.frame_base = 0x00000000;
BX_UHCI_THIS hub.usb_sof.sof_timing = 0x40;
for (j=0; j<USB_NUM_PORTS; j++) {
for (j=0; j<USB_UHCI_NUM_PORTS; j++) {
BX_UHCI_THIS hub.usb_port[j].connect_changed = 0;
BX_UHCI_THIS hub.usb_port[j].line_dminus = 0;
BX_UHCI_THIS hub.usb_port[j].line_dplus = 0;
@ -193,18 +200,14 @@ void bx_usb_uhci_c::reset(unsigned type)
BX_UHCI_THIS hub.usb_port[j].enabled = 0;
BX_UHCI_THIS hub.usb_port[j].able_changed = 0;
BX_UHCI_THIS hub.usb_port[j].status = 0;
if (BX_UHCI_THIS hub.usb_port[j].device == NULL) {
sprintf(pname, "port%d", j+1);
init_device(j, SIM->get_param_string(pname, SIM->get_param(BXPN_USB_UHCI))->getptr());
} else {
usb_set_connect_status(j, BX_UHCI_THIS hub.usb_port[j].device->get_type(), 1);
}
}
if (BX_UHCI_THIS hub.usb_port[0].device == NULL) {
init_device(0, SIM->get_param_string(BXPN_UHCI_PORT1)->getptr());
} else {
usb_set_connect_status(0, BX_UHCI_THIS hub.usb_port[0].device->get_type(), 1);
}
if (BX_UHCI_THIS hub.usb_port[1].device == NULL) {
init_device(1, SIM->get_param_string(BXPN_UHCI_PORT2)->getptr());
} else {
usb_set_connect_status(1, BX_UHCI_THIS hub.usb_port[1].device->get_type(), 1);
}
}
void bx_usb_uhci_c::register_state(void)
@ -214,7 +217,7 @@ void bx_usb_uhci_c::register_state(void)
bx_list_c *hub, *usb_cmd, *usb_st, *usb_en, *port;
bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "usb_uhci", "USB UHCI State");
hub = new bx_list_c(list, "hub", USB_NUM_PORTS + 7);
hub = new bx_list_c(list, "hub", USB_UHCI_NUM_PORTS + 7);
usb_cmd = new bx_list_c(hub, "usb_command", 8);
new bx_shadow_bool_c(usb_cmd, "max_packet_size", &BX_UHCI_THIS hub.usb_command.max_packet_size);
new bx_shadow_bool_c(usb_cmd, "configured", &BX_UHCI_THIS hub.usb_command.configured);
@ -239,7 +242,7 @@ void bx_usb_uhci_c::register_state(void)
new bx_shadow_num_c(hub, "frame_num", &BX_UHCI_THIS hub.usb_frame_num.frame_num, BASE_HEX);
new bx_shadow_num_c(hub, "frame_base", &BX_UHCI_THIS hub.usb_frame_base.frame_base, BASE_HEX);
new bx_shadow_num_c(hub, "sof_timing", &BX_UHCI_THIS hub.usb_sof.sof_timing, BASE_HEX);
for (j=0; j<USB_NUM_PORTS; j++) {
for (j=0; j<USB_UHCI_NUM_PORTS; j++) {
sprintf(portnum, "port%d", j+1);
port = new bx_list_c(hub, portnum, 11);
new bx_shadow_bool_c(port, "suspend", &BX_UHCI_THIS hub.usb_port[j].suspend);
@ -270,7 +273,7 @@ void bx_usb_uhci_c::after_restore_state(void)
{
BX_INFO(("new base address: 0x%04x", BX_UHCI_THIS hub.base_ioaddr));
}
for (int j=0; j<USB_NUM_PORTS; j++) {
for (int j=0; j<USB_UHCI_NUM_PORTS; j++) {
if (BX_UHCI_THIS hub.usb_port[j].device != NULL) {
BX_UHCI_THIS hub.usb_port[j].device->after_restore_state();
}
@ -404,7 +407,7 @@ Bit32u bx_usb_uhci_c::read(Bit32u address, unsigned io_len)
case 0x12: // port #2
case 0x13:
port = (offset & 0x0F) >> 1;
if (port < USB_NUM_PORTS) {
if (port < USB_UHCI_NUM_PORTS) {
val = BX_UHCI_THIS hub.usb_port[port].suspend << 12
| 1 << 10 // some Root Hubs have bit 10 set ?????
| BX_UHCI_THIS hub.usb_port[port].reset << 9
@ -469,7 +472,7 @@ void bx_usb_uhci_c::write(Bit32u address, Bit32u value, unsigned io_len)
// HCRESET
if (BX_UHCI_THIS hub.usb_command.host_reset) {
BX_UHCI_THIS reset(0);
for (unsigned i=0; i<USB_NUM_PORTS; i++) {
for (unsigned i=0; i<USB_UHCI_NUM_PORTS; i++) {
if (BX_UHCI_THIS hub.usb_port[i].status) {
if (BX_UHCI_THIS hub.usb_port[i].device != NULL) {
BX_UHCI_THIS hub.usb_port[i].device->usb_send_msg(USB_MSG_RESET);
@ -577,7 +580,7 @@ void bx_usb_uhci_c::write(Bit32u address, Bit32u value, unsigned io_len)
case 0x10: // port #1
case 0x12: // port #2
port = (offset & 0x0F) >> 1;
if ((port < USB_NUM_PORTS) && (io_len == 2)) {
if ((port < USB_UHCI_NUM_PORTS) && (io_len == 2)) {
// If the ports reset bit is set, don't allow any writes unless the new write will clear the reset bit
if (BX_UHCI_THIS hub.usb_port[port].reset & (value & (1<<9)))
break;
@ -642,7 +645,7 @@ void bx_usb_uhci_c::usb_timer(void)
// If the "global reset" bit was set by software
if (BX_UHCI_THIS global_reset) {
for (i=0; i<USB_NUM_PORTS; i++) {
for (i=0; i<USB_UHCI_NUM_PORTS; i++) {
BX_UHCI_THIS hub.usb_port[i].able_changed = 0;
BX_UHCI_THIS hub.usb_port[i].connect_changed = 0;
BX_UHCI_THIS hub.usb_port[i].enabled = 0;
@ -837,7 +840,7 @@ bx_bool bx_usb_uhci_c::DoTransfer(Bit32u address, Bit32u queue_num, struct TD *t
// find device address
bx_bool at_least_one = 0;
for (i=0; i<USB_NUM_PORTS; i++) {
for (i=0; i<USB_UHCI_NUM_PORTS; i++) {
if (BX_UHCI_THIS hub.usb_port[i].device != NULL) {
if (BX_UHCI_THIS hub.usb_port[i].device->get_connected()) {
at_least_one = 1;
@ -1113,33 +1116,22 @@ const char *bx_usb_uhci_c::usb_param_handler(bx_param_string_c *param, int set,
const char *oldval, const char *val, int maxlen)
{
usbdev_type type = USB_DEV_TYPE_NONE;
int portnum;
// handler for USB runtime parameters
if (set) {
char pname[BX_PATHNAME_LEN];
param->get_param_path(pname, BX_PATHNAME_LEN);
if (!strcmp(pname, BXPN_UHCI_PORT1)) {
BX_INFO(("USB port #1 experimental device change"));
if (!strcmp(val, "none") && BX_UHCI_THIS hub.usb_port[0].status) {
if (BX_UHCI_THIS hub.usb_port[0].device != NULL) {
type = BX_UHCI_THIS hub.usb_port[0].device->get_type();
portnum = atoi(param->get_name()+4) - 1;
if ((portnum >= 0) && (portnum < USB_UHCI_NUM_PORTS)) {
BX_INFO(("USB port #%d experimental device change", portnum+1));
if (!strcmp(val, "none") && BX_UHCI_THIS hub.usb_port[portnum].status) {
if (BX_UHCI_THIS hub.usb_port[portnum].device != NULL) {
type = BX_UHCI_THIS hub.usb_port[portnum].device->get_type();
}
usb_set_connect_status(0, type, 0);
} else if (strcmp(val, "none") && !BX_UHCI_THIS hub.usb_port[0].status) {
init_device(0, val);
}
} else if (!strcmp(pname, BXPN_UHCI_PORT2)) {
BX_INFO(("USB port #2 experimental device change"));
if (!strcmp(val, "none") && BX_UHCI_THIS hub.usb_port[1].status) {
if (BX_UHCI_THIS hub.usb_port[1].device != NULL) {
type = BX_UHCI_THIS hub.usb_port[1].device->get_type();
}
usb_set_connect_status(1, type, 0);
} else if (strcmp(val, "none") && !BX_UHCI_THIS hub.usb_port[1].status) {
init_device(1, val);
usb_set_connect_status(portnum, type, 0);
} else if (strcmp(val, "none") && !BX_UHCI_THIS hub.usb_port[portnum].status) {
init_device(portnum, val);
}
} else {
BX_PANIC(("usb_param_handler called with unexpected parameter '%s'", pname));
BX_PANIC(("usb_param_handler called with unexpected parameter '%s'", param->get_name()));
}
}
return val;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: usb_uhci.h,v 1.8 2009-03-03 18:29:51 vruppert Exp $
// $Id: usb_uhci.h,v 1.9 2009-03-04 18:20:50 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2009 Benjamin D Lunt (fys at frontiernet net)
@ -29,7 +29,7 @@
# define BX_UHCI_THIS_PTR this
#endif
#define USB_NUM_PORTS 2 /* UHCI supports 2 ports per root hub */
#define USB_UHCI_NUM_PORTS 2 /* UHCI supports 2 ports per root hub */
typedef struct {
Bit32u base_ioaddr;
@ -153,7 +153,7 @@ typedef struct {
bx_bool enabled;
bx_bool connect_changed;
bx_bool status;
} usb_port[USB_NUM_PORTS];
} usb_port[USB_UHCI_NUM_PORTS];
Bit8u pci_conf[256];
Bit8u devfunc;