* [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines
@ 2024-09-06 12:25 Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 1/8] usb/uhci: checkpatch cleanup Guenter Roeck
` (7 more replies)
0 siblings, 8 replies; 16+ messages in thread
From: Guenter Roeck @ 2024-09-06 12:25 UTC (permalink / raw)
To: qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm,
Guenter Roeck
Some machines (like Aspeed ARM) only support a sysbus UHCI controller.
The current UHCI implementation in qemu only supports PCI based UHCI
controllers.
This patch series separates basic and PCI functionality from the hcd-uhci
implementation and then adds uhci-sysbus support. This is then used
to implement and enable sysbus based UHCI support for Aspeed machines.
The series is submitted as RFC since I am quite sure that I didn't get
everything right. All code surrounding VMStates deserves special scrutiny,
as well as the changes outside hw/usb/ and hw/arm/.
A side effect of this patch series is that all Aspeed machines will now
instantiate UHCI, even if the machine does not actually support it
(it also always instantiates both EHCI ports, so that is not really
different). This means that the default USB bus is now the UHCI bus,
not the second EHCI bus. The bus number must therefore now be specified
explicitly when attaching a device unless attaching it to the UHCI port
is ok. I don't know if it is possible to avoid that and to ensure that
the default USB port is still the second EHCI port.
The code was tested on x86 machines to ensure that the existing UHCI
implementation still works. It was also tested on various Aspeed machines
with enabled UHCI ports (ast2500-evb, ast2600-evb, and rainier-bmc).
----------------------------------------------------------------
Guenter Roeck (8):
usb/uhci: checkpatch cleanup
usb/uhci: Introduce and use register defines
usb/uhci: Move PCI-related code into a separate file
usb/uhci: enlarge uhci memory space
usb/uhci: Add support for usb-uhci-sysbus
usb/uhci: Add aspeed specific read and write functions
aspeed: Add uhci support for ast2600
aspeed: Add uhci support for ast2400 and ast2500
hw/arm/Kconfig | 1 +
hw/arm/aspeed_ast2400.c | 14 ++
hw/arm/aspeed_ast2600.c | 13 ++
hw/isa/Kconfig | 4 +-
hw/isa/vt82c686.c | 4 +-
hw/usb/Kconfig | 10 +-
hw/usb/hcd-uhci-pci.c | 255 ++++++++++++++++++++++++++++++++
hw/usb/hcd-uhci-pci.h | 63 ++++++++
hw/usb/hcd-uhci-sysbus.c | 201 +++++++++++++++++++++++++
hw/usb/hcd-uhci-sysbus.h | 34 +++++
hw/usb/hcd-uhci.c | 337 +++++++++++++-----------------------------
hw/usb/hcd-uhci.h | 30 ++--
hw/usb/meson.build | 2 +
hw/usb/vt82c686-uhci-pci.c | 18 +--
include/hw/arm/aspeed_soc.h | 3 +
include/hw/southbridge/piix.h | 4 +-
include/hw/usb/uhci-regs.h | 11 ++
17 files changed, 737 insertions(+), 267 deletions(-)
create mode 100644 hw/usb/hcd-uhci-pci.c
create mode 100644 hw/usb/hcd-uhci-pci.h
create mode 100644 hw/usb/hcd-uhci-sysbus.c
create mode 100644 hw/usb/hcd-uhci-sysbus.h
^ permalink raw reply [flat|nested] 16+ messages in thread
* [RFC PATCH 1/8] usb/uhci: checkpatch cleanup
2024-09-06 12:25 [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines Guenter Roeck
@ 2024-09-06 12:25 ` Guenter Roeck
2024-09-09 7:48 ` Cédric Le Goater
2024-09-06 12:25 ` [RFC PATCH 2/8] usb/uhci: Introduce and use register defines Guenter Roeck
` (6 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Guenter Roeck @ 2024-09-06 12:25 UTC (permalink / raw)
To: qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm,
Guenter Roeck
Fix reported checkpatch issues to prepare for next patches
in the series.
No functional change.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
hw/usb/hcd-uhci.c | 90 +++++++++++++++++++++++++++++------------------
1 file changed, 56 insertions(+), 34 deletions(-)
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index a03cf22e69..dfcc3e05c0 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -67,7 +67,7 @@ struct UHCIPCIDeviceClass {
UHCIInfo info;
};
-/*
+/*
* Pending async transaction.
* 'packet' must be the first field because completion
* handler does "(UHCIAsync *) pkt" cast.
@@ -220,8 +220,9 @@ static void uhci_async_cancel(UHCIAsync *async)
uhci_async_unlink(async);
trace_usb_uhci_packet_cancel(async->queue->token, async->td_addr,
async->done);
- if (!async->done)
+ if (!async->done) {
usb_cancel_packet(&async->packet);
+ }
uhci_async_free(async);
}
@@ -322,7 +323,7 @@ static void uhci_reset(DeviceState *dev)
s->fl_base_addr = 0;
s->sof_timing = 64;
- for(i = 0; i < UHCI_PORTS; i++) {
+ for (i = 0; i < UHCI_PORTS; i++) {
port = &s->ports[i];
port->ctrl = 0x0080;
if (port->port.dev && port->port.dev->attached) {
@@ -387,7 +388,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
trace_usb_uhci_mmio_writew(addr, val);
- switch(addr) {
+ switch (addr) {
case 0x00:
if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
/* start frame processing */
@@ -404,7 +405,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
int i;
/* send reset on the USB bus */
- for(i = 0; i < UHCI_PORTS; i++) {
+ for (i = 0; i < UHCI_PORTS; i++) {
port = &s->ports[i];
usb_device_reset(port->port.dev);
}
@@ -425,10 +426,13 @@ static void uhci_port_write(void *opaque, hwaddr addr,
break;
case 0x02:
s->status &= ~val;
- /* XXX: the chip spec is not coherent, so we add a hidden
- register to distinguish between IOC and SPD */
- if (val & UHCI_STS_USBINT)
+ /*
+ * XXX: the chip spec is not coherent, so we add a hidden
+ * register to distinguish between IOC and SPD
+ */
+ if (val & UHCI_STS_USBINT) {
s->status2 = 0;
+ }
uhci_update_irq(s);
break;
case 0x04:
@@ -436,8 +440,9 @@ static void uhci_port_write(void *opaque, hwaddr addr,
uhci_update_irq(s);
break;
case 0x06:
- if (s->status & UHCI_STS_HCHALTED)
+ if (s->status & UHCI_STS_HCHALTED) {
s->frnum = val & 0x7ff;
+ }
break;
case 0x08:
s->fl_base_addr &= 0xffff0000;
@@ -464,8 +469,8 @@ static void uhci_port_write(void *opaque, hwaddr addr,
dev = port->port.dev;
if (dev && dev->attached) {
/* port reset */
- if ( (val & UHCI_PORT_RESET) &&
- !(port->ctrl & UHCI_PORT_RESET) ) {
+ if ((val & UHCI_PORT_RESET) &&
+ !(port->ctrl & UHCI_PORT_RESET)) {
usb_device_reset(dev);
}
}
@@ -487,7 +492,7 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, unsigned size)
UHCIState *s = opaque;
uint32_t val;
- switch(addr) {
+ switch (addr) {
case 0x00:
val = s->cmd;
break;
@@ -533,12 +538,13 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, unsigned size)
}
/* signal resume if controller suspended */
-static void uhci_resume (void *opaque)
+static void uhci_resume(void *opaque)
{
UHCIState *s = (UHCIState *)opaque;
- if (!s)
+ if (!s) {
return;
+ }
if (s->cmd & UHCI_CMD_EGSM) {
s->cmd |= UHCI_CMD_FGR;
@@ -674,7 +680,8 @@ static int uhci_handle_td_error(UHCIState *s, UHCI_TD *td, uint32_t td_addr,
return ret;
}
-static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_t *int_mask)
+static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async,
+ uint32_t *int_mask)
{
int len = 0, max_len;
uint8_t pid;
@@ -682,8 +689,9 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_
max_len = ((td->token >> 21) + 1) & 0x7ff;
pid = td->token & 0xff;
- if (td->ctrl & TD_CTRL_IOS)
+ if (td->ctrl & TD_CTRL_IOS) {
td->ctrl &= ~TD_CTRL_ACTIVE;
+ }
if (async->packet.status != USB_RET_SUCCESS) {
return uhci_handle_td_error(s, td, async->td_addr,
@@ -693,12 +701,15 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_
len = async->packet.actual_length;
td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
- /* The NAK bit may have been set by a previous frame, so clear it
- here. The docs are somewhat unclear, but win2k relies on this
- behavior. */
+ /*
+ * The NAK bit may have been set by a previous frame, so clear it
+ * here. The docs are somewhat unclear, but win2k relies on this
+ * behavior.
+ */
td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
- if (td->ctrl & TD_CTRL_IOC)
+ if (td->ctrl & TD_CTRL_IOC) {
*int_mask |= 0x01;
+ }
if (pid == USB_TOKEN_IN) {
pci_dma_write(&s->dev, td->buffer, async->buf, len);
@@ -780,9 +791,11 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
if (async) {
if (queuing) {
- /* we are busy filling the queue, we are not prepared
- to consume completed packages then, just leave them
- in async state */
+ /*
+ * we are busy filling the queue, we are not prepared
+ * to consume completed packages then, just leave them
+ * in async state
+ */
return TD_RESULT_ASYNC_CONT;
}
if (!async->done) {
@@ -832,7 +845,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
}
usb_packet_addbuf(&async->packet, async->buf, max_len);
- switch(pid) {
+ switch (pid) {
case USB_TOKEN_OUT:
case USB_TOKEN_SETUP:
pci_dma_read(&s->dev, td->buffer, async->buf, max_len);
@@ -911,12 +924,15 @@ static void qhdb_reset(QhDb *db)
static int qhdb_insert(QhDb *db, uint32_t addr)
{
int i;
- for (i = 0; i < db->count; i++)
- if (db->addr[i] == addr)
+ for (i = 0; i < db->count; i++) {
+ if (db->addr[i] == addr) {
return 1;
+ }
+ }
- if (db->count >= UHCI_MAX_QUEUES)
+ if (db->count >= UHCI_MAX_QUEUES) {
return 1;
+ }
db->addr[db->count++] = addr;
return 0;
@@ -970,8 +986,10 @@ static void uhci_process_frame(UHCIState *s)
for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) {
if (!s->completions_only && s->frame_bytes >= s->frame_bandwidth) {
- /* We've reached the usb 1.1 bandwidth, which is
- 1280 bytes/frame, stop processing */
+ /*
+ * We've reached the usb 1.1 bandwidth, which is
+ * 1280 bytes/frame, stop processing
+ */
trace_usb_uhci_frame_stop_bandwidth();
break;
}
@@ -1120,8 +1138,10 @@ static void uhci_frame_timer(void *opaque)
uhci_async_validate_begin(s);
uhci_process_frame(s);
uhci_async_validate_end(s);
- /* The spec says frnum is the frame currently being processed, and
- * the guest must look at frnum - 1 on interrupt, so inc frnum now */
+ /*
+ * The spec says frnum is the frame currently being processed, and
+ * the guest must look at frnum - 1 on interrupt, so inc frnum now
+ */
s->frnum = (s->frnum + 1) & 0x7ff;
s->expire_time += frame_t;
}
@@ -1174,7 +1194,7 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
if (s->masterbus) {
USBPort *ports[UHCI_PORTS];
- for(i = 0; i < UHCI_PORTS; i++) {
+ for (i = 0; i < UHCI_PORTS; i++) {
ports[i] = &s->ports[i].port;
}
usb_register_companion(s->masterbus, ports, UHCI_PORTS,
@@ -1200,8 +1220,10 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
memory_region_init_io(&s->io_bar, OBJECT(s), &uhci_ioport_ops, s,
"uhci", 0x20);
- /* Use region 4 for consistency with real hardware. BSD guests seem
- to rely on this. */
+ /*
+ * Use region 4 for consistency with real hardware. BSD guests seem
+ * to rely on this.
+ */
pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
}
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 2/8] usb/uhci: Introduce and use register defines
2024-09-06 12:25 [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 1/8] usb/uhci: checkpatch cleanup Guenter Roeck
@ 2024-09-06 12:25 ` Guenter Roeck
2024-09-09 7:48 ` Cédric Le Goater
2024-09-06 12:25 ` [RFC PATCH 3/8] usb/uhci: Move PCI-related code into a separate file Guenter Roeck
` (5 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Guenter Roeck @ 2024-09-06 12:25 UTC (permalink / raw)
To: qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm,
Guenter Roeck
Introduce defines for UHCI registers to simplify adding register access
in subsequent patches of the series.
No functional change.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
hw/usb/hcd-uhci.c | 32 ++++++++++++++++----------------
include/hw/usb/uhci-regs.h | 11 +++++++++++
2 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index dfcc3e05c0..8bc163f688 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -389,7 +389,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
trace_usb_uhci_mmio_writew(addr, val);
switch (addr) {
- case 0x00:
+ case UHCI_USBCMD:
if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
/* start frame processing */
trace_usb_uhci_schedule_start();
@@ -424,7 +424,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
}
}
break;
- case 0x02:
+ case UHCI_USBSTS:
s->status &= ~val;
/*
* XXX: the chip spec is not coherent, so we add a hidden
@@ -435,27 +435,27 @@ static void uhci_port_write(void *opaque, hwaddr addr,
}
uhci_update_irq(s);
break;
- case 0x04:
+ case UHCI_USBINTR:
s->intr = val;
uhci_update_irq(s);
break;
- case 0x06:
+ case UHCI_USBFRNUM:
if (s->status & UHCI_STS_HCHALTED) {
s->frnum = val & 0x7ff;
}
break;
- case 0x08:
+ case UHCI_USBFLBASEADD:
s->fl_base_addr &= 0xffff0000;
s->fl_base_addr |= val & ~0xfff;
break;
- case 0x0a:
+ case UHCI_USBFLBASEADD + 2:
s->fl_base_addr &= 0x0000ffff;
s->fl_base_addr |= (val << 16);
break;
- case 0x0c:
+ case UHCI_USBSOF:
s->sof_timing = val & 0xff;
break;
- case 0x10 ... 0x1f:
+ case UHCI_USBPORTSC1 ... UHCI_USBPORTSC4:
{
UHCIPort *port;
USBDevice *dev;
@@ -493,28 +493,28 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, unsigned size)
uint32_t val;
switch (addr) {
- case 0x00:
+ case UHCI_USBCMD:
val = s->cmd;
break;
- case 0x02:
+ case UHCI_USBSTS:
val = s->status;
break;
- case 0x04:
+ case UHCI_USBINTR:
val = s->intr;
break;
- case 0x06:
+ case UHCI_USBFRNUM:
val = s->frnum;
break;
- case 0x08:
+ case UHCI_USBFLBASEADD:
val = s->fl_base_addr & 0xffff;
break;
- case 0x0a:
+ case UHCI_USBFLBASEADD + 2:
val = (s->fl_base_addr >> 16) & 0xffff;
break;
- case 0x0c:
+ case UHCI_USBSOF:
val = s->sof_timing;
break;
- case 0x10 ... 0x1f:
+ case UHCI_USBPORTSC1 ... UHCI_USBPORTSC4:
{
UHCIPort *port;
int n;
diff --git a/include/hw/usb/uhci-regs.h b/include/hw/usb/uhci-regs.h
index fd45d29db0..5b81714e5c 100644
--- a/include/hw/usb/uhci-regs.h
+++ b/include/hw/usb/uhci-regs.h
@@ -1,6 +1,17 @@
#ifndef HW_USB_UHCI_REGS_H
#define HW_USB_UHCI_REGS_H
+#define UHCI_USBCMD 0
+#define UHCI_USBSTS 2
+#define UHCI_USBINTR 4
+#define UHCI_USBFRNUM 6
+#define UHCI_USBFLBASEADD 8
+#define UHCI_USBSOF 0x0c
+#define UHCI_USBPORTSC1 0x10
+#define UHCI_USBPORTSC2 0x12
+#define UHCI_USBPORTSC3 0x14
+#define UHCI_USBPORTSC4 0x16
+
#define UHCI_CMD_FGR (1 << 4)
#define UHCI_CMD_EGSM (1 << 3)
#define UHCI_CMD_GRESET (1 << 2)
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 3/8] usb/uhci: Move PCI-related code into a separate file
2024-09-06 12:25 [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 1/8] usb/uhci: checkpatch cleanup Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 2/8] usb/uhci: Introduce and use register defines Guenter Roeck
@ 2024-09-06 12:25 ` Guenter Roeck
2024-11-12 6:32 ` Thomas Huth
2024-09-06 12:25 ` [RFC PATCH 4/8] usb/uhci: enlarge uhci memory space Guenter Roeck
` (4 subsequent siblings)
7 siblings, 1 reply; 16+ messages in thread
From: Guenter Roeck @ 2024-09-06 12:25 UTC (permalink / raw)
To: qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm,
Guenter Roeck
Some machines (like Aspeed ARM) only have a sysbus UHCI controller.
The current UHCI implementation only supports PCI based UHCI controllers.
Move the UHCI-PCI device code into a separate file so that it is possible
to create a sysbus UHCI device without PCI dependency.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
hw/isa/Kconfig | 4 +-
hw/isa/vt82c686.c | 4 +-
hw/usb/Kconfig | 6 +-
hw/usb/hcd-uhci-pci.c | 255 ++++++++++++++++++++++++++++++++++
hw/usb/hcd-uhci-pci.h | 63 +++++++++
hw/usb/hcd-uhci.c | 221 +++++------------------------
hw/usb/hcd-uhci.h | 30 ++--
hw/usb/meson.build | 1 +
hw/usb/vt82c686-uhci-pci.c | 18 +--
include/hw/southbridge/piix.h | 4 +-
10 files changed, 386 insertions(+), 220 deletions(-)
create mode 100644 hw/usb/hcd-uhci-pci.c
create mode 100644 hw/usb/hcd-uhci-pci.h
diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 73c6470805..b0e536fad9 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -47,7 +47,7 @@ config PIIX
select IDE_PIIX
select ISA_BUS
select MC146818RTC
- select USB_UHCI
+ select USB_UHCI_PCI
config VT82C686
bool
@@ -55,7 +55,7 @@ config VT82C686
select ISA_SUPERIO
select ACPI
select ACPI_SMBUS
- select USB_UHCI
+ select USB_UHCI_PCI
select APM
select I8254
select I8257
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 505b44c4e6..de317b11cb 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -26,7 +26,7 @@
#include "hw/intc/i8259.h"
#include "hw/irq.h"
#include "hw/dma/i8257.h"
-#include "hw/usb/hcd-uhci.h"
+#include "hw/usb/hcd-uhci-pci.h"
#include "hw/timer/i8254.h"
#include "hw/rtc/mc146818rtc.h"
#include "migration/vmstate.h"
@@ -598,7 +598,7 @@ struct ViaISAState {
ViaSuperIOState via_sio;
MC146818RtcState rtc;
PCIIDEState ide;
- UHCIState uhci[2];
+ UHCIPCIState uhci[2];
ViaPMState pm;
ViaAC97State ac97;
PCIDevice mc97;
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index 84bc7fbe36..7d034738ce 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -2,10 +2,14 @@ config USB
bool
config USB_UHCI
+ bool
+ select USB
+
+config USB_UHCI_PCI
bool
default y if PCI_DEVICES
depends on PCI
- select USB
+ select USB_UHCI
config USB_OHCI
bool
diff --git a/hw/usb/hcd-uhci-pci.c b/hw/usb/hcd-uhci-pci.c
new file mode 100644
index 0000000000..4036fe9c27
--- /dev/null
+++ b/hw/usb/hcd-uhci-pci.c
@@ -0,0 +1,255 @@
+/*
+ * USB UHCI controller emulation
+ * PCI code
+ *
+ * Copyright (c) 2005 Fabrice Bellard
+ *
+ * Copyright (c) 2008 Max Krasnyansky
+ * Magor rewrite of the UHCI data structures parser and frame processor
+ * Support for fully async operation and multiple outstanding transactions
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/usb.h"
+#include "migration/vmstate.h"
+#include "hw/pci/pci.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+#include "qom/object.h"
+#include "hcd-uhci-pci.h"
+
+struct UHCIPCIDeviceClass {
+ PCIDeviceClass parent_class;
+ UHCIPCIInfo info;
+};
+
+static const VMStateDescription vmstate_uhci = {
+ .name = "pci_uhci",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_PCI_DEVICE(dev, UHCIPCIState),
+ VMSTATE_STRUCT(state, UHCIPCIState, 1, vmstate_uhci_state, UHCIState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void uhci_pci_reset(UHCIState *uhci)
+{
+ UHCIPCIState *pstate = container_of(uhci, UHCIPCIState, state);
+ PCIDevice *d = &pstate->dev;
+
+ d->config[0x6a] = 0x01; /* usb clock */
+ d->config[0x6b] = 0x00;
+
+ uhci_state_reset(uhci);
+}
+
+void usb_uhci_common_realize_pci(PCIDevice *dev, Error **errp)
+{
+ Error *err = NULL;
+ UHCIPCIDeviceClass *u = UHCI_PCI_GET_CLASS(dev);
+ UHCIPCIState *uhci = UHCI_PCI(dev);
+ UHCIState *s = &uhci->state;
+ uint8_t *pci_conf = dev->config;
+
+ pci_conf[PCI_CLASS_PROG] = 0x00;
+ /* TODO: reset value should be 0. */
+ pci_conf[USB_SBRN] = USB_RELEASE_1; /* release number */
+ pci_config_set_interrupt_pin(pci_conf, u->info.irq_pin + 1);
+
+ s->irq = pci_allocate_irq(dev);
+ s->masterbus = uhci->masterbus;
+ s->firstport = uhci->firstport;
+ s->maxframes = uhci->maxframes;
+ s->frame_bandwidth = uhci->frame_bandwidth;
+ s->as = pci_get_address_space(dev);
+ s->uhci_reset = uhci_pci_reset;
+
+ usb_uhci_init(s, DEVICE(dev), &err);
+
+ /*
+ * Use region 4 for consistency with real hardware. BSD guests seem
+ * to rely on this.
+ */
+ pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->mem);
+}
+
+static void uhci_pci_reset_pci(DeviceState *dev)
+{
+ PCIDevice *d = PCI_DEVICE(dev);
+ UHCIPCIState *uhci = UHCI_PCI(d);
+
+ uhci_pci_reset(&uhci->state);
+}
+
+static void usb_uhci_pci_exit(PCIDevice *dev)
+{
+ UHCIPCIState *uhci = UHCI_PCI(dev);
+ UHCIState *s = &uhci->state;
+
+ usb_uhci_exit(s);
+
+ qemu_free_irq(s->irq);
+}
+
+static Property uhci_properties_companion[] = {
+ DEFINE_PROP_STRING("masterbus", UHCIPCIState, masterbus),
+ DEFINE_PROP_UINT32("firstport", UHCIPCIState, firstport, 0),
+ DEFINE_PROP_UINT32("bandwidth", UHCIPCIState, frame_bandwidth, 1280),
+ DEFINE_PROP_UINT32("maxframes", UHCIPCIState, maxframes, 128),
+ DEFINE_PROP_END_OF_LIST(),
+};
+static Property uhci_properties_standalone[] = {
+ DEFINE_PROP_UINT32("bandwidth", UHCIPCIState, frame_bandwidth, 1280),
+ DEFINE_PROP_UINT32("maxframes", UHCIPCIState, maxframes, 128),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void uhci_pci_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+ k->class_id = PCI_CLASS_SERIAL_USB;
+ dc->vmsd = &vmstate_uhci;
+ dc->reset = uhci_pci_reset_pci;
+ set_bit(DEVICE_CATEGORY_USB, dc->categories);
+}
+
+static const TypeInfo uhci_pci_type_info = {
+ .name = TYPE_UHCI_PCI,
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(UHCIPCIState),
+ .class_size = sizeof(UHCIPCIDeviceClass),
+ .class_init = uhci_pci_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { },
+ },
+};
+
+void uhci_pci_data_class_init(ObjectClass *klass, void *data)
+{
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ UHCIPCIDeviceClass *u = UHCI_PCI_CLASS(klass);
+ UHCIPCIInfo *info = data;
+
+ k->realize = info->realize ? info->realize : usb_uhci_common_realize_pci;
+ k->exit = info->unplug ? usb_uhci_pci_exit : NULL;
+ k->vendor_id = info->vendor_id;
+ k->device_id = info->device_id;
+ k->revision = info->revision;
+ if (!info->unplug) {
+ /* uhci controllers in companion setups can't be hotplugged */
+ dc->hotpluggable = false;
+ device_class_set_props(dc, uhci_properties_companion);
+ } else {
+ device_class_set_props(dc, uhci_properties_standalone);
+ }
+ if (info->notuser) {
+ dc->user_creatable = false;
+ }
+ u->info = *info;
+}
+
+static UHCIPCIInfo uhci_pci_info[] = {
+ {
+ .name = TYPE_PIIX3_USB_UHCI,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371SB_2,
+ .revision = 0x01,
+ .irq_pin = 3,
+ .unplug = true,
+ },{
+ .name = TYPE_PIIX4_USB_UHCI,
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82371AB_2,
+ .revision = 0x01,
+ .irq_pin = 3,
+ .unplug = true,
+ },{
+ .name = TYPE_ICH9_USB_UHCI(1), /* 00:1d.0 */
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
+ .revision = 0x03,
+ .irq_pin = 0,
+ .unplug = false,
+ },{
+ .name = TYPE_ICH9_USB_UHCI(2), /* 00:1d.1 */
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
+ .revision = 0x03,
+ .irq_pin = 1,
+ .unplug = false,
+ },{
+ .name = TYPE_ICH9_USB_UHCI(3), /* 00:1d.2 */
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
+ .revision = 0x03,
+ .irq_pin = 2,
+ .unplug = false,
+ },{
+ .name = TYPE_ICH9_USB_UHCI(4), /* 00:1a.0 */
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI4,
+ .revision = 0x03,
+ .irq_pin = 0,
+ .unplug = false,
+ },{
+ .name = TYPE_ICH9_USB_UHCI(5), /* 00:1a.1 */
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI5,
+ .revision = 0x03,
+ .irq_pin = 1,
+ .unplug = false,
+ },{
+ .name = TYPE_ICH9_USB_UHCI(6), /* 00:1a.2 */
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI6,
+ .revision = 0x03,
+ .irq_pin = 2,
+ .unplug = false,
+ }
+};
+
+static void uhci_pci_register_types(void)
+{
+ TypeInfo type_info = {
+ .parent = TYPE_UHCI_PCI,
+ .class_init = uhci_pci_data_class_init,
+ };
+ int i;
+
+ type_register_static(&uhci_pci_type_info);
+
+ for (i = 0; i < ARRAY_SIZE(uhci_pci_info); i++) {
+ type_info.name = uhci_pci_info[i].name;
+ type_info.class_data = uhci_pci_info + i;
+ type_register(&type_info);
+ }
+}
+
+type_init(uhci_pci_register_types)
diff --git a/hw/usb/hcd-uhci-pci.h b/hw/usb/hcd-uhci-pci.h
new file mode 100644
index 0000000000..25d3e0eb97
--- /dev/null
+++ b/hw/usb/hcd-uhci-pci.h
@@ -0,0 +1,63 @@
+/*
+ * USB UHCI controller emulation
+ *
+ * Copyright (c) 2005 Fabrice Bellard
+ *
+ * Copyright (c) 2008 Max Krasnyansky
+ * Magor rewrite of the UHCI data structures parser and frame processor
+ * Support for fully async operation and multiple outstanding transactions
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef HW_USB_HCD_UHCI_PCI_H
+#define HW_USB_HCD_UHCI_PCI_H
+
+#include "hcd-uhci.h"
+
+#define TYPE_UHCI_PCI "pci-uhci"
+
+struct UHCIPCIState {
+ PCIDevice dev;
+ UHCIState state;
+
+ /* Properties */
+ char *masterbus;
+ uint32_t firstport;
+ uint32_t frame_bandwidth;
+ uint32_t maxframes;
+ uint32_t num_ports;
+};
+
+OBJECT_DECLARE_TYPE(UHCIPCIState, UHCIPCIDeviceClass, UHCI_PCI)
+
+typedef struct UHCIPCIInfo {
+ const char *name;
+ uint16_t vendor_id;
+ uint16_t device_id;
+ uint8_t revision;
+ uint8_t irq_pin;
+ void (*realize)(PCIDevice *dev, Error **errp);
+ bool unplug;
+ bool notuser; /* disallow user_creatable */
+} UHCIPCIInfo;
+
+void usb_uhci_common_realize_pci(PCIDevice *dev, Error **errp);
+void uhci_pci_data_class_init(ObjectClass *klass, void *data);
+
+#endif /* HW_USB_HCD_UHCI_PCI_H */
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 8bc163f688..68b72f8d3b 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -30,7 +30,6 @@
#include "hw/usb.h"
#include "hw/usb/uhci-regs.h"
#include "migration/vmstate.h"
-#include "hw/pci/pci.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
@@ -62,11 +61,6 @@ enum {
typedef struct UHCIAsync UHCIAsync;
-struct UHCIPCIDeviceClass {
- PCIDeviceClass parent_class;
- UHCIInfo info;
-};
-
/*
* Pending async transaction.
* 'packet' must be the first field because completion
@@ -302,20 +296,13 @@ static void uhci_update_irq(UHCIState *s)
qemu_set_irq(s->irq, level);
}
-static void uhci_reset(DeviceState *dev)
+void uhci_state_reset(UHCIState *s)
{
- PCIDevice *d = PCI_DEVICE(dev);
- UHCIState *s = UHCI(d);
- uint8_t *pci_conf;
int i;
UHCIPort *port;
trace_usb_uhci_reset();
- pci_conf = s->dev.config;
-
- pci_conf[0x6a] = 0x01; /* usb clock */
- pci_conf[0x6b] = 0x00;
s->cmd = 0;
s->status = UHCI_STS_HCHALTED;
s->status2 = 0;
@@ -336,6 +323,11 @@ static void uhci_reset(DeviceState *dev)
uhci_update_irq(s);
}
+static void uhci_reset(UHCIState *s)
+{
+ s->uhci_reset(s);
+}
+
static const VMStateDescription vmstate_uhci_port = {
.name = "uhci port",
.version_id = 1,
@@ -357,13 +349,12 @@ static int uhci_post_load(void *opaque, int version_id)
return 0;
}
-static const VMStateDescription vmstate_uhci = {
+const VMStateDescription vmstate_uhci_state = {
.name = "uhci",
- .version_id = 3,
+ .version_id = 4,
.minimum_version_id = 1,
.post_load = uhci_post_load,
.fields = (const VMStateField[]) {
- VMSTATE_PCI_DEVICE(dev, UHCIState),
VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState, NULL),
VMSTATE_STRUCT_ARRAY(ports, UHCIState, UHCI_PORTS, 1,
vmstate_uhci_port, UHCIPort),
@@ -409,11 +400,11 @@ static void uhci_port_write(void *opaque, hwaddr addr,
port = &s->ports[i];
usb_device_reset(port->port.dev);
}
- uhci_reset(DEVICE(s));
+ uhci_reset(s);
return;
}
if (val & UHCI_CMD_HCRESET) {
- uhci_reset(DEVICE(s));
+ uhci_reset(s);
return;
}
s->cmd = val;
@@ -628,9 +619,21 @@ static USBDevice *uhci_find_device(UHCIState *s, uint8_t addr)
return NULL;
}
+static void uhci_dma_read(UHCIState *s, dma_addr_t addr, void *buf,
+ dma_addr_t len)
+{
+ dma_memory_read(s->as, addr, buf, len, MEMTXATTRS_UNSPECIFIED);
+}
+
+static void uhci_dma_write(UHCIState *s, dma_addr_t addr, void *buf,
+ dma_addr_t len)
+{
+ dma_memory_write(s->as, addr, buf, len, MEMTXATTRS_UNSPECIFIED);
+}
+
static void uhci_read_td(UHCIState *s, UHCI_TD *td, uint32_t link)
{
- pci_dma_read(&s->dev, link & ~0xf, td, sizeof(*td));
+ uhci_dma_read(s, link & ~0xf, td, sizeof(*td));
le32_to_cpus(&td->link);
le32_to_cpus(&td->ctrl);
le32_to_cpus(&td->token);
@@ -712,7 +715,7 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async,
}
if (pid == USB_TOKEN_IN) {
- pci_dma_write(&s->dev, td->buffer, async->buf, len);
+ uhci_dma_write(s, td->buffer, async->buf, len);
if ((td->ctrl & TD_CTRL_SPD) && len < max_len) {
*int_mask |= 0x02;
/* short packet: do not update QH */
@@ -848,7 +851,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
switch (pid) {
case USB_TOKEN_OUT:
case USB_TOKEN_SETUP:
- pci_dma_read(&s->dev, td->buffer, async->buf, max_len);
+ uhci_dma_read(s, td->buffer, async->buf, max_len);
usb_handle_packet(q->ep->dev, &async->packet);
if (async->packet.status == USB_RET_SUCCESS) {
async->packet.actual_length = max_len;
@@ -976,7 +979,7 @@ static void uhci_process_frame(UHCIState *s)
frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
- pci_dma_read(&s->dev, frame_addr, &link, 4);
+ uhci_dma_read(s, frame_addr, &link, 4);
le32_to_cpus(&link);
int_mask = 0;
@@ -1016,7 +1019,7 @@ static void uhci_process_frame(UHCIState *s)
}
}
- pci_dma_read(&s->dev, link & ~0xf, &qh, sizeof(qh));
+ uhci_dma_read(s, link & ~0xf, &qh, sizeof(qh));
le32_to_cpus(&qh.link);
le32_to_cpus(&qh.el_link);
@@ -1041,7 +1044,7 @@ static void uhci_process_frame(UHCIState *s)
if (old_td_ctrl != td.ctrl) {
/* update the status bits of the TD */
val = cpu_to_le32(td.ctrl);
- pci_dma_write(&s->dev, (link & ~0xf) + 4, &val, sizeof(val));
+ uhci_dma_write(s, (link & ~0xf) + 4, &val, sizeof(val));
}
switch (ret) {
@@ -1069,7 +1072,7 @@ static void uhci_process_frame(UHCIState *s)
/* update QH element link */
qh.el_link = link;
val = cpu_to_le32(qh.el_link);
- pci_dma_write(&s->dev, (curr_qh & ~0xf) + 4, &val, sizeof(val));
+ uhci_dma_write(s, (curr_qh & ~0xf) + 4, &val, sizeof(val));
if (!depth_first(link)) {
/* done with this QH */
@@ -1178,20 +1181,11 @@ static USBPortOps uhci_port_ops = {
static USBBusOps uhci_bus_ops = {
};
-void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
+void usb_uhci_init(UHCIState *s, DeviceState *dev, Error **errp)
{
Error *err = NULL;
- UHCIPCIDeviceClass *u = UHCI_GET_CLASS(dev);
- UHCIState *s = UHCI(dev);
- uint8_t *pci_conf = s->dev.config;
int i;
- pci_conf[PCI_CLASS_PROG] = 0x00;
- /* TODO: reset value should be 0. */
- pci_conf[USB_SBRN] = USB_RELEASE_1; /* release number */
- pci_config_set_interrupt_pin(pci_conf, u->info.irq_pin + 1);
- s->irq = pci_allocate_irq(dev);
-
if (s->masterbus) {
USBPort *ports[UHCI_PORTS];
for (i = 0; i < UHCI_PORTS; i++) {
@@ -1212,25 +1206,17 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
}
}
- s->bh = qemu_bh_new_guarded(uhci_bh, s, &DEVICE(dev)->mem_reentrancy_guard);
+ s->bh = qemu_bh_new_guarded(uhci_bh, s, &dev->mem_reentrancy_guard);
s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uhci_frame_timer, s);
s->num_ports_vmstate = UHCI_PORTS;
QTAILQ_INIT(&s->queues);
- memory_region_init_io(&s->io_bar, OBJECT(s), &uhci_ioport_ops, s,
+ memory_region_init_io(&s->mem, OBJECT(s), &uhci_ioport_ops, s,
"uhci", 0x20);
-
- /*
- * Use region 4 for consistency with real hardware. BSD guests seem
- * to rely on this.
- */
- pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
}
-static void usb_uhci_exit(PCIDevice *dev)
+void usb_uhci_exit(UHCIState *s)
{
- UHCIState *s = UHCI(dev);
-
trace_usb_uhci_exit();
if (s->frame_timer) {
@@ -1248,144 +1234,3 @@ static void usb_uhci_exit(PCIDevice *dev)
usb_bus_release(&s->bus);
}
}
-
-static Property uhci_properties_companion[] = {
- DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
- DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
- DEFINE_PROP_UINT32("bandwidth", UHCIState, frame_bandwidth, 1280),
- DEFINE_PROP_UINT32("maxframes", UHCIState, maxframes, 128),
- DEFINE_PROP_END_OF_LIST(),
-};
-static Property uhci_properties_standalone[] = {
- DEFINE_PROP_UINT32("bandwidth", UHCIState, frame_bandwidth, 1280),
- DEFINE_PROP_UINT32("maxframes", UHCIState, maxframes, 128),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void uhci_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
- k->class_id = PCI_CLASS_SERIAL_USB;
- dc->vmsd = &vmstate_uhci;
- dc->reset = uhci_reset;
- set_bit(DEVICE_CATEGORY_USB, dc->categories);
-}
-
-static const TypeInfo uhci_pci_type_info = {
- .name = TYPE_UHCI,
- .parent = TYPE_PCI_DEVICE,
- .instance_size = sizeof(UHCIState),
- .class_size = sizeof(UHCIPCIDeviceClass),
- .abstract = true,
- .class_init = uhci_class_init,
- .interfaces = (InterfaceInfo[]) {
- { INTERFACE_CONVENTIONAL_PCI_DEVICE },
- { },
- },
-};
-
-void uhci_data_class_init(ObjectClass *klass, void *data)
-{
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- DeviceClass *dc = DEVICE_CLASS(klass);
- UHCIPCIDeviceClass *u = UHCI_CLASS(klass);
- UHCIInfo *info = data;
-
- k->realize = info->realize ? info->realize : usb_uhci_common_realize;
- k->exit = info->unplug ? usb_uhci_exit : NULL;
- k->vendor_id = info->vendor_id;
- k->device_id = info->device_id;
- k->revision = info->revision;
- if (!info->unplug) {
- /* uhci controllers in companion setups can't be hotplugged */
- dc->hotpluggable = false;
- device_class_set_props(dc, uhci_properties_companion);
- } else {
- device_class_set_props(dc, uhci_properties_standalone);
- }
- if (info->notuser) {
- dc->user_creatable = false;
- }
- u->info = *info;
-}
-
-static UHCIInfo uhci_info[] = {
- {
- .name = TYPE_PIIX3_USB_UHCI,
- .vendor_id = PCI_VENDOR_ID_INTEL,
- .device_id = PCI_DEVICE_ID_INTEL_82371SB_2,
- .revision = 0x01,
- .irq_pin = 3,
- .unplug = true,
- },{
- .name = TYPE_PIIX4_USB_UHCI,
- .vendor_id = PCI_VENDOR_ID_INTEL,
- .device_id = PCI_DEVICE_ID_INTEL_82371AB_2,
- .revision = 0x01,
- .irq_pin = 3,
- .unplug = true,
- },{
- .name = TYPE_ICH9_USB_UHCI(1), /* 00:1d.0 */
- .vendor_id = PCI_VENDOR_ID_INTEL,
- .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
- .revision = 0x03,
- .irq_pin = 0,
- .unplug = false,
- },{
- .name = TYPE_ICH9_USB_UHCI(2), /* 00:1d.1 */
- .vendor_id = PCI_VENDOR_ID_INTEL,
- .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
- .revision = 0x03,
- .irq_pin = 1,
- .unplug = false,
- },{
- .name = TYPE_ICH9_USB_UHCI(3), /* 00:1d.2 */
- .vendor_id = PCI_VENDOR_ID_INTEL,
- .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
- .revision = 0x03,
- .irq_pin = 2,
- .unplug = false,
- },{
- .name = TYPE_ICH9_USB_UHCI(4), /* 00:1a.0 */
- .vendor_id = PCI_VENDOR_ID_INTEL,
- .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI4,
- .revision = 0x03,
- .irq_pin = 0,
- .unplug = false,
- },{
- .name = TYPE_ICH9_USB_UHCI(5), /* 00:1a.1 */
- .vendor_id = PCI_VENDOR_ID_INTEL,
- .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI5,
- .revision = 0x03,
- .irq_pin = 1,
- .unplug = false,
- },{
- .name = TYPE_ICH9_USB_UHCI(6), /* 00:1a.2 */
- .vendor_id = PCI_VENDOR_ID_INTEL,
- .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI6,
- .revision = 0x03,
- .irq_pin = 2,
- .unplug = false,
- }
-};
-
-static void uhci_register_types(void)
-{
- TypeInfo uhci_type_info = {
- .parent = TYPE_UHCI,
- .class_init = uhci_data_class_init,
- };
- int i;
-
- type_register_static(&uhci_pci_type_info);
-
- for (i = 0; i < ARRAY_SIZE(uhci_info); i++) {
- uhci_type_info.name = uhci_info[i].name;
- uhci_type_info.class_data = uhci_info + i;
- type_register(&uhci_type_info);
- }
-}
-
-type_init(uhci_register_types)
diff --git a/hw/usb/hcd-uhci.h b/hw/usb/hcd-uhci.h
index 6d26b94e92..1ffa93f703 100644
--- a/hw/usb/hcd-uhci.h
+++ b/hw/usb/hcd-uhci.h
@@ -32,6 +32,7 @@
#include "qemu/timer.h"
#include "hw/pci/pci_device.h"
#include "hw/usb.h"
+#include "hw/sysbus.h"
typedef struct UHCIQueue UHCIQueue;
@@ -42,9 +43,12 @@ typedef struct UHCIPort {
uint16_t ctrl;
} UHCIPort;
-typedef struct UHCIState {
- PCIDevice dev;
- MemoryRegion io_bar;
+typedef struct UHCIState UHCIState;
+
+struct UHCIState {
+ MemoryRegion mem;
+ AddressSpace *as;
+ void (*uhci_reset)(UHCIState *);
USBBus bus; /* Note unused when we're a companion controller */
uint16_t cmd; /* cmd register */
uint16_t status;
@@ -72,24 +76,18 @@ typedef struct UHCIState {
char *masterbus;
uint32_t firstport;
uint32_t maxframes;
-} UHCIState;
+};
-#define TYPE_UHCI "pci-uhci-usb"
-OBJECT_DECLARE_TYPE(UHCIState, UHCIPCIDeviceClass, UHCI)
+#define TYPE_UHCI "uhci-usb"
+OBJECT_DECLARE_TYPE(UHCIState, UHCIDeviceClass, UHCI)
-typedef struct UHCIInfo {
- const char *name;
- uint16_t vendor_id;
- uint16_t device_id;
- uint8_t revision;
- uint8_t irq_pin;
- void (*realize)(PCIDevice *dev, Error **errp);
- bool unplug;
- bool notuser; /* disallow user_creatable */
-} UHCIInfo;
+extern const VMStateDescription vmstate_uhci_state;
void uhci_data_class_init(ObjectClass *klass, void *data);
void usb_uhci_common_realize(PCIDevice *dev, Error **errp);
+void usb_uhci_init(UHCIState *s, DeviceState *dev, Error **errp);
+void uhci_state_reset(UHCIState *s);
+void usb_uhci_exit(UHCIState *s);
#define TYPE_PIIX3_USB_UHCI "piix3-usb-uhci"
#define TYPE_PIIX4_USB_UHCI "piix4-usb-uhci"
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
index d7de1003e3..a41b54ac02 100644
--- a/hw/usb/meson.build
+++ b/hw/usb/meson.build
@@ -13,6 +13,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_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'))
diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c
index 6162806172..7fdb4697f9 100644
--- a/hw/usb/vt82c686-uhci-pci.c
+++ b/hw/usb/vt82c686-uhci-pci.c
@@ -1,17 +1,17 @@
#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/isa/vt82c686.h"
-#include "hcd-uhci.h"
+#include "hcd-uhci-pci.h"
static void uhci_isa_set_irq(void *opaque, int irq_num, int level)
{
- UHCIState *s = opaque;
+ UHCIPCIState *s = opaque;
via_isa_set_irq(&s->dev, 0, level);
}
static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
{
- UHCIState *s = UHCI(dev);
+ UHCIPCIState *s = UHCI_PCI(dev);
uint8_t *pci_conf = s->dev.config;
/* USB misc control 1/2 */
@@ -21,12 +21,12 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
/* USB legacy support */
pci_set_long(pci_conf + 0xc0, 0x00002000);
- usb_uhci_common_realize(dev, errp);
- object_unref(s->irq);
- s->irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
+ usb_uhci_common_realize_pci(dev, errp);
+ object_unref(s->state.irq);
+ s->state.irq = qemu_allocate_irq(uhci_isa_set_irq, &s->state, 0);
}
-static UHCIInfo uhci_info[] = {
+static UHCIPCIInfo uhci_info[] = {
{
.name = TYPE_VT82C686B_USB_UHCI,
.vendor_id = PCI_VENDOR_ID_VIA,
@@ -41,9 +41,9 @@ static UHCIInfo uhci_info[] = {
};
static const TypeInfo vt82c686b_usb_uhci_type_info = {
- .parent = TYPE_UHCI,
+ .parent = TYPE_UHCI_PCI,
.name = TYPE_VT82C686B_USB_UHCI,
- .class_init = uhci_data_class_init,
+ .class_init = uhci_pci_data_class_init,
.class_data = uhci_info,
};
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 86709ba2e4..ceb05548fe 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -16,7 +16,7 @@
#include "hw/acpi/piix4.h"
#include "hw/ide/pci.h"
#include "hw/rtc/mc146818rtc.h"
-#include "hw/usb/hcd-uhci.h"
+#include "hw/usb/hcd-uhci-pci.h"
/* PIRQRC[A:D]: PIRQx Route Control Registers */
#define PIIX_PIRQCA 0x60
@@ -57,7 +57,7 @@ struct PIIXState {
MC146818RtcState rtc;
PCIIDEState ide;
- UHCIState uhci;
+ UHCIPCIState uhci;
PIIX4PMState pm;
uint32_t smb_io_base;
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 4/8] usb/uhci: enlarge uhci memory space
2024-09-06 12:25 [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines Guenter Roeck
` (2 preceding siblings ...)
2024-09-06 12:25 ` [RFC PATCH 3/8] usb/uhci: Move PCI-related code into a separate file Guenter Roeck
@ 2024-09-06 12:25 ` Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 5/8] usb/uhci: Add support for usb-uhci-sysbus Guenter Roeck
` (3 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Guenter Roeck @ 2024-09-06 12:25 UTC (permalink / raw)
To: qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm,
Guenter Roeck
hcd-uhci-sysbus will require more memory than hcd-uhci-pci
since registers for some hardware (specifically Aspeed) don't
map 1:1.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
hw/usb/hcd-uhci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 68b72f8d3b..d2993a98b8 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1212,7 +1212,7 @@ void usb_uhci_init(UHCIState *s, DeviceState *dev, Error **errp)
QTAILQ_INIT(&s->queues);
memory_region_init_io(&s->mem, OBJECT(s), &uhci_ioport_ops, s,
- "uhci", 0x20);
+ "uhci", 0x100);
}
void usb_uhci_exit(UHCIState *s)
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 5/8] usb/uhci: Add support for usb-uhci-sysbus
2024-09-06 12:25 [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines Guenter Roeck
` (3 preceding siblings ...)
2024-09-06 12:25 ` [RFC PATCH 4/8] usb/uhci: enlarge uhci memory space Guenter Roeck
@ 2024-09-06 12:25 ` Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 6/8] usb/uhci: Add aspeed specific read and write functions Guenter Roeck
` (2 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Guenter Roeck @ 2024-09-06 12:25 UTC (permalink / raw)
To: qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm,
Guenter Roeck
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
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 1ad60da7aa..8b1253fae5 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -606,6 +606,7 @@ config ASPEED_SOC
select PMBUS
select MAX31785
select FSI_APB2OPB_ASPEED
+ select USB_UHCI_SYSBUS
config MPS2
bool
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index 7d034738ce..fe5375050c 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -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
diff --git a/hw/usb/hcd-uhci-sysbus.c b/hw/usb/hcd-uhci-sysbus.c
new file mode 100644
index 0000000000..6f2428cc15
--- /dev/null
+++ b/hw/usb/hcd-uhci-sysbus.c
@@ -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);
diff --git a/hw/usb/hcd-uhci-sysbus.h b/hw/usb/hcd-uhci-sysbus.h
new file mode 100644
index 0000000000..c491b9fc92
--- /dev/null
+++ b/hw/usb/hcd-uhci-sysbus.h
@@ -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 */
diff --git a/hw/usb/meson.build b/hw/usb/meson.build
index a41b54ac02..b0dd4b5169 100644
--- a/hw/usb/meson.build
+++ b/hw/usb/meson.build
@@ -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'))
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 6/8] usb/uhci: Add aspeed specific read and write functions
2024-09-06 12:25 [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines Guenter Roeck
` (4 preceding siblings ...)
2024-09-06 12:25 ` [RFC PATCH 5/8] usb/uhci: Add support for usb-uhci-sysbus Guenter Roeck
@ 2024-09-06 12:25 ` Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 7/8] aspeed: Add uhci support for ast2600 Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 8/8] aspeed: Add uhci support for ast2400 and ast2500 Guenter Roeck
7 siblings, 0 replies; 16+ messages in thread
From: Guenter Roeck @ 2024-09-06 12:25 UTC (permalink / raw)
To: qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm,
Guenter Roeck
Aspeed uses non-standard UHCI register addresses. On top of that,
registers are 32 bit wide instead of 16 bit.
Map Aspeed UHCI addresses to standard UHCI addresses and where needed
combine/split 32 bit accesses to solve the problem.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
hw/usb/hcd-uhci-sysbus.c | 101 +++++++++++++++++++++++++++++++++++++++
hw/usb/hcd-uhci-sysbus.h | 11 +++++
2 files changed, 112 insertions(+)
diff --git a/hw/usb/hcd-uhci-sysbus.c b/hw/usb/hcd-uhci-sysbus.c
index 6f2428cc15..ba5398beeb 100644
--- a/hw/usb/hcd-uhci-sysbus.c
+++ b/hw/usb/hcd-uhci-sysbus.c
@@ -20,7 +20,9 @@
#include "qemu/osdep.h"
#include "hw/irq.h"
+#include "hw/usb/uhci-regs.h"
#include "qapi/error.h"
+#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "hw/usb.h"
@@ -88,6 +90,99 @@ static void uhci_sysbus_class_init(ObjectClass *klass, void *data)
dc->reset = uhci_sysbus_reset_sysbus;
}
+static hwaddr aspeed_uhci_chip_to_uhci(hwaddr addr)
+{
+ switch (addr) {
+ case 0x00:
+ return UHCI_USBCMD;
+ case 0x04:
+ return UHCI_USBSTS;
+ case 0x08:
+ return UHCI_USBINTR;
+ case 0x0c:
+ return UHCI_USBFLBASEADD;
+ case 0x80:
+ return UHCI_USBFRNUM;
+ case 0x84:
+ return UHCI_USBSOF;
+ case 0x88:
+ return UHCI_USBPORTSC1;
+ case 0x8c:
+ return UHCI_USBPORTSC2;
+ case 0x90:
+ return UHCI_USBPORTSC3;
+ case 0x94:
+ return UHCI_USBPORTSC4;
+ default: /* unimplemented */
+ qemu_log_mask(LOG_UNIMP, "Unimplemented Aspeed UHCI register 0x%lx\n",
+ addr);
+ return 0x20;
+ }
+}
+
+/*
+ * Aspeed UHCI registers are 32 bit wide.
+ * Convert to 16 bit to access standard UHCI code.
+ */
+static uint64_t aspeed_uhci_port_read(void *opaque, hwaddr addr, unsigned size)
+{
+ UHCIState *uhci = opaque;
+ MemoryRegion *mr = &uhci->mem;
+ hwaddr uaddr = aspeed_uhci_chip_to_uhci(addr);
+
+ if (uaddr == UHCI_USBFLBASEADD) {
+ return mr->ops->read(opaque, uaddr, 2) |
+ mr->ops->read(opaque, uaddr + 2, 2) << 16;
+ }
+ return mr->ops->read(opaque, uaddr, 2);
+}
+
+static void aspeed_uhci_port_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned size)
+{
+ UHCIState *uhci = opaque;
+ MemoryRegion *mr = &uhci->mem;
+ hwaddr uaddr = aspeed_uhci_chip_to_uhci(addr);
+
+ if (uaddr == UHCI_USBFLBASEADD) {
+ mr->ops->write(opaque, uaddr, val & 0xffff, 2);
+ mr->ops->write(opaque, uaddr + 2, val >> 16, 2);
+ } else {
+ mr->ops->write(opaque, uaddr, val, 2);
+ }
+}
+
+static const MemoryRegionOps aspeed_uhci_mmio_ops = {
+ .read = aspeed_uhci_port_read,
+ .write = aspeed_uhci_port_write,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void uhci_sysbus_aspeed_realize(DeviceState *dev, Error **errp)
+{
+ UHCISysBusState *s = SYSBUS_UHCI(dev);
+ ASPEEDUHCIState *f = ASPEED_UHCI(dev);
+ UHCIState *uhci = &s->uhci;
+
+ uhci_sysbus_realize(dev, errp);
+
+ memory_region_init_io(&f->mem_aspeed, OBJECT(f), &aspeed_uhci_mmio_ops,
+ uhci, "aspeed", 0x100);
+ memory_region_add_subregion(&uhci->mem, 0, &f->mem_aspeed);
+}
+
+static void uhci_sysbus_aspeed_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = uhci_sysbus_aspeed_realize;
+ set_bit(DEVICE_CATEGORY_USB, dc->categories);
+ dc->desc = "ASPEED UHCI USB Controller";
+ dc->reset = uhci_sysbus_reset_sysbus;
+}
+
static const TypeInfo uhci_sysbus_types[] = {
{
.name = TYPE_SYSBUS_UHCI,
@@ -95,6 +190,12 @@ static const TypeInfo uhci_sysbus_types[] = {
.instance_size = sizeof(UHCISysBusState),
.class_init = uhci_sysbus_class_init,
},
+ {
+ .name = TYPE_ASPEED_UHCI,
+ .parent = TYPE_SYSBUS_UHCI,
+ .instance_size = sizeof(ASPEEDUHCIState),
+ .class_init = uhci_sysbus_aspeed_class_init,
+ },
};
DEFINE_TYPES(uhci_sysbus_types);
diff --git a/hw/usb/hcd-uhci-sysbus.h b/hw/usb/hcd-uhci-sysbus.h
index c491b9fc92..75c4716c40 100644
--- a/hw/usb/hcd-uhci-sysbus.h
+++ b/hw/usb/hcd-uhci-sysbus.h
@@ -4,6 +4,7 @@
#include "hcd-uhci.h"
#define TYPE_SYSBUS_UHCI "sysbus-uhci"
+#define TYPE_ASPEED_UHCI "aspeed-uhci"
OBJECT_DECLARE_SIMPLE_TYPE(UHCISysBusState, SYSBUS_UHCI)
@@ -20,4 +21,14 @@ struct UHCISysBusState {
uint32_t num_ports;
};
+OBJECT_DECLARE_SIMPLE_TYPE(ASPEEDUHCIState, ASPEED_UHCI)
+
+struct ASPEEDUHCIState {
+ /*< private >*/
+ UHCISysBusState parent_obj;
+ /*< public >*/
+
+ MemoryRegion mem_aspeed;
+};
+
#endif /* HW_USB_HCD_UHCI_SYSBUS_H */
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 7/8] aspeed: Add uhci support for ast2600
2024-09-06 12:25 [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines Guenter Roeck
` (5 preceding siblings ...)
2024-09-06 12:25 ` [RFC PATCH 6/8] usb/uhci: Add aspeed specific read and write functions Guenter Roeck
@ 2024-09-06 12:25 ` Guenter Roeck
2024-09-09 7:49 ` Cédric Le Goater
2024-09-06 12:25 ` [RFC PATCH 8/8] aspeed: Add uhci support for ast2400 and ast2500 Guenter Roeck
7 siblings, 1 reply; 16+ messages in thread
From: Guenter Roeck @ 2024-09-06 12:25 UTC (permalink / raw)
To: qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm,
Guenter Roeck
Enable UHCO support for the ast2600 SoC. With this patch, the UHCI port
is successfully instantiated on the rainier-bmc and ast2600-evb machines.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
hw/arm/aspeed_ast2600.c | 13 +++++++++++++
include/hw/arm/aspeed_soc.h | 3 +++
2 files changed, 16 insertions(+)
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index be3eb70cdd..cd7e4ae6c9 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -33,6 +33,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
[ASPEED_DEV_SPI2] = 0x1E631000,
[ASPEED_DEV_EHCI1] = 0x1E6A1000,
[ASPEED_DEV_EHCI2] = 0x1E6A3000,
+ [ASPEED_DEV_UHCI] = 0x1E6B0000,
[ASPEED_DEV_MII1] = 0x1E650000,
[ASPEED_DEV_MII2] = 0x1E650008,
[ASPEED_DEV_MII3] = 0x1E650010,
@@ -110,6 +111,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
[ASPEED_DEV_SDHCI] = 43,
[ASPEED_DEV_EHCI1] = 5,
[ASPEED_DEV_EHCI2] = 9,
+ [ASPEED_DEV_UHCI] = 10,
[ASPEED_DEV_EMMC] = 15,
[ASPEED_DEV_GPIO] = 40,
[ASPEED_DEV_GPIO_1_8V] = 11,
@@ -206,6 +208,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
TYPE_PLATFORM_EHCI);
}
+ object_initialize_child(obj, "uhci", &s->uhci, TYPE_ASPEED_UHCI);
+
snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
object_initialize_child(obj, "sdmc", &s->sdmc, typename);
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
@@ -481,6 +485,15 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
}
+ /* UHCI */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->uhci), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->uhci), 0,
+ sc->memmap[ASPEED_DEV_UHCI]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uhci), 0,
+ aspeed_soc_get_irq(s, ASPEED_DEV_UHCI));
+
/* SDMC - SDRAM Memory Controller */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
return;
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 624d489e0d..b54849db72 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -34,6 +34,7 @@
#include "hw/gpio/aspeed_gpio.h"
#include "hw/sd/aspeed_sdhci.h"
#include "hw/usb/hcd-ehci.h"
+#include "hw/usb/hcd-uhci-sysbus.h"
#include "qom/object.h"
#include "hw/misc/aspeed_lpc.h"
#include "hw/misc/unimp.h"
@@ -72,6 +73,7 @@ struct AspeedSoCState {
AspeedSMCState fmc;
AspeedSMCState spi[ASPEED_SPIS_NUM];
EHCISysBusState ehci[ASPEED_EHCIS_NUM];
+ ASPEEDUHCIState uhci;
AspeedSBCState sbc;
AspeedSLIState sli;
AspeedSLIState sliio;
@@ -193,6 +195,7 @@ enum {
ASPEED_DEV_SPI2,
ASPEED_DEV_EHCI1,
ASPEED_DEV_EHCI2,
+ ASPEED_DEV_UHCI,
ASPEED_DEV_VIC,
ASPEED_DEV_INTC,
ASPEED_DEV_SDMC,
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [RFC PATCH 8/8] aspeed: Add uhci support for ast2400 and ast2500
2024-09-06 12:25 [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines Guenter Roeck
` (6 preceding siblings ...)
2024-09-06 12:25 ` [RFC PATCH 7/8] aspeed: Add uhci support for ast2600 Guenter Roeck
@ 2024-09-06 12:25 ` Guenter Roeck
2024-09-09 7:49 ` Cédric Le Goater
7 siblings, 1 reply; 16+ messages in thread
From: Guenter Roeck @ 2024-09-06 12:25 UTC (permalink / raw)
To: qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm,
Guenter Roeck
Enable UHCI support for ast2400 and ast2500 SoCs. With this patch,
the UHCI port is successfully instantiated on the ast2500-evb machine.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
hw/arm/aspeed_ast2400.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/hw/arm/aspeed_ast2400.c b/hw/arm/aspeed_ast2400.c
index d125886207..93bfe3e3dd 100644
--- a/hw/arm/aspeed_ast2400.c
+++ b/hw/arm/aspeed_ast2400.c
@@ -31,6 +31,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
[ASPEED_DEV_FMC] = 0x1E620000,
[ASPEED_DEV_SPI1] = 0x1E630000,
[ASPEED_DEV_EHCI1] = 0x1E6A1000,
+ [ASPEED_DEV_UHCI] = 0x1E6B0000,
[ASPEED_DEV_VIC] = 0x1E6C0000,
[ASPEED_DEV_SDMC] = 0x1E6E0000,
[ASPEED_DEV_SCU] = 0x1E6E2000,
@@ -68,6 +69,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
[ASPEED_DEV_SPI2] = 0x1E631000,
[ASPEED_DEV_EHCI1] = 0x1E6A1000,
[ASPEED_DEV_EHCI2] = 0x1E6A3000,
+ [ASPEED_DEV_UHCI] = 0x1E6B0000,
[ASPEED_DEV_VIC] = 0x1E6C0000,
[ASPEED_DEV_SDMC] = 0x1E6E0000,
[ASPEED_DEV_SCU] = 0x1E6E2000,
@@ -107,6 +109,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
[ASPEED_DEV_FMC] = 19,
[ASPEED_DEV_EHCI1] = 5,
[ASPEED_DEV_EHCI2] = 13,
+ [ASPEED_DEV_UHCI] = 14,
[ASPEED_DEV_SDMC] = 0,
[ASPEED_DEV_SCU] = 21,
[ASPEED_DEV_ADC] = 31,
@@ -199,6 +202,8 @@ static void aspeed_ast2400_soc_init(Object *obj)
TYPE_PLATFORM_EHCI);
}
+ object_initialize_child(obj, "uhci", &s->uhci, TYPE_ASPEED_UHCI);
+
snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
object_initialize_child(obj, "sdmc", &s->sdmc, typename);
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
@@ -393,6 +398,15 @@ static void aspeed_ast2400_soc_realize(DeviceState *dev, Error **errp)
aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
}
+ /* UHCI */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->uhci), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->uhci), 0,
+ sc->memmap[ASPEED_DEV_UHCI]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uhci), 0,
+ aspeed_soc_get_irq(s, ASPEED_DEV_UHCI));
+
/* SDMC - SDRAM Memory Controller */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
return;
--
2.45.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 1/8] usb/uhci: checkpatch cleanup
2024-09-06 12:25 ` [RFC PATCH 1/8] usb/uhci: checkpatch cleanup Guenter Roeck
@ 2024-09-09 7:48 ` Cédric Le Goater
0 siblings, 0 replies; 16+ messages in thread
From: Cédric Le Goater @ 2024-09-09 7:48 UTC (permalink / raw)
To: Guenter Roeck, qemu-devel
Cc: Steven Lee, Troy Lee, Jamin Lin, Peter Maydell, Andrew Jeffery,
Joel Stanley, BALATON Zoltan, Michael S . Tsirkin,
Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm
On 9/6/24 14:25, Guenter Roeck wrote:
> Fix reported checkpatch issues to prepare for next patches
> in the series.
>
> No functional change.
>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/usb/hcd-uhci.c | 90 +++++++++++++++++++++++++++++------------------
> 1 file changed, 56 insertions(+), 34 deletions(-)
>
> diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
> index a03cf22e69..dfcc3e05c0 100644
> --- a/hw/usb/hcd-uhci.c
> +++ b/hw/usb/hcd-uhci.c
> @@ -67,7 +67,7 @@ struct UHCIPCIDeviceClass {
> UHCIInfo info;
> };
>
> -/*
> +/*
> * Pending async transaction.
> * 'packet' must be the first field because completion
> * handler does "(UHCIAsync *) pkt" cast.
> @@ -220,8 +220,9 @@ static void uhci_async_cancel(UHCIAsync *async)
> uhci_async_unlink(async);
> trace_usb_uhci_packet_cancel(async->queue->token, async->td_addr,
> async->done);
> - if (!async->done)
> + if (!async->done) {
> usb_cancel_packet(&async->packet);
> + }
> uhci_async_free(async);
> }
>
> @@ -322,7 +323,7 @@ static void uhci_reset(DeviceState *dev)
> s->fl_base_addr = 0;
> s->sof_timing = 64;
>
> - for(i = 0; i < UHCI_PORTS; i++) {
> + for (i = 0; i < UHCI_PORTS; i++) {
> port = &s->ports[i];
> port->ctrl = 0x0080;
> if (port->port.dev && port->port.dev->attached) {
> @@ -387,7 +388,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
>
> trace_usb_uhci_mmio_writew(addr, val);
>
> - switch(addr) {
> + switch (addr) {
> case 0x00:
> if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
> /* start frame processing */
> @@ -404,7 +405,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
> int i;
>
> /* send reset on the USB bus */
> - for(i = 0; i < UHCI_PORTS; i++) {
> + for (i = 0; i < UHCI_PORTS; i++) {
> port = &s->ports[i];
> usb_device_reset(port->port.dev);
> }
> @@ -425,10 +426,13 @@ static void uhci_port_write(void *opaque, hwaddr addr,
> break;
> case 0x02:
> s->status &= ~val;
> - /* XXX: the chip spec is not coherent, so we add a hidden
> - register to distinguish between IOC and SPD */
> - if (val & UHCI_STS_USBINT)
> + /*
> + * XXX: the chip spec is not coherent, so we add a hidden
> + * register to distinguish between IOC and SPD
> + */
> + if (val & UHCI_STS_USBINT) {
> s->status2 = 0;
> + }
> uhci_update_irq(s);
> break;
> case 0x04:
> @@ -436,8 +440,9 @@ static void uhci_port_write(void *opaque, hwaddr addr,
> uhci_update_irq(s);
> break;
> case 0x06:
> - if (s->status & UHCI_STS_HCHALTED)
> + if (s->status & UHCI_STS_HCHALTED) {
> s->frnum = val & 0x7ff;
> + }
> break;
> case 0x08:
> s->fl_base_addr &= 0xffff0000;
> @@ -464,8 +469,8 @@ static void uhci_port_write(void *opaque, hwaddr addr,
> dev = port->port.dev;
> if (dev && dev->attached) {
> /* port reset */
> - if ( (val & UHCI_PORT_RESET) &&
> - !(port->ctrl & UHCI_PORT_RESET) ) {
> + if ((val & UHCI_PORT_RESET) &&
> + !(port->ctrl & UHCI_PORT_RESET)) {
> usb_device_reset(dev);
> }
> }
> @@ -487,7 +492,7 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, unsigned size)
> UHCIState *s = opaque;
> uint32_t val;
>
> - switch(addr) {
> + switch (addr) {
> case 0x00:
> val = s->cmd;
> break;
> @@ -533,12 +538,13 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, unsigned size)
> }
>
> /* signal resume if controller suspended */
> -static void uhci_resume (void *opaque)
> +static void uhci_resume(void *opaque)
> {
> UHCIState *s = (UHCIState *)opaque;
>
> - if (!s)
> + if (!s) {
> return;
> + }
>
> if (s->cmd & UHCI_CMD_EGSM) {
> s->cmd |= UHCI_CMD_FGR;
> @@ -674,7 +680,8 @@ static int uhci_handle_td_error(UHCIState *s, UHCI_TD *td, uint32_t td_addr,
> return ret;
> }
>
> -static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_t *int_mask)
> +static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async,
> + uint32_t *int_mask)
> {
> int len = 0, max_len;
> uint8_t pid;
> @@ -682,8 +689,9 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_
> max_len = ((td->token >> 21) + 1) & 0x7ff;
> pid = td->token & 0xff;
>
> - if (td->ctrl & TD_CTRL_IOS)
> + if (td->ctrl & TD_CTRL_IOS) {
> td->ctrl &= ~TD_CTRL_ACTIVE;
> + }
>
> if (async->packet.status != USB_RET_SUCCESS) {
> return uhci_handle_td_error(s, td, async->td_addr,
> @@ -693,12 +701,15 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_
> len = async->packet.actual_length;
> td->ctrl = (td->ctrl & ~0x7ff) | ((len - 1) & 0x7ff);
>
> - /* The NAK bit may have been set by a previous frame, so clear it
> - here. The docs are somewhat unclear, but win2k relies on this
> - behavior. */
> + /*
> + * The NAK bit may have been set by a previous frame, so clear it
> + * here. The docs are somewhat unclear, but win2k relies on this
> + * behavior.
> + */
> td->ctrl &= ~(TD_CTRL_ACTIVE | TD_CTRL_NAK);
> - if (td->ctrl & TD_CTRL_IOC)
> + if (td->ctrl & TD_CTRL_IOC) {
> *int_mask |= 0x01;
> + }
>
> if (pid == USB_TOKEN_IN) {
> pci_dma_write(&s->dev, td->buffer, async->buf, len);
> @@ -780,9 +791,11 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
>
> if (async) {
> if (queuing) {
> - /* we are busy filling the queue, we are not prepared
> - to consume completed packages then, just leave them
> - in async state */
> + /*
> + * we are busy filling the queue, we are not prepared
> + * to consume completed packages then, just leave them
> + * in async state
> + */
> return TD_RESULT_ASYNC_CONT;
> }
> if (!async->done) {
> @@ -832,7 +845,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
> }
> usb_packet_addbuf(&async->packet, async->buf, max_len);
>
> - switch(pid) {
> + switch (pid) {
> case USB_TOKEN_OUT:
> case USB_TOKEN_SETUP:
> pci_dma_read(&s->dev, td->buffer, async->buf, max_len);
> @@ -911,12 +924,15 @@ static void qhdb_reset(QhDb *db)
> static int qhdb_insert(QhDb *db, uint32_t addr)
> {
> int i;
> - for (i = 0; i < db->count; i++)
> - if (db->addr[i] == addr)
> + for (i = 0; i < db->count; i++) {
> + if (db->addr[i] == addr) {
> return 1;
> + }
> + }
>
> - if (db->count >= UHCI_MAX_QUEUES)
> + if (db->count >= UHCI_MAX_QUEUES) {
> return 1;
> + }
>
> db->addr[db->count++] = addr;
> return 0;
> @@ -970,8 +986,10 @@ static void uhci_process_frame(UHCIState *s)
>
> for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) {
> if (!s->completions_only && s->frame_bytes >= s->frame_bandwidth) {
> - /* We've reached the usb 1.1 bandwidth, which is
> - 1280 bytes/frame, stop processing */
> + /*
> + * We've reached the usb 1.1 bandwidth, which is
> + * 1280 bytes/frame, stop processing
> + */
> trace_usb_uhci_frame_stop_bandwidth();
> break;
> }
> @@ -1120,8 +1138,10 @@ static void uhci_frame_timer(void *opaque)
> uhci_async_validate_begin(s);
> uhci_process_frame(s);
> uhci_async_validate_end(s);
> - /* The spec says frnum is the frame currently being processed, and
> - * the guest must look at frnum - 1 on interrupt, so inc frnum now */
> + /*
> + * The spec says frnum is the frame currently being processed, and
> + * the guest must look at frnum - 1 on interrupt, so inc frnum now
> + */
> s->frnum = (s->frnum + 1) & 0x7ff;
> s->expire_time += frame_t;
> }
> @@ -1174,7 +1194,7 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
>
> if (s->masterbus) {
> USBPort *ports[UHCI_PORTS];
> - for(i = 0; i < UHCI_PORTS; i++) {
> + for (i = 0; i < UHCI_PORTS; i++) {
> ports[i] = &s->ports[i].port;
> }
> usb_register_companion(s->masterbus, ports, UHCI_PORTS,
> @@ -1200,8 +1220,10 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
> memory_region_init_io(&s->io_bar, OBJECT(s), &uhci_ioport_ops, s,
> "uhci", 0x20);
>
> - /* Use region 4 for consistency with real hardware. BSD guests seem
> - to rely on this. */
> + /*
> + * Use region 4 for consistency with real hardware. BSD guests seem
> + * to rely on this.
> + */
> pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
> }
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 2/8] usb/uhci: Introduce and use register defines
2024-09-06 12:25 ` [RFC PATCH 2/8] usb/uhci: Introduce and use register defines Guenter Roeck
@ 2024-09-09 7:48 ` Cédric Le Goater
0 siblings, 0 replies; 16+ messages in thread
From: Cédric Le Goater @ 2024-09-09 7:48 UTC (permalink / raw)
To: Guenter Roeck, qemu-devel
Cc: Steven Lee, Troy Lee, Jamin Lin, Peter Maydell, Andrew Jeffery,
Joel Stanley, BALATON Zoltan, Michael S . Tsirkin,
Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm
On 9/6/24 14:25, Guenter Roeck wrote:
> Introduce defines for UHCI registers to simplify adding register access
> in subsequent patches of the series.
>
> No functional change.
>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/usb/hcd-uhci.c | 32 ++++++++++++++++----------------
> include/hw/usb/uhci-regs.h | 11 +++++++++++
> 2 files changed, 27 insertions(+), 16 deletions(-)
>
> diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
> index dfcc3e05c0..8bc163f688 100644
> --- a/hw/usb/hcd-uhci.c
> +++ b/hw/usb/hcd-uhci.c
> @@ -389,7 +389,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
> trace_usb_uhci_mmio_writew(addr, val);
>
> switch (addr) {
> - case 0x00:
> + case UHCI_USBCMD:
> if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
> /* start frame processing */
> trace_usb_uhci_schedule_start();
> @@ -424,7 +424,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
> }
> }
> break;
> - case 0x02:
> + case UHCI_USBSTS:
> s->status &= ~val;
> /*
> * XXX: the chip spec is not coherent, so we add a hidden
> @@ -435,27 +435,27 @@ static void uhci_port_write(void *opaque, hwaddr addr,
> }
> uhci_update_irq(s);
> break;
> - case 0x04:
> + case UHCI_USBINTR:
> s->intr = val;
> uhci_update_irq(s);
> break;
> - case 0x06:
> + case UHCI_USBFRNUM:
> if (s->status & UHCI_STS_HCHALTED) {
> s->frnum = val & 0x7ff;
> }
> break;
> - case 0x08:
> + case UHCI_USBFLBASEADD:
> s->fl_base_addr &= 0xffff0000;
> s->fl_base_addr |= val & ~0xfff;
> break;
> - case 0x0a:
> + case UHCI_USBFLBASEADD + 2:
> s->fl_base_addr &= 0x0000ffff;
> s->fl_base_addr |= (val << 16);
> break;
> - case 0x0c:
> + case UHCI_USBSOF:
> s->sof_timing = val & 0xff;
> break;
> - case 0x10 ... 0x1f:
> + case UHCI_USBPORTSC1 ... UHCI_USBPORTSC4:
> {
> UHCIPort *port;
> USBDevice *dev;
> @@ -493,28 +493,28 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, unsigned size)
> uint32_t val;
>
> switch (addr) {
> - case 0x00:
> + case UHCI_USBCMD:
> val = s->cmd;
> break;
> - case 0x02:
> + case UHCI_USBSTS:
> val = s->status;
> break;
> - case 0x04:
> + case UHCI_USBINTR:
> val = s->intr;
> break;
> - case 0x06:
> + case UHCI_USBFRNUM:
> val = s->frnum;
> break;
> - case 0x08:
> + case UHCI_USBFLBASEADD:
> val = s->fl_base_addr & 0xffff;
> break;
> - case 0x0a:
> + case UHCI_USBFLBASEADD + 2:
> val = (s->fl_base_addr >> 16) & 0xffff;
> break;
> - case 0x0c:
> + case UHCI_USBSOF:
> val = s->sof_timing;
> break;
> - case 0x10 ... 0x1f:
> + case UHCI_USBPORTSC1 ... UHCI_USBPORTSC4:
> {
> UHCIPort *port;
> int n;
> diff --git a/include/hw/usb/uhci-regs.h b/include/hw/usb/uhci-regs.h
> index fd45d29db0..5b81714e5c 100644
> --- a/include/hw/usb/uhci-regs.h
> +++ b/include/hw/usb/uhci-regs.h
> @@ -1,6 +1,17 @@
> #ifndef HW_USB_UHCI_REGS_H
> #define HW_USB_UHCI_REGS_H
>
> +#define UHCI_USBCMD 0
> +#define UHCI_USBSTS 2
> +#define UHCI_USBINTR 4
> +#define UHCI_USBFRNUM 6
> +#define UHCI_USBFLBASEADD 8
> +#define UHCI_USBSOF 0x0c
> +#define UHCI_USBPORTSC1 0x10
> +#define UHCI_USBPORTSC2 0x12
> +#define UHCI_USBPORTSC3 0x14
> +#define UHCI_USBPORTSC4 0x16
> +
> #define UHCI_CMD_FGR (1 << 4)
> #define UHCI_CMD_EGSM (1 << 3)
> #define UHCI_CMD_GRESET (1 << 2)
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 7/8] aspeed: Add uhci support for ast2600
2024-09-06 12:25 ` [RFC PATCH 7/8] aspeed: Add uhci support for ast2600 Guenter Roeck
@ 2024-09-09 7:49 ` Cédric Le Goater
0 siblings, 0 replies; 16+ messages in thread
From: Cédric Le Goater @ 2024-09-09 7:49 UTC (permalink / raw)
To: Guenter Roeck, qemu-devel
Cc: Steven Lee, Troy Lee, Jamin Lin, Peter Maydell, Andrew Jeffery,
Joel Stanley, BALATON Zoltan, Michael S . Tsirkin,
Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm
On 9/6/24 14:25, Guenter Roeck wrote:
> Enable UHCO support for the ast2600 SoC. With this patch, the UHCI port
> is successfully instantiated on the rainier-bmc and ast2600-evb machines.
>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/arm/aspeed_ast2600.c | 13 +++++++++++++
> include/hw/arm/aspeed_soc.h | 3 +++
> 2 files changed, 16 insertions(+)
>
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index be3eb70cdd..cd7e4ae6c9 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -33,6 +33,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
> [ASPEED_DEV_SPI2] = 0x1E631000,
> [ASPEED_DEV_EHCI1] = 0x1E6A1000,
> [ASPEED_DEV_EHCI2] = 0x1E6A3000,
> + [ASPEED_DEV_UHCI] = 0x1E6B0000,
> [ASPEED_DEV_MII1] = 0x1E650000,
> [ASPEED_DEV_MII2] = 0x1E650008,
> [ASPEED_DEV_MII3] = 0x1E650010,
> @@ -110,6 +111,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
> [ASPEED_DEV_SDHCI] = 43,
> [ASPEED_DEV_EHCI1] = 5,
> [ASPEED_DEV_EHCI2] = 9,
> + [ASPEED_DEV_UHCI] = 10,
> [ASPEED_DEV_EMMC] = 15,
> [ASPEED_DEV_GPIO] = 40,
> [ASPEED_DEV_GPIO_1_8V] = 11,
> @@ -206,6 +208,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
> TYPE_PLATFORM_EHCI);
> }
>
> + object_initialize_child(obj, "uhci", &s->uhci, TYPE_ASPEED_UHCI);
> +
> snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
> object_initialize_child(obj, "sdmc", &s->sdmc, typename);
> object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
> @@ -481,6 +485,15 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
> aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
> }
>
> + /* UHCI */
> + if (!sysbus_realize(SYS_BUS_DEVICE(&s->uhci), errp)) {
> + return;
> + }
> + aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->uhci), 0,
> + sc->memmap[ASPEED_DEV_UHCI]);
> + sysbus_connect_irq(SYS_BUS_DEVICE(&s->uhci), 0,
> + aspeed_soc_get_irq(s, ASPEED_DEV_UHCI));
> +
> /* SDMC - SDRAM Memory Controller */
> if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
> return;
> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> index 624d489e0d..b54849db72 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -34,6 +34,7 @@
> #include "hw/gpio/aspeed_gpio.h"
> #include "hw/sd/aspeed_sdhci.h"
> #include "hw/usb/hcd-ehci.h"
> +#include "hw/usb/hcd-uhci-sysbus.h"
> #include "qom/object.h"
> #include "hw/misc/aspeed_lpc.h"
> #include "hw/misc/unimp.h"
> @@ -72,6 +73,7 @@ struct AspeedSoCState {
> AspeedSMCState fmc;
> AspeedSMCState spi[ASPEED_SPIS_NUM];
> EHCISysBusState ehci[ASPEED_EHCIS_NUM];
> + ASPEEDUHCIState uhci;
> AspeedSBCState sbc;
> AspeedSLIState sli;
> AspeedSLIState sliio;
> @@ -193,6 +195,7 @@ enum {
> ASPEED_DEV_SPI2,
> ASPEED_DEV_EHCI1,
> ASPEED_DEV_EHCI2,
> + ASPEED_DEV_UHCI,
> ASPEED_DEV_VIC,
> ASPEED_DEV_INTC,
> ASPEED_DEV_SDMC,
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 8/8] aspeed: Add uhci support for ast2400 and ast2500
2024-09-06 12:25 ` [RFC PATCH 8/8] aspeed: Add uhci support for ast2400 and ast2500 Guenter Roeck
@ 2024-09-09 7:49 ` Cédric Le Goater
0 siblings, 0 replies; 16+ messages in thread
From: Cédric Le Goater @ 2024-09-09 7:49 UTC (permalink / raw)
To: Guenter Roeck, qemu-devel
Cc: Steven Lee, Troy Lee, Jamin Lin, Peter Maydell, Andrew Jeffery,
Joel Stanley, BALATON Zoltan, Michael S . Tsirkin,
Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm
On 9/6/24 14:25, Guenter Roeck wrote:
> Enable UHCI support for ast2400 and ast2500 SoCs. With this patch,
> the UHCI port is successfully instantiated on the ast2500-evb machine.
>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/arm/aspeed_ast2400.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/hw/arm/aspeed_ast2400.c b/hw/arm/aspeed_ast2400.c
> index d125886207..93bfe3e3dd 100644
> --- a/hw/arm/aspeed_ast2400.c
> +++ b/hw/arm/aspeed_ast2400.c
> @@ -31,6 +31,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
> [ASPEED_DEV_FMC] = 0x1E620000,
> [ASPEED_DEV_SPI1] = 0x1E630000,
> [ASPEED_DEV_EHCI1] = 0x1E6A1000,
> + [ASPEED_DEV_UHCI] = 0x1E6B0000,
> [ASPEED_DEV_VIC] = 0x1E6C0000,
> [ASPEED_DEV_SDMC] = 0x1E6E0000,
> [ASPEED_DEV_SCU] = 0x1E6E2000,
> @@ -68,6 +69,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
> [ASPEED_DEV_SPI2] = 0x1E631000,
> [ASPEED_DEV_EHCI1] = 0x1E6A1000,
> [ASPEED_DEV_EHCI2] = 0x1E6A3000,
> + [ASPEED_DEV_UHCI] = 0x1E6B0000,
> [ASPEED_DEV_VIC] = 0x1E6C0000,
> [ASPEED_DEV_SDMC] = 0x1E6E0000,
> [ASPEED_DEV_SCU] = 0x1E6E2000,
> @@ -107,6 +109,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
> [ASPEED_DEV_FMC] = 19,
> [ASPEED_DEV_EHCI1] = 5,
> [ASPEED_DEV_EHCI2] = 13,
> + [ASPEED_DEV_UHCI] = 14,
> [ASPEED_DEV_SDMC] = 0,
> [ASPEED_DEV_SCU] = 21,
> [ASPEED_DEV_ADC] = 31,
> @@ -199,6 +202,8 @@ static void aspeed_ast2400_soc_init(Object *obj)
> TYPE_PLATFORM_EHCI);
> }
>
> + object_initialize_child(obj, "uhci", &s->uhci, TYPE_ASPEED_UHCI);
> +
> snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
> object_initialize_child(obj, "sdmc", &s->sdmc, typename);
> object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
> @@ -393,6 +398,15 @@ static void aspeed_ast2400_soc_realize(DeviceState *dev, Error **errp)
> aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
> }
>
> + /* UHCI */
> + if (!sysbus_realize(SYS_BUS_DEVICE(&s->uhci), errp)) {
> + return;
> + }
> + aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->uhci), 0,
> + sc->memmap[ASPEED_DEV_UHCI]);
> + sysbus_connect_irq(SYS_BUS_DEVICE(&s->uhci), 0,
> + aspeed_soc_get_irq(s, ASPEED_DEV_UHCI));
> +
> /* SDMC - SDRAM Memory Controller */
> if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
> return;
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 3/8] usb/uhci: Move PCI-related code into a separate file
2024-09-06 12:25 ` [RFC PATCH 3/8] usb/uhci: Move PCI-related code into a separate file Guenter Roeck
@ 2024-11-12 6:32 ` Thomas Huth
2024-11-12 14:50 ` Guenter Roeck
0 siblings, 1 reply; 16+ messages in thread
From: Thomas Huth @ 2024-11-12 6:32 UTC (permalink / raw)
To: Guenter Roeck, qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm
On 06/09/2024 14.25, Guenter Roeck wrote:
> Some machines (like Aspeed ARM) only have a sysbus UHCI controller.
> The current UHCI implementation only supports PCI based UHCI controllers.
> Move the UHCI-PCI device code into a separate file so that it is possible
> to create a sysbus UHCI device without PCI dependency.
Hi Guenter,
I think there's a bug in here ...
> diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c
> index 6162806172..7fdb4697f9 100644
> --- a/hw/usb/vt82c686-uhci-pci.c
> +++ b/hw/usb/vt82c686-uhci-pci.c
> @@ -1,17 +1,17 @@
> #include "qemu/osdep.h"
> #include "hw/irq.h"
> #include "hw/isa/vt82c686.h"
> -#include "hcd-uhci.h"
> +#include "hcd-uhci-pci.h"
>
> static void uhci_isa_set_irq(void *opaque, int irq_num, int level)
> {
> - UHCIState *s = opaque;
> + UHCIPCIState *s = opaque;
You use UHCIPCIState as parameter for the irq-related functions...
> via_isa_set_irq(&s->dev, 0, level);
> }
>
> static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
> {
> - UHCIState *s = UHCI(dev);
> + UHCIPCIState *s = UHCI_PCI(dev);
> uint8_t *pci_conf = s->dev.config;
>
> /* USB misc control 1/2 */
> @@ -21,12 +21,12 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
> /* USB legacy support */
> pci_set_long(pci_conf + 0xc0, 0x00002000);
>
> - usb_uhci_common_realize(dev, errp);
> - object_unref(s->irq);
> - s->irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
> + usb_uhci_common_realize_pci(dev, errp);
> + object_unref(s->state.irq);
> + s->state.irq = qemu_allocate_irq(uhci_isa_set_irq, &s->state, 0);
... but you set it up with UHCIInfo as parameter here. I think this line
should rather be:
s->state.irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
Shouldn't it?
Thomas
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 3/8] usb/uhci: Move PCI-related code into a separate file
2024-11-12 6:32 ` Thomas Huth
@ 2024-11-12 14:50 ` Guenter Roeck
2024-11-12 15:10 ` Cédric Le Goater
0 siblings, 1 reply; 16+ messages in thread
From: Guenter Roeck @ 2024-11-12 14:50 UTC (permalink / raw)
To: Thomas Huth, qemu-devel
Cc: Cédric Le Goater, Steven Lee, Troy Lee, Jamin Lin,
Peter Maydell, Andrew Jeffery, Joel Stanley, BALATON Zoltan,
Michael S . Tsirkin, Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm
Hi Thomas,
On 11/11/24 22:32, Thomas Huth wrote:
> On 06/09/2024 14.25, Guenter Roeck wrote:
>> Some machines (like Aspeed ARM) only have a sysbus UHCI controller.
>> The current UHCI implementation only supports PCI based UHCI controllers.
>> Move the UHCI-PCI device code into a separate file so that it is possible
>> to create a sysbus UHCI device without PCI dependency.
>
> Hi Guenter,
>
> I think there's a bug in here ...
>
>> diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c
>> index 6162806172..7fdb4697f9 100644
>> --- a/hw/usb/vt82c686-uhci-pci.c
>> +++ b/hw/usb/vt82c686-uhci-pci.c
>> @@ -1,17 +1,17 @@
>> #include "qemu/osdep.h"
>> #include "hw/irq.h"
>> #include "hw/isa/vt82c686.h"
>> -#include "hcd-uhci.h"
>> +#include "hcd-uhci-pci.h"
>> static void uhci_isa_set_irq(void *opaque, int irq_num, int level)
>> {
>> - UHCIState *s = opaque;
>> + UHCIPCIState *s = opaque;
>
> You use UHCIPCIState as parameter for the irq-related functions...
>
>> via_isa_set_irq(&s->dev, 0, level);
>> }
>> static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
>> {
>> - UHCIState *s = UHCI(dev);
>> + UHCIPCIState *s = UHCI_PCI(dev);
>> uint8_t *pci_conf = s->dev.config;
>> /* USB misc control 1/2 */
>> @@ -21,12 +21,12 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
>> /* USB legacy support */
>> pci_set_long(pci_conf + 0xc0, 0x00002000);
>> - usb_uhci_common_realize(dev, errp);
>> - object_unref(s->irq);
>> - s->irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
>> + usb_uhci_common_realize_pci(dev, errp);
>> + object_unref(s->state.irq);
>> + s->state.irq = qemu_allocate_irq(uhci_isa_set_irq, &s->state, 0);
>
> ... but you set it up with UHCIInfo as parameter here. I think this line should rather be:
>
> s->state.irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
>
> Shouldn't it?
>
Yes, you are correct. Thanks for reporting it. Turns out I had fixed that in the
meantime, but did not remember to send another version. Is there any interest,
and should I resend ?
Thanks,
Guenter
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [RFC PATCH 3/8] usb/uhci: Move PCI-related code into a separate file
2024-11-12 14:50 ` Guenter Roeck
@ 2024-11-12 15:10 ` Cédric Le Goater
0 siblings, 0 replies; 16+ messages in thread
From: Cédric Le Goater @ 2024-11-12 15:10 UTC (permalink / raw)
To: Guenter Roeck, Thomas Huth, qemu-devel
Cc: Steven Lee, Troy Lee, Jamin Lin, Peter Maydell, Andrew Jeffery,
Joel Stanley, BALATON Zoltan, Michael S . Tsirkin,
Marcel Apfelbaum, Hervé Poussineau,
Philippe Mathieu-Daudé, Paolo Bonzini, qemu-arm
On 11/12/24 15:50, Guenter Roeck wrote:
> Hi Thomas,
>
> On 11/11/24 22:32, Thomas Huth wrote:
>> On 06/09/2024 14.25, Guenter Roeck wrote:
>>> Some machines (like Aspeed ARM) only have a sysbus UHCI controller.
>>> The current UHCI implementation only supports PCI based UHCI controllers.
>>> Move the UHCI-PCI device code into a separate file so that it is possible
>>> to create a sysbus UHCI device without PCI dependency.
>>
>> Hi Guenter,
>>
>> I think there's a bug in here ...
>>
>>> diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c
>>> index 6162806172..7fdb4697f9 100644
>>> --- a/hw/usb/vt82c686-uhci-pci.c
>>> +++ b/hw/usb/vt82c686-uhci-pci.c
>>> @@ -1,17 +1,17 @@
>>> #include "qemu/osdep.h"
>>> #include "hw/irq.h"
>>> #include "hw/isa/vt82c686.h"
>>> -#include "hcd-uhci.h"
>>> +#include "hcd-uhci-pci.h"
>>> static void uhci_isa_set_irq(void *opaque, int irq_num, int level)
>>> {
>>> - UHCIState *s = opaque;
>>> + UHCIPCIState *s = opaque;
>>
>> You use UHCIPCIState as parameter for the irq-related functions...
>>
>>> via_isa_set_irq(&s->dev, 0, level);
>>> }
>>> static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
>>> {
>>> - UHCIState *s = UHCI(dev);
>>> + UHCIPCIState *s = UHCI_PCI(dev);
>>> uint8_t *pci_conf = s->dev.config;
>>> /* USB misc control 1/2 */
>>> @@ -21,12 +21,12 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
>>> /* USB legacy support */
>>> pci_set_long(pci_conf + 0xc0, 0x00002000);
>>> - usb_uhci_common_realize(dev, errp);
>>> - object_unref(s->irq);
>>> - s->irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
>>> + usb_uhci_common_realize_pci(dev, errp);
>>> + object_unref(s->state.irq);
>>> + s->state.irq = qemu_allocate_irq(uhci_isa_set_irq, &s->state, 0);
>>
>> ... but you set it up with UHCIInfo as parameter here. I think this line should rather be:
>>
>> s->state.irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
>>
>> Shouldn't it?
>>
>
> Yes, you are correct. Thanks for reporting it. Turns out I had fixed that in the
> meantime, but did not remember to send another version. Is there any interest,
> and should I resend ?
Please do. I was planning on merging the obvious ones in QEMU 10.0
and spend more time reviewing the others.
Thanks,
C.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2024-11-12 15:11 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-06 12:25 [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 1/8] usb/uhci: checkpatch cleanup Guenter Roeck
2024-09-09 7:48 ` Cédric Le Goater
2024-09-06 12:25 ` [RFC PATCH 2/8] usb/uhci: Introduce and use register defines Guenter Roeck
2024-09-09 7:48 ` Cédric Le Goater
2024-09-06 12:25 ` [RFC PATCH 3/8] usb/uhci: Move PCI-related code into a separate file Guenter Roeck
2024-11-12 6:32 ` Thomas Huth
2024-11-12 14:50 ` Guenter Roeck
2024-11-12 15:10 ` Cédric Le Goater
2024-09-06 12:25 ` [RFC PATCH 4/8] usb/uhci: enlarge uhci memory space Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 5/8] usb/uhci: Add support for usb-uhci-sysbus Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 6/8] usb/uhci: Add aspeed specific read and write functions Guenter Roeck
2024-09-06 12:25 ` [RFC PATCH 7/8] aspeed: Add uhci support for ast2600 Guenter Roeck
2024-09-09 7:49 ` Cédric Le Goater
2024-09-06 12:25 ` [RFC PATCH 8/8] aspeed: Add uhci support for ast2400 and ast2500 Guenter Roeck
2024-09-09 7:49 ` Cédric Le Goater
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).