QEMU-Arm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jamin Lin <jamin_lin@aspeedtech.com>
To: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Cédric Le Goater" <clg@kaod.org>,
	"Steven Lee" <steven_lee@aspeedtech.com>,
	"Troy Lee" <leetroy@gmail.com>,
	"Kane Chen" <kane_chen@aspeedtech.com>,
	"Andrew Jeffery" <andrew@codeconstruct.com.au>,
	"Joel Stanley" <joel@jms.id.au>,
	"open list:ARM TCG CPUs" <qemu-arm@nongnu.org>,
	"open list:All patches CC here" <qemu-devel@nongnu.org>
Cc: Jamin Lin <jamin_lin@aspeedtech.com>, Troy Lee <troy_lee@aspeedtech.com>
Subject: [PATCH v1 0/3] hw/usb: Add ASPEED USB Device Controller (UDC)
Date: Fri, 3 Jul 2026 07:43:33 +0000	[thread overview]
Message-ID: <20260703074332.1049473-1-jamin_lin@aspeedtech.com> (raw)

This series adds a QEMU model for the ASPEED USB Device Controller (UDC),
driven by the Linux "aspeed_udc" gadget driver.

It is the first 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 this series 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.  [this series]

2. AST1030 UDC. The AST1030 has no USB host controller, so testing its UDC
   needs a second QEMU instance. The plan is to redirect the UDC gadget out
   of the guest using libusbredir and attach it to another QEMU that runs a
   USB host (a VMM, or an AST2600 / AST2700 guest).  [on-going]
   
3. ASPEED vHub, as a longer-term goal towards BMC KVM / Virtual Media support
   in QEMU.  [future]

This series implements goal 1 only.

Design
------
The UDC is modelled as two QOM objects, because a single object cannot be
both a SysBusDevice and a USBDevice:

  - "aspeed.udc": the sysbus device (MMIO register map, IRQ and DMA engine)
    that the guest gadget driver programs.

  - "aspeed.udc-gadget": a user-creatable USB device presented on a USB host
    controller's bus. It links back to its controller through the "udc"
    property.

The SoC creates the controller; the gadget is added on the command line, e.g.

  -device aspeed.udc-gadget,udc=/machine/soc/udc
     
Test result:
-----------
The default ASPEED SDK prebuilt image does not enable the UDC driver, so
build a kernel with CONFIG_USB_ASPEED_UDC=y first.

Start QEMU with the gadget attached to the on-SoC EHCI:

  qemu-system-arm -machine ast2600-evb -drive file=<image>,if=mtd,format=raw \
      -device aspeed.udc-gadget,udc=/machine/soc/udc -nographic

In the guest, bring up a mass-storage gadget and verify enumeration and I/O:

1. Before: only the host controllers are present
root@ast2600-default:~# lsusb
unable to initialize usb specBus 001 Device 001: ID 1d6b:0002 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty ehci_hcd EHCI Host Controller
Bus 002 Device 001: ID 1d6b:0001 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty uhci_hcd Generic UHCI Host Controller

2. Enable the gadget
root@ast2600-default:~# ./usb-storage.sh
Using UDC: 1e6a2000.usb
[  598.582205] Mass Storage Function, version: 2009/09/11
[  598.582635] LUN: removable file: (no medium)
USB Mass Storage gadget is enabled.
Backing file: /home/root/jamin
root@ast2600-default:~# [  598.876395] usb 1-1: new high-speed USB device number 2 using ehci-platform
[  599.070035] usb 1-1: New USB device found, idVendor=1d6b, idProduct=0104, bcdDevice= 1.00
[  599.070821] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  599.071448] usb 1-1: Product: ASPEED USB Storage
[  599.072687] usb 1-1: Manufacturer: ASPEED
[  599.073384] usb 1-1: SerialNumber: 1234567890
[  599.103625] usb-storage 1-1:1.0: USB Mass Storage device detected
[  599.136326] scsi host0: usb-storage 1-1:1.0
[  600.230921] scsi 0:0:0:0: Direct-Access     Linux    File-Stor Gadget 0618 PQ: 0 ANSI: 2
[  600.243758] sd 0:0:0:0: Attached scsi generic sg0 type 0
[  600.263452] sd 0:0:0:0: Power-on or device reset occurred
[  600.289381] sd 0:0:0:0: [sda] 2048 512-byte logical blocks: (1.05 MB/1.00 MiB)
[  600.297896] sd 0:0:0:0: [sda] Write Protect is off
[  600.306379] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[  600.424608]  sda:
[  600.425526] sd 0:0:0:0: [sda] Attached SCSI removable disk

3. After: the gadget enumerates on the EHCI bus
root@ast2600-default:~# lsusb
unable to initialize usb specBus 001 Device 001: ID 1d6b:0002 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty ehci_hcd EHCI Host Controller
Bus 001 Device 002: ID 1d6b:0104 ASPEED ASPEED USB Storage
Bus 002 Device 001: ID 1d6b:0001 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty uhci_hcd Generic UHCI Host Controller

4. Mount and verify data
root@ast2600-default:~# mount /dev/sda /mnt/
root@ast2600-default:~# sha256sum /mnt/testfile
3308890a1289f6a327c014537523e8ebd0833301af3d25a7c5893dc7050d2c70  /mnt/testfile
root@ast2600-default:~# umount /mnt


5. Stop the gadget -> clean disconnect
root@ast2600-default:~# ./usb-storage.sh stop
Stopping USB gadget...
[  669.866439] usb 1-1: USB disconnect, device number 2
Stopped.
root@ast2600-default:~# [  669.968156] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[  669.969307] sd 0:0:0:0: [sda] Synchronize Cache(10) failed: Result: hostbyte=0x01 driverbyte=DRIVER_OK

