xref: /DragonOS/kernel/src/driver/video/fbdev/vesafb.rs (revision e7071df6a47c100381a8bc2000022e82d422361a)
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         tty::serial::serial8250::send_to_default_serial8250_port,
32         video::fbdev::base::{fbmem::frame_buffer_manager, FbVisual},
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     },
42     init::{boot_params, initcall::INITCALL_DEVICE},
43     libs::{
44         align::page_align_up,
45         once::Once,
46         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
47         spinlock::SpinLock,
48     },
49     mm::{
50         allocator::page_frame::PageFrameCount, no_init::pseudo_map_phys, MemoryManagementArch,
51         PhysAddr, VirtAddr,
52     },
53 };
54 
55 use super::base::{
56     fbmem::FbDevice, BlankMode, BootTimeVideoType, FbAccel, FbActivateFlags, FbId, FbState, FbType,
57     FbVModeFlags, FbVarScreenInfo, FbVideoMode, FixedScreenInfo, FrameBuffer, FrameBufferInfo,
58     FrameBufferOps,
59 };
60 
61 /// 当前机器上面是否有vesa帧缓冲区
62 static HAS_VESA_FB: AtomicBool = AtomicBool::new(false);
63 
64 lazy_static! {
65     static ref VESAFB_FIX_INFO: RwLock<FixedScreenInfo> = RwLock::new(FixedScreenInfo {
66         id: FixedScreenInfo::name2id("VESA VGA"),
67         fb_type: FbType::PackedPixels,
68         accel: FbAccel::None,
69         ..Default::default()
70     });
71     static ref VESAFB_DEFINED: RwLock<FbVarScreenInfo> = RwLock::new(FbVarScreenInfo {
72         activate: FbActivateFlags::FB_ACTIVATE_NOW,
73         height: None,
74         width: None,
75         right_margin: 32,
76         upper_margin: 16,
77         lower_margin: 4,
78         vsync_len: 4,
79         vmode: FbVModeFlags::FB_VMODE_NONINTERLACED,
80 
81         ..Default::default()
82     });
83 }
84 
85 #[derive(Debug)]
86 #[cast_to([sync] Device)]
87 #[cast_to([sync] PlatformDevice)]
88 pub struct VesaFb {
89     inner: SpinLock<InnerVesaFb>,
90     kobj_state: LockedKObjectState,
91 }
92 
93 impl VesaFb {
94     pub const NAME: &'static str = "vesa_vga";
95     pub fn new() -> Self {
96         return Self {
97             inner: SpinLock::new(InnerVesaFb {
98                 bus: None,
99                 class: None,
100                 driver: None,
101                 kern_inode: None,
102                 parent: None,
103                 kset: None,
104                 kobj_type: None,
105                 device_state: DeviceState::NotInitialized,
106                 pdev_id: 0,
107                 pdev_id_auto: false,
108                 fb_id: FbId::INIT,
109                 fb_device: None,
110                 fb_state: FbState::Suspended,
111             }),
112             kobj_state: LockedKObjectState::new(None),
113         };
114     }
115 }
116 
117 #[derive(Debug)]
118 struct InnerVesaFb {
119     bus: Option<Weak<dyn Bus>>,
120     class: Option<Arc<dyn Class>>,
121     driver: Option<Weak<dyn Driver>>,
122     kern_inode: Option<Arc<KernFSInode>>,
123     parent: Option<Weak<dyn KObject>>,
124     kset: Option<Arc<KSet>>,
125     kobj_type: Option<&'static dyn KObjType>,
126     device_state: DeviceState,
127     pdev_id: i32,
128     pdev_id_auto: bool,
129     fb_id: FbId,
130     fb_device: Option<Arc<FbDevice>>,
131     fb_state: FbState,
132 }
133 
134 impl FrameBuffer for VesaFb {
135     fn fb_id(&self) -> FbId {
136         self.inner.lock().fb_id
137     }
138 
139     fn set_fb_id(&self, id: FbId) {
140         self.inner.lock().fb_id = id;
141     }
142 }
143 
144 impl PlatformDevice for VesaFb {
145     fn pdev_name(&self) -> &str {
146         Self::NAME
147     }
148 
149     fn set_pdev_id(&self, id: i32) {
150         self.inner.lock().pdev_id = id;
151     }
152 
153     fn set_pdev_id_auto(&self, id_auto: bool) {
154         self.inner.lock().pdev_id_auto = id_auto;
155     }
156 
157     fn compatible_table(&self) -> CompatibleTable {
158         todo!()
159     }
160 
161     fn is_initialized(&self) -> bool {
162         self.inner.lock().device_state == DeviceState::Initialized
163     }
164 
165     fn set_state(&self, set_state: DeviceState) {
166         self.inner.lock().device_state = set_state;
167     }
168 }
169 
170 impl Device for VesaFb {
171     fn dev_type(&self) -> DeviceType {
172         DeviceType::Char
173     }
174 
175     fn id_table(&self) -> IdTable {
176         IdTable::new(self.name(), None)
177     }
178 
179     fn bus(&self) -> Option<Weak<dyn Bus>> {
180         self.inner.lock().bus.clone()
181     }
182 
183     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
184         self.inner.lock().bus = bus;
185     }
186 
187     fn set_class(&self, class: Option<Arc<dyn Class>>) {
188         self.inner.lock().class = class;
189     }
190 
191     fn driver(&self) -> Option<Arc<dyn Driver>> {
192         self.inner.lock().driver.clone()?.upgrade()
193     }
194 
195     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
196         self.inner.lock().driver = driver;
197     }
198 
199     fn is_dead(&self) -> bool {
200         false
201     }
202 
203     fn can_match(&self) -> bool {
204         true
205     }
206 
207     fn set_can_match(&self, _can_match: bool) {}
208 
209     fn state_synced(&self) -> bool {
210         true
211     }
212 }
213 
214 impl KObject for VesaFb {
215     fn as_any_ref(&self) -> &dyn core::any::Any {
216         self
217     }
218 
219     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
220         self.inner.lock().kern_inode = inode;
221     }
222 
223     fn inode(&self) -> Option<Arc<KernFSInode>> {
224         self.inner.lock().kern_inode.clone()
225     }
226 
227     fn parent(&self) -> Option<Weak<dyn KObject>> {
228         self.inner.lock().parent.clone()
229     }
230 
231     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
232         self.inner.lock().parent = parent;
233     }
234 
235     fn kset(&self) -> Option<Arc<KSet>> {
236         self.inner.lock().kset.clone()
237     }
238 
239     fn set_kset(&self, kset: Option<Arc<KSet>>) {
240         self.inner.lock().kset = kset;
241     }
242 
243     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
244         self.inner.lock().kobj_type
245     }
246 
247     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
248         self.inner.lock().kobj_type = ktype;
249     }
250 
251     fn name(&self) -> String {
252         Self::NAME.to_string()
253     }
254 
255     fn set_name(&self, _name: String) {
256         // do nothing
257     }
258 
259     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
260         self.kobj_state.read()
261     }
262 
263     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
264         self.kobj_state.write()
265     }
266 
267     fn set_kobj_state(&self, state: KObjectState) {
268         *self.kobj_state.write() = state;
269     }
270 }
271 
272 impl FrameBufferOps for VesaFb {
273     fn fb_open(&self, _user: bool) {
274         todo!()
275     }
276 
277     fn fb_release(&self, _user: bool) {
278         todo!()
279     }
280 
281     fn fb_set_color_register(
282         &self,
283         _regno: u16,
284         _red: u16,
285         _green: u16,
286         _blue: u16,
287     ) -> Result<(), SystemError> {
288         todo!()
289     }
290 
291     fn fb_blank(&self, _blank_mode: BlankMode) -> Result<(), SystemError> {
292         todo!()
293     }
294 
295     fn fb_destroy(&self) {
296         todo!()
297     }
298 }
299 
300 impl FrameBufferInfo for VesaFb {
301     fn fb_device(&self) -> Option<Arc<FbDevice>> {
302         self.inner.lock().fb_device.clone()
303     }
304 
305     fn set_fb_device(&self, device: Option<Arc<FbDevice>>) {
306         self.inner.lock().fb_device = device;
307     }
308 
309     fn screen_size(&self) -> usize {
310         todo!()
311     }
312 
313     fn current_fb_var(&self) -> FbVarScreenInfo {
314         VESAFB_DEFINED.read().clone()
315     }
316 
317     fn current_fb_fix(&self) -> FixedScreenInfo {
318         VESAFB_FIX_INFO.read().clone()
319     }
320 
321     fn video_mode(&self) -> Option<&FbVideoMode> {
322         todo!()
323     }
324 
325     fn state(&self) -> FbState {
326         self.inner.lock().fb_state
327     }
328 }
329 
330 #[derive(Debug)]
331 #[cast_to([sync] PlatformDriver)]
332 struct VesaFbDriver {
333     inner: SpinLock<InnerVesaFbDriver>,
334     kobj_state: LockedKObjectState,
335 }
336 
337 impl VesaFbDriver {
338     pub fn new() -> Arc<Self> {
339         let r = Arc::new(Self {
340             inner: SpinLock::new(InnerVesaFbDriver {
341                 ktype: None,
342                 kset: None,
343                 parent: None,
344                 kernfs_inode: None,
345                 devices: Vec::new(),
346                 bus: None,
347                 self_ref: Weak::new(),
348             }),
349             kobj_state: LockedKObjectState::new(None),
350         });
351 
352         r.inner.lock().self_ref = Arc::downgrade(&r);
353 
354         return r;
355     }
356 }
357 
358 #[derive(Debug)]
359 struct InnerVesaFbDriver {
360     ktype: Option<&'static dyn KObjType>,
361     kset: Option<Arc<KSet>>,
362     parent: Option<Weak<dyn KObject>>,
363     kernfs_inode: Option<Arc<KernFSInode>>,
364     devices: Vec<Arc<dyn Device>>,
365     bus: Option<Weak<dyn Bus>>,
366 
367     self_ref: Weak<VesaFbDriver>,
368 }
369 
370 impl VesaFbDriver {
371     const NAME: &'static str = "vesa-framebuffer";
372 }
373 
374 impl PlatformDriver for VesaFbDriver {
375     fn probe(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
376         let device = device
377             .clone()
378             .arc_any()
379             .downcast::<VesaFb>()
380             .map_err(|_| SystemError::EINVAL)?;
381 
382         device.set_driver(Some(self.inner.lock_irqsave().self_ref.clone()));
383 
384         return Ok(());
385     }
386 
387     fn remove(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
388         todo!()
389     }
390 
391     fn shutdown(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
392         // do nothing
393         return Ok(());
394     }
395 
396     fn suspend(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
397         // do nothing
398         return Ok(());
399     }
400 
401     fn resume(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
402         todo!()
403     }
404 }
405 
406 impl Driver for VesaFbDriver {
407     fn id_table(&self) -> Option<IdTable> {
408         Some(IdTable::new(VesaFb::NAME.to_string(), None))
409     }
410 
411     fn devices(&self) -> Vec<Arc<dyn Device>> {
412         self.inner.lock().devices.clone()
413     }
414 
415     fn add_device(&self, device: Arc<dyn Device>) {
416         let mut guard = self.inner.lock();
417         // check if the device is already in the list
418         if guard.devices.iter().any(|dev| Arc::ptr_eq(dev, &device)) {
419             return;
420         }
421 
422         guard.devices.push(device);
423     }
424 
425     fn delete_device(&self, device: &Arc<dyn Device>) {
426         let mut guard = self.inner.lock();
427         guard.devices.retain(|dev| !Arc::ptr_eq(dev, device));
428     }
429 
430     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
431         self.inner.lock().bus = bus;
432     }
433 
434     fn bus(&self) -> Option<Weak<dyn Bus>> {
435         self.inner.lock().bus.clone()
436     }
437 
438     fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
439         return &[&VesaFbAnonAttributeGroup];
440     }
441 }
442 
443 impl KObject for VesaFbDriver {
444     fn as_any_ref(&self) -> &dyn core::any::Any {
445         self
446     }
447 
448     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
449         self.inner.lock().kernfs_inode = inode;
450     }
451 
452     fn inode(&self) -> Option<Arc<KernFSInode>> {
453         self.inner.lock().kernfs_inode.clone()
454     }
455 
456     fn parent(&self) -> Option<Weak<dyn KObject>> {
457         self.inner.lock().parent.clone()
458     }
459 
460     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
461         self.inner.lock().parent = parent;
462     }
463 
464     fn kset(&self) -> Option<Arc<KSet>> {
465         self.inner.lock().kset.clone()
466     }
467 
468     fn set_kset(&self, kset: Option<Arc<KSet>>) {
469         self.inner.lock().kset = kset;
470     }
471 
472     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
473         self.inner.lock().ktype
474     }
475 
476     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
477         self.inner.lock().ktype = ktype;
478     }
479 
480     fn name(&self) -> String {
481         Self::NAME.to_string()
482     }
483 
484     fn set_name(&self, _name: String) {
485         // do nothing
486     }
487 
488     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
489         self.kobj_state.read()
490     }
491 
492     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
493         self.kobj_state.write()
494     }
495 
496     fn set_kobj_state(&self, state: KObjectState) {
497         *self.kobj_state.write() = state;
498     }
499 }
500 
501 #[derive(Debug)]
502 struct VesaFbAnonAttributeGroup;
503 
504 impl AttributeGroup for VesaFbAnonAttributeGroup {
505     fn name(&self) -> Option<&str> {
506         None
507     }
508 
509     fn attrs(&self) -> &[&'static dyn Attribute] {
510         &[&AnonAttrPhysAddr as &'static dyn Attribute]
511     }
512 
513     fn is_visible(
514         &self,
515         _kobj: Arc<dyn KObject>,
516         attr: &'static dyn Attribute,
517     ) -> Option<ModeType> {
518         Some(attr.mode())
519     }
520 }
521 
522 #[derive(Debug)]
523 struct AnonAttrPhysAddr;
524 
525 impl Attribute for AnonAttrPhysAddr {
526     fn name(&self) -> &str {
527         "smem_start"
528     }
529 
530     fn mode(&self) -> ModeType {
531         ModeType::S_IRUGO
532     }
533 
534     fn support(&self) -> SysFSOpsSupport {
535         SysFSOpsSupport::SHOW
536     }
537 
538     fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
539         sysfs_emit_str(
540             buf,
541             format!(
542                 "0x{:x}\n",
543                 VESAFB_FIX_INFO
544                     .read()
545                     .smem_start
546                     .unwrap_or(PhysAddr::new(0))
547                     .data()
548             )
549             .as_str(),
550         )
551     }
552 }
553 
554 #[unified_init(INITCALL_DEVICE)]
555 pub fn vesa_fb_driver_init() -> Result<(), SystemError> {
556     let driver = VesaFbDriver::new();
557 
558     platform_driver_manager().register(driver)?;
559 
560     return Ok(());
561 }
562 
563 /// 在内存管理初始化之前,初始化vesafb
564 pub fn vesafb_early_init() -> Result<VirtAddr, SystemError> {
565     let mut _reserved: u32 = 0;
566 
567     let mut fb_info: MaybeUninit<multiboot_tag_framebuffer_info_t> = MaybeUninit::uninit();
568     //从multiboot2中读取帧缓冲区信息至fb_info
569 
570     // todo: 换成rust的,并且检测是否成功获取
571     unsafe {
572         multiboot2_iter(
573             Some(multiboot2_get_Framebuffer_info),
574             fb_info.as_mut_ptr() as usize as *mut c_void,
575             &mut _reserved as *mut c_uint,
576         )
577     };
578     unsafe { fb_info.assume_init() };
579     let fb_info: multiboot_tag_framebuffer_info_t = unsafe { core::mem::transmute(fb_info) };
580 
581     // todo: 判断是否有vesa帧缓冲区,这里暂时直接设置true
582     HAS_VESA_FB.store(true, core::sync::atomic::Ordering::SeqCst);
583 
584     let width = fb_info.framebuffer_width;
585     let height = fb_info.framebuffer_height;
586 
587     let mut boot_params_guard = boot_params().write();
588     let boottime_screen_info = &mut boot_params_guard.screen_info;
589 
590     boottime_screen_info.is_vga = true;
591 
592     boottime_screen_info.lfb_base = PhysAddr::new(fb_info.framebuffer_addr as usize);
593 
594     if fb_info.framebuffer_type == 2 {
595         //当type=2时,width与height用字符数表示,故depth=8
596         boottime_screen_info.origin_video_cols = width as u8;
597         boottime_screen_info.origin_video_lines = height as u8;
598         boottime_screen_info.video_type = BootTimeVideoType::Mda;
599         boottime_screen_info.lfb_depth = 8;
600     } else {
601         //否则为图像模式,depth应参照帧缓冲区信息里面的每个像素的位数
602         boottime_screen_info.lfb_width = width;
603         boottime_screen_info.lfb_height = height;
604         boottime_screen_info.video_type = BootTimeVideoType::Vlfb;
605         boottime_screen_info.lfb_depth = fb_info.framebuffer_bpp as u8;
606     }
607 
608     boottime_screen_info.lfb_size =
609         (width * height * ((fb_info.framebuffer_bpp as u32 + 7) / 8)) as usize;
610 
611     let buf_vaddr = VirtAddr::new(0xffff800003200000);
612     boottime_screen_info.lfb_virt_base = Some(buf_vaddr);
613 
614     let init_text = "Video driver to map.\n\0";
615     send_to_default_serial8250_port(init_text.as_bytes());
616 
617     // 地址映射
618     let paddr = PhysAddr::new(fb_info.framebuffer_addr as usize);
619     let count =
620         PageFrameCount::new(page_align_up(boottime_screen_info.lfb_size) / MMArch::PAGE_SIZE);
621     unsafe { pseudo_map_phys(buf_vaddr, paddr, count) };
622     return Ok(buf_vaddr);
623 }
624 
625 #[unified_init(INITCALL_DEVICE)]
626 fn vesa_fb_device_init() -> Result<(), SystemError> {
627     // 如果没有vesa帧缓冲区,直接返回
628     if !HAS_VESA_FB.load(core::sync::atomic::Ordering::SeqCst) {
629         return Ok(());
630     }
631 
632     static INIT: Once = Once::new();
633     INIT.call_once(|| {
634         kinfo!("vesa fb device init");
635 
636         let mut fix_info_guard = VESAFB_FIX_INFO.write_irqsave();
637         let mut var_info_guard = VESAFB_DEFINED.write_irqsave();
638 
639         let boot_params_guard = boot_params().read();
640         let boottime_screen_info = &boot_params_guard.screen_info;
641 
642         fix_info_guard.smem_start = Some(boottime_screen_info.lfb_base);
643         fix_info_guard.smem_len = boottime_screen_info.lfb_size;
644 
645         if boottime_screen_info.video_type == BootTimeVideoType::Mda {
646             fix_info_guard.visual = FbVisual::Mono10;
647             var_info_guard.bits_per_pixel = 8;
648             fix_info_guard.line_length = (boottime_screen_info.origin_video_cols as u32)
649                 * (var_info_guard.bits_per_pixel / 8);
650             var_info_guard.xres_virtual = boottime_screen_info.origin_video_cols as u32;
651             var_info_guard.yres_virtual = boottime_screen_info.origin_video_lines as u32;
652         } else {
653             fix_info_guard.visual = FbVisual::TrueColor;
654             var_info_guard.bits_per_pixel = boottime_screen_info.lfb_depth as u32;
655             fix_info_guard.line_length =
656                 (boottime_screen_info.lfb_width as u32) * (var_info_guard.bits_per_pixel / 8);
657             var_info_guard.xres_virtual = boottime_screen_info.lfb_width as u32;
658             var_info_guard.yres_virtual = boottime_screen_info.lfb_height as u32;
659         }
660 
661         drop(var_info_guard);
662         drop(fix_info_guard);
663 
664         let device = Arc::new(VesaFb::new());
665         device_manager().device_default_initialize(&(device.clone() as Arc<dyn Device>));
666 
667         platform_device_manager()
668             .device_add(device.clone() as Arc<dyn PlatformDevice>)
669             .expect("vesa_fb_device_init: platform_device_manager().device_add failed");
670 
671         frame_buffer_manager()
672             .register_fb(device.clone() as Arc<dyn FrameBuffer>)
673             .expect("vesa_fb_device_init: frame_buffer_manager().register_fb failed");
674 
675         // 设置vesa fb的状态为运行中
676         device.inner.lock().fb_state = FbState::Running;
677     });
678 
679     return Ok(());
680 }
681