diff options
| author | salmonik <salmonik@tuta.io> | 2026-08-02 01:34:58 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-08-02 01:35:37 +0200 |
| commit | 94d40dadeddfb40cd4fd237294037a562405a2c2 (patch) | |
| tree | d099fa89a248b53eb7c17ca08489d05e3f50fa8f /rsdos/src/main.rs | |
| parent | rsnix v0.5.3: fix real-hardware scroll wedge — per-word display push (diff) | |
| download | rs-dos-94d40dadeddfb40cd4fd237294037a562405a2c2.tar.gz rs-dos-94d40dadeddfb40cd4fd237294037a562405a2c2.zip | |
v0.5.4: shadow backbuffer can no longer alias the framebuffer
Real-hardware scroll freeze (no exception, QEMU-clean) — the per-word
push (0.5.3) did not fix it, so the wedge is upstream of the push.
A QEMU slow-display simulation (new DISPLAY_STALL knob + shell 'stall'
command busy-waits per display store, mimicking an uncached real-GPU
framebuffer) proved the per-word push and shadow memmove are slow but
finite — the shell keeps ticking, scrolls eventually complete. The
freeze mechanism QEMU cannot exhibit is the shadow *landing on the
framebuffer*: the heap free list spans the fb hole, so the 1.9 MB heap
shadow can alias the display on machines where firmware reports the fb
as ConventionalMemory — every scroll then becomes an MMIO->MMIO memcpy
on an uncached framebuffer, which wedges real hardware (a stall, no
fault, hence no dump).
Fix:
- gop::init_shadow(): allocate the shadow from the fb-aware page
allocator (init_page_allocator marks fb pages used per-page), so it
can never overlap the display; heap allocation kept only as a
fallback with an explicit overlap rejection. Boot log now prints
'gop: shadow @ <addr> ... origin=page-alloc|heap|none'.
- Scroll shadow memmove converted to per-word stores (belt and
suspenders — immune to any future fb-aliased shadow).
- Verified on QEMU: shadow @ 0x100000 vs fb 0x80000000..0x801d5000,
overlap=false; all 5 test suites pass; scroll completes even under
the stalled-display simulation.
Diffstat (limited to '')
| -rw-r--r-- | rsdos/src/main.rs | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/rsdos/src/main.rs b/rsdos/src/main.rs index 6dbad5f..3153930 100644 --- a/rsdos/src/main.rs +++ b/rsdos/src/main.rs | |||
| @@ -172,6 +172,7 @@ pub unsafe extern "efiapi" fn efi_main(image_handle: Handle, system_table: *mut | |||
| 172 | } else { | 172 | } else { |
| 173 | rsnix::serial_println!("pages: init FAILED"); | 173 | rsnix::serial_println!("pages: init FAILED"); |
| 174 | } | 174 | } |
| 175 | rsnix::gop::init_shadow(); | ||
| 175 | if rsnix::memory::page_self_test() { | 176 | if rsnix::memory::page_self_test() { |
| 176 | rsnix::serial_println!("pages: self-test OK (alloc/free/runs)"); | 177 | rsnix::serial_println!("pages: self-test OK (alloc/free/runs)"); |
| 177 | } else { | 178 | } else { |
