xref: /DragonOS/kernel/src/driver/video/fbdev/vesafb.rs (revision c3dc6f2ff9169c309d1cbf47dcb9e4528d509b2f)
1 use core::{
2     ffi::{c_uint, c_void},
3     mem::MaybeUninit,
4     sync::atomic::AtomicBool,
5 };
6 
7 use alloc::{
8     string::{String, ToString},
9     sync::{Arc, Weak},
10     vec::Vec,
11 };
12 use system_error::SystemError;
13 use unified_init::macros::unified_init;
14 
15 use crate::{
16     arch::MMArch,
17     driver::{
18         base::{
19             class::Class,
20             device::{
21                 bus::Bus, device_manager, driver::Driver, Device, DeviceState, DeviceType, IdTable,
22             },
23             kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
24             kset::KSet,
25             platform::{
26                 platform_device::{platform_device_manager, PlatformDevice},
27                 platform_driver::{platform_driver_manager, PlatformDriver},
28                 CompatibleTable,
29             },
30         },
31         serial::serial8250::send_to_default_serial8250_port,
32         video::fbdev::base::{fbmem::frame_buffer_manager, FbVisual, FRAME_BUFFER_SET},
33     },
34     filesystem::{
35         kernfs::KernFSInode,
36         sysfs::{file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport},
37         vfs::syscall::ModeType,
38     },
39     include::bindings::bindings::{
40         multiboot2_get_Framebuffer_info, multiboot2_iter, multiboot_tag_framebuffer_info_t,
41         FRAME_BUFFER_MAPPING_OFFSET,
42     },
43     init::{boot_params, initcall::INITCALL_DEVICE},
44     libs::{
45         align::page_align_up,
46         once::Once,
47         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
48         spinlock::SpinLock,
49     },
50     mm::{
51         allocator::page_frame::PageFrameCount, no_init::pseudo_map_phys, MemoryManagementArch,
52         PhysAddr, VirtAddr,
53     },
54 };
55 
56 use super::base::{
57     fbmem::FbDevice, BlankMode, BootTimeVideoType, FbAccel, FbActivateFlags, FbId, FbState, FbType,
58     FbVModeFlags, FbVarScreenInfo, FbVideoMode, FixedScreenInfo, FrameBuffer, FrameBufferInfo,
59     FrameBufferInfoData, FrameBufferOps,
60 };
61 
62 /// 当前机器上面是否有vesa帧缓冲区
63 static HAS_VESA_FB: AtomicBool = AtomicBool::new(false);
64 
65 lazy_static! {
66     static ref VESAFB_FIX_INFO: RwLock<FixedScreenInfo> = RwLock::new(FixedScreenInfo {
67         id: FixedScreenInfo::name2id("VESA VGA"),
68         fb_type: FbType::PackedPixels,
69         accel: FbAccel::None,
70         ..Default::default()
71     });
72     static ref VESAFB_DEFINED: RwLock<FbVarScreenInfo> = RwLock::new(FbVarScreenInfo {
73         activate: FbActivateFlags::FB_ACTIVATE_NOW,
74         height: None,
75         width: None,
76         right_margin: 32,
77         upper_margin: 16,
78         lower_margin: 4,
79         vsync_len: 4,
80         vmode: FbVModeFlags::FB_VMODE_NONINTERLACED,
81 
82         ..Default::default()
83     });
84 }
85 
86 #[derive(Debug)]
87 #[cast_to([sync] Device)]
88 #[cast_to([sync] PlatformDevice)]
89 pub struct VesaFb {
90     inner: SpinLock<InnerVesaFb>,
91     kobj_state: LockedKObjectState,
92     fb_data: RwLock<FrameBufferInfoData>,
93 }
94 
95 impl VesaFb {
96     pub const NAME: &'static str = "vesa_vga";
97     pub fn new() -> Self {
98         let mut fb_info_data = FrameBufferInfoData::new();
99         fb_info_data.pesudo_palette.resize(256, 0);
100         return Self {
101             inner: SpinLock::new(InnerVesaFb {
102                 bus: None,
103                 class: None,
104                 driver: None,
105                 kern_inode: None,
106                 parent: None,
107                 kset: None,
108                 kobj_type: None,
109                 device_state: DeviceState::NotInitialized,
110                 pdev_id: 0,
111                 pdev_id_auto: false,
112                 fb_id: FbId::INIT,
113                 fb_device: None,
114                 fb_state: FbState::Suspended,
115             }),
116             kobj_state: LockedKObjectState::new(None),
117             fb_data: RwLock::new(fb_info_data),
118         };
119     }
120 }
121 
122 #[derive(Debug)]
123 struct InnerVesaFb {
124     bus: Option<Weak<dyn Bus>>,
125     class: Option<Arc<dyn Class>>,
126     driver: Option<Weak<dyn Driver>>,
127     kern_inode: Option<Arc<KernFSInode>>,
128     parent: Option<Weak<dyn KObject>>,
129     kset: Option<Arc<KSet>>,
130     kobj_type: Option<&'static dyn KObjType>,
131     device_state: DeviceState,
132     pdev_id: i32,
133     pdev_id_auto: bool,
134     fb_id: FbId,
135     fb_device: Option<Arc<FbDevice>>,
136     fb_state: FbState,
137 }
138 
139 impl FrameBuffer for VesaFb {
140     fn fb_id(&self) -> FbId {
141         self.inner.lock().fb_id
142     }
143 
144     fn set_fb_id(&self, id: FbId) {
145         self.inner.lock().fb_id = id;
146     }
147 }
148 
149 impl PlatformDevice for VesaFb {
150     fn pdev_name(&self) -> &str {
151         Self::NAME
152     }
153 
154     fn set_pdev_id(&self, id: i32) {
155         self.inner.lock().pdev_id = id;
156     }
157 
158     fn set_pdev_id_auto(&self, id_auto: bool) {
159         self.inner.lock().pdev_id_auto = id_auto;
160     }
161 
162     fn compatible_table(&self) -> CompatibleTable {
163         todo!()
164     }
165 
166     fn is_initialized(&self) -> bool {
167         self.inner.lock().device_state == DeviceState::Initialized
168     }
169 
170     fn set_state(&self, set_state: DeviceState) {
171         self.inner.lock().device_state = set_state;
172     }
173 }
174 
175 impl Device for VesaFb {
176     fn dev_type(&self) -> DeviceType {
177         DeviceType::Char
178     }
179 
180     fn id_table(&self) -> IdTable {
181         IdTable::new(self.name(), None)
182     }
183 
184     fn bus(&self) -> Option<Weak<dyn Bus>> {
185         self.inner.lock().bus.clone()
186     }
187 
188     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
189         self.inner.lock().bus = bus;
190     }
191 
192     fn set_class(&self, class: Option<Arc<dyn Class>>) {
193         self.inner.lock().class = class;
194     }
195 
196     fn driver(&self) -> Option<Arc<dyn Driver>> {
197         self.inner.lock().driver.clone()?.upgrade()
198     }
199 
200     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
201         self.inner.lock().driver = driver;
202     }
203 
204     fn is_dead(&self) -> bool {
205         false
206     }
207 
208     fn can_match(&self) -> bool {
209         true
210     }
211 
212     fn set_can_match(&self, _can_match: bool) {}
213 
214     fn state_synced(&self) -> bool {
215         true
216     }
217 }
218 
219 impl KObject for VesaFb {
220     fn as_any_ref(&self) -> &dyn core::any::Any {
221         self
222     }
223 
224     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
225         self.inner.lock().kern_inode = inode;
226     }
227 
228     fn inode(&self) -> Option<Arc<KernFSInode>> {
229         self.inner.lock().kern_inode.clone()
230     }
231 
232     fn parent(&self) -> Option<Weak<dyn KObject>> {
233         self.inner.lock().parent.clone()
234     }
235 
236     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
237         self.inner.lock().parent = parent;
238     }
239 
240     fn kset(&self) -> Option<Arc<KSet>> {
241         self.inner.lock().kset.clone()
242     }
243 
244     fn set_kset(&self, kset: Option<Arc<KSet>>) {
245         self.inner.lock().kset = kset;
246     }
247 
248     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
249         self.inner.lock().kobj_type
250     }
251 
252     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
253         self.inner.lock().kobj_type = ktype;
254     }
255 
256     fn name(&self) -> String {
257         Self::NAME.to_string()
258     }
259 
260     fn set_name(&self, _name: String) {
261         // do nothing
262     }
263 
264     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
265         self.kobj_state.read()
266     }
267 
268     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
269         self.kobj_state.write()
270     }
271 
272     fn set_kobj_state(&self, state: KObjectState) {
273         *self.kobj_state.write() = state;
274     }
275 }
276 
277 impl FrameBufferOps for VesaFb {
278     fn fb_open(&self, _user: bool) {
279         todo!()
280     }
281 
282     fn fb_release(&self, _user: bool) {
283         todo!()
284     }
285 
286     fn fb_set_color_register(
287         &self,
288         regno: u16,
289         mut red: u16,
290         mut green: u16,
291         mut blue: u16,
292     ) -> Result<(), SystemError> {
293         let mut fb_data = self.framebuffer_info_data().write();
294         let var = self.current_fb_var();
295         if regno as usize >= fb_data.pesudo_palette.len() {
296             return Err(SystemError::E2BIG);
297         }
298 
299         if var.bits_per_pixel == 8 {
300             todo!("vesa_setpalette todo");
301         } else if regno < 16 {
302             match var.bits_per_pixel {
303                 16 => {
304                     if var.red.offset == 10 {
305                         // RGB 1:5:5:5
306                         fb_data.pesudo_palette[regno as usize] = ((red as u32 & 0xf800) >> 1)
307                             | ((green as u32 & 0xf800) >> 6)
308                             | ((blue as u32 & 0xf800) >> 11);
309                     } else {
310                         fb_data.pesudo_palette[regno as usize] = (red as u32 & 0xf800)
311                             | ((green as u32 & 0xfc00) >> 5)
312                             | ((blue as u32 & 0xf800) >> 11);
313                     }
314                 }
315                 24 | 32 => {
316                     red >>= 8;
317                     green >>= 8;
318                     blue >>= 8;
319                     fb_data.pesudo_palette[regno as usize] = ((red as u32) << var.red.offset)
320                         | ((green as u32) << var.green.offset)
321                         | ((blue as u32) << var.blue.offset);
322                 }
323                 _ => {}
324             }
325         }
326 
327         Ok(())
328     }
329 
330     fn fb_blank(&self, _blank_mode: BlankMode) -> Result<(), SystemError> {
331         todo!()
332     }
333 
334     fn fb_destroy(&self) {
335         todo!()
336     }
337 
338     fn fb_read(&self, buf: &mut [u8], pos: usize) -> Result<usize, SystemError> {
339         let bp = boot_params().read();
340 
341         let vaddr = bp.screen_info.lfb_virt_base.ok_or(SystemError::ENODEV)?;
342         let size = self.current_fb_fix().smem_len;
343         drop(bp);
344         if pos >= size {
345             return Ok(0);
346         }
347 
348         let pos = pos as i64;
349         let size = size as i64;
350 
351         let len = core::cmp::min(size - pos, buf.len() as i64) as usize;
352 
353         let slice = unsafe { core::slice::from_raw_parts(vaddr.as_ptr::<u8>(), size as usize) };
354         buf[..len].copy_from_slice(&slice[pos as usize..(pos as usize + len)]);
355 
356         return Ok(len);
357     }
358 
359     fn fb_write(&self, buf: &[u8], pos: usize) -> Result<usize, SystemError> {
360         let bp = boot_params().read();
361 
362         let vaddr = bp.screen_info.lfb_virt_base.ok_or(SystemError::ENODEV)?;
363         let size = self.current_fb_fix().smem_len;
364 
365         if pos >= size {
366             return Ok(0);
367         }
368 
369         let pos = pos as i64;
370         let size = size as i64;
371 
372         let len = core::cmp::min(size - pos, buf.len() as i64) as usize;
373 
374         let slice = unsafe { core::slice::from_raw_parts_mut(vaddr.as_ptr::<u8>(), size as usize) };
375         slice[pos as usize..(pos as usize + len)].copy_from_slice(&buf[..len]);
376 
377         return Ok(len);
378     }
379 
380     fn fb_image_blit(&self, image: &super::base::FbImage) {
381         self.generic_imageblit(image);
382     }
383 
384     /// ## 填充矩形
385     fn fb_fillrect(&self, rect: super::base::FillRectData) -> Result<(), SystemError> {
386         // kwarn!("rect {rect:?}");
387 
388         let boot_param = boot_params().read();
389         let screen_base = boot_param
390             .screen_info
391             .lfb_virt_base
392             .ok_or(SystemError::ENODEV)?;
393         let fg;
394         if self.current_fb_fix().visual == FbVisual::TrueColor
395             || self.current_fb_fix().visual == FbVisual::DirectColor
396         {
397             fg = self.fb_data.read().pesudo_palette[rect.color as usize];
398         } else {
399             fg = rect.color;
400         }
401 
402         let bpp = self.current_fb_var().bits_per_pixel;
403         // 每行像素数
404         let line_offset = self.current_fb_var().xres;
405         match bpp {
406             32 => {
407                 let base = screen_base.as_ptr::<u32>();
408 
409                 for y in rect.dy..(rect.dy + rect.height) {
410                     for x in rect.dx..(rect.dx + rect.width) {
411                         unsafe { *base.add((y * line_offset + x) as usize) = fg };
412                     }
413                 }
414             }
415             _ => todo!(),
416         }
417 
418         Ok(())
419     }
420 
421     fn fb_copyarea(&self, data: super::base::CopyAreaData) -> Result<(), SystemError> {
422         let bp = boot_params().read();
423         let base = bp.screen_info.lfb_virt_base.ok_or(SystemError::ENODEV)?;
424         let var = self.current_fb_var();
425 
426         if data.sx < 0
427             || data.sy < 0
428             || data.sx as u32 > var.xres
429             || data.sx as u32 + data.width > var.xres
430             || data.sy as u32 > var.yres
431             || data.sy as u32 + data.height > var.yres
432         {
433             return Err(SystemError::EINVAL);
434         }
435 
436         let bytes_per_pixel = var.bits_per_pixel >> 3;
437         let bytes_per_line = var.xres * bytes_per_pixel;
438 
439         let sy = data.sy as u32;
440         let sx = data.sx as u32;
441 
442         let dst = {
443             let mut dst = base;
444             if data.dy < 0 {
445                 dst -= VirtAddr::new((((-data.dy) as u32) * bytes_per_line) as usize);
446             } else {
447                 dst += VirtAddr::new(((data.dy as u32) * bytes_per_line) as usize);
448             }
449 
450             if data.dx > 0 && (data.dx as u32) < var.xres {
451                 dst += VirtAddr::new(((data.dx as u32) * bytes_per_pixel) as usize);
452             }
453 
454             dst
455         };
456         let src = base + VirtAddr::new((sy * bytes_per_line + sx * bytes_per_pixel) as usize);
457 
458         match bytes_per_pixel {
459             4 => {
460                 // 32bpp
461                 let mut dst = dst.as_ptr::<u32>();
462                 let mut src = src.as_ptr::<u32>();
463 
464                 for y in 0..data.height as usize {
465                     if (data.dy + y as i32) < 0 || (data.dy + y as i32) > var.yres as i32 {
466                         unsafe {
467                             // core::ptr::copy(src, dst, data.width as usize);
468                             src = src.add(var.xres as usize);
469                             dst = dst.add(var.xres as usize);
470                         }
471                         continue;
472                     }
473                     if data.dx < 0 {
474                         if ((-data.dx) as u32) < data.width {
475                             unsafe {
476                                 core::ptr::copy(
477                                     src.add((-data.dx) as usize),
478                                     dst,
479                                     (data.width as usize) - (-data.dx) as usize,
480                                 );
481                                 src = src.add(var.xres as usize);
482                                 dst = dst.add(var.xres as usize);
483                             }
484                         }
485                     } else if data.dx as u32 + data.width > var.xres {
486                         if (data.dx as u32) < var.xres {
487                             unsafe {
488                                 core::ptr::copy(src, dst, (var.xres - data.dx as u32) as usize);
489                                 src = src.add(var.xres as usize);
490                                 dst = dst.add(var.xres as usize);
491                             }
492                         }
493                     } else {
494                         for i in 0..data.width as usize {
495                             unsafe { *(dst.add(i)) = *(src.add(i)) }
496                         }
497                         unsafe {
498                             // core::ptr::copy(src, dst, data.width as usize);
499                             src = src.add(var.xres as usize);
500                             dst = dst.add(var.xres as usize);
501                         }
502                     }
503                 }
504             }
505             _ => {
506                 todo!()
507             }
508         }
509         Ok(())
510     }
511 }
512 
513 impl FrameBufferInfo for VesaFb {
514     fn fb_device(&self) -> Option<Arc<FbDevice>> {
515         self.inner.lock().fb_device.clone()
516     }
517 
518     fn set_fb_device(&self, device: Option<Arc<FbDevice>>) {
519         self.inner.lock().fb_device = device;
520     }
521 
522     fn screen_size(&self) -> usize {
523         todo!()
524     }
525 
526     fn current_fb_var(&self) -> FbVarScreenInfo {
527         VESAFB_DEFINED.read().clone()
528     }
529 
530     fn current_fb_fix(&self) -> FixedScreenInfo {
531         VESAFB_FIX_INFO.read().clone()
532     }
533 
534     fn video_mode(&self) -> Option<&FbVideoMode> {
535         todo!()
536     }
537 
538     fn state(&self) -> FbState {
539         self.inner.lock().fb_state
540     }
541 
542     fn framebuffer_info_data(&self) -> &RwLock<FrameBufferInfoData> {
543         &self.fb_data
544     }
545 }
546 
547 #[derive(Debug)]
548 #[cast_to([sync] PlatformDriver)]
549 struct VesaFbDriver {
550     inner: SpinLock<InnerVesaFbDriver>,
551     kobj_state: LockedKObjectState,
552 }
553 
554 impl VesaFbDriver {
555     pub fn new() -> Arc<Self> {
556         let r = Arc::new(Self {
557             inner: SpinLock::new(InnerVesaFbDriver {
558                 ktype: None,
559                 kset: None,
560                 parent: None,
561                 kernfs_inode: None,
562                 devices: Vec::new(),
563                 bus: None,
564                 self_ref: Weak::new(),
565             }),
566             kobj_state: LockedKObjectState::new(None),
567         });
568 
569         r.inner.lock().self_ref = Arc::downgrade(&r);
570 
571         return r;
572     }
573 }
574 
575 #[derive(Debug)]
576 struct InnerVesaFbDriver {
577     ktype: Option<&'static dyn KObjType>,
578     kset: Option<Arc<KSet>>,
579     parent: Option<Weak<dyn KObject>>,
580     kernfs_inode: Option<Arc<KernFSInode>>,
581     devices: Vec<Arc<dyn Device>>,
582     bus: Option<Weak<dyn Bus>>,
583 
584     self_ref: Weak<VesaFbDriver>,
585 }
586 
587 impl VesaFbDriver {
588     const NAME: &'static str = "vesa-framebuffer";
589 }
590 
591 impl PlatformDriver for VesaFbDriver {
592     fn probe(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
593         let device = device
594             .clone()
595             .arc_any()
596             .downcast::<VesaFb>()
597             .map_err(|_| SystemError::EINVAL)?;
598 
599         device.set_driver(Some(self.inner.lock_irqsave().self_ref.clone()));
600 
601         return Ok(());
602     }
603 
604     fn remove(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
605         todo!()
606     }
607 
608     fn shutdown(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
609         // do nothing
610         return Ok(());
611     }
612 
613     fn suspend(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
614         // do nothing
615         return Ok(());
616     }
617 
618     fn resume(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
619         todo!()
620     }
621 }
622 
623 impl Driver for VesaFbDriver {
624     fn id_table(&self) -> Option<IdTable> {
625         Some(IdTable::new(VesaFb::NAME.to_string(), None))
626     }
627 
628     fn devices(&self) -> Vec<Arc<dyn Device>> {
629         self.inner.lock().devices.clone()
630     }
631 
632     fn add_device(&self, device: Arc<dyn Device>) {
633         let mut guard = self.inner.lock();
634         // check if the device is already in the list
635         if guard.devices.iter().any(|dev| Arc::ptr_eq(dev, &device)) {
636             return;
637         }
638 
639         guard.devices.push(device);
640     }
641 
642     fn delete_device(&self, device: &Arc<dyn Device>) {
643         let mut guard = self.inner.lock();
644         guard.devices.retain(|dev| !Arc::ptr_eq(dev, device));
645     }
646 
647     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
648         self.inner.lock().bus = bus;
649     }
650 
651     fn bus(&self) -> Option<Weak<dyn Bus>> {
652         self.inner.lock().bus.clone()
653     }
654 
655     fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
656         return &[&VesaFbAnonAttributeGroup];
657     }
658 }
659 
660 impl KObject for VesaFbDriver {
661     fn as_any_ref(&self) -> &dyn core::any::Any {
662         self
663     }
664 
665     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
666         self.inner.lock().kernfs_inode = inode;
667     }
668 
669     fn inode(&self) -> Option<Arc<KernFSInode>> {
670         self.inner.lock().kernfs_inode.clone()
671     }
672 
673     fn parent(&self) -> Option<Weak<dyn KObject>> {
674         self.inner.lock().parent.clone()
675     }
676 
677     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
678         self.inner.lock().parent = parent;
679     }
680 
681     fn kset(&self) -> Option<Arc<KSet>> {
682         self.inner.lock().kset.clone()
683     }
684 
685     fn set_kset(&self, kset: Option<Arc<KSet>>) {
686         self.inner.lock().kset = kset;
687     }
688 
689     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
690         self.inner.lock().ktype
691     }
692 
693     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
694         self.inner.lock().ktype = ktype;
695     }
696 
697     fn name(&self) -> String {
698         Self::NAME.to_string()
699     }
700 
701     fn set_name(&self, _name: String) {
702         // do nothing
703     }
704 
705     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
706         self.kobj_state.read()
707     }
708 
709     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
710         self.kobj_state.write()
711     }
712 
713     fn set_kobj_state(&self, state: KObjectState) {
714         *self.kobj_state.write() = state;
715     }
716 }
717 
718 #[derive(Debug)]
719 struct VesaFbAnonAttributeGroup;
720 
721 impl AttributeGroup for VesaFbAnonAttributeGroup {
722     fn name(&self) -> Option<&str> {
723         None
724     }
725 
726     fn attrs(&self) -> &[&'static dyn Attribute] {
727         &[&AnonAttrPhysAddr as &'static dyn Attribute]
728     }
729 
730     fn is_visible(
731         &self,
732         _kobj: Arc<dyn KObject>,
733         attr: &'static dyn Attribute,
734     ) -> Option<ModeType> {
735         Some(attr.mode())
736     }
737 }
738 
739 #[derive(Debug)]
740 struct AnonAttrPhysAddr;
741 
742 impl Attribute for AnonAttrPhysAddr {
743     fn name(&self) -> &str {
744         "smem_start"
745     }
746 
747     fn mode(&self) -> ModeType {
748         ModeType::S_IRUGO
749     }
750 
751     fn support(&self) -> SysFSOpsSupport {
752         SysFSOpsSupport::ATTR_SHOW
753     }
754 
755     fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
756         sysfs_emit_str(
757             buf,
758             format!(
759                 "0x{:x}\n",
760                 VESAFB_FIX_INFO
761                     .read()
762                     .smem_start
763                     .unwrap_or(PhysAddr::new(0))
764                     .data()
765             )
766             .as_str(),
767         )
768     }
769 }
770 
771 #[unified_init(INITCALL_DEVICE)]
772 pub fn vesa_fb_driver_init() -> Result<(), SystemError> {
773     let driver = VesaFbDriver::new();
774 
775     platform_driver_manager().register(driver)?;
776 
777     return Ok(());
778 }
779 
780 /// 在内存管理初始化之前,初始化vesafb
781 pub fn vesafb_early_init() -> Result<VirtAddr, SystemError> {
782     let mut _reserved: u32 = 0;
783 
784     let mut fb_info: MaybeUninit<multiboot_tag_framebuffer_info_t> = MaybeUninit::uninit();
785     //从multiboot2中读取帧缓冲区信息至fb_info
786 
787     // todo: 换成rust的,并且检测是否成功获取
788     unsafe {
789         multiboot2_iter(
790             Some(multiboot2_get_Framebuffer_info),
791             fb_info.as_mut_ptr() as usize as *mut c_void,
792             &mut _reserved as *mut c_uint,
793         )
794     };
795     unsafe { fb_info.assume_init() };
796     let fb_info: multiboot_tag_framebuffer_info_t = unsafe { core::mem::transmute(fb_info) };
797 
798     // todo: 判断是否有vesa帧缓冲区,这里暂时直接设置true
799     HAS_VESA_FB.store(true, core::sync::atomic::Ordering::SeqCst);
800 
801     let width = fb_info.framebuffer_width;
802     let height = fb_info.framebuffer_height;
803 
804     let mut boot_params_guard = boot_params().write();
805     let boottime_screen_info = &mut boot_params_guard.screen_info;
806 
807     boottime_screen_info.is_vga = true;
808 
809     boottime_screen_info.lfb_base = PhysAddr::new(fb_info.framebuffer_addr as usize);
810 
811     if fb_info.framebuffer_type == 2 {
812         //当type=2时,width与height用字符数表示,故depth=8
813         boottime_screen_info.origin_video_cols = width as u8;
814         boottime_screen_info.origin_video_lines = height as u8;
815         boottime_screen_info.video_type = BootTimeVideoType::Mda;
816         boottime_screen_info.lfb_depth = 8;
817     } else {
818         //否则为图像模式,depth应参照帧缓冲区信息里面的每个像素的位数
819         boottime_screen_info.lfb_width = width;
820         boottime_screen_info.lfb_height = height;
821         boottime_screen_info.video_type = BootTimeVideoType::Vlfb;
822         boottime_screen_info.lfb_depth = fb_info.framebuffer_bpp as u8;
823     }
824 
825     boottime_screen_info.lfb_size =
826         (width * height * ((fb_info.framebuffer_bpp as u32 + 7) / 8)) as usize;
827 
828     // let buf_vaddr = VirtAddr::new(0xffff800003200000);
829     let buf_vaddr = VirtAddr::new(
830         crate::include::bindings::bindings::SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE as usize
831             + FRAME_BUFFER_MAPPING_OFFSET as usize,
832     );
833     boottime_screen_info.lfb_virt_base = Some(buf_vaddr);
834 
835     let init_text = "Video driver to map.\n\0";
836     send_to_default_serial8250_port(init_text.as_bytes());
837 
838     // 地址映射
839     let paddr = PhysAddr::new(fb_info.framebuffer_addr as usize);
840     let count =
841         PageFrameCount::new(page_align_up(boottime_screen_info.lfb_size) / MMArch::PAGE_SIZE);
842     unsafe { pseudo_map_phys(buf_vaddr, paddr, count) };
843     return Ok(buf_vaddr);
844 }
845 
846 #[unified_init(INITCALL_DEVICE)]
847 fn vesa_fb_device_init() -> Result<(), SystemError> {
848     // 如果没有vesa帧缓冲区,直接返回
849     if !HAS_VESA_FB.load(core::sync::atomic::Ordering::SeqCst) {
850         return Ok(());
851     }
852 
853     static INIT: Once = Once::new();
854     INIT.call_once(|| {
855         kinfo!("vesa fb device init");
856         let device = Arc::new(VesaFb::new());
857 
858         let mut fb_fix = VESAFB_FIX_INFO.write_irqsave();
859         let mut fb_var = VESAFB_DEFINED.write_irqsave();
860 
861         let boot_params_guard = boot_params().read();
862         let boottime_screen_info = &boot_params_guard.screen_info;
863 
864         fb_fix.smem_start = Some(boottime_screen_info.lfb_base);
865         fb_fix.smem_len = boottime_screen_info.lfb_size;
866 
867         if boottime_screen_info.video_type == BootTimeVideoType::Mda {
868             fb_fix.visual = FbVisual::Mono10;
869             fb_var.bits_per_pixel = 8;
870             fb_fix.line_length =
871                 (boottime_screen_info.origin_video_cols as u32) * (fb_var.bits_per_pixel / 8);
872             fb_var.xres_virtual = boottime_screen_info.origin_video_cols as u32;
873             fb_var.yres_virtual = boottime_screen_info.origin_video_lines as u32;
874         } else {
875             fb_fix.visual = FbVisual::TrueColor;
876             fb_var.bits_per_pixel = boottime_screen_info.lfb_depth as u32;
877             fb_fix.line_length =
878                 (boottime_screen_info.lfb_width as u32) * (fb_var.bits_per_pixel / 8);
879             fb_var.xres_virtual = boottime_screen_info.lfb_width as u32;
880             fb_var.yres_virtual = boottime_screen_info.lfb_height as u32;
881             fb_var.xres = boottime_screen_info.lfb_width as u32;
882             fb_var.yres = boottime_screen_info.lfb_height as u32;
883         }
884 
885         fb_var.red.length = boottime_screen_info.red_size as u32;
886         fb_var.green.length = boottime_screen_info.green_size as u32;
887         fb_var.blue.length = boottime_screen_info.blue_size as u32;
888 
889         fb_var.red.offset = boottime_screen_info.red_pos as u32;
890         fb_var.green.offset = boottime_screen_info.green_pos as u32;
891         fb_var.blue.offset = boottime_screen_info.blue_pos as u32;
892 
893         // TODO: 这里是暂时这样写的,初始化为RGB888格式,后续vesa初始化完善后删掉下面
894         fb_var.red.offset = 16;
895         fb_var.green.offset = 8;
896         fb_var.blue.offset = 0;
897 
898         if fb_var.bits_per_pixel >= 1 && fb_var.bits_per_pixel <= 8 {
899             fb_var.red.length = fb_var.bits_per_pixel;
900             fb_var.green.length = fb_var.bits_per_pixel;
901             fb_var.blue.length = fb_var.bits_per_pixel;
902         }
903 
904         device_manager().device_default_initialize(&(device.clone() as Arc<dyn Device>));
905 
906         platform_device_manager()
907             .device_add(device.clone() as Arc<dyn PlatformDevice>)
908             .expect("vesa_fb_device_init: platform_device_manager().device_add failed");
909 
910         frame_buffer_manager()
911             .register_fb(device.clone() as Arc<dyn FrameBuffer>)
912             .expect("vesa_fb_device_init: frame_buffer_manager().register_fb failed");
913 
914         // 加入全局fb表
915         let mut guard = FRAME_BUFFER_SET.write();
916         if guard.get(device.fb_id().data() as usize).unwrap().is_some() {
917             kwarn!(
918                 "vesa_fb_device_init: There is already an element {:?} in the FRAME_BUFFER_SET",
919                 device.fb_id()
920             );
921         }
922         guard[device.fb_id().data() as usize] = Some(device.clone());
923 
924         // 设置vesa fb的状态为运行中
925         device.inner.lock().fb_state = FbState::Running;
926     });
927 
928     return Ok(());
929 }
930