Started implementing USB EHCI support. The PCI and MMIO register behaviour is

almost implemented, the port owner handling and the UHCI companion controllers
are present. High speed devices are not yet supported, since the EHCI scheduler
code has not been written yet (e.g. porting from Qemu). Low and full speed
devices should be detected correctly and work after port ownership change to
UHCI. 6 ports are available and the bochsrc syntax is similar to other HCs.
This commit is contained in:
Volker Ruppert 2015-12-06 20:03:42 +00:00
parent 5e635a87bb
commit 0ba744b9fe
10 changed files with 1288 additions and 7 deletions

View File

@ -195,6 +195,7 @@
#define BX_USE_PCIDEV_SMF 1 // PCI-DEV
#define BX_USE_USB_UHCI_SMF 1 // USB UHCI hub
#define BX_USE_USB_OHCI_SMF 1 // USB OHCI hub
#define BX_USE_USB_EHCI_SMF 1 // USB EHCI hub
#define BX_USE_USB_XHCI_SMF 1 // USB xHCI hub
#define BX_USE_PCIPNIC_SMF 1 // PCI pseudo NIC
#define BX_USE_E1000_SMF 1 // Intel(R) Gigabit Ethernet
@ -215,8 +216,8 @@
|| !BX_USE_PAR_SMF || !BX_USE_PIC_SMF || !BX_USE_PIT_SMF \
|| !BX_USE_SER_SMF || !BX_USE_UM_SMF || !BX_USE_VGA_SMF \
|| !BX_USE_SB16_SMF || !BX_USE_ES1370_SMF || !BX_USE_DEV_SMF \
|| !BX_USE_PCI_SMF || !BX_USE_P2I_SMF \
|| !BX_USE_USB_UHCI_SMF || !BX_USE_USB_OHCI_SMF || !BX_USE_USB_XHCI_SMF \
|| !BX_USE_PCI_SMF || !BX_USE_P2I_SMF || !BX_USE_USB_UHCI_SMF \
|| !BX_USE_USB_OHCI_SMF || !BX_USE_USB_EHCI_SMF || !BX_USE_USB_XHCI_SMF \
|| !BX_USE_PCIPNIC_SMF || !BX_USE_PIDE_SMF || !BX_USE_ACPI_SMF \
|| !BX_USE_NE2K_SMF || !BX_USE_EFI_SMF || !BX_USE_GAMEPORT_SMF \
|| !BX_USE_E1000_SMF || !BX_USE_PCIDEV_SMF || !BX_USE_CIRRUS_SMF)
@ -820,13 +821,19 @@ typedef
// USB host controllers
#define BX_SUPPORT_USB_UHCI 0
#define BX_SUPPORT_USB_OHCI 0
#define BX_SUPPORT_USB_EHCI 0
#define BX_SUPPORT_USB_XHCI 0
#define BX_SUPPORT_PCIUSB (BX_SUPPORT_USB_UHCI || BX_SUPPORT_USB_OHCI || BX_SUPPORT_USB_XHCI)
#define BX_SUPPORT_PCIUSB \
(BX_SUPPORT_USB_UHCI || BX_SUPPORT_USB_OHCI || BX_SUPPORT_USB_EHCI || BX_SUPPORT_USB_XHCI)
#if (BX_SUPPORT_PCIUSB && !BX_SUPPORT_PCI)
#error To enable USB, you must also enable PCI
#endif
#if (BX_SUPPORT_USB_EHCI && !BX_SUPPORT_USB_UHCI)
#error To enable EHCI, you must also enable UHCI
#endif
// MS bus mouse support
#define BX_SUPPORT_BUSMOUSE 0

View File

