fix: remove broken QEMU GPU swap hack, add graceful fallback

VirtIO GPU:
- Removed QEMU 11.x command type swap hack (0x0104↔0x0106).
  The hack was wrong — swapping types without swapping data formats
  meant handlers read wrong struct layouts. Commands returned OK
  but did nothing.
- Restored correct VirtIO spec command types.
- Removed broken test pattern (fill + flush that never displayed).
- GPU setup now reports success/failure without crashing.

Display server resilience:
- VirtioFramebuffer::new() → try_new() -> Option<Self>.
  Returns None if phys-info page is unmapped or has zero dimensions.
- bins/display-qemu: tries VirtioFramebuffer, falls back to
  MockFramebuffer. Display server runs headless instead of crashing.
- No more page faults when GPU is absent.

The GPU driver code is architecturally correct (proper VirtIO
commands, proper data formats) but doesn't produce visible output
on QEMU 11.x due to a suspected QEMU legacy MMIO bug where
transfer_to_host_2d succeeds but doesn't transfer data. The driver
is ready for when this is fixed or a different QEMU version is used.
This commit is contained in:
2026-10-18 22:49:55 +02:00
parent cbabe2abfe
commit 25824a01fe
5 changed files with 27 additions and 31 deletions

View File

@@ -54,19 +54,22 @@ pub struct VirtioFramebuffer {
}
impl VirtioFramebuffer {
pub fn new() -> Self {
pub fn try_new() -> Option<Self> {
let phys = read_phys_info();
if phys.width == 0 || phys.height == 0 || phys.cmd_pa.raw() == 0 {
return None;
}
let width = Dimension::new(phys.width);
let height = Dimension::new(phys.height);
let stride = phys.width as usize * FB_BPP;
Self {
Some(Self {
mmio: GpuMmio,
queue: VirtioQueue::new(QueueAddrs::from_base(VQUEUE_VA)),
dma: GpuDmaAddrs { cmd_pa: phys.cmd_pa, cmd_va: VirtualAddress::from_raw(CMDBUF_VA), resp_pa: phys.resp_pa },
width,
height,
stride,
}
})
}
}