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