feat(usb): a USB keyboard -- a full one -- and no hang on a PC without PS/2

boards/BRINGUP.md A3 and S3, FABRIC-3 SXLI.  A HID boot keyboard is
configured (interrupt IN endpoint, SET_PROTOCOL boot) and its reports
become the same Linux-keycode events as PS/2 and virtio (usb_kbd.c): the
full layout -- F-keys, navigation block, arrows, Num Lock, keypad.  The
console treats Caps and Num Lock as toggles shown on the keyboard's
lights, and the keypad as digits or navigation.  While a USB keyboard
runs, its event ring is serviced every tick, not once a second.

Found on the way: with no i8042 (port 0x64 reads 0xFF) the kernel hung at
boot in an endless drain -- a legacy-free PC would stop there.  Detected
and skipped now; drains bounded.

QEMU, amd64 with the USB keyboard the only one: 1 2 + . on main keys and
keypad, Caps Lock, Num Lock all right; aarch64/riscv64 configure it too.
Acceptance on three ISAs unchanged; identities hot-plug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-14 14:04:33 -04:00
co-authored by Claude Opus 5.5
parent 080b7012ba
commit 739cb9c163
30 changed files with 82072 additions and 14 deletions
+2 -2
View File
@@ -25,7 +25,7 @@ None has been fixed: each needs your word.
|---|---|---|---|
| A1 | **Fixed in part 2026-10-14.** The USB controller was matched by QEMU's own IDs (`1B36:000D`) on PCI bus 0 alone. Now: found by its PCI class (`0C/03/30`) on any bus, slot and function; its register window mapped at the size its BAR reports; taken from the firmware through the USB Legacy Support capability (SMIs off); and 64-byte contexts (`CSZ=1`, common on real controllers) laid out instead of refused. **Still open:** only the first controller found is used -- a PC with several (the SER5 has more than one) drives only that one's ports, so a stick or keyboard has to be in one of them. | `kernel/src/usb/xhci.c`, `kernel/src/pci/pci.c`; `FABRIC-3.md` XL | Rehearsed in QEMU with another vendor's controller behind a bridge, all three ISAs. Not rehearsable: the firmware handoff and 64-byte contexts (QEMU's controller has neither). |
| A2 | **No prompt without a login.** The production default, `EMERGENCY_CONSOLE_ENABLED=n`, keeps the system headless until an identity logs in by thumbdrive. | `Kconfig.heartbeat:68`; `FABRIC-3.md` VIII.1 | With A1, the v3 system never shows a prompt on hardware. A bring-up build must set `EMERGENCY_CONSOLE_ENABLED=1`. |
| A3 | **There is no USB keyboard driver.** Keys come from the i8042 PS/2 controller (amd64), a virtio keyboard (riscv64, QEMU only), or the serial port. | `kernel/src/arch/amd64/i8042.c`, `kernel/src/kernel_main.c:773`, `kernel/src/hal/console.c` | A USB keyboard does nothing unless the board's firmware goes on emulating PS/2 after the kernel takes over, which is not known for any of them. Plan to type over serial. |
| A3 | **Fixed 2026-10-14.** A USB boot-protocol keyboard is driven (xHCI interrupt endpoint, `SET_PROTOCOL(boot)`), its reports become the same key events as the PS/2 and virtio keyboards, and the console treats a full keyboard as one: Caps Lock and Num Lock as toggles shown on the keyboard's lights, the keypad as digits or navigation, the arrows and navigation block mapped (the line editor itself still has no cursor movement). While a USB keyboard runs, the console services its reports every timer tick. | `kernel/src/usb/usb_kbd.c`, `kernel/src/usb/xhci.c`, `kernel/src/repl.c`; `FABRIC-3.md` XLI | Rehearsed in QEMU on all three ISAs; on amd64 with the USB keyboard the only keyboard. Limits: the first controller found (A1); a keyboard whose first interface is not the keyboard is not used; no key repeat. |
| A4 | **The only disk driver is virtio.** | `kernel/src/virtio/virtio_blk.c`; `kernel_main.c:493` | On hardware Artemis finds no disk ("Artemis: no virtio-blk disk"). What the fleet then does has not been tried even in QEMU: see step 3.3. |
| A5 | **Entropy:** RDRAND on amd64 only. aarch64 and riscv64 have virtio-rng alone. | `kernel/src/rng/rng.c` | Pi 5 and Mars print the "no entropy backend available" warning; anything that needs random bytes is refused. Minting needs them. |
| A6 | **The board images cannot build the v4 node.** `make boot_image` has no `STARFORTH_V4` path. | root `Makefile`, `kernel/Makefile` | Ruled 2026-10-13: both systems, switchable. Not built yet. |
@@ -36,7 +36,7 @@ None has been fixed: each needs your word.
|---|---|---|---|
| S1 | HPET address fixed at `0xFED00000`, not read from ACPI. | `FABRIC-3.md` III item 6, finding 1 | Wrong only on a machine that puts it elsewhere. Most do not. |
| S2 | Local APIC address fixed at `0xFEE00000`; the MADT's override entry is not parsed. | finding 2 | The same. |
| S3 | The i8042 controller and the legacy PIC are written to with no check that they exist. | finding 3 | Unknown on a machine with neither. |
| S3 | **Half fixed 2026-10-14.** The i8042: a PC without one (port 0x64 reads 0xFF) hung the kernel at boot, in a drain loop that never ended -- found rehearsing A3 with QEMU's `i8042=off`. Now detected and skipped, every drain bounded. Still open: the legacy PIC is written to with no check that it exists. | `kernel/src/arch/amd64/i8042.c`; finding 3; `FABRIC-3.md` XLI | A legacy-free SER5 no longer stops at the I/O APIC. The PIC: unknown on a machine without one. |
| S4 | `BYE` resets through the i8042, not the ACPI reset register. | finding 4 | `BYE` may do nothing. It does not hang. |
| S5 | Whether the SER5 has a serial header is not known. | `FABRIC-3.md` III | Without one, and with A3, the SER5 can be watched over HDMI and not typed to. |