From 363e24bcd18a28948f63fa78ac8a4eaa8784fe59 Mon Sep 17 00:00:00 2001 From: salmonik Date: Sun, 1 Nov 2026 16:33:09 +0100 Subject: scripts: add test-usb; fix duplicate -bios in the test harness - test-usb boots an EHCI and an xHCI controller with a mouse + keyboard and asserts enumeration, report decoding, and input reaching the shell. The EHCI case asserts one key end-to-end (QEMU's EHCI model delivers only the first report through root-port split transactions); the xHCI case asserts a whole typed command. - lib.sh: qemu_args() already supplies -bios, so the fresh OVMF varstore copy was silently overridden by the system firmware. Pass the copy last (QEMU honours the last -bios) so tests really boot clean NVRAM. - DEBUG_NOTES: document why USB never worked on the OptiPlex (EHCI shipped with DEBUG_MATRIX enabled, no RMH/hub support, only the first controller, no boot protocol, unbounded DMA), the success/failure log to look for on hardware, and the QEMU coverage limits. - Makefile: add test-usb and include it in `make test`. --- scripts/tests/test-usb.sh | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100755 scripts/tests/test-usb.sh (limited to 'scripts/tests/test-usb.sh') diff --git a/scripts/tests/test-usb.sh b/scripts/tests/test-usb.sh new file mode 100755 index 0000000..55a3f2b --- /dev/null +++ b/scripts/tests/test-usb.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# +# scripts/tests/test-usb.sh — USB host-controller + HID regression. +# +# Boots twice, once with an EHCI (USB2) controller and once with an xHCI +# (USB3) controller, each with a HID mouse and keyboard: +# +# • both devices must enumerate and arm their interrupt-IN endpoints +# • a keyboard report must be decoded (scancode path) +# • the key must reach the shell (WM input routing) +# +# QEMU limitation: its EHCI model delivers only the *first* report for a +# full/low-speed device serviced by root-port split transactions, so the EHCI +# case asserts one key end-to-end (a regression in enumeration/arming fails +# earlier). The xHCI case has no splits and asserts a whole typed command. +# Mouse report delivery cannot be injected into usb-mouse headless; the +# hardware run (OptiPlex) is the arbiter for both. +# +# Usage: ./scripts/tests/test-usb.sh +# Env: SYSTEM_IMG, OVMF, QEMU (see scripts/lib.sh) +# +set -euo pipefail +source "$(dirname "$0")/../lib.sh" + +echo "==> 1/3 build (kernel + bins)" +build_all + +echo "==> 2/3 stage system image" +stage_image --force + +# Per-controller log/socket files; test_boot() reads these globals. +case_boot() { + local name="$1" + shift + LOG="/tmp/rsdos-usb-$name-serial.log" + SOCK="/tmp/rsdos-usb-$name-qmon.sock" + QPID="/tmp/rsdos-usb-$name-qpid" + QLOG="/tmp/rsdos-usb-$name-qemu.log" + test_boot "$@" +} + +case_arms() { + wait_log "$LOG" "HID mouse armed" 20 || fail "$1: mouse not enumerated" + wait_log "$LOG" "HID keyboard armed" 20 || fail "$1: keyboard not enumerated" + sleep 1 +} + +case_done() { + kill "$(cat "$QPID" 2>/dev/null)" 2>/dev/null || true + sleep 0.5 + echo " $1: mouse + keyboard OK" +} + +echo "==> 3/3 EHCI (USB2) enumeration" +case_boot ehci \ + -device usb-ehci,id=ehci \ + -device usb-mouse,bus=ehci.0,port=1 \ + -device usb-kbd,bus=ehci.0,port=2 +case_arms ehci +sendkeys "h" +wait_log "$LOG" "kbd report" 10 || fail "ehci: no keyboard report decoded" +tr -d '\r' < "$LOG" | grep -qx "h" || fail "ehci: typed key did not reach the shell" +case_done ehci + +echo "==> 3/3 xHCI (USB3) enumeration" +case_boot xhci \ + -device qemu-xhci,id=xhci \ + -device usb-mouse,bus=xhci.0 \ + -device usb-kbd,bus=xhci.0 +case_arms xhci +sendkeys "he" +wait_log "$LOG" "kbd report" 10 || fail "xhci: no keyboard report decoded" +wait_log "$LOG" "unknown command: he" 15 || fail "xhci: typed text did not reach the shell" +case_done xhci + +echo "" +echo "PASS — USB enumeration + HID input (EHCI and xHCI)" -- cgit v1.2.3