Skip to content

Virtio GPU: Redrawing with timer interrupt on RISCV #122

@wrenger

Description

@wrenger

Hi, first of all, thanks for the great bindings.

I am having problems redrawing the frame buffer periodically using a timer. The first succeeds, but all further draw calls fail with an IO Error. Maybe I do not understand the procedure correctly...

pub struct VirtGPU {
    gpu: VirtIOGpu<HalImpl, MmioTransport>,
}

pub static VGPU: OnceLock<Spin<VirtGPU>> = OnceLock::new();

impl VirtGPU {
    pub fn new(transport: MmioTransport) -> Self {
        Self {
            gpu: VirtIOGpu::new(transport).expect("initialize gpu driver"),
        }
    }

    pub fn draw(&mut self) -> virtio_drivers::Result<()> {
        let (width, height) = self.gpu.resolution()?;
        let width = width as usize;
        let height = height as usize;
        serial!("GPU resolution is {width}x{height}");
        let fb = self.gpu.setup_framebuffer()?; // <- IO Error happens here
        let fb = unsafe {
            core::slice::from_raw_parts_mut(fb.as_ptr() as *mut u32, fb.len() / size_of::<u32>())
        };
        serial!("Framebuffer size is {} ({})", fb.len(), width * height);

        /// Update the framebuffer...

        self.gpu.flush()?;
        Ok(())
    }
}

The MmioTransport is initialized as in the RISCV example.
A timer interrupt calls draw periodically. The first draw call succeeds; all subsequent ones fail in setup_framebuffer.

QEMU command line:

qemu-system-riscv32 -m 2G -machine virt -device virtio-gpu-device -serial mon:stdio -gdb tcp::1234 -no-shutdown -no-reboot target/debug/kernel

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions