base fork sync (upstream 59cf8189) + P3-B/C doc closure + hub proof script

Base fork:
- Merged upstream/main 59cf8189 (13 upstream commits) into submodule/base
  as 9bbdc2ca; 3 conflicts resolved by hand (irq_reactor.rs process_one_event
  refactor + SPURIOUS_REBOOT reapply; randd simplification + fcntl reapply;
  Makefile /dev symlink block). verify-fork-functions gate now passes for
  base. kernel (11 fns) and relibc (2 fns) remain behind upstream — tracked
  as T-7d82cf6f / T-a5699340 / T-f5b7a0ea for dedicated sessions.
- Also landed earlier: upgrade-forks.sh cd-back bug fix (7e7ef73a).

Docs:
- P3-B marked COMPLETE (premise was stale: usbhubd is interrupt-driven
  with polling fallback today).
- P3-C marked hub-side COMPLETE (PortIndicator set in event loop);
  keyboard LED sync remains P5-C scope.
- README USB/Bluetooth row upgraded from red/in-progress to reflect
  P2-A/B/C + P3-A/B/C reality.

Validation:
- New test-usb-hub-qemu.sh (P8-B): boots QEMU with usb-hub + usb-kbd
  behind it, validates usbhubd spawn, 8-port descriptor read, change-
  detection mode, HID registration behind the hub, no panics. Cannot
  run until kernel+relibc syncs unblock the image build.
