Skip to content

Virtio GPU: Redrawing with timer interrupt on RISCV #122

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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions