Skip to main content

axdriver_virtio/
gpu.rs

1use axdriver_base::{BaseDriverOps, DevResult, DeviceType};
2use axdriver_display::{DisplayDriverOps, DisplayInfo, FrameBuffer};
3use virtio_drivers::{Hal, device::gpu::VirtIOGpu as InnerDev, transport::Transport};
4
5use crate::as_dev_err;
6
7/// The VirtIO GPU device driver.
8pub struct VirtIoGpuDev<H: Hal, T: Transport> {
9    inner: InnerDev<H, T>,
10    info: DisplayInfo,
11}
12
13unsafe impl<H: Hal, T: Transport> Send for VirtIoGpuDev<H, T> {}
14unsafe impl<H: Hal, T: Transport> Sync for VirtIoGpuDev<H, T> {}
15
16impl<H: Hal, T: Transport> VirtIoGpuDev<H, T> {
17    /// Creates a new driver instance and initializes the device, or returns
18    /// an error if any step fails.
19    pub fn try_new(transport: T) -> DevResult<Self> {
20        let mut virtio = InnerDev::new(transport).unwrap();
21
22        // get framebuffer
23        let fbuffer = virtio.setup_framebuffer().unwrap();
24        let fb_base_vaddr = fbuffer.as_mut_ptr() as usize;
25        let fb_size = fbuffer.len();
26        let (width, height) = virtio.resolution().unwrap();
27        let info = DisplayInfo {
28            width,
29            height,
30            fb_base_vaddr,
31            fb_size,
32        };
33
34        Ok(Self {
35            inner: virtio,
36            info,
37        })
38    }
39}
40
41impl<H: Hal, T: Transport> BaseDriverOps for VirtIoGpuDev<H, T> {
42    fn device_name(&self) -> &str {
43        "virtio-gpu"
44    }
45
46    fn device_type(&self) -> DeviceType {
47        DeviceType::Display
48    }
49}
50
51impl<H: Hal, T: Transport> DisplayDriverOps for VirtIoGpuDev<H, T> {
52    fn info(&self) -> DisplayInfo {
53        self.info
54    }
55
56    fn fb(&self) -> FrameBuffer<'_> {
57        unsafe {
58            FrameBuffer::from_raw_parts_mut(self.info.fb_base_vaddr as *mut u8, self.info.fb_size)
59        }
60    }
61
62    fn need_flush(&self) -> bool {
63        true
64    }
65
66    fn flush(&mut self) -> DevResult {
67        self.inner.flush().map_err(as_dev_err)
68    }
69}