riscv64: virtio-keyboard-pci, interrupt-driven keyboard input (item 4.3.5c)
Punch list §25 item 4.3.5c complete. Amended from a nonexistent MMIO transport to PCI (matching the board's actual virtio-blk-pci precedent). New virtio-input driver: eventq with pre-posted buffers, PLIC source computed at runtime from PCI slot/pin (derived live from this host's QEMU riscv64 DTB), mandatory ISR-status read, PCI interrupt-disable-bit check. New VKBD-EVENT/VKBD-DEBUG FORTH words. Verified with a real QEMU sendkey keypress: exact KEY_A/press match, two real interrupts serviced, zero exceptions. Three-arch acceptance boot clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5f4df673c1
commit
8251aebcf8
@@ -24,6 +24,14 @@ extern void riscv64_install_vectors(void);
|
||||
* convention as riscv64_install_vectors above. */
|
||||
extern void riscv64_timer_rearm(void);
|
||||
|
||||
/* Defined in virtio_input.c (item 4.3.5c). g_virtio_input_plic_source is 0
|
||||
* (plic_claim()'s own "nothing pending" sentinel) until
|
||||
* virtio_input_find_keyboard() finds a real device and computes its
|
||||
* routed source -- so this branch is inert on any boot where the device
|
||||
* isn't present, same as the generic dispatch was inert before 4.3.5c. */
|
||||
extern uint32_t g_virtio_input_plic_source;
|
||||
extern void virtio_input_isr(void);
|
||||
|
||||
/* scause cause codes for supervisor-mode interrupts (RISC-V Privileged Spec
|
||||
* §4.1.9, Table "Supervisor cause register values"). */
|
||||
#define SCAUSE_INTERRUPT_BIT (1ULL << 63)
|
||||
@@ -51,14 +59,12 @@ volatile uint32_t g_plic_claim_count = 0;
|
||||
* permanently and silently. Ordering it ahead of @c heartbeat_tick() means a
|
||||
* fault in the bookkeeping cannot also cost the next tick.
|
||||
*
|
||||
* Supervisor external (cause 9, item 4.3.5b): claim/dispatch/complete
|
||||
* through the PLIC. No source is enabled by default (see plic.c), so this
|
||||
* branch is normally never reached; a future consumer enabling its own
|
||||
* source is what makes it fire. Dispatch here is deliberately generic --
|
||||
* this item is pure PLIC substrate, not a device driver -- a future
|
||||
* consumer (4.3.5c) is expected to extend this with real per-source
|
||||
* handling, the same way i8042's keyboard branch sits in amd64's
|
||||
* isr_common_handler().
|
||||
* Supervisor external (cause 9): claim/dispatch/complete through the PLIC
|
||||
* (substrate, item 4.3.5b). Source 10 (UART) stays unclaimed by anything
|
||||
* here -- 4.3.5b's own synthetic-interrupt self-test that used it was run
|
||||
* once and reverted, not a standing consumer. virtio-input (item 4.3.5c)
|
||||
* is the first real per-source dispatch, the same shape as i8042's
|
||||
* keyboard branch in amd64's isr_common_handler().
|
||||
*
|
||||
* Any other cause is ignored rather than fatal: an unexpected-but-harmless
|
||||
* asynchronous interrupt should not take the kernel down.
|
||||
@@ -76,6 +82,9 @@ void riscv64_interrupt_handler(uint64_t scause)
|
||||
uint32_t irq = plic_claim();
|
||||
if (irq != 0) {
|
||||
g_plic_claim_count++;
|
||||
if (irq == g_virtio_input_plic_source) {
|
||||
virtio_input_isr();
|
||||
}
|
||||
plic_complete(irq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ EFI_RUNTIME_SERVICES *g_sk_runtime_services = NULL;
|
||||
#include "starkernel/repl.h"
|
||||
#include "starkernel/pci.h"
|
||||
#include "starkernel/virtio_blk.h"
|
||||
#include "starkernel/virtio_input.h"
|
||||
#include "block_subsystem.h"
|
||||
#include "vm.h" /* DictEntry, vm_find_word, ACL_MODE_STRICT */
|
||||
#include "version.h"
|
||||
@@ -584,6 +585,14 @@ static void kernel_main_deep(BootInfo *boot_info) {
|
||||
}
|
||||
}
|
||||
|
||||
/* item 4.3.5c: virtio-keyboard-pci, riscv64 only today. Unconditional
|
||||
* call site, same as virtio_blk_find_artemis() above -- the function
|
||||
* itself no-ops with a console message on architectures/boards where
|
||||
* the device isn't present or interrupt routing isn't implemented yet
|
||||
* (see virtio_input.c's enable_interrupt_route()), so dictionary/boot
|
||||
* sequence parity across all three architectures is unaffected. */
|
||||
(void)virtio_input_find_keyboard();
|
||||
|
||||
/* Copy capsule directory header to heap (has pointer field needing update) */
|
||||
CapsuleDirHeader *live_dir = (CapsuleDirHeader *)kmalloc(sizeof(CapsuleDirHeader));
|
||||
if (!live_dir) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,14 @@
|
||||
* @par KBD-DEBUG ( -- isr_count spurious_count )
|
||||
* Standing diagnostic: count of real keyboard IRQs serviced and count of
|
||||
* LAPIC spurious-vector interrupts, both since boot.
|
||||
*
|
||||
* @par VKBD-EVENT ( -- code value -1 | 0 )
|
||||
* Item 4.3.5c. Pop one decoded EV_KEY event (Linux input-event code/value
|
||||
* pair) off the virtio-input interrupt-fed ring buffer. Kernel-only,
|
||||
* riscv64-only today (virtio-keyboard-pci); no-op elsewhere.
|
||||
*
|
||||
* @par VKBD-DEBUG ( -- isr_count )
|
||||
* Standing diagnostic: count of virtio-input ISR invocations since boot.
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
#include "starkernel/i8042.h"
|
||||
#endif
|
||||
|
||||
#if defined(__STARKERNEL__) && defined(ARCH_RISCV64)
|
||||
#include "starkernel/virtio_input.h"
|
||||
#endif
|
||||
|
||||
/* KBD-SCAN ( -- c -1 | 0 ) */
|
||||
static void kbw_scan(VM *vm)
|
||||
{
|
||||
@@ -50,8 +54,46 @@ static void kbw_debug(VM *vm)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* VKBD-EVENT ( -- code value -1 | 0 ): item 4.3.5c, riscv64 virtio-input.
|
||||
* Pop one decoded EV_KEY event off the interrupt-fed ring buffer. Pushes
|
||||
* code and value and -1 (true) if one was available, or just 0 (false) if
|
||||
* the buffer was empty. Distinct word from KBD-SCAN rather than a shared
|
||||
* one: different device, different event shape (Linux-style code/value
|
||||
* pair vs. a raw XT scancode byte) -- convergence onto one interface is
|
||||
* item 4.3.5f's explicit job, not this one's. */
|
||||
static void kbw_vevent(VM *vm)
|
||||
{
|
||||
#if defined(__STARKERNEL__) && defined(ARCH_RISCV64)
|
||||
uint16_t code;
|
||||
uint32_t value;
|
||||
if (virtio_input_pop_event(&code, &value)) {
|
||||
vm_push(vm, (cell_t)code);
|
||||
vm_push(vm, (cell_t)value);
|
||||
vm_push(vm, -1);
|
||||
} else {
|
||||
vm_push(vm, 0);
|
||||
}
|
||||
#else
|
||||
vm_push(vm, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* VKBD-DEBUG ( -- isr_count ): standing diagnostic, same shape as
|
||||
* KBD-DEBUG -- confirms the virtio-input interrupt path is alive. */
|
||||
extern volatile uint32_t g_virtio_input_isr_count;
|
||||
static void kbw_vdebug(VM *vm)
|
||||
{
|
||||
#if defined(__STARKERNEL__) && defined(ARCH_RISCV64)
|
||||
vm_push(vm, (cell_t)g_virtio_input_isr_count);
|
||||
#else
|
||||
vm_push(vm, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void register_keyboard_words(VM *vm)
|
||||
{
|
||||
register_word(vm, "KBD-SCAN", kbw_scan);
|
||||
register_word(vm, "KBD-DEBUG", kbw_debug);
|
||||
register_word(vm, "VKBD-EVENT", kbw_vevent);
|
||||
register_word(vm, "VKBD-DEBUG", kbw_vdebug);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user