@ -1534,9 +1534,28 @@ AC_ARG_ENABLE(usb-ohci,
]
)
AC_MSG_CHECKING(for experimental USB EHCI support)
AC_ARG_ENABLE(usb-ehci,
AS_HELP_STRING([--enable-usb-ehci], [enable experimental USB EHCI support (no - incomplete)]),
[if test "$enableval" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(BX_SUPPORT_USB_EHCI, 1)
USBHC_OBJS="$USBHC_OBJS usb_ehci.o"
USBHC_DLL_TARGETS="$USBHC_DLL_TARGETS bx_usb_ehci.dll"
use_usb=1
else
AC_MSG_RESULT(no)
AC_DEFINE(BX_SUPPORT_USB_EHCI, 0)
fi],
[
AC_MSG_RESULT(no)
AC_DEFINE(BX_SUPPORT_USB_EHCI, 0)
]
)
AC_MSG_CHECKING(for experimental USB xHCI support)
AC_ARG_ENABLE(usb-xhci,
AS_HELP_STRING([--enable-usb-xhci], [enable experimental USB xHCI support (no - incomplete)]),
AS_HELP_STRING([--enable-usb-xhci], [enable experimental USB xHCI support (no)]),
[if test "$enableval" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(BX_SUPPORT_USB_XHCI, 1)

View File

@ -1044,6 +1044,7 @@ bx_bool bx_devices_c::is_usb_enabled(void)
{
if (PLUG_device_present("usb_ohci") ||
PLUG_device_present("usb_uhci") ||
PLUG_device_present("usb_ehci") ||
PLUG_device_present("usb_xhci")) {
return 1;
}

View File

@ -100,6 +100,9 @@ libbx_usb_common.la: usb_common.lo $(USBDEV_OBJS:.o=.lo) scsi_device.lo
libbx_usb_uhci.la: usb_uhci.lo uhci_core.lo
$(LIBTOOL) --mode=link --tag CXX $(CXX) -module usb_uhci.lo uhci_core.lo -o libbx_usb_uhci.la -rpath $(PLUGIN_PATH)
libbx_usb_ehci.la: usb_ehci.lo uhci_core.lo
$(LIBTOOL) --mode=link --tag CXX $(CXX) -module usb_ehci.lo uhci_core.lo -o libbx_usb_ehci.la -rpath $(PLUGIN_PATH)
#### building DLLs for win32 (Cygwin and MinGW/MSYS)
bx_%.dll: %.o
$(CXX) $(CXXFLAGS) -shared -o $@ $< $(WIN32_DLL_IMPORT_LIBRARY)
@ -114,6 +117,9 @@ bx_usb_uhci.dll: usb_uhci.o uhci_core.o
bx_usb_ohci.dll: usb_ohci.o
@LINK_DLL@ usb_ohci.o $(WIN32_DLL_IMPORT_LIBRARY)
bx_usb_ehci.dll: usb_ehci.o uhci_core.o
@LINK_DLL@ usb_ehci.o uhci_core.o $(WIN32_DLL_IMPORT_LIBRARY)
bx_usb_xhci.dll: usb_xhci.o
@LINK_DLL@ usb_xhci.o $(WIN32_DLL_IMPORT_LIBRARY)
@ -161,6 +167,12 @@ usb_common.o: usb_common.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
../../param_names.h usb_common.h usb_hid.h usb_hub.h usb_msd.h usb_cbi.h \
usb_printer.h
usb_ehci.o: usb_ehci.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
../../memory/memory.h ../../pc_system.h ../../gui/gui.h \
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
../../param_names.h ../pci.h usb_common.h uhci_core.h usb_ehci.h
usb_hid.o: usb_hid.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
@ -230,6 +242,12 @@ usb_common.lo: usb_common.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
../../param_names.h usb_common.h usb_hid.h usb_hub.h usb_msd.h usb_cbi.h \
usb_printer.h
usb_ehci.lo: usb_ehci.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \
../../memory/memory.h ../../pc_system.h ../../gui/gui.h \
../../instrument/stubs/instrument.h ../../plugin.h ../../extplugin.h \
../../param_names.h ../pci.h usb_common.h uhci_core.h usb_ehci.h
usb_hid.lo: usb_hid.@CPP_SUFFIX@ ../iodev.h ../../bochs.h ../../config.h \
../../osdep.h ../../bx_debug/debug.h ../../config.h ../../osdep.h \
../../gui/siminterface.h ../../cpudb.h ../../gui/paramtree.h \

1060
bochs/iodev/usb/usb_ehci.cc Normal file

File diff suppressed because it is too large Load Diff

166
bochs/iodev/usb/usb_ehci.h Normal file
View File

@ -0,0 +1,166 @@
/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Experimental USB EHCI adapter (partly ported from Qemu)
//
// Copyright (C) 2015 The Bochs Project
//
// Copyright(c) 2008 Emutex Ltd. (address@hidden)
// Copyright(c) 2011-2012 Red Hat, Inc.
//
// Red Hat Authors:
// Gerd Hoffmann <kraxel@redhat.com>
// Hans de Goede <hdegoede@redhat.com>
//
// EHCI project was started by Mark Burkley, with contributions by
// Niels de Vos. David S. Ahern continued working on it. Kevin Wolf,
// Jan Kiszka and Vincent Palatin contributed bugfixes.
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
/////////////////////////////////////////////////////////////////////////
#ifndef BX_IODEV_USB_EHCI_H
#define BX_IODEV_USB_EHCI_H
#if BX_USE_USB_EHCI_SMF
# define BX_EHCI_THIS theUSB_EHCI->
# define BX_EHCI_THIS_PTR theUSB_EHCI
#else
# define BX_EHCI_THIS this->
# define BX_EHCI_THIS_PTR this
#endif
#define USB_EHCI_PORTS 6
typedef struct {
int frame_timer_index;
Bit8u usbsts_pending;
Bit32u usbsts_frindex;
Bit64u last_run_usec;
struct {
Bit8u CapLength;
Bit8u Reserved;
Bit16u HciVersion;
Bit32u HcsParams;
Bit32u HccParams;
} cap_regs;
struct {
struct {
Bit8u itc;
bx_bool iaad;
bx_bool ase;
bx_bool pse;
bx_bool hcreset;
bx_bool rs;
} UsbCmd;
struct {
bx_bool ass;
bx_bool pss;
bx_bool recl;
bx_bool hchalted;
Bit8u inti;
} UsbSts;
Bit8u UsbIntr;
Bit32u FrIndex;
Bit32u CtrlDsSegment;
Bit32u PeriodicListBase;
Bit32u AsyncListAddr;
Bit32u ConfigFlag;
} op_regs;
struct {
// our data
usb_device_c *device; // device connected to this port
bx_bool owner_change;
struct {
bx_bool woe;
bx_bool wde;
bx_bool wce;
Bit8u ptc;
Bit8u pic;
bx_bool po;
bx_bool pp;
Bit8u ls;
bx_bool pr;
bx_bool sus;
bx_bool fpr;
bx_bool occ;
bx_bool oca;
bx_bool pec;
bx_bool ped;
bx_bool csc;
bx_bool ccs;
} portsc;
} usb_port[USB_EHCI_PORTS];
} bx_usb_ehci_t;
class bx_usb_ehci_c : public bx_devmodel_c, public bx_pci_device_stub_c {
public:
bx_usb_ehci_c();
virtual ~bx_usb_ehci_c();
virtual void init(void);
virtual void reset(unsigned);
virtual void register_state(void);
virtual void after_restore_state(void);
virtual Bit32u pci_read_handler(Bit8u address, unsigned io_len);
virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len);
static const char *usb_param_handler(bx_param_string_c *param, int set,
const char *oldval, const char *val, int maxlen);
private:
bx_uhci_core_c *uhci[3];
bx_usb_ehci_t hub;
Bit8u devfunc;
Bit8u device_change;
int rt_conf_id;
Bit8u *device_buffer;
void reset_hc();
void reset_port(int);
static void init_device(Bit8u port, bx_list_c *portconf);
static void remove_device(Bit8u port);
static void set_connect_status(Bit8u port, int type, bx_bool connected);
static void change_port_owner(int port);
static int broadcast_packet(USBPacket *p, const int port);
void update_irq(void);
void raise_irq(Bit8u intr);
void commit_irq(void);
void update_frindex(int frames);
static void ehci_frame_handler(void *);
void ehci_frame_timer(void);
#if BX_USE_USB_EHCI_SMF
static bx_bool read_handler(bx_phy_address addr, unsigned len, void *data, void *param);
static bx_bool write_handler(bx_phy_address addr, unsigned len, void *data, void *param);
#else
bx_bool read_handler(bx_phy_address addr, unsigned len, void *data, void *param);
bx_bool write_handler(bx_phy_address addr, unsigned len, void *data, void *param);
#endif
static void runtime_config_handler(void *);
void runtime_config(void);
};
#endif // BX_IODEV_USB_EHCI_H

View File

@ -661,6 +661,9 @@ int bx_init_main(int argc, char *argv[])
#if BX_SUPPORT_USB_UHCI
fprintf(stderr, "usb_uhci\n");
#endif
#if BX_SUPPORT_USB_EHCI
fprintf(stderr, "usb_ehci\n");
#endif
#if BX_SUPPORT_USB_XHCI
fprintf(stderr, "usb_xhci\n");
#endif

View File

@ -165,6 +165,8 @@
#define BXPN_UHCI_ENABLED "ports.usb.uhci.enabled"
#define BXPN_USB_OHCI "ports.usb.ohci"
#define BXPN_OHCI_ENABLED "ports.usb.ohci.enabled"
#define BXPN_USB_EHCI "ports.usb.ehci"
#define BXPN_EHCI_ENABLED "ports.usb.ehci.enabled"
#define BXPN_USB_XHCI "ports.usb.xhci"
#define BXPN_XHCI_ENABLED "ports.usb.xhci.enabled"
#define BXPN_NE2K "network.ne2k"

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2013 The Bochs Project
// Copyright (C) 2002-2015 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -879,11 +879,14 @@ static builtin_plugin_t builtin_opt_plugins[] = {
#if BX_SUPPORT_SB16
BUILTIN_PLUGIN_ENTRY(sb16),
#endif
#if BX_SUPPORT_USB_UHCI
BUILTIN_PLUGIN_ENTRY(usb_uhci),
#endif
#if BX_SUPPORT_USB_OHCI
BUILTIN_PLUGIN_ENTRY(usb_ohci),
#endif
#if BX_SUPPORT_USB_UHCI
BUILTIN_PLUGIN_ENTRY(usb_uhci),
#if BX_SUPPORT_USB_EHCI
BUILTIN_PLUGIN_ENTRY(usb_ehci),
#endif
#if BX_SUPPORT_USB_XHCI
BUILTIN_PLUGIN_ENTRY(usb_xhci),

View File

@ -67,6 +67,7 @@ extern "C" {
#define BX_PLUGIN_USB_COMMON "usb_common"
#define BX_PLUGIN_USB_UHCI "usb_uhci"
#define BX_PLUGIN_USB_OHCI "usb_ohci"
#define BX_PLUGIN_USB_EHCI "usb_ehci"
#define BX_PLUGIN_USB_XHCI "usb_xhci"
#define BX_PLUGIN_PCIPNIC "pcipnic"
#define BX_PLUGIN_E1000 "e1000"
@ -396,6 +397,7 @@ DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(pcidev)
DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(usb_common)
DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(usb_uhci)
DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(usb_ohci)
DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(usb_ehci)
DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(usb_xhci)
DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(soundmod)
DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(sb16)