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
next reply other threads:[~2026-07-03 7:44 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.