Skip to main content

godspeed/driver/
input.rs

1// SPDX-License-Identifier: Apache-2.0
2//! A driver's INPUT: handing what the user typed to the console, and saying input is up.
3//!
4//! # Why this exists
5//!
6//! A keyboard driver's job ends at the console's input ring: each byte it decodes is pushed there and
7//! reaches the shell exactly as a serial keystroke does. `xhci`, `ehci` and `dwc2` each reached past the
8//! standard library for it, with the SDK's `ctx.console_push`; this is the same call, in the shape the
9//! promise covers (`docs/driver-library.md`, step 5).
10//!
11//! # What it is, and is not
12//!
13//! Authority the kernel granted at spawn, `CONSOLE_PUSH`, and nothing more. Without it both calls do
14//! nothing, which is the SDK's behaviour unchanged. A keyboard's keystrokes are commands, so a holder is
15//! inside the shell's trust perimeter (CLAUDE.md 6.4, SEC-2); this module adds no authority to that.
16//! What a key MEANS - the HID usage table, auto-repeat - is the device's and stays out of here.
17//!
18//! ```ignore
19//! gs::driver::input::push(&ctx, b'a');
20//! gs::driver::input::ready(&ctx); // once, when setup is finished either way
21//! ```
22
23#[cfg(not(test))]
24use godspeed_sdk::service_context::ServiceContext;
25
26/// Push one byte into the console's input ring, as if it were typed on the serial console. Does nothing
27/// for a driver that was not granted `CONSOLE_PUSH`.
28#[cfg(not(test))]
29#[inline(always)]
30pub fn push(ctx: &ServiceContext, byte: u8) {
31    ctx.console_push(byte)
32}
33
34/// Say that this driver has just printed a notice over the console (a device plugged in or out), so the
35/// program reading it can put its line back: pushes `NOTICE_SIGNAL` (`godspeed_sdk::hid`), which no key
36/// produces. Not an Enter, which would answer a question or run a half-typed line. Does nothing without
37/// `CONSOLE_PUSH`.
38#[cfg(not(test))]
39#[inline(always)]
40pub fn notice_shown(ctx: &ServiceContext) {
41    ctx.console_push(godspeed_sdk::hid::NOTICE_SIGNAL)
42}
43
44/// Say that input setup is finished - the end-of-boot signal the shell watches to clear the boot screen.
45/// Called in every terminal path of a keyboard driver's setup, found or not. Does nothing without
46/// `CONSOLE_PUSH`.
47#[cfg(not(test))]
48#[inline(always)]
49pub fn ready(ctx: &ServiceContext) {
50    ctx.signal_input_ready()
51}