+ Philippe Mathieu-Daudé <[email protected]> + Cédric Le Goater <[email protected]>
Thanks, Jamin > Subject: [PATCH v1 00/19] hw/usb: Add a usbredir server transport and > AST1030 UDC support > > This series redirects a USB device emulated in one QEMU instance to a USB > host controller emulated in another one, over the usbredir protocol, and uses > it > to bring up the ASPEED AST1030 USB Device Controller (UDC). > > It is the second step of a larger plan to model USB device-side support on > ASPEED BMC/BIC SoCs, which has three goals: > > 1. Model the ASPEED UDC (AST2600 / AST1030). The AST2600 also has USB > host > (EHCI) controllers, so that work targets the AST2600 UDC: its gadget can > be attached to the SoC's own EHCI bus, letting the guest enumerate its > own gadget and exercise the UDC end-to-end. [Done] > > https://lore.kernel.org/qemu-devel/20260902021542.3194812-1-jamin_lin@as > peedtech.com/ > > 2. AST1030 UDC. The AST1030 has no USB host controller, so testing its UDC > needs a second QEMU instance. The UDC gadget is redirected out of the > guest with libusbredir and attached to another QEMU that runs a USB host > (a VMM, or an AST2600 / AST2700 guest). [this series] > > 3. ASPEED vHub, as a longer-term goal towards BMC KVM / Virtual Media > support in QEMU. [future] > > This series implements goal 2. > > The transport > ============= > > usb-redir-server exports a locally emulated USB device to a remote USB host > over the usbredir protocol, so a device emulated in one QEMU instance can be > enumerated by a host controller emulated in another one. > > The left column is a request going to the device. The right column is the > answer coming back. The middle hop carries usbredir messages over a socket. > The top and bottom hops carry USBPackets inside QEMU. > > remote QEMU: guest driver -> EHCI/XHCI > | ^ > USBPacket | | USBPacket > v | > "usb-redir" (the client) > | ^ > usbredir | chardev socket | usbredir > v | > usb-redir-server (the server, this series) > | ^ > USBPacket | | USBPacket > v | > any USBDevice, "-device <dev>,bus=<id>.0" > > "usb-redir" (hw/usb/redirect.c) is the client: > - it takes a USBPacket from the remote guest and writes it to the socket > as a usbredir message > - it reads the answer from the socket and completes the USBPacket > > usb-redir-server is the server. It does the same thing, but backwards: > - it reads a usbredir message from the socket and runs it as a USBPacket > on the bus below > - it takes the result of that USBPacket and writes it back to the same > socket as a usbredir message, for the client to read > > A USB device has to sit on a USB bus, and in QEMU a USB bus is always made > by a host controller. So usb-redir-server makes one and acts as the host > controller on this side. It models no real chip: its cable is the chardev > socket. > The real host is in the other QEMU. > > usbredir carries one device, not a bus. A hub cannot be exported: the protocol > has no device address field. To export several devices, run one > usb-redir-server > per device, each with its own chardev. > > AST1030 gadget to an AST2700 host > ================================= > > QEMU #1 -M ast1030-evb QEMU #2 -M > ast2700a2-evb > +-----------------------------+ +-----------------------------+ > | Zephyr usb_dc_aspeed | | Linux ehci-platform > | > +--------------+--------------+ +--------------+--------------+ > | MMIO | MMIO > +--------------v--------------+ +--------------v--------------+ > | aspeed.udc | | EHCI3 (usb-bus.3) > | > +--------------+--------------+ +--------------+--------------+ > | USBPacket | USBPacket > +--------------v--------------+ +--------------v--------------+ > | aspeed.udc-gadget | | usb-redir > | > +--------------+--------------+ +--------------+--------------+ > | USBPacket | > +--------------v--------------+ | > | usb-redir-server | | > +--------------+--------------+ | > | | > +=========== unix socket ============+ > usbredir protocol > > Testing > ======= > > 1. AST1030 CDC-ACM gadget, enumerated by an AST2700 host > -------------------------------------------------------- > > The device side owns the socket and has to be started first. > > $ qemu-system-arm -M ast1030-evb -nographic \ > -kernel zephyr.bin \ > -chardev socket,id=u,path=/tmp/usbredir.sock,server=on,wait=off \ > -device usb-redir-server,id=udcredir,chardev=u \ > -device aspeed.udc-gadget,bus=udcredir.0,udc=/machine/soc/udc > > uart:~$ usb enable > uart:~$ usb print 1 > > $ qemu-system-aarch64 -M ast2700a2-evb -nographic \ > -drive file=image-bmc,if=mtd,format=raw -snapshot \ > -net nic -net user \ > -chardev socket,id=r,path=/tmp/usbredir.sock \ > -device usb-redir,chardev=r,bus=usb-bus.3 > > root@ast2700-default:~# lsusb > Bus 001 Device 001: ID 1d6b:0002 Linux 6.18.36 ehci_hcd EHCI Host > Controller > Bus 001 Device 002: ID 2245:1030 ZEPHYR Zephyr DFU sample > > Data was checked: > > 2700 -> 1030 echo '1234567890' > /dev/ttyACM0 > 1030 console: Print Data: 0x31 0x32 ... 0x30 > > 2. A plain usb-storage exported the same way > -------------------------------------------- > > Any USBDevice can be exported, not just the UDC gadget. The machine on the > exporting side is only a container for usb-redir-server, so it does not have > to > run anything. > > $ qemu-system-arm -M ast2600-evb -nographic -serial null \ > -chardev socket,id=u,path=/tmp/storage.sock,server=on,wait=off \ > -device usb-redir-server,id=keyredir,chardev=u \ > -drive id=usbdisk,if=none,file=disk.img,format=raw -snapshot \ > -device usb-storage,bus=keyredir.0,id=mystorage,drive=usbdisk > > $ qemu-system-aarch64 -M ast2700a2-evb -nographic \ > -drive file=image-bmc,if=mtd,format=raw -snapshot \ > -net nic -net user \ > -chardev socket,id=r,path=/tmp/storage.sock \ > -device usb-redir,chardev=r,bus=usb-bus.3 > > root@ast2700-default:~# lsusb > Bus 001 Device 001: ID 1d6b:0002 Linux 6.18.36 ehci_hcd EHCI Host > Controller > Bus 001 Device 002: ID 46f4:0001 QEMU QEMU USB HARDDRIVE > > root@ast2700-default:~# mount /dev/sda /mnt/usb > MOUNTED > > A 4 MiB file was written, unmounted and remounted, and the sha256 > matched. > > v1 > 1. Add a usbredir server transport > 1. Add a usbredir server device > 2. Announce the exported device > 3. Implement control transfers > 4. Implement bulk and interrupt transfers > 5. Stream interrupt IN endpoints > 2. ASPEED UDC > 1. Make the SETUP buffer byte addressable > 2. Support single-stage IN transfers > 3. Clear EP_POOL_ACK when no endpoint ack is left > 4. Mask the reserved bits on register writes > 5. Use the endpoint max packet size for OUT transfers > 6. Test the usbredir server transport > 7. Add the USB device controller for AST1030 > > Jamin Lin (19): > hw/usb/bus: Let a bus opt out of automatic hub insertion > hw/usb/redirect-server: Add a usbredir server device > hw/usb/redirect-server: Connect usbredirparser to a chardev > hw/usb/redirect-server: Announce the exported device > hw/usb/redirect-server: Implement control transfers > hw/usb/redirect-server: Implement bulk and interrupt transfers > hw/usb/redirect-server: Stream interrupt IN endpoints > hw/arm/aspeed: Enable the usbredir server transport > hw/usb/aspeed-udc: Make the SETUP buffer byte addressable > hw/usb/aspeed-udc: Mask the reserved bits on register writes > hw/usb/aspeed-udc: Clear EP_POOL_ACK when no endpoint ack is left > hw/usb/aspeed-udc: Rename the transfer helpers after their DMA mode > hw/usb/aspeed-udc: Store the EP_DMA_STS write first > hw/usb/aspeed-udc: Pick the EP_DMA_STS path by direction > hw/usb/aspeed-udc: Support single-stage IN transfers > hw/usb/aspeed-udc: Use the endpoint max packet size for OUT transfers > hw/usb/aspeed-udc: Add trace events for the transfer paths > hw/arm/aspeed_ast10x0: Add the USB device controller > tests/functional/arm/test_aspeed_ast1030: Test the usbredir server > transport > > include/hw/arm/aspeed_soc.h | 1 + > include/hw/usb/aspeed-udc.h | 13 +- > include/hw/usb/redirect-server.h | 116 ++ > include/hw/usb/usb.h | 1 + > hw/arm/aspeed.c | 6 + > hw/arm/aspeed_ast10x0.c | 17 +- > hw/usb/aspeed-udc.c | 290 +++- > hw/usb/bus.c | 3 +- > hw/usb/redirect-server.c | 1604 > +++++++++++++++++++ > hw/usb/meson.build | 3 +- > hw/usb/trace-events | 36 + > tests/functional/arm/meson.build | 1 + > tests/functional/arm/test_aspeed_ast1030.py | 52 + > 13 files changed, 2088 insertions(+), 55 deletions(-) create mode 100644 > include/hw/usb/redirect-server.h create mode 100644 > hw/usb/redirect-server.c > > -- > 2.53.0
