fix: GPU display at correct resolution, clean up diagnostics

- Add GET_DISPLAY_INFO command to query QEMU's preferred resolution
  (was hardcoded 640x480, QEMU wanted 1280x800)
- Allocate framebuffer matching actual display dimensions
- Remove debug diagnostic output from display server and snake
This commit is contained in:
2026-10-19 00:24:37 +02:00
parent f5ac7189a9
commit 68849f698b
3 changed files with 60 additions and 20 deletions

View File

@@ -13,10 +13,8 @@ const VQUEUE_VA: usize = 0x21000;
const CMDBUF_VA: usize = 0x23000;
const PHYSINFO_VA: usize = 0x24000;
const FB_VA: usize = 0x100000;
const FB_WIDTH: Dimension = Dimension::new(640);
const FB_HEIGHT: Dimension = Dimension::new(480);
const FB_BPP: usize = 4;
const FB_PAGES: usize = (FB_WIDTH.raw() as usize * FB_HEIGHT.raw() as usize * FB_BPP + 4095) / 4096;
const DEFAULT_WIDTH: Dimension = Dimension::new(640);
const DEFAULT_HEIGHT: Dimension = Dimension::new(480);
pub fn configure(uart: &Uart, display_pid: ProcessId) {
let gpu = match VirtioGpu::probe() {
@@ -38,8 +36,36 @@ pub fn configure(uart: &Uart, display_pid: ProcessId) {
let cmd_phys = mmu::allocator::alloc_zeroed_page();
map_page(pt, CMDBUF_VA, cmd_phys);
let fb_phys = alloc_contiguous(FB_PAGES);
map_range(pt, FB_VA, fb_phys, FB_PAGES);
gpu.init_device(vq_phys);
let queue = hw_virtio::queue::VirtioQueue::new(
hw_virtio::queue::QueueAddrs::from_base(vq_phys),
);
let dma = hw_virtio::gpu::GpuDmaAddrs {
cmd_pa: types::address::PhysicalAddress::from_raw(cmd_phys),
cmd_va: types::address::VirtualAddress::from_raw(cmd_phys),
resp_pa: types::address::PhysicalAddress::from_raw(cmd_phys + 512),
};
use hw_virtio::mmio::MmioAccess;
let (width, height) = match hw_virtio::gpu::get_display_info(gpu.mmio(), &queue, &dma) {
Some((w, h)) => {
uart.write_str("k-os: GPU display: ");
uart.write_dec(w as usize);
uart.put_char(b'x');
uart.write_dec(h as usize);
uart.put_char(b'\n');
(Dimension::new(w as u16), Dimension::new(h as u16))
}
None => {
uart.write_str("k-os: GPU display: using default 640x480\n");
(DEFAULT_WIDTH, DEFAULT_HEIGHT)
}
};
let fb_pages = (width.raw() as usize * height.raw() as usize * 4 + 4095) / 4096;
let fb_phys = alloc_contiguous(fb_pages);
map_range(pt, FB_VA, fb_phys, fb_pages);
let info_phys = mmu::allocator::alloc_zeroed_page();
map_page(pt, PHYSINFO_VA, info_phys);
@@ -48,12 +74,11 @@ pub fn configure(uart: &Uart, display_pid: ProcessId) {
core::ptr::write_volatile(info, cmd_phys as u64);
core::ptr::write_volatile(info.add(1), (cmd_phys + 512) as u64);
core::ptr::write_volatile(info.add(2), fb_phys as u64);
core::ptr::write_volatile(info.add(3), FB_WIDTH.raw() as u64);
core::ptr::write_volatile(info.add(4), FB_HEIGHT.raw() as u64);
core::ptr::write_volatile(info.add(3), width.raw() as u64);
core::ptr::write_volatile(info.add(4), height.raw() as u64);
}
gpu.init_device(vq_phys);
if gpu.setup_framebuffer(cmd_phys, vq_phys, fb_phys, FB_WIDTH, FB_HEIGHT) {
if gpu.setup_framebuffer(cmd_phys, vq_phys, fb_phys, width, height) {
uart.write_str("k-os: VirtIO GPU configured\n");
} else {
uart.write_str("k-os: VirtIO GPU setup failed (display will be headless)\n");