@@ -606,6 +606,7 @@ config ASPEED_SOC
select PMBUS
select MAX31785
select FSI_APB2OPB_ASPEED
+ select USB_UHCI_SYSBUS
config MPS2
bool
@@ -11,6 +11,10 @@ config USB_UHCI_PCI
depends on PCI
select USB_UHCI
+config USB_UHCI_SYSBUS
+ bool
+ select USB_UHCI
+
config USB_OHCI
bool
select USB
new file mode 100644
@@ -0,0 +1,100 @@
+/*
+ * QEMU USB UHCI Emulation
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 CodeSourcery
+ * Copyright (c) 2024 Red Hat, Inc.
+ *
+ * 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.1 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "hw/usb.h"
+#include "migration/vmstate.h"
+#include "hw/sysbus.h"
+#include "hw/qdev-dma.h"
+#include "hw/qdev-properties.h"
+#include "trace.h"
+#include "hcd-uhci.h"
+#include "hcd-uhci-sysbus.h"
+
+static void uhci_sysbus_reset(UHCIState *uhci)
+{
+ uhci_state_reset(uhci);
+}
+
+static void uhci_sysbus_realize(DeviceState *dev, Error **errp)
+{
+ UHCISysBusState *s = SYSBUS_UHCI(dev);
+ UHCIState *uhci = &s->uhci;
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ Error *err = NULL;
+
+ uhci->masterbus = s->masterbus;
+ uhci->firstport = s->firstport;
+ uhci->maxframes = s->maxframes;
+ uhci->frame_bandwidth = s->frame_bandwidth;
+ uhci->as = &address_space_memory;
+ uhci->uhci_reset = uhci_sysbus_reset;
+
+ usb_uhci_init(uhci, dev, &err);
+
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_init_irq(sbd, &uhci->irq);
+ sysbus_init_mmio(sbd, &uhci->mem);
+}
+
+static void uhci_sysbus_reset_sysbus(DeviceState *dev)
+{
+ UHCISysBusState *s = SYSBUS_UHCI(dev);
+ UHCIState *uhci = &s->uhci;
+
+ uhci_sysbus_reset(uhci);
+}
+
+static Property uhci_sysbus_properties[] = {
+ DEFINE_PROP_STRING("masterbus", UHCISysBusState, masterbus),
+ DEFINE_PROP_UINT32("firstport", UHCISysBusState, firstport, 0),
+ DEFINE_PROP_UINT32("bandwidth", UHCISysBusState, frame_bandwidth, 1280),
+ DEFINE_PROP_UINT32("maxframes", UHCISysBusState, maxframes, 128),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void uhci_sysbus_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = uhci_sysbus_realize;
+ set_bit(DEVICE_CATEGORY_USB, dc->categories);
+ dc->desc = "UHCI USB Controller";
+ device_class_set_props(dc, uhci_sysbus_properties);
+ dc->reset = uhci_sysbus_reset_sysbus;
+}
+
+static const TypeInfo uhci_sysbus_types[] = {
+ {
+ .name = TYPE_SYSBUS_UHCI,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(UHCISysBusState),
+ .class_init = uhci_sysbus_class_init,
+ },
+};
+
+DEFINE_TYPES(uhci_sysbus_types);
new file mode 100644
@@ -0,0 +1,23 @@
+#ifndef HW_USB_HCD_UHCI_SYSBUS_H
+#define HW_USB_HCD_UHCI_SYSBUS_H
+
+#include "hcd-uhci.h"
+
+#define TYPE_SYSBUS_UHCI "sysbus-uhci"
+
+OBJECT_DECLARE_SIMPLE_TYPE(UHCISysBusState, SYSBUS_UHCI)
+
+struct UHCISysBusState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+ UHCIState uhci;
+
+ char *masterbus;
+ uint32_t firstport;
+ uint32_t frame_bandwidth;
+ uint32_t maxframes;
+ uint32_t num_ports;
+};
+
+#endif /* HW_USB_HCD_UHCI_SYSBUS_H */
@@ -14,6 +14,7 @@ system_ss.add(when: 'CONFIG_USB', if_true: files(
# usb host adapters
system_ss.add(when: 'CONFIG_USB_UHCI', if_true: files('hcd-uhci.c'))
system_ss.add(when: 'CONFIG_USB_UHCI_PCI', if_true: files('hcd-uhci-pci.c'))
+system_ss.add(when: 'CONFIG_USB_UHCI_SYSBUS', if_true: files('hcd-uhci-sysbus.c'))
system_ss.add(when: 'CONFIG_USB_OHCI', if_true: files('hcd-ohci.c'))
system_ss.add(when: 'CONFIG_USB_OHCI_PCI', if_true: files('hcd-ohci-pci.c'))
system_ss.add(when: 'CONFIG_USB_OHCI_SYSBUS', if_true: files('hcd-ohci-sysbus.c'))
Signed-off-by: Guenter Roeck <linux@roeck-us.net> --- hw/arm/Kconfig | 1 + hw/usb/Kconfig | 4 ++ hw/usb/hcd-uhci-sysbus.c | 100 +++++++++++++++++++++++++++++++++++++++ hw/usb/hcd-uhci-sysbus.h | 23 +++++++++ hw/usb/meson.build | 1 + 5 files changed, 129 insertions(+) create mode 100644 hw/usb/hcd-uhci-sysbus.c create mode 100644 hw/usb/hcd-uhci-sysbus.h