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
7pub 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 pub fn try_new(transport: T) -> DevResult<Self> {
20 let mut virtio = InnerDev::new(transport).unwrap();
21
22 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}