- more PCI register behaviour fixes

- added "ioaddr" and "irq" to the "usb1" bochsrc option
- number of ports is limited to 2 for a USB UHCI root hub
- the PCI configuration space is now a part of the usb hub structure
This commit is contained in:
Volker Ruppert 2003-01-25 16:04:48 +00:00
parent 2a5b04afb5
commit 0fe3cabe10

View File

@ -219,18 +219,19 @@ diff -urN ../bochs/configure.in ./configure.in
[ --enable-dc2300-vlb-ide enable Promise DC2300 VLB-IDE support], [ --enable-dc2300-vlb-ide enable Promise DC2300 VLB-IDE support],
diff -urN ../bochs/gui/siminterface.h ./gui/siminterface.h diff -urN ../bochs/gui/siminterface.h ./gui/siminterface.h
--- ../bochs/gui/siminterface.h 2002-12-17 16:53:29.000000000 +0100 --- ../bochs/gui/siminterface.h 2002-12-17 16:53:29.000000000 +0100
+++ ./gui/siminterface.h 2003-01-22 23:35:11.000000000 +0100 +++ ./gui/siminterface.h 2003-01-25 13:27:18.000000000 +0100
@@ -272,6 +272,9 @@ @@ -272,6 +272,10 @@
BXP_COM3_PATH, BXP_COM3_PATH,
BXP_COM4_ENABLED, BXP_COM4_ENABLED,
BXP_COM4_PATH, BXP_COM4_PATH,
+#define BXP_PARAMS_PER_USB_HUB 2 +#define BXP_PARAMS_PER_USB_HUB 3
+ BXP_USB1_ENABLED, + BXP_USB1_ENABLED,
+ BXP_USB1_PATH, + BXP_USB1_IOADDR,
+ BXP_USB1_IRQ,
BXP_PRIVATE_COLORMAP, BXP_PRIVATE_COLORMAP,
BXP_FULLSCREEN, BXP_FULLSCREEN,
BXP_SCREENMODE, BXP_SCREENMODE,
@@ -413,6 +416,13 @@ @@ -413,6 +417,15 @@
(bx_id)(BXP_COM1_ENABLED + (((x)-1)*BXP_PARAMS_PER_SERIAL_PORT)) (bx_id)(BXP_COM1_ENABLED + (((x)-1)*BXP_PARAMS_PER_SERIAL_PORT))
#define BXP_COMx_PATH(x) \ #define BXP_COMx_PATH(x) \
(bx_id)(BXP_COM1_PATH + (((x)-1)*BXP_PARAMS_PER_SERIAL_PORT)) (bx_id)(BXP_COM1_PATH + (((x)-1)*BXP_PARAMS_PER_SERIAL_PORT))
@ -238,19 +239,22 @@ diff -urN ../bochs/gui/siminterface.h ./gui/siminterface.h
+// use x=1 +// use x=1
+#define BXP_USBx_ENABLED(x) \ +#define BXP_USBx_ENABLED(x) \
+ (bx_id)(BXP_USB1_ENABLED + (((x)-1)*BXP_PARAMS_PER_USB_HUB)) + (bx_id)(BXP_USB1_ENABLED + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
+#define BXP_USBx_PATH(x) \ +#define BXP_USBx_IOADDR(x) \
+ (bx_id)(BXP_USB1_PATH + (((x)-1)*BXP_PARAMS_PER_USB_HUB)) + (bx_id)(BXP_USB1_IOADDR + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
+// +#define BXP_USBx_IRQ(x) \
+ (bx_id)(BXP_USB1_IRQ + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
+
// use x=1,2 // use x=1,2
#define BXP_PARPORTx_ENABLED(x) \ #define BXP_PARPORTx_ENABLED(x) \
(bx_id)(BXP_PARPORT1_ENABLED + (((x)-1)*BXP_PARAMS_PER_PARALLEL_PORT)) (bx_id)(BXP_PARPORT1_ENABLED + (((x)-1)*BXP_PARAMS_PER_PARALLEL_PORT))
@@ -1148,6 +1158,11 @@ @@ -1148,6 +1161,12 @@
bx_param_string_c *Odev; bx_param_string_c *Odev;
} bx_serial_options; } bx_serial_options;
+typedef struct { +typedef struct {
+ bx_param_bool_c *Oenabled; + bx_param_bool_c *Oenabled;
+ bx_param_string_c *Odev; + bx_param_num_c *Oioaddr;
+ bx_param_num_c *Oirq;
+ } bx_usb_options; + } bx_usb_options;
+ +
@ -336,10 +340,10 @@ diff -urN ../bochs/iodev/iodev.h ./iodev/iodev.h
#if BX_SUPPORT_APIC #if BX_SUPPORT_APIC
diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
--- ../bochs/iodev/pciusb.cc 1970-01-01 01:00:00.000000000 +0100 --- ../bochs/iodev/pciusb.cc 1970-01-01 01:00:00.000000000 +0100
+++ ./iodev/pciusb.cc 2003-01-24 14:08:48.000000000 +0100 +++ ./iodev/pciusb.cc 2003-01-25 16:33:57.000000000 +0100
@@ -0,0 +1,701 @@ @@ -0,0 +1,666 @@
+///////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////
+// $Id: patch.usb-fys,v 1.3 2003-01-24 15:14:15 vruppert Exp $ +// $Id: patch.usb-fys,v 1.4 2003-01-25 16:04:48 vruppert Exp $
+///////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////
+// +//
+// Copyright (C) 2003 MandrakeSoft S.A. +// Copyright (C) 2003 MandrakeSoft S.A.
@ -417,22 +421,23 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ +
+ if (!bx_options.usb[0].Oenabled->get()) return; + if (!bx_options.usb[0].Oenabled->get()) return;
+ +
+ DEV_register_irq(USB_IRQ, "USB Hub #1"); + Bit16u base_ioaddr = bx_options.usb[0].Oioaddr->get();
+ Bit8u irq = bx_options.usb[0].Oirq->get();
+ +
+#if ((USB_NUM_PORTS < 2) || (USB_NUM_PORTS > 8)) + DEV_register_irq(irq, "USB Hub #1");
+ BX_PANIC(("USB root hub must have at least 2 and at most 8 ports")); + BX_USB_THIS hub[0].irq = irq;
+#endif
+ +
+ // Call our timer routine every 1mS (1,000uS) + // Call our timer routine every 1mS (1,000uS)
+ // Continuous and active + // Continuous and active
+ BX_USB_THIS hub[0].timer_index = + BX_USB_THIS hub[0].timer_index =
+ bx_pc_system.register_timer(this, usb_timer_handler, 1000, 1,1, "usb.timer"); + bx_pc_system.register_timer(this, usb_timer_handler, 1000, 1,1, "usb.timer");
+ +
+ for (unsigned addr=0xFF40; addr<=0xFF5F; addr++) { + for (unsigned addr=base_ioaddr; addr<=(unsigned)(base_ioaddr+0x14); addr++) {
+ BX_DEBUG(("register read/write: 0x%04x", addr)); + BX_DEBUG(("register read/write: 0x%04x", addr));
+ DEV_register_ioread_handler(this, read_handler, addr, "USB Port 1", 7); + DEV_register_ioread_handler(this, read_handler, addr, "USB Hub #1", 7);
+ DEV_register_iowrite_handler(this, write_handler, addr, "USB Port 1", 7); + DEV_register_iowrite_handler(this, write_handler, addr, "USB Hub #1", 7);
+ } + }
+ BX_USB_THIS hub[0].base_ioaddr = base_ioaddr;
+ +
+ DEV_register_pci_handlers(this, + DEV_register_pci_handlers(this,
+ pci_read_handler, + pci_read_handler,
@ -441,10 +446,10 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ "Experimental PCI USB"); + "Experimental PCI USB");
+ +
+ for (unsigned i=0; i<256; i++) { + for (unsigned i=0; i<256; i++) {
+ BX_USB_THIS s.pci_conf[i] = 0x0; + BX_USB_THIS hub[0].pci_conf[i] = 0x0;
+ } + }
+ +
+ BX_INFO(("usb1 at 0xff40-ff5f irq %d", USB_IRQ)); + BX_INFO(("usb1 at 0x%04x-0x%04x irq %d", base_ioaddr, base_ioaddr+0x13, irq));
+} +}
+ +
+ void + void
@ -458,18 +463,24 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ { 0x02, 0x20 }, { 0x03, 0x70 }, // 0x7020 = device + { 0x02, 0x20 }, { 0x03, 0x70 }, // 0x7020 = device
+ { 0x04, 0x05 }, { 0x05, 0x00 }, // command_io + { 0x04, 0x05 }, { 0x05, 0x00 }, // command_io
+ { 0x06, 0x80 }, { 0x07, 0x02 }, // status + { 0x06, 0x80 }, { 0x07, 0x02 }, // status
+ { 0x08, 0x01 }, // revision number
+ { 0x09, 0x00 }, // interface + { 0x09, 0x00 }, // interface
+ { 0x0a, 0x03 }, // class_sub USB Host Controller + { 0x0a, 0x03 }, // class_sub USB Host Controller
+ { 0x0b, 0x0c }, // class_base Serial Bus Controller + { 0x0b, 0x0c }, // class_base Serial Bus Controller
+ { 0x0D, 0x20 }, // bus latency + { 0x0D, 0x20 }, // bus latency
+ { 0x0e, 0x00 }, // header_type_generic + { 0x0e, 0x00 }, // header_type_generic
+ { 0x20, 0x41 }, { 0x21, 0xFF }, { 0x22, 0x00 }, { 0x23, 0x00 }, // address space + // address space 0x20 - 0x23
+ { 0x3c, 0x09 }, // IRQ + { 0x20, ((bx_options.usb[0].Oioaddr->get() & 0xE0) | 0x01) },
+ { 0x3d, 0x04 } // INT + { 0x21, (bx_options.usb[0].Oioaddr->get() >> 8) },
+ { 0x22, 0x00 }, { 0x23, 0x00 },
+ { 0x3c, bx_options.usb[0].Oirq->get() }, // IRQ
+ { 0x3d, 0x04 }, // INT
+ { 0x6a, 0x01 }, // USB clock
+ { 0xc1, 0x20 } // PIRQ enable
+ +
+ }; + };
+ for (unsigned i = 0; i < sizeof(reset_vals) / sizeof(*reset_vals); ++i) { + for (unsigned i = 0; i < sizeof(reset_vals) / sizeof(*reset_vals); ++i) {
+ BX_USB_THIS s.pci_conf[reset_vals[i].addr] = reset_vals[i].val; + BX_USB_THIS hub[0].pci_conf[reset_vals[i].addr] = reset_vals[i].val;
+ } + }
+ +
+ // reset locals + // reset locals
@ -534,74 +545,39 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ UNUSED(this_ptr); + UNUSED(this_ptr);
+#endif // !BX_USE_PCIUSB_SMF +#endif // !BX_USE_PCIUSB_SMF
+ Bit32u val = 0x0; + Bit32u val = 0x0;
+ Bit8u port; + Bit8u offset,port;
+ +
+ BX_DEBUG(("register read from address 0x%04x - ", (unsigned) address)); + BX_DEBUG(("register read from address 0x%04x - ", (unsigned) address));
+ +
+ offset = address - BX_USB_THIS hub[0].base_ioaddr;
+ +
+ switch (address) { + switch (offset) {
+ case 0xFF4C: // Start of Frame Modify + case 0x0C: // Start of Frame Modify
+ case 0xFF51: // port0 (high byte read) + case 0x11: // port0 (high byte read)
+ case 0xFF53: // port1 (high byte read) + case 0x13: // port1 (high byte read)
+#if USB_NUM_PORTS == 3
+ case 0xFF55: // port2 (high byte read)
+#endif
+#if USB_NUM_PORTS == 4
+ case 0xFF57: // port3 (high byte read)
+#endif
+#if USB_NUM_PORTS == 5
+ case 0xFF59: // port4 (high byte read)
+#endif
+#if USB_NUM_PORTS == 6
+ case 0xFF5B: // port5 (high byte read)
+#endif
+#if USB_NUM_PORTS == 7
+ case 0xFF5D: // port6 (high byte read)
+#endif
+#if USB_NUM_PORTS == 8
+ case 0xFF5F: // port7 (high byte read)
+#endif
+ if (io_len != 1) + if (io_len != 1)
+ BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len)); + BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
+ break; + break;
+ case 0xFF50: // port0 + case 0x10: // port0
+ case 0xFF52: // port1 + case 0x12: // port1
+#if USB_NUM_PORTS == 3
+ case 0xFF54: // port2
+#endif
+#if USB_NUM_PORTS == 4
+ case 0xFF56: // port3
+#endif
+#if USB_NUM_PORTS == 5
+ case 0xFF58: // port4
+#endif
+#if USB_NUM_PORTS == 6
+ case 0xFF5A: // port5
+#endif
+#if USB_NUM_PORTS == 7
+ case 0xFF5C: // port6
+#endif
+#if USB_NUM_PORTS == 8
+ case 0xFF5E: // port7
+#endif
+ if ((io_len < 1) || (io_len > 2)) + if ((io_len < 1) || (io_len > 2))
+ BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len)); + BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
+ break; + break;
+ case 0xFF40: // command register (16-bit) + case 0x00: // command register (16-bit)
+ case 0xFF42: // status register (16-bit) + case 0x02: // status register (16-bit)
+ case 0xFF44: // interrupt enable register (1-bit) + case 0x04: // interrupt enable register (1-bit)
+ case 0xFF46: // frame number register (16-bit) + case 0x06: // frame number register (16-bit)
+ if (io_len != 2) + if (io_len != 2)
+ BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len)); + BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
+ break; + break;
+ case 0xFF48: // frame base register (32-bit) + case 0x08: // frame base register (32-bit)
+ if (io_len != 4) + if (io_len != 4)
+ BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len)); + BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
+ break; + break;
+ } + }
+ +
+ switch (address) { + switch (offset) {
+ case 0xFF40: // command register (16-bit) + case 0x00: // command register (16-bit)
+ val = BX_USB_THIS hub[0].usb_command.max_packet_size << 7 + val = BX_USB_THIS hub[0].usb_command.max_packet_size << 7
+ | BX_USB_THIS hub[0].usb_command.configured << 6 + | BX_USB_THIS hub[0].usb_command.configured << 6
+ | BX_USB_THIS hub[0].usb_command.debug << 5 + | BX_USB_THIS hub[0].usb_command.debug << 5
@ -612,7 +588,7 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ | BX_USB_THIS hub[0].usb_command.schedule; + | BX_USB_THIS hub[0].usb_command.schedule;
+ break; + break;
+ +
+ case 0xFF42: // status register (16-bit) + case 0x02: // status register (16-bit)
+ val = BX_USB_THIS hub[0].usb_status.host_halted << 5 + val = BX_USB_THIS hub[0].usb_status.host_halted << 5
+ | BX_USB_THIS hub[0].usb_status.host_error << 4 + | BX_USB_THIS hub[0].usb_status.host_error << 4
+ | BX_USB_THIS hub[0].usb_status.pci_error << 3 + | BX_USB_THIS hub[0].usb_status.pci_error << 3
@ -621,34 +597,28 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ | BX_USB_THIS hub[0].usb_status.interrupt; + | BX_USB_THIS hub[0].usb_status.interrupt;
+ break; + break;
+ +
+ case 0xFF44: // interrupt enable register (16-bit) + case 0x04: // interrupt enable register (16-bit)
+ val = BX_USB_THIS hub[0].usb_enable.short_packet << 3 + val = BX_USB_THIS hub[0].usb_enable.short_packet << 3
+ | BX_USB_THIS hub[0].usb_enable.on_complete << 2 + | BX_USB_THIS hub[0].usb_enable.on_complete << 2
+ | BX_USB_THIS hub[0].usb_enable.resume << 1 + | BX_USB_THIS hub[0].usb_enable.resume << 1
+ | BX_USB_THIS hub[0].usb_enable.timeout_crc; + | BX_USB_THIS hub[0].usb_enable.timeout_crc;
+ break; + break;
+ +
+ case 0xFF46: // frame number register (16-bit) + case 0x06: // frame number register (16-bit)
+ val = BX_USB_THIS hub[0].usb_frame_num.frame_num; + val = BX_USB_THIS hub[0].usb_frame_num.frame_num;
+ break; + break;
+ +
+ case 0xFF48: // frame base register (32-bit) + case 0x08: // frame base register (32-bit)
+ val = BX_USB_THIS hub[0].usb_frame_base.frame_base; + val = BX_USB_THIS hub[0].usb_frame_base.frame_base;
+ break; + break;
+ +
+ case 0xFF4C: // start of Frame Modify register (8-bit) + case 0x0C: // start of Frame Modify register (8-bit)
+ val = BX_USB_THIS hub[0].usb_sof.sof_timing; + val = BX_USB_THIS hub[0].usb_sof.sof_timing;
+ break; + break;
+ +
+ case 0xFF50: // port0 + case 0x10: // port0
+ case 0xFF52: // port1 + case 0x12: // port1
+ case 0xFF54: // port2 + port = (offset & 0x0F) >> 1;
+ case 0xFF56: // port3
+ case 0xFF58: // port4
+ case 0xFF5A: // port5
+ case 0xFF5C: // port6
+ case 0xFF5E: // port7
+ port = (address & 0x0F) >> 1;
+ if (port < USB_NUM_PORTS) { + if (port < USB_NUM_PORTS) {
+ val = BX_USB_THIS hub[0].usb_port[port].suspend << 12 + val = BX_USB_THIS hub[0].usb_port[port].suspend << 12
+ | BX_USB_THIS hub[0].usb_port[port].reset << 9 + | BX_USB_THIS hub[0].usb_port[port].reset << 9
@ -694,50 +664,34 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+#else +#else
+ UNUSED(this_ptr); + UNUSED(this_ptr);
+#endif // !BX_USE_PCIUSB_SMF +#endif // !BX_USE_PCIUSB_SMF
+ Bit8u port; + Bit8u offset,port;
+ +
+ BX_DEBUG(("register write to address 0x%04x - ", (unsigned) address)); + BX_DEBUG(("register write to address 0x%04x - ", (unsigned) address));
+ +
+ switch (address) { + offset = address - BX_USB_THIS hub[0].base_ioaddr;
+ case 0xFF4C: // Start of Frame Modify +
+ switch (offset) {
+ case 0x0C: // Start of Frame Modify
+ if (io_len != 1) + if (io_len != 1)
+ BX_PANIC(("io write to port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len)); + BX_PANIC(("io write to port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
+ break; + break;
+ case 0xFF40: // command register (16-bit) + case 0x00: // command register (16-bit)
+ case 0xFF42: // status register (16-bit) + case 0x02: // status register (16-bit)
+ case 0xFF44: // interrupt enable register (1-bit) + case 0x04: // interrupt enable register (1-bit)
+ case 0xFF46: // frame number register (16-bit) + case 0x06: // frame number register (16-bit)
+ case 0xFF50: // port0 + case 0x10: // port0
+ case 0xFF52: // port1 + case 0x12: // port1
+#if USB_NUM_PORTS == 3
+ case 0xFF54: // port2
+#endif
+#if USB_NUM_PORTS == 4
+ case 0xFF56: // port3
+#endif
+#if USB_NUM_PORTS == 5
+ case 0xFF58: // port4
+#endif
+#if USB_NUM_PORTS == 6
+ case 0xFF5A: // port5
+#endif
+#if USB_NUM_PORTS == 7
+ case 0xFF5C: // port6
+#endif
+#if USB_NUM_PORTS == 8
+ case 0xFF5E: // port7
+#endif
+ if (io_len != 2) + if (io_len != 2)
+ BX_PANIC(("io write to port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len)); + BX_PANIC(("io write to port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
+ break; + break;
+ case 0xFF48: // frame base register (32-bit) + case 0x08: // frame base register (32-bit)
+ if (io_len != 4) + if (io_len != 4)
+ BX_PANIC(("io write to port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len)); + BX_PANIC(("io write to port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
+ break; + break;
+ } + }
+ +
+ switch (address) { + switch (offset) {
+ case 0xFF40: // command register (16-bit) (R/W) + case 0x00: // command register (16-bit) (R/W)
+ if (value & 0xFF00) + if (value & 0xFF00)
+ BX_ERROR(("write to command register with bits 15:8 not zero: 0x%04x", value)); + BX_ERROR(("write to command register with bits 15:8 not zero: 0x%04x", value));
+ +
@ -768,7 +722,7 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ +
+ break; + break;
+ +
+ case 0xFF42: // status register (16-bit) (R/WC) + case 0x02: // status register (16-bit) (R/WC)
+ if (value & 0xFFC0) + if (value & 0xFFC0)
+ BX_ERROR(("write to status register with bits 15:6 not zero: 0x%04x", value)); + BX_ERROR(("write to status register with bits 15:6 not zero: 0x%04x", value));
+ +
@ -780,7 +734,7 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ BX_USB_THIS hub[0].usb_status.interrupt = (value & 0x01) ? 0: BX_USB_THIS hub[0].usb_status.interrupt; + BX_USB_THIS hub[0].usb_status.interrupt = (value & 0x01) ? 0: BX_USB_THIS hub[0].usb_status.interrupt;
+ break; + break;
+ +
+ case 0xFF44: // interrupt enable register (16-bit) + case 0x04: // interrupt enable register (16-bit)
+ if (value & 0xFFF0) + if (value & 0xFFF0)
+ BX_ERROR(("write to interrupt enable register with bits 15:4 not zero: 0x%04x", value)); + BX_ERROR(("write to interrupt enable register with bits 15:4 not zero: 0x%04x", value));
+ +
@ -793,7 +747,7 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ +
+ break; + break;
+ +
+ case 0xFF46: // frame number register (16-bit) + case 0x06: // frame number register (16-bit)
+ if (value & 0xF800) + if (value & 0xF800)
+ BX_ERROR(("write to frame number register with bits 15:11 not zero: 0x%04x", value)); + BX_ERROR(("write to frame number register with bits 15:11 not zero: 0x%04x", value));
+ +
@ -805,29 +759,23 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ +
+ break; + break;
+ +
+ case 0xFF48: // frame base register (32-bit) + case 0x08: // frame base register (32-bit)
+ if (value & 0xFFF) + if (value & 0xFFF)
+ BX_PANIC(("write to frame base register with bits 11:0 not zero: 0x%08x", value)); + BX_PANIC(("write to frame base register with bits 11:0 not zero: 0x%08x", value));
+ +
+ BX_USB_THIS hub[0].usb_frame_base.frame_base = value; + BX_USB_THIS hub[0].usb_frame_base.frame_base = value;
+ break; + break;
+ +
+ case 0xFF4C: // start of Frame Modify register (8-bit) + case 0x0C: // start of Frame Modify register (8-bit)
+ if (value & 0x80) + if (value & 0x80)
+ BX_ERROR(("write to SOF Modify register with bit 7 not zero: 0x%04x", value)); + BX_ERROR(("write to SOF Modify register with bit 7 not zero: 0x%04x", value));
+ +
+ BX_USB_THIS hub[0].usb_sof.sof_timing = value; + BX_USB_THIS hub[0].usb_sof.sof_timing = value;
+ break; + break;
+ +
+ case 0xFF50: // port0 + case 0x10: // port0
+ case 0xFF52: // port1 + case 0x12: // port1
+ case 0xFF54: // port2 + port = (offset & 0x0F) >> 1;
+ case 0xFF56: // port3
+ case 0xFF58: // port4
+ case 0xFF5A: // port5
+ case 0xFF5C: // port6
+ case 0xFF5E: // port7
+ port = (address & 0x0F) >> 1;
+ if (port < USB_NUM_PORTS) { + if (port < USB_NUM_PORTS) {
+ if (value & ((1<<5) | (1<<4) | (1<<0))) + if (value & ((1<<5) | (1<<4) | (1<<0)))
+ BX_PANIC(("write to one or more read-only bits in port%d register: 0x%04x", port, value)); + BX_PANIC(("write to one or more read-only bits in port%d register: 0x%04x", port, value));
@ -928,7 +876,7 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ Bit32u value = 0; + Bit32u value = 0;
+ +
+ if (io_len > 4 || io_len == 0) { + if (io_len > 4 || io_len == 0) {
+ BX_DEBUG(("Experimental USB PCI read register 0x%02x, len=%u !", + BX_ERROR(("Experimental USB PCI read register 0x%02x, len=%u !",
+ (unsigned) address, (unsigned) io_len)); + (unsigned) address, (unsigned) io_len));
+ return 0xffffffff; + return 0xffffffff;
+ } + }
@ -954,6 +902,7 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ } + }
+ break; + break;
+ case 0x0c: pszName = "(cache line size) "; break; + case 0x0c: pszName = "(cache line size) "; break;
+ case 0x20: pszName = "(base address) "; break;
+ case 0x28: pszName = "(cardbus cis) "; break; + case 0x28: pszName = "(cardbus cis) "; break;
+ case 0x2c: pszName = "(subsys. vendor+) "; break; + case 0x2c: pszName = "(subsys. vendor+) "; break;
+ case 0x30: pszName = "(rom base) "; break; + case 0x30: pszName = "(rom base) "; break;
@ -967,8 +916,8 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ szTmp[0] = '\0'; + szTmp[0] = '\0';
+ szTmp2[0] = '\0'; + szTmp2[0] = '\0';
+ for (unsigned i=0; i<io_len; i++) { + for (unsigned i=0; i<io_len; i++) {
+ value |= (BX_USB_THIS s.pci_conf[address+i] << (i*8)); + value |= (BX_USB_THIS hub[0].pci_conf[address+i] << (i*8));
+ sprintf(szTmp2, "%02x", (BX_USB_THIS s.pci_conf[address+i])); + sprintf(szTmp2, "%02x", (BX_USB_THIS hub[0].pci_conf[address+i]));
+ strrev(szTmp2); + strrev(szTmp2);
+ strcat(szTmp, szTmp2); + strcat(szTmp, szTmp2);
+ } + }
@ -999,7 +948,7 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+#endif // !BX_USE_PCIUSB_SMF +#endif // !BX_USE_PCIUSB_SMF
+ +
+ if (io_len > 4 || io_len == 0) { + if (io_len > 4 || io_len == 0) {
+ BX_DEBUG(("Experimental USB PCI write register 0x%02x, len=%u !", + BX_ERROR(("Experimental USB PCI write register 0x%02x, len=%u !",
+ (unsigned) address, (unsigned) io_len)); + (unsigned) address, (unsigned) io_len));
+ return; + return;
+ } + }
@ -1012,23 +961,43 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+ for (unsigned i=0; i<io_len; i++) { + for (unsigned i=0; i<io_len; i++) {
+ const Bit8u value8 = (value >> (i*8)) & 0xFF; + const Bit8u value8 = (value >> (i*8)) & 0xFF;
+ switch (address+i) { + switch (address+i) {
+ case 0x20: // + case 0x20: // Base address
+ BX_USB_THIS s.pci_conf[address+i] = (value8 & 0xe0) | 0x01; + BX_USB_THIS hub[0].pci_conf[address+i] = (value8 & 0xe0) | 0x01;
+ sprintf(szTmp2, "%02x", (value8 & 0xe0) | 0x01); + sprintf(szTmp2, "%02x", (value8 & 0xe0) | 0x01);
+ break; + break;
+ case 0x22: // Oh, no, you're not writing to rom_base! + case 0x10: // Reserved
+ case 0x11: //
+ case 0x12: //
+ case 0x13: //
+ case 0x14: //
+ case 0x15: //
+ case 0x16: //
+ case 0x17: //
+ case 0x18: //
+ case 0x19: //
+ case 0x1a: //
+ case 0x1b: //
+ case 0x1c: //
+ case 0x1d: //
+ case 0x1e: //
+ case 0x1f: //
+ case 0x22: // Always 0
+ case 0x23: // + case 0x23: //
+ case 0x30: // + case 0x24: // Reserved
+ case 0x25: //
+ case 0x26: //
+ case 0x27: //
+ case 0x30: // Oh, no, you're not writing to rom_base!
+ case 0x31: // + case 0x31: //
+ case 0x32: // + case 0x32: //
+ case 0x33: // + case 0x33: //
+ case 0x3d: // + case 0x3d: //
+ case 0x04: // disallowing write to command + case 0x05: // disallowing write to command hi-byte
+ case 0x06: // disallowing write to status lo-byte (is that expected?) + case 0x06: // disallowing write to status lo-byte (is that expected?)
+ strcpy(szTmp2, ".."); + strcpy(szTmp2, "..");
+ break; + break;
+ default: + default:
+ BX_USB_THIS s.pci_conf[address+i] = value8; + BX_USB_THIS hub[0].pci_conf[address+i] = value8;
+ sprintf(szTmp2, "%02x", value8); + sprintf(szTmp2, "%02x", value8);
+ } + }
+ strrev(szTmp2); + strrev(szTmp2);
@ -1041,10 +1010,10 @@ diff -urN ../bochs/iodev/pciusb.cc ./iodev/pciusb.cc
+#endif // BX_PCI_SUPPORT && BX_PCI_USB_SUPPORT +#endif // BX_PCI_SUPPORT && BX_PCI_USB_SUPPORT
diff -urN ../bochs/iodev/pciusb.h ./iodev/pciusb.h diff -urN ../bochs/iodev/pciusb.h ./iodev/pciusb.h
--- ../bochs/iodev/pciusb.h 1970-01-01 01:00:00.000000000 +0100 --- ../bochs/iodev/pciusb.h 1970-01-01 01:00:00.000000000 +0100
+++ ./iodev/pciusb.h 2003-01-23 17:40:20.000000000 +0100 +++ ./iodev/pciusb.h 2003-01-25 14:12:43.000000000 +0100
@@ -0,0 +1,196 @@ @@ -0,0 +1,195 @@
+///////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////
+// $Id: patch.usb-fys,v 1.3 2003-01-24 15:14:15 vruppert Exp $ +// $Id: patch.usb-fys,v 1.4 2003-01-25 16:04:48 vruppert Exp $
+///////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////
+// +//
+// Copyright (C) 2003 MandrakeSoft S.A. +// Copyright (C) 2003 MandrakeSoft S.A.
@ -1082,12 +1051,13 @@ diff -urN ../bochs/iodev/pciusb.h ./iodev/pciusb.h
+#define BX_USB_MAXDEV 1 +#define BX_USB_MAXDEV 1
+#define BX_USB_CONFDEV 1 /* only 1 USB hub currently */ +#define BX_USB_CONFDEV 1 /* only 1 USB hub currently */
+ +
+#define USB_IRQ 0x09 +#define USB_NUM_PORTS 2 /* UHCI supports 2 ports per root hub */
+#define USB_NUM_PORTS 2 // two for now, allows up to 8(?)
+ +
+typedef struct { +typedef struct {
+ +
+ int timer_index; + Bit16u base_ioaddr;
+ Bit8u irq;
+ int timer_index;
+ +
+ // Registers + // Registers
+ // Base + 0x00 Command register + // Base + 0x00 Command register
@ -1205,6 +1175,8 @@ diff -urN ../bochs/iodev/pciusb.h ./iodev/pciusb.h
+ bx_bool status; + bx_bool status;
+ } usb_port[USB_NUM_PORTS]; + } usb_port[USB_NUM_PORTS];
+ +
+ Bit8u pci_conf[256];
+
+} bx_usb_t; +} bx_usb_t;
+ +
+ +
@ -1218,10 +1190,6 @@ diff -urN ../bochs/iodev/pciusb.h ./iodev/pciusb.h
+ +
+private: +private:
+ +
+ struct {
+ Bit8u pci_conf[256];
+ } s;
+
+ bx_usb_t hub[BX_USB_MAXDEV]; + bx_usb_t hub[BX_USB_MAXDEV];
+ Bit8u global_reset; + Bit8u global_reset;
+ +
@ -1241,11 +1209,22 @@ diff -urN ../bochs/iodev/pciusb.h ./iodev/pciusb.h
+}; +};
diff -urN ../bochs/main.cc ./main.cc diff -urN ../bochs/main.cc ./main.cc
--- ../bochs/main.cc 2003-01-13 21:50:12.000000000 +0100 --- ../bochs/main.cc 2003-01-13 21:50:12.000000000 +0100
+++ ./main.cc 2003-01-22 23:51:49.000000000 +0100 +++ ./main.cc 2003-01-25 13:29:22.000000000 +0100
@@ -805,6 +805,30 @@ @@ -747,7 +747,8 @@
par_ser_init_list); // initialize serial and parallel port options
menu->get_options ()->set (menu->SHOW_PARENT); #define PAR_SER_INIT_LIST_MAX \
((BXP_PARAMS_PER_PARALLEL_PORT * BX_N_PARALLEL_PORTS) \
- + (BXP_PARAMS_PER_SERIAL_PORT * BX_N_SERIAL_PORTS))
+ + (BXP_PARAMS_PER_SERIAL_PORT * BX_N_SERIAL_PORTS) \
+ + (BXP_PARAMS_PER_USB_HUB * BX_N_USB_HUBS))
bx_param_c *par_ser_init_list[1+PAR_SER_INIT_LIST_MAX];
bx_param_c **par_ser_ptr = &par_ser_init_list[0];
@@ -797,6 +798,43 @@
*par_ser_ptr++ = bx_options.com[i].Oenabled;
*par_ser_ptr++ = bx_options.com[i].Odev;
}
+
+ // usb hubs + // usb hubs
+ for (i=0; i<BX_N_USB_HUBS; i++) { + for (i=0; i<BX_N_USB_HUBS; i++) {
+ // options for USB hub + // options for USB hub
@ -1256,24 +1235,36 @@ diff -urN ../bochs/main.cc ./main.cc
+ strdup(name), + strdup(name),
+ strdup(descr), + strdup(descr),
+ (i==0)?1 : 0); // only enable the first by default + (i==0)?1 : 0); // only enable the first by default
+ sprintf (name, "Pathname of the usb device for USB%d", i+1); + bx_options.usb[i].Oioaddr = new bx_param_num_c (
+ bx_options.usb[i].Odev = new bx_param_filename_c ( + BXP_USBx_IOADDR(i+1),
+ BXP_USBx_PATH(i+1), + "USB ioaddr",
+ strdup(name), + "IO base adress of USB hub",
+ "", + 0, 0xffe0,
+ "", BX_PATHNAME_LEN); + (i==0)?0xff40 : 0);
+ deplist = new bx_list_c (BXP_NULL, 1); + bx_options.usb[i].Oirq = new bx_param_num_c (
+ deplist->add (bx_options.usb[i].Odev); + BXP_USBx_IRQ(i+1),
+ "USB irq",
+ "IRQ of USB hub",
+ 0, 15,
+ (i==0)?9 : 0);
+ deplist = new bx_list_c (BXP_NULL, 2);
+ deplist->add (bx_options.usb[i].Oioaddr);
+ deplist->add (bx_options.usb[i].Oirq);
+ bx_options.usb[i].Oenabled->set_dependent_list (deplist); + bx_options.usb[i].Oenabled->set_dependent_list (deplist);
+ // add to menu + // add to menu
+ *par_ser_ptr++ = bx_options.usb[i].Oenabled; + *par_ser_ptr++ = bx_options.usb[i].Oenabled;
+ *par_ser_ptr++ = bx_options.usb[i].Odev; + *par_ser_ptr++ = bx_options.usb[i].Oioaddr;
+ } + *par_ser_ptr++ = bx_options.usb[i].Oirq;
+ +
bx_options.rom.Opath = new bx_param_filename_c (BXP_ROM_PATH, + bx_options.usb[i].Oioaddr->set_ask_format (
"romimage", + BX_WITH_WX? "I/O Address :"
"Pathname of ROM image to load", + : "Enter new ioaddr: [0x%x] ");
@@ -2924,7 +2948,20 @@ + bx_options.usb[i].Oioaddr->set_base (16);
+ }
// add final NULL at the end, and build the menu
*par_ser_ptr = NULL;
menu = new bx_list_c (BXP_MENU_SERIAL_PARALLEL,
@@ -2924,7 +2962,26 @@
} }
} }
#endif #endif
@ -1283,10 +1274,16 @@ diff -urN ../bochs/main.cc ./main.cc
+ if (!strncmp(params[i], "enabled=", 8)) { + if (!strncmp(params[i], "enabled=", 8)) {
+ bx_options.usb[0].Oenabled->set (atol(&params[i][8])); + bx_options.usb[0].Oenabled->set (atol(&params[i][8]));
+ } + }
+ else if (!strncmp(params[i], "dev=", 4)) { + else if (!strncmp(params[i], "ioaddr=", 7)) {
+ bx_options.usb[0].Odev->set (&params[i][4]); + if ( (params[i][7] == '0') && (params[i][8] == 'x') )
+ bx_options.usb[0].Oioaddr->set (strtoul (&params[i][7], NULL, 16));
+ else
+ bx_options.usb[0].Oioaddr->set (strtoul (&params[i][7], NULL, 10));
+ bx_options.usb[0].Oenabled->set (1); + bx_options.usb[0].Oenabled->set (1);
+ } + }
+ else if (!strncmp(params[i], "irq=", 4)) {
+ bx_options.usb[0].Oirq->set (atol(&params[i][4]));
+ }
+ else { + else {
+ PARSE_ERR(("%s: unknown parameter for usb1 ignored.", context)); + PARSE_ERR(("%s: unknown parameter for usb1 ignored.", context));
+ } + }
@ -1295,7 +1292,7 @@ diff -urN ../bochs/main.cc ./main.cc
else if (!strcmp(params[0], "floppy_bootsig_check")) { else if (!strcmp(params[0], "floppy_bootsig_check")) {
if (num_params != 2) { if (num_params != 2) {
PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context)); PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context));
@@ -3661,6 +3698,17 @@ @@ -3661,6 +3718,18 @@
} }
int int
@ -1303,7 +1300,8 @@ diff -urN ../bochs/main.cc ./main.cc
+{ +{
+ fprintf (fp, "usb%d: enabled=%d", n, opt->Oenabled->get ()); + fprintf (fp, "usb%d: enabled=%d", n, opt->Oenabled->get ());
+ if (opt->Oenabled->get ()) { + if (opt->Oenabled->get ()) {
+ fprintf (fp, ", dev=\"%s\"", opt->Odev->getptr ()); + fprintf (fp, ", ioaddr=0x%04x, irq=%d", opt->Oioaddr->get (),
+ opt->Oirq->get ());
+ } + }
+ fprintf (fp, "\n"); + fprintf (fp, "\n");
+ return 0; + return 0;
@ -1313,7 +1311,7 @@ diff -urN ../bochs/main.cc ./main.cc
bx_write_sb16_options (FILE *fp, bx_sb16_options *opt) bx_write_sb16_options (FILE *fp, bx_sb16_options *opt)
{ {
if (!opt->Opresent->get ()) { if (!opt->Opresent->get ()) {
@@ -3786,6 +3834,7 @@ @@ -3786,6 +3855,7 @@
//bx_write_serial_options (fp, &bx_options.com[1], 2); //bx_write_serial_options (fp, &bx_options.com[1], 2);
//bx_write_serial_options (fp, &bx_options.com[2], 3); //bx_write_serial_options (fp, &bx_options.com[2], 3);
//bx_write_serial_options (fp, &bx_options.com[3], 4); //bx_write_serial_options (fp, &bx_options.com[3], 4);