aarch64: virtio-keyboard-pci, interrupt-driven keyboard input (item 4.3.5e)

Punch list §25 item 4.3.5e complete.

Extended virtio_input.c with a GIC-routed interrupt path alongside 4.3.5c's
PLIC one -- same capability walk, feature negotiation, eventq handling
(confirming §27.5.1's prediction that these items would share most of the
driver). aarch64_irq_handler() dispatches to virtio_input_isr() before its
EOIR write, same claim-dispatch-complete ordering riscv64 uses. Verified
with a real QEMU sendkey keypress: exact KEY_A/press match, two real
interrupts serviced, identical result to riscv64. Found (not fixed) an
unrelated pre-existing bug: BYE's cold-reset path faults on aarch64,
discovered incidentally since nobody had exercised it from a monitored
session before. Three-arch acceptance boot clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-08 12:29:27 -04:00
co-authored by Claude Sonnet 5
parent 2a2d7c5e5e
commit a373c9124a
18 changed files with 72523 additions and 78 deletions
+19
View File
@@ -33,6 +33,14 @@ extern uint32_t apic_timer_ppi(void);
extern void apic_eoi_intid(uint32_t intid);
extern void apic_timer_rearm(void);
/* Defined in virtio_input.c (item 4.3.5e). g_virtio_input_gic_intid is 0
* (not a valid SPI INTID -- SPIs start at 32) until
* virtio_input_find_keyboard() finds a real device and computes its routed
* INTID, so this branch is inert on any boot where the device isn't
* present. Same extern-in-place convention as the rest of this file. */
extern uint32_t g_virtio_input_gic_intid;
extern void virtio_input_isr(void);
/* INTID 1023 = "spurious" (GICv2 spec): the CPU interface has nothing
* pending, typically because another interrupt at the same or higher
* priority raced this one to acknowledgement. Architecturally defined,
@@ -64,6 +72,13 @@ extern void apic_timer_rearm(void);
* the rest of the dispatch means a fault in @c heartbeat_tick() cannot
* also cost the next tick — same discipline as @c riscv64_timer_rearm()
* (item 0.3).
*
* virtio-input (item 4.3.5e, @c g_virtio_input_gic_intid): dispatched
* **before** the @c GICC_EOIR write below, not after — the ISR itself is
* what deasserts the device's (level-triggered) interrupt line by reading
* its ISR-status capability; EOI'ing first would let the GIC immediately
* re-signal a still-asserted line. Same claim-dispatch-complete ordering
* @c riscv64_interrupt_handler() uses for its own PLIC-routed devices.
*/
void aarch64_irq_handler(void)
{
@@ -74,6 +89,10 @@ void aarch64_irq_handler(void)
heartbeat_tick();
}
if (intid == g_virtio_input_gic_intid) {
virtio_input_isr();
}
if (intid != GIC_INTID_SPURIOUS) {
apic_eoi_intid(intid);
}