This commit is contained in:
2026-07-19 05:48:45 +09:00
parent 7e7ef73a8c
commit ba46a4c715
4 changed files with 206 additions and 16 deletions
+1 -1
View File
@@ -137,7 +137,7 @@ successfully on branch `0.3.1`. Graphics packages are frozen at latest upstream
| KWin | 🟡 Builds successfully (redox-drm + Qt6 Wayland); runtime blocked by Qt6 Wayland crash in `wl_proxy_add_listener` |
| KDE Plasma | 🔴 Runtime blocked by Qt6 Wayland null+8 crash — depends on KWin |
| WiFi (Intel iwlwifi) | 🟡 VFIO/passthrough bounded runtime validation framework exists |
| USB / Bluetooth | 🔴 USB maturity work in progress; Bluetooth controller path planned |
| USB / Bluetooth | 🟡 xHCI mature in QEMU: 51-flag quirks, capability gating, 36-code error recovery, Linux hub enumeration state machine; storage BOT proven; hub runtime proof + UAS/HID expansion open; Bluetooth controller path planned |
**Where help is most wanted:**
Qt6 Wayland protocol crash — the #1 blocker for graphical desktop · AMD/Intel GPU hardware validation on bare metal · USB controller maturity · WiFi native control plane · cub AUR pipeline hardening · package maintainers for the growing recipe catalog · tlc VFS remote backends and archive support
+14 -14
View File
@@ -371,30 +371,30 @@ U1/U2 LPM on hub ports (P7); interrupt-EP usage on USB 3 hubs without one
**Exit met:** complete hub enumeration including power timing, USB 3 hub
handling, and TT accumulation.
### P3-B: Hub interrupt-driven change detection
### P3-B: Hub interrupt-driven change detection ✅ COMPLETE (verified 2026-07-18)
**Reference:** `linux-7.1/drivers/usb/core/hub.c:1000+` `hub_irq()`.
Current usbhubd polls at 100ms intervals. Linux uses hub interrupt endpoints (`USB_ENDPOINT_DIR_IN` + `USB_USAGE_TYPE_INTERRUPT`) for immediate change notification.
**Status:** Implemented (predates the P3-A pass; verified during it).
~~Current usbhubd polls at 100ms intervals~~ — stale premise; usbhubd is
interrupt-driven today:
**Tasks:**
1. ✅ EP1 interrupt endpoint discovered and opened (`EndpointTy::Interrupt` + `EndpDirection::In`).
2. ✅ Status-change bitmap read via `transfer_read()`; per-bit port dispatch (Linux `hub_irq()` → `kick_hub_wq` equivalent).
3. ✅ Fallback to full polling (200 ms) only when EP1 is absent or fails — matches the exit criterion for USB 3 hubs without interrupt endpoints.
1. Add interrupt endpoint configuration to usbhubd (USB hub interrupt endpoint is always EP1).
2. Subscribe to interrupt IN transfers for status change bitmap.
3. Fall back to polling only when interrupt endpoint is unavailable.
**Exit met:** interrupt-driven on USB 2 hubs; polling fallback otherwise.
**Exit:** interrupt-driven on USB 2 hubs; polling fallback on USB 3 hubs (which lack interrupt endpoints).
### P3-C: Port LED control
### P3-C: Port LED control ✅ HUB-SIDE COMPLETE (verified 2026-07-18)
**Reference:** `linux-7.1/drivers/usb/host/xhci-port.h:64-67` (PORT_LED_OFF/AMBER/GREEN).
**Tasks:**
**Status:** Hub-side done — usbhubd sets `SetPortFeature(PORT_INDICATOR)`
on connected+enabled+!resetting ports in the event loop.
1. Expose hub port LED control via `SET_HUB_FEATURE(PORT_INDICATOR)`.
2. Implement in usbhidd keyboard LED sync (cross-couple with P5-C).
**Exit:** port LEDs controllable via scheme.
**Remaining (P5-C scope, not P3):** keyboard LED state sync in usbhidd
(Caps/Num/Scroll Lock → HID SET_REPORT output), cross-coupled with the
input stack.
---
+190
View File
@@ -0,0 +1,190 @@
#!/usr/bin/env bash
# Launch or validate USB hub enumeration (P3-A state machine) in QEMU.
#
# Topology under test:
# qemu-xhci root port 1 → usb-hub (USB 2.0, 8 ports)
# └─ hub port 2 → usb-kbd
# qemu-xhci root port 2 → usb-tablet (control case, direct attach)
#
# Validates: hub descriptor read, usbhubd spawn, EP1 change detection or
# polling fallback, power-on, debounce, reset-wait, attach delegation to
# xhcid, child enumeration behind the hub (usbhidd spawn), no panics.
set -euo pipefail
find_uefi_firmware() {
local candidates=(
"/usr/share/ovmf/x64/OVMF.4m.fd"
"/usr/share/OVMF/x64/OVMF.4m.fd"
"/usr/share/ovmf/x64/OVMF_CODE.4m.fd"
"/usr/share/OVMF/x64/OVMF_CODE.4m.fd"
"/usr/share/ovmf/OVMF.fd"
"/usr/share/OVMF/OVMF_CODE.fd"
"/usr/share/qemu/edk2-x86_64-code.fd"
)
local path
for path in "${candidates[@]}"; do
if [[ -f "$path" ]]; then
printf '%s\n' "$path"
return 0
fi
done
return 1
}
usage() {
cat <<'USAGE'
Usage: test-usb-hub-qemu.sh [--check] [config]
Boot or validate USB hub enumeration (usbhubd P3-A state machine) on a
Red Bear image in QEMU. Defaults to redbear-mini.
USAGE
}
check_mode=0
config="redbear-mini"
for arg in "$@"; do
case "$arg" in
--help|-h|help)
usage
exit 0
;;
--check)
check_mode=1
;;
redbear-*)
config="$arg"
;;
esac
done
firmware="$(find_uefi_firmware)" || {
echo "ERROR: no usable x86_64 UEFI firmware found" >&2
exit 1
}
arch="${ARCH:-$(uname -m)}"
image="build/$arch/$config/harddrive.img"
extra="build/$arch/$config/extra.img"
if [[ ! -f "$image" ]]; then
echo "ERROR: missing image $image" >&2
echo "Build it first with: ./local/scripts/build-redbear.sh $config" >&2
exit 1
fi
if [[ ! -f "$extra" ]]; then
truncate -s 1g "$extra"
fi
pkill -f "qemu-system-x86_64.*$image" 2>/dev/null || true
sleep 1
if [[ "$check_mode" -eq 1 ]]; then
log_file="build/$arch/$config/usb-hub-check.log"
rm -f "$log_file"
set +e
timeout 180s qemu-system-x86_64 \
-name "Red Bear OS x86_64" \
-device qemu-xhci,id=xhci \
-device usb-hub,bus=xhci.0,port=1 \
-device usb-kbd,bus=xhci.0,port=1.2 \
-device usb-tablet,bus=xhci.0,port=2 \
-smp 4 \
-m 2048 \
-bios "$firmware" \
-chardev stdio,id=debug,signal=off,mux=on \
-serial chardev:debug \
-mon chardev=debug \
-machine q35 \
-device ich9-intel-hda -device hda-output \
-device virtio-net,netdev=net0 \
-netdev user,id=net0 \
-nographic -vga none \
-drive file="$image",format=raw,if=none,id=drv0,snapshot=on \
-device nvme,drive=drv0,serial=NVME_SERIAL \
-drive file="$extra",format=raw,if=none,id=drv1,snapshot=on \
-device nvme,drive=drv1,serial=NVME_EXTRA \
-enable-kvm -cpu host \
> "$log_file" 2>&1
status=$?
set -e
fail=0
# 1. xhcid detected the controller.
if ! grep -q "^.*XHCI " "$log_file"; then
echo "ERROR: xHCI controller not detected in boot log; see $log_file" >&2
exit 1
fi
# 2. usbhubd spawned for the hub device.
if ! grep -q "USB HUB driver spawned" "$log_file"; then
echo "ERROR: usbhubd did not spawn for the QEMU usb-hub" >&2
echo " Expected: 'USB HUB driver spawned'" >&2
echo " See $log_file" >&2
exit 1
fi
# 3. Hub descriptor read succeeded (QEMU usb-hub exposes 8 ports).
if ! grep -q "usbhubd: 8 port(s) detected" "$log_file"; then
echo "ERROR: hub descriptor read failed or wrong port count" >&2
echo " Expected: 'usbhubd: 8 port(s) detected'" >&2
grep -i "usbhubd" "$log_file" | tail -10 >&2 || true
echo " See $log_file" >&2
exit 1
fi
# 4. Change detection is active (interrupt EP or polling fallback).
if ! grep -Eq "interrupt endpoint opened for change detection|no interrupt endpoint found, using polling|interrupt endpoint open failed .*falling back to polling" "$log_file"; then
echo "ERROR: usbhubd did not report a change-detection mode" >&2
echo " See $log_file" >&2
exit 1
fi
# 5. HID class driver spawned — the usb-kbd sits BEHIND the hub, so
# a registered producer proves the hub port enumeration chain
# (power-on → debounce → reset-wait → attach → xhcid enumerate).
if ! grep -q "usbhidd: registered producer" "$log_file"; then
echo "ERROR: usbhidd did not register — child enumeration behind hub failed" >&2
echo " Expected: 'usbhidd: registered producer'" >&2
echo " See $log_file" >&2
exit 1
fi
# 6. No panics anywhere in the boot.
if grep -qiE "panic|RUST_BACKTRACE" "$log_file"; then
echo "ERROR: panic detected in boot log" >&2
grep -iE "panic|RUST_BACKTRACE" "$log_file" | head -5 >&2
echo " See $log_file" >&2
exit 1
fi
echo "HUB_ENUMERATION=ok"
echo "HUB_LOG=$log_file"
echo "USB hub enumeration confirmed in $log_file"
exit 0
fi
exec qemu-system-x86_64 \
-name "Red Bear OS x86_64" \
-device qemu-xhci,id=xhci \
-device usb-hub,bus=xhci.0,port=1 \
-device usb-kbd,bus=xhci.0,port=1.2 \
-device usb-tablet,bus=xhci.0,port=2 \
-smp 4 \
-m 2048 \
-bios "$firmware" \
-chardev stdio,id=debug,signal=off,mux=on \
-serial chardev:debug \
-mon chardev=debug \
-machine q35 \
-device ich9-intel-hda -device hda-output \
-device virtio-net,netdev=net0 \
-netdev user,id=net0 \
-vga std \
-drive file="$image",format=raw,if=none,id=drv0,snapshot=on \
-device nvme,drive=drv0,serial=NVME_SERIAL \
-drive file="$extra",format=raw,if=none,id=drv1,snapshot=on \
-device nvme,drive=drv1,serial=NVME_EXTRA \
-enable-kvm -cpu host