root@ast2600-default:~# lsusb
unable to initialize usb specBus 001 Device 001: ID 1d6b:0002 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty ehci_hcd EHCI Host Controller
Bus 002 Device 001: ID 1d6b:0001 Linux 6.18.20-dirty-32e49fb4a22b-g32e49fb4a22b-dirty uhci_hcd Generic UHCI Host Controller


The contents of this scripts
---------------------------
root@ast2600-default:~# cat  usb-storage.sh
#!/bin/sh
set -e

G=/sys/kernel/config/usb_gadget/g1
IMG=/home/root/jamin
SIZE_MB=64

mount_configfs()
{
    mountpoint -q /sys/kernel/config || mount -t configfs none /sys/kernel/config
}

get_udc()
{
    ls /sys/class/udc | head -n 1
}

stop_gadget()
{
    if [ ! -d "$G" ]; then
        return
    fi

    echo "Stopping USB gadget..."

    # Unbind UDC first
    if [ -f "$G/UDC" ]; then
        echo "" > "$G/UDC" 2>/dev/null || true
    fi

    # Clear backing file to release image
    if [ -f "$G/functions/mass_storage.0/lun.0/file" ]; then
        echo "" > "$G/functions/mass_storage.0/lun.0/file" 2>/dev/null || true
    fi

    # Remove function link from config
    rm -f "$G/configs/c.1/mass_storage.0" 2>/dev/null || true

    echo "Stopped."
}

start_gadget()
{
    mount_configfs

    UDC="$(get_udc)"
    if [ -z "$UDC" ]; then
        echo "ERROR: No UDC found in /sys/class/udc"
        exit 1
    fi

    stop_gadget

    echo "Using UDC: $UDC"

    modprobe libcomposite 2>/dev/null || true

    mkdir -p "$G"
    cd "$G"

    echo 0x1d6b > idVendor
    echo 0x0104 > idProduct
    echo 0x0200 > bcdUSB
    echo 0x0100 > bcdDevice

    mkdir -p strings/0x409
    echo "1234567890" > strings/0x409/serialnumber
    echo "ASPEED" > strings/0x409/manufacturer
    echo "ASPEED USB Storage" > strings/0x409/product

    mkdir -p configs/c.1/strings/0x409
    echo "Mass Storage" > configs/c.1/strings/0x409/configuration
    echo 120 > configs/c.1/MaxPower

    if [ ! -f "$IMG" ]; then
        echo "Creating backing image: $IMG"
        dd if=/dev/zero of="$IMG" bs=1M count="$SIZE_MB"
        mkfs.vfat "$IMG"
    fi

    mkdir -p functions/mass_storage.0

    # Make sure old LUN is detached before changing attributes
    echo "" > functions/mass_storage.0/lun.0/file 2>/dev/null || true

    echo 0 > functions/mass_storage.0/stall
    echo 0 > functions/mass_storage.0/lun.0/cdrom
    echo 0 > functions/mass_storage.0/lun.0/ro
    echo 1 > functions/mass_storage.0/lun.0/removable
    echo "$IMG" > functions/mass_storage.0/lun.0/file

    ln -sf functions/mass_storage.0 configs/c.1/mass_storage.0

    echo "$UDC" > UDC

    echo "USB Mass Storage gadget is enabled."
    echo "Backing file: $IMG"
}

case "$1" in
    start|"")
        start_gadget
        ;;
    stop)
        stop_gadget
        ;;
    restart)
        stop_gadget
        sleep 1
        start_gadget
        ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
        ;;
esac


v1:
  1. Add ASPEED UDC device controller
  2. Add ASPEED UDC gadget USB device

Jamin Lin (3):
  hw/usb/aspeed-udc: Add ASPEED UDC device controller
  hw/usb/aspeed-udc: Add ASPEED UDC gadget USB device
  hw/arm/aspeed_ast2600: Wire up the UDC

 hw/arm/Kconfig              |   1 +
 hw/arm/aspeed_ast2600.c     |  13 +
 hw/usb/Kconfig              |   4 +
 hw/usb/aspeed-udc.c         | 930 ++++++++++++++++++++++++++++++++++++
 hw/usb/meson.build          |   1 +
 hw/usb/trace-events         |  16 +
 include/hw/arm/aspeed_soc.h |   2 +
 include/hw/usb/aspeed-udc.h |  84 ++++
 8 files changed, 1051 insertions(+)
 create mode 100644 hw/usb/aspeed-udc.c
 create mode 100644 include/hw/usb/aspeed-udc.h

-- 
2.53.0


             reply	other threads:[~2026-07-03  7:43 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-03  7:43 Jamin Lin [this message]
2026-07-03  7:43 ` [PATCH v1 1/3] hw/usb/aspeed-udc: Add ASPEED UDC device controller Jamin Lin
2026-07-09 21:03   ` Philippe Mathieu-Daudé
2026-07-03  7:43 ` [PATCH v1 2/3] hw/usb/aspeed-udc: Add ASPEED UDC gadget USB device Jamin Lin
2026-07-03  7:43 ` [PATCH v1 3/3] hw/arm/aspeed_ast2600: Wire up the UDC Jamin Lin
2026-07-09 21:10   ` Philippe Mathieu-Daudé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260703074332.1049473-1-jamin_lin@aspeedtech.com \
    --to=jamin_lin@aspeedtech.com \
    --cc=andrew@codeconstruct.com.au \
    --cc=clg@kaod.org \
    --cc=joel@jms.id.au \
    --cc=kane_chen@aspeedtech.com \
    --cc=leetroy@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=steven_lee@aspeedtech.com \
    --cc=troy_lee@aspeedtech.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox