1use crate::drivers::bus::virtio::VirtioHal;
2use crate::sync::UPIntrFreeCell;
3use alloc::{sync::Arc, vec::Vec};
4use core::any::Any;
5use embedded_graphics::pixelcolor::Rgb888;
6use tinybmp::Bmp;
7use virtio_drivers::{VirtIOGpu, VirtIOHeader};
8const VIRTIO7: usize = 0x10007000;
9pub trait GpuDevice: Send + Sync + Any {
10 fn get_framebuffer(&self) -> &mut [u8];
11 fn flush(&self);
12}
13
14lazy_static::lazy_static!(
15 pub static ref GPU_DEVICE: Arc<dyn GpuDevice> = Arc::new(VirtIOGpuWrapper::new());
16);
17
18pub struct VirtIOGpuWrapper {
19 gpu: UPIntrFreeCell<VirtIOGpu<'static, VirtioHal>>,
20 fb: &'static [u8],
21}
22static BMP_DATA: &[u8] = include_bytes!("../../assert/mouse.bmp");
23impl VirtIOGpuWrapper {
24 pub fn new() -> Self {
25 unsafe {
26 let mut virtio =
27 VirtIOGpu::<VirtioHal>::new(&mut *(VIRTIO7 as *mut VirtIOHeader)).unwrap();
28
29 let fbuffer = virtio.setup_framebuffer().unwrap();
30 let len = fbuffer.len();
31 let ptr = fbuffer.as_mut_ptr();
32 let fb = core::slice::from_raw_parts_mut(ptr, len);
33
34 let bmp = Bmp::<Rgb888>::from_slice(BMP_DATA).unwrap();
35 let raw = bmp.as_raw();
36 let mut b = Vec::new();
37 for i in raw.image_data().chunks(3) {
38 let mut v = i.to_vec();
39 b.append(&mut v);
40 if i == [255, 255, 255] {
41 b.push(0x0)
42 } else {
43 b.push(0xff)
44 }
45 }
46 virtio.setup_cursor(b.as_slice(), 50, 50, 50, 50).unwrap();
47
48 Self {
49 gpu: UPIntrFreeCell::new(virtio),
50 fb,
51 }
52 }
53 }
54}
55
56impl GpuDevice for VirtIOGpuWrapper {
57 fn flush(&self) {
58 self.gpu.exclusive_access().flush().unwrap();
59 }
60 fn get_framebuffer(&self) -> &mut [u8] {
61 unsafe {
62 let ptr = self.fb.as_ptr() as *const _ as *mut u8;
63 core::slice::from_raw_parts_mut(ptr, self.fb.len())
64 }
65 }
66}