Add input module: broadcast keyboard events over IPC

Programs can now subscribe to keyboard events (key_down/key_up/key_press)
and drivers can broadcast them, through a new user-space input service.

The delivery model is forced by danos IPC: a synchronous rendezvous holds
one pending reply, so a server cannot park N subscribers blocked in a
"wait for next event" call — delivery must be push. But a synchronous push
has no timeout and the kernel never wakes a sender parked on a dead peer's
endpoint, so one dying subscriber would hang all input. So this lands the
roadmap's planned asynchronous buffered send and builds the service on it:

- ipc_send (syscall 26): non-blocking post to an endpoint's bounded payload
  ring, delivered through reply_wait as a buffered message (notify_message_bit).
  A full ring drops the oldest. It can never hang on a dead/slow peer.
- input-protocol + runtime.input helpers (subscribe/next, connectSource/
  publish) — the first real consumer of M13 capability passing: a subscriber
  hands the service its own endpoint as a capability.
- input service (fan-out via ipc_send, dead-subscriber pruning), a synthetic
  input-source, and input-test; the ps2-bus keyboard driver publishes to it.
  Real IRQ1 scancode decoding (which must live in the bus, the PNP0303 owner)
  is a documented follow-up; the source is synthetic for now.
- build/init wiring, an `input` QEMU case, and docs/input.md.

Full QEMU suite 48/48, including the new input case and every IPC/endpoint
regression (ipc, ipc-call, ipc-cap, vfs, hpet, bus, irqfree).
This commit is contained in:
Daniel Samson
2026-07-11 15:03:24 +01:00
parent 2a583d55a8
commit 65244e3103
19 changed files with 765 additions and 5 deletions
+14 -1
View File
@@ -36,8 +36,21 @@ pub fn main() void {
// served through the bus and does not claim the controller itself.
_ = runtime.system.write("system/drivers/ps2-bus/keyboard: served by ps2-bus (controller owned by bus)\n");
// Broadcast keyboard events through the input service so programs can listen for them
// (docs/input.md). Until the bus reads real IRQ1 scancodes and hands them here (a
// follow-up), we publish the same synthetic stand-in stream the demo source uses — the
// fan-out path is real, only the source of the bytes is placeholder.
var source = runtime.input.connectSource() orelse {
_ = runtime.system.write("system/drivers/ps2-bus/keyboard: input service unavailable\n");
return;
};
_ = runtime.system.write("system/drivers/ps2-bus/keyboard: ok\n");
while (true) runtime.system.sleep(1000);
var step: usize = 0;
while (true) : (step +%= 1) {
_ = source.publish(runtime.input.syntheticEvent(step));
runtime.system.sleep(200);
}
}
pub const panic = runtime.panic;