+ 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

Reply via email to