diff options
| author | salmonik <salmonik@tuta.io> | 2026-08-01 23:44:41 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-08-01 23:44:41 +0200 |
| commit | fffec0f04dfcc63bef39eb0441cfad7b584da484 (patch) | |
| tree | 394dc1897e04d0aac400061494023d1d16a89dd2 /CONTEXT.md | |
| parent | rsnix v0.5.2: fault diagnostics + real-hardware scroll-crash hardening (diff) | |
| download | rs-dos-fffec0f04dfcc63bef39eb0441cfad7b584da484.tar.gz rs-dos-fffec0f04dfcc63bef39eb0441cfad7b584da484.zip | |
rsnix v0.5.3: fix real-hardware scroll wedge — per-word display push
The real-hardware crash (2 lines of white + freeze, no CPU exception
even with the 0.5.2 fault dumps) pointed away from a fault and at a
stall: the scroll's full-frame push used one 1.92 MB rep-movsb to the
framebuffer. On QEMU the framebuffer is RAM, so it flies; on a real
GPU the framebuffer is uncached MMIO and the CPU's fast-string burst
path can stall forever — the shell wedges mid-instruction, the cursor
task's own writes wedge too, no exception fires (MMIO writes don't
fault), and the screen shows the torn partial push (the white bands).
The boot-time clear() always worked on the same hardware and uses
per-word volatile stores, so the scroll push now uses the identical
pattern: shadow reads (cached RAM, cheap) + individually-posted
display stores. Interruptible between stores, never a bulk burst,
and functionally identical on QEMU (all 5 suites re-pass).
Also converts the no-shadow fallback shift to the same per-word
pattern. CONTEXT.md updated (scroll-cost note + versioning).
Diffstat (limited to '')
| -rw-r--r-- | CONTEXT.md | 19 |
1 files changed, 14 insertions, 5 deletions
| @@ -113,13 +113,17 @@ Workspace version is `a.b.c` (single version for all crates): | |||
| 113 | 113 | ||
| 114 | Bump the workspace version in the root `Cargo.toml` when a change of | 114 | Bump the workspace version in the root `Cargo.toml` when a change of |
| 115 | that class lands — do not leave the version to drift. Current: | 115 | that class lands — do not leave the version to drift. Current: |
| 116 | `0.5.2` — the GUI era landed with 0.5.0 (graphics layer + cursor | 116 | `0.5.3` — the GUI era landed with 0.5.0 (graphics layer + cursor |
| 117 | compositor); 0.5.1 fixed the canvas at 800×600; 0.5.2 added fault | 117 | compositor); 0.5.1 fixed the canvas at 800×600; 0.5.2 added fault |
| 118 | diagnostics (screen + serial dumps for every CPU exception) and | 118 | diagnostics (screen + serial dumps for every CPU exception) and |
| 119 | real-hardware hardening (framebuffer-size clamping, fb-region exclusion | 119 | real-hardware hardening (framebuffer-size clamping, fb-region exclusion |
| 120 | from the allocators, authoritative fb geometry logging). A future | 120 | from the allocators, authoritative fb geometry logging); 0.5.3 fixed |
| 121 | major GUI overhaul (graphics windows beyond the text surface) would be | 121 | the real-hardware scroll wedge — the scroll's full-frame push is now |
| 122 | the `a` bump (1.0.0). | 122 | per-word volatile stores like the boot-time `clear()` instead of one |
| 123 | 1.92 MB rep-movsb, which can stall forever on an uncached real-GPU | ||
| 124 | framebuffer (a stall, not an exception — hence no crash dump). A | ||
| 125 | future major GUI overhaul (graphics windows beyond the text surface) | ||
| 126 | would be the `a` bump (1.0.0). | ||
| 123 | 127 | ||
| 124 | ## Project layout | 128 | ## Project layout |
| 125 | 129 | ||
| @@ -553,7 +557,12 @@ Workspace of four crates, all built for the `x86_64-unknown-uefi` target: | |||
| 553 | shadow too; scrolling is a cached shadow memcpy + one write-only | 557 | shadow too; scrolling is a cached shadow memcpy + one write-only |
| 554 | push to the display — the display is never *read* (uncached reads | 558 | push to the display — the display is never *read* (uncached reads |
| 555 | were the killer, since real-hardware GOP framebuffers are | 559 | were the killer, since real-hardware GOP framebuffers are |
| 556 | uncacheable/write-combining). | 560 | uncacheable/write-combining). **The push is per-word volatile |
| 561 | stores (0.5.3), not one bulk rep-movsb**: a 1.92 MB REP MOVS to an | ||
| 562 | uncached real-GPU framebuffer wedged the CPU on some hardware (a | ||
| 563 | stall, not an exception — no dump fired), while the boot-time | ||
| 564 | `clear()` — the same per-word pattern — always worked. QEMU's | ||
| 565 | RAM-backed framebuffer never showed it. | ||
| 557 | 2. deferred scroll batching (`vt::PENDING_SCROLLS`): the logical grid | 566 | 2. deferred scroll batching (`vt::PENDING_SCROLLS`): the logical grid |
| 558 | scrolls instantly in RAM while the framebuffer shift+push is | 567 | scrolls instantly in RAM while the framebuffer shift+push is |
| 559 | deferred; N pending scrolls cost one push. Bursts of streaming | 568 | deferred; N pending scrolls cost one push. Bursts of streaming |
