summaryrefslogtreecommitdiffstats
path: root/CONTEXT.md
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-01 19:34:40 +0200
committersalmonik <salmonik@tuta.io>2026-08-01 19:34:40 +0200
commit9b9758e5ee2564b04685eadf2b9ce23dd1060b86 (patch)
tree57fce9e715510ec70df70dc399b4440f3480fd77 /CONTEXT.md
parentfix pi-lens warnings: unwraps, shell SC2046, dup code (fmtbuf/scripts/hexdump... (diff)
downloadrs-dos-9b9758e5ee2564b04685eadf2b9ce23dd1060b86.tar.gz
rs-dos-9b9758e5ee2564b04685eadf2b9ce23dd1060b86.zip
rsnix v0.4.0: GUI input foundation — PS/2 mouse + scheduler message queues
Mouse (IRQ12, stream mode): ByteRing generalized for both PS/2 devices, ISR routes data-port bytes by the controller's aux bit; mouse_init with bounded-ACK handshake (boots without a mouse); packet decoder with bit-3 resync, screen-relative deltas, buttons. Exposed as /dev/mouse, the `mouse` stream command, and `make test-mouse`. Message queues (ADR 0003's GUI-era primitive): every task gets a static 16-slot TaskMsg ring; send/recv/recv_blocking with direct wake + tick scan safety net for the lost-wakeup race; `msgrecv`/`send` commands, `mouse <id>` routes real IRQ12 events into a task's queue, jobs shows q=. `make test-msg` + `make test-disk` regression pass.
Diffstat (limited to 'CONTEXT.md')
-rw-r--r--CONTEXT.md73
1 files changed, 72 insertions, 1 deletions
diff --git a/CONTEXT.md b/CONTEXT.md
index 112b8de..9ceb81d 100644
--- a/CONTEXT.md
+++ b/CONTEXT.md
@@ -113,7 +113,9 @@ Workspace version is `a.b.c` (single version for all crates):
113 113
114Bump the workspace version in the root `Cargo.toml` when a change of 114Bump the workspace version in the root `Cargo.toml` when a change of
115that class lands — do not leave the version to drift. Current: 115that class lands — do not leave the version to drift. Current:
116`0.2.0`; the multitasking work lands as a `b` bump (`0.3.0`). 116`0.4.0` — the GUI input foundation (PS/2 mouse + scheduler message
117queues) landed as a `b` bump; the GUI era itself is reserved for the
118`a` bump (1.0.0).
117 119
118## Project layout 120## Project layout
119 121
@@ -404,6 +406,75 @@ Workspace of four crates, all built for the `x86_64-unknown-uefi` target:
404 `bg overflow` dies on the guard page with the machine intact; full 406 `bg overflow` dies on the guard page with the machine intact; full
405 regression (rescan/til/klog/grammar/pager) re-passes. 407 regression (rescan/til/klog/grammar/pager) re-passes.
406 408
409✅ **PS/2 mouse** — auxiliary-channel driver on IRQ12, stream mode
410 (3-byte packets), the GUI's second input device:
411
412- `interrupts`: the keyboard byte ring is generalised to `ByteRing`;
413 IRQ12 (vector 44) gets its own ring and stub. Both PS/2 handlers
414 route each data-port byte by the controller status register's aux
415 bit (bit 5), so keyboard and mouse never steal each other's bytes
416 even when both are pending at once. PIC unmask now covers IRQ2
417 (cascade) and IRQ12 (slave bit 4).
418- `ps2`: `mouse_init()` enables the aux port, sets config bits
419 IRQ12+aux-clock (preserving the keyboard bit), then `set defaults`
420 (100 Hz / 4 counts/mm / 1:1) + `enable reporting` via the 0xD4
421 channel — each waits for the device ACK with a bounded timeout so
422 a machine without a mouse boots normally (log: `ps2: mouse not
423 present`). `try_poll_mouse()` reassembles packets in main
424 context from the raw byte ring; the packet-start marker (bit 3)
425 resyncs the stream after any lost byte. Events are **screen-
426 relative** (`dx` + = right, `dy` + = down — the PS/2 Y-up wire
427 convention is negated), buttons decoded; 9-bit sign extension via
428 the packet sign bits.
429- `fs`: `/dev/mouse` char device — `cat /dev/mouse` drains up to 32
430 pending events (`dx=+N dy=+N buttons=L-R`), reports
431 `mouse: no PS/2 mouse` / `mouse: no events` otherwise.
432- shell: `mouse` command streams live events (10 ms poll via
433 `sleep_ms`) until ^C.
434
435 Verified in QEMU (`make test-mouse`, headless, via the monitor's
436 `mouse_move`/`mouse_button` HMP commands): boot line `ps2: mouse
437 ready`, `/dev/mouse` drains a pre-consumer move (`8,4`), the live
438 stream decodes `mouse_move 20 7` → `dx=+20 dy=+7 buttons=---`,
439 `mouse_button 1` → `buttons=L--`, a held-button move
440 (`-5,-3` while L down) → `dx=-5 dy=-3 buttons=L--`, release,
441 and ^C stops the stream. `make test-disk` regression re-passes.
442
443✅ **Scheduler message queues (the GUI-era primitive from ADR 0003)** —
444 every task gets a static 16-slot ring of `TaskMsg` (4 KB in .bss,
445 no ISR-time allocation):
446
447- `TaskMsg` = `Key(KeyEvent)` | `Mouse(MouseEvent)` | `Timer` |
448 `User(u64)` — input uses the same decoded types the PS/2 drivers
449 produce, so window input routing is literally "post what the
450 console would have gotten"; `User(u64)` is the generic escape
451 hatch. `KeyEvent`/`MouseEvent` derive Copy for ring storage.
452- `sched::send(id, msg)` — posts from any context (task, shell, ISR)
453 under the scheduler lock; wakes a Blocked task straight to Ready;
454 errors cleanly on a gone task or a full queue (input is lossy
455 under extreme load by design). `recv()` pops without blocking;
456 `recv_blocking()` marks the task Blocked and yields. **Lost-wakeup
457 safety net**: the tick scan also wakes Blocked tasks whose queue is
458 non-empty, so a task that blocked *after* its message arrived (or
459 whose poster never woke it) is picked up within one 10 ms tick.
460- shell: `msgrecv` spawns a task that blocks on recv and logs every
461 message to serial (`msgrecv[2]: Key(F3)` …); `send <id> <type>
462 [args]` posts `user <n>` / `timer` / `mouse <dx> <dy> <btn>`
463 (1=L 2=R 4=M) / `key <name>` (enter esc tab space bksp arrows
464 home end pgup pgdn del ctrl-c f1..f12, or a single char); `jobs`
465 now shows `q=` (pending message count).
466- **Real-input routing, proven**: `mouse <id>` (angle brackets) streams
467 decoded IRQ12 events into that task's queue instead of the console
468 — the exact loop the window manager will run. `msgrecv` + `mouse 2`
469 - `mouse_move 20 7` showed `msgrecv[2]: Mouse(+20,+7 …)` in QEMU.
470
471 Verified in QEMU (`make test-msg`): all six message types delivered
472 in order (user, timer, key enter/ctrl-c/f3, synthesized mouse),
473 real routed mouse moves (including a held-button move), the 17th
474 send against a 16-cap queue reports `queue full` (tested against
475 the shell's never-consumed queue), and `jobs` shows q=0 + task back
476 to `blocked` after draining. `make test-disk` regression re-passes.
477
407## Known issues / perf notes 478## Known issues / perf notes
408 479
409- **Scroll cost** — scrolling still shifts the whole framebuffer (a 480- **Scroll cost** — scrolling still shifts the whole framebuffer (a