#!/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)"