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

@@ -22,7 +22,7 @@ pub fn create_2d(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs,
}
pub fn attach_backing(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, resource_id: u32, fb_pa: PhysicalAddress, fb_size: u32) -> bool {
write_cmd_header(dma.cmd_va, 0x0106);
write_cmd_header(dma.cmd_va, 0x0104);
unsafe {
let p = dma.cmd_va.raw() as *mut u8;
core::ptr::write_volatile(p.add(24) as *mut u32, resource_id);
@@ -60,7 +60,7 @@ pub fn transfer_to_host(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDm
}
pub fn resource_flush(mmio: &impl MmioAccess, queue: &VirtioQueue, dma: &GpuDmaAddrs, resource_id: u32, x: u32, y: u32, w: u32, h: u32) -> bool {
write_cmd_header(dma.cmd_va, 0x0104);
write_cmd_header(dma.cmd_va, 0x0106);
unsafe {
let p = dma.cmd_va.raw() as *mut u8;
core::ptr::write_volatile(p.add(24) as *mut u32, x);