1c566df45SLoGin use core::sync::atomic::{AtomicBool, Ordering}; 2bacd691cSlogin 3bacd691cSlogin use crate::{ 41496ba7bSLoGin arch::MMArch, 5c566df45SLoGin init::boot_params, 61496ba7bSLoGin libs::{ 71496ba7bSLoGin align::page_align_up, 81496ba7bSLoGin lib_ui::screen_manager::{ScmBuffer, ScmBufferFlag, ScmBufferInfo}, 91496ba7bSLoGin rwlock::{RwLock, RwLockReadGuard}, 101496ba7bSLoGin spinlock::SpinLock, 111496ba7bSLoGin }, 121496ba7bSLoGin mm::{ 13*cf7f801eSMemoryShore allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, page::EntryFlags, 14c75ef4e2SLoGin MemoryManagementArch, 151496ba7bSLoGin }, 161496ba7bSLoGin time::timer::{Timer, TimerFunction}, 17bacd691cSlogin }; 1891e9d4abSLoGin use alloc::{boxed::Box, sync::Arc}; 192eab6dd7S曾俊 use log::info; 2091e9d4abSLoGin use system_error::SystemError; 21bacd691cSlogin 22418ad41fSLoGin pub mod console; 2308a2ee40SLoGin pub mod fbdev; 2408a2ee40SLoGin 251496ba7bSLoGin static mut __MAMAGER: Option<VideoRefreshManager> = None; 261496ba7bSLoGin 271496ba7bSLoGin pub fn video_refresh_manager() -> &'static VideoRefreshManager { 281496ba7bSLoGin return unsafe { 29b5b571e0SLoGin __MAMAGER 301496ba7bSLoGin .as_ref() 311496ba7bSLoGin .expect("Video refresh manager has not been initialized yet!") 321496ba7bSLoGin }; 331496ba7bSLoGin } 34b5b571e0SLoGin #[allow(clippy::type_complexity)] 351496ba7bSLoGin ///管理显示刷新变量的结构体 361496ba7bSLoGin pub struct VideoRefreshManager { 371496ba7bSLoGin device_buffer: RwLock<ScmBufferInfo>, 382755467cS曾俊 refresh_target: RwLock<Option<Arc<SpinLock<Box<[u8]>>>>>, 3978bf93f0SYJwu2023 running: AtomicBool, 40bacd691cSlogin } 41bacd691cSlogin 421496ba7bSLoGin const REFRESH_INTERVAL: u64 = 30; 431496ba7bSLoGin 441496ba7bSLoGin impl VideoRefreshManager { 451496ba7bSLoGin /** 461496ba7bSLoGin * @brief 启动定时刷新 471496ba7bSLoGin * @return 启动成功: true, 失败: false 481496ba7bSLoGin */ 491496ba7bSLoGin pub fn run_video_refresh(&self) -> bool { 501496ba7bSLoGin //设置Manager运行标志 511496ba7bSLoGin let res = self.set_run(); 521496ba7bSLoGin 531496ba7bSLoGin //设置成功则开始任务,否则直接返回false 541496ba7bSLoGin if res { 551496ba7bSLoGin //第一次将expire_jiffies设置小一点,使得这次刷新尽快开始,后续的刷新将按照REFRESH_INTERVAL间隔进行 561496ba7bSLoGin let timer = Timer::new(VideoRefreshExecutor::new(), 1); 571496ba7bSLoGin //将新一次定时任务加入队列 581496ba7bSLoGin timer.activate(); 591496ba7bSLoGin } 601496ba7bSLoGin return res; 61bacd691cSlogin } 62bacd691cSlogin 631496ba7bSLoGin /// 停止定时刷新 641496ba7bSLoGin #[allow(dead_code)] 651496ba7bSLoGin pub fn stop_video_refresh(&self) { 661496ba7bSLoGin self.running.store(false, Ordering::SeqCst); 67bacd691cSlogin } 68bacd691cSlogin 69bacd691cSlogin fn set_run(&self) -> bool { 701496ba7bSLoGin let res = self 71bacd691cSlogin .running 721496ba7bSLoGin .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst); 73b5b571e0SLoGin return res.is_ok(); 74bacd691cSlogin } 75bacd691cSlogin 761496ba7bSLoGin /** 771496ba7bSLoGin * @brief VBE帧缓存区的地址重新映射 781496ba7bSLoGin * 将帧缓存区映射到地址SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE处 791496ba7bSLoGin */ 801496ba7bSLoGin fn init_frame_buffer(&self) { 812eab6dd7S曾俊 info!("Re-mapping VBE frame buffer..."); 82c75ef4e2SLoGin let buf_vaddr = boot_params() 83c75ef4e2SLoGin .read_irqsave() 84c75ef4e2SLoGin .screen_info 85c75ef4e2SLoGin .lfb_virt_base 86c75ef4e2SLoGin .unwrap(); 871496ba7bSLoGin 8802343d0bSLoGin let mut frame_buffer_info_guard = self.device_buffer.write(); 8902343d0bSLoGin if let ScmBuffer::DeviceBuffer(vaddr) = &mut (frame_buffer_info_guard).buf { 901496ba7bSLoGin *vaddr = buf_vaddr; 911496ba7bSLoGin } 921496ba7bSLoGin 931496ba7bSLoGin // 地址映射 94c566df45SLoGin let mut paddr = boot_params().read().screen_info.lfb_base; 951496ba7bSLoGin let count = PageFrameCount::new( 9602343d0bSLoGin page_align_up(frame_buffer_info_guard.buf_size()) / MMArch::PAGE_SIZE, 971496ba7bSLoGin ); 98*cf7f801eSMemoryShore let page_flags: EntryFlags<MMArch> = EntryFlags::new().set_execute(true).set_write(true); 991496ba7bSLoGin 1001496ba7bSLoGin let mut kernel_mapper = KernelMapper::lock(); 1011496ba7bSLoGin let mut kernel_mapper = kernel_mapper.as_mut(); 1021496ba7bSLoGin assert!(kernel_mapper.is_some()); 1031496ba7bSLoGin let mut vaddr = buf_vaddr; 1041496ba7bSLoGin unsafe { 1051496ba7bSLoGin for _ in 0..count.data() { 1061496ba7bSLoGin let flusher = kernel_mapper 1071496ba7bSLoGin .as_mut() 1081496ba7bSLoGin .unwrap() 1091496ba7bSLoGin .map_phys(vaddr, paddr, page_flags) 1101496ba7bSLoGin .unwrap(); 1111496ba7bSLoGin 1121496ba7bSLoGin flusher.flush(); 1131496ba7bSLoGin vaddr += MMArch::PAGE_SIZE; 1141496ba7bSLoGin paddr += MMArch::PAGE_SIZE; 115bacd691cSlogin } 116bacd691cSlogin } 117bacd691cSlogin 1182eab6dd7S曾俊 info!("VBE frame buffer successfully Re-mapped!"); 119bacd691cSlogin } 1201496ba7bSLoGin 1211496ba7bSLoGin /** 1221496ba7bSLoGin * @brief 初始化显示模块,需先低级初始化才能高级初始化 1231496ba7bSLoGin * @param level 初始化等级 1241496ba7bSLoGin * false -> 低级初始化:不使用double buffer 1251496ba7bSLoGin * true ->高级初始化:增加double buffer的支持 1261496ba7bSLoGin * @return int 1271496ba7bSLoGin */ 1281496ba7bSLoGin pub fn video_reinitialize(&self, level: bool) -> Result<(), SystemError> { 1291496ba7bSLoGin if !level { 1301496ba7bSLoGin self.init_frame_buffer(); 1311496ba7bSLoGin } else { 1321496ba7bSLoGin // 开启屏幕计时刷新 1331496ba7bSLoGin assert!(self.run_video_refresh()); 1341496ba7bSLoGin } 1351496ba7bSLoGin return Ok(()); 1361496ba7bSLoGin } 1371496ba7bSLoGin 1381496ba7bSLoGin /** 1391496ba7bSLoGin * @brief 设置帧缓冲区刷新目标 1401496ba7bSLoGin * 1411496ba7bSLoGin * @param buf 1421496ba7bSLoGin * @return int 1431496ba7bSLoGin */ 1441496ba7bSLoGin pub fn set_refresh_target(&self, buf_info: &ScmBufferInfo) -> Result<(), SystemError> { 1451496ba7bSLoGin let mut refresh_target = self.refresh_target.write_irqsave(); 1461496ba7bSLoGin if let ScmBuffer::DoubleBuffer(double_buffer) = &buf_info.buf { 1471496ba7bSLoGin *refresh_target = Some(double_buffer.clone()); 1481496ba7bSLoGin return Ok(()); 1491496ba7bSLoGin } 1501496ba7bSLoGin return Err(SystemError::EINVAL); 1511496ba7bSLoGin } 152b5b571e0SLoGin #[allow(clippy::type_complexity)] 1531496ba7bSLoGin #[allow(dead_code)] 1542755467cS曾俊 pub fn refresh_target(&self) -> RwLockReadGuard<'_, Option<Arc<SpinLock<Box<[u8]>>>>> { 1551496ba7bSLoGin let x = self.refresh_target.read(); 1561496ba7bSLoGin 1571496ba7bSLoGin return x; 1581496ba7bSLoGin } 1591496ba7bSLoGin 1601496ba7bSLoGin pub fn device_buffer(&self) -> RwLockReadGuard<'_, ScmBufferInfo> { 1611496ba7bSLoGin return self.device_buffer.read(); 1621496ba7bSLoGin } 1631496ba7bSLoGin 1641a72a751SLoGin /// 在riscv64平台下暂时不支持 1651a72a751SLoGin #[cfg(target_arch = "riscv64")] 1661a72a751SLoGin pub unsafe fn video_init() -> Result<(), SystemError> { 1671a72a751SLoGin return Err(SystemError::ENOSYS); 1681a72a751SLoGin } 1691a72a751SLoGin 1701a72a751SLoGin /// 此函数用于初始化显示驱动,为后续的图形输出做好准备。 171c566df45SLoGin #[cfg(target_arch = "x86_64")] 1721496ba7bSLoGin pub unsafe fn video_init() -> Result<(), SystemError> { 173c566df45SLoGin use crate::{ 174c566df45SLoGin arch::driver::video::arch_video_early_init, 17552da9a59SGnoCiYeH driver::{ 17652da9a59SGnoCiYeH serial::serial8250::send_to_default_serial8250_port, 17752da9a59SGnoCiYeH video::fbdev::base::BootTimeVideoType, 17852da9a59SGnoCiYeH }, 1791496ba7bSLoGin }; 1801496ba7bSLoGin 181c566df45SLoGin arch_video_early_init()?; 182c566df45SLoGin 183c566df45SLoGin let boot_params_guard = boot_params().read(); 184c566df45SLoGin let screen_info = &boot_params_guard.screen_info; 185c566df45SLoGin let buf_vaddr = screen_info.lfb_virt_base.unwrap(); 186c566df45SLoGin 187c566df45SLoGin let buf_flag: ScmBufferFlag; 188c566df45SLoGin let device_buffer: ScmBufferInfo; 189c566df45SLoGin 190c566df45SLoGin if screen_info.video_type == BootTimeVideoType::Mda { 191c566df45SLoGin buf_flag = ScmBufferFlag::SCM_BF_TEXT | ScmBufferFlag::SCM_BF_FB; 192c566df45SLoGin device_buffer = ScmBufferInfo::new_device_buffer( 193c566df45SLoGin screen_info.origin_video_cols.into(), 194c566df45SLoGin screen_info.origin_video_lines.into(), 195c566df45SLoGin screen_info.lfb_size as u32, 196c566df45SLoGin screen_info.lfb_depth.into(), 197c566df45SLoGin buf_flag, 1981496ba7bSLoGin buf_vaddr, 1991496ba7bSLoGin ) 2001496ba7bSLoGin .unwrap(); 201c566df45SLoGin } else { 202c566df45SLoGin // 图形模式 203c566df45SLoGin buf_flag = ScmBufferFlag::SCM_BF_PIXEL | ScmBufferFlag::SCM_BF_FB; 204c566df45SLoGin device_buffer = ScmBufferInfo::new_device_buffer( 205c566df45SLoGin screen_info.lfb_width, 206c566df45SLoGin screen_info.lfb_height, 207c566df45SLoGin screen_info.lfb_size as u32, 208c566df45SLoGin screen_info.lfb_depth.into(), 209c566df45SLoGin buf_flag, 210c566df45SLoGin buf_vaddr, 211c566df45SLoGin ) 212c566df45SLoGin .unwrap(); 213c566df45SLoGin } 2141496ba7bSLoGin 2151496ba7bSLoGin let result = Self { 2161496ba7bSLoGin device_buffer: RwLock::new(device_buffer), 2171496ba7bSLoGin refresh_target: RwLock::new(None), 2181496ba7bSLoGin running: AtomicBool::new(false), 2191496ba7bSLoGin }; 2201496ba7bSLoGin 2211496ba7bSLoGin __MAMAGER = Some(result); 2221496ba7bSLoGin 2231496ba7bSLoGin let init_text = "Video driver initialized.\n\0"; 224a03c4f9dSLoGin send_to_default_serial8250_port(init_text.as_bytes()); 2251496ba7bSLoGin return Ok(()); 2261496ba7bSLoGin } 2271496ba7bSLoGin } 2281496ba7bSLoGin 2291496ba7bSLoGin //刷新任务执行器 2301496ba7bSLoGin #[derive(Debug)] 2311496ba7bSLoGin struct VideoRefreshExecutor; 2321496ba7bSLoGin 2331496ba7bSLoGin impl VideoRefreshExecutor { 2341496ba7bSLoGin fn new() -> Box<VideoRefreshExecutor> { 2351496ba7bSLoGin return Box::new(VideoRefreshExecutor); 2361496ba7bSLoGin } 2371496ba7bSLoGin } 2381496ba7bSLoGin 2391496ba7bSLoGin impl TimerFunction for VideoRefreshExecutor { 2401496ba7bSLoGin /** 2411496ba7bSLoGin * @brief 交给定时器执行的任务,此方法不应手动调用 2421496ba7bSLoGin * @return Ok(()) 2431496ba7bSLoGin */ 244b5b571e0SLoGin #[allow(clippy::type_complexity)] 2451496ba7bSLoGin fn run(&mut self) -> Result<(), SystemError> { 2461496ba7bSLoGin // 获得Manager 2471496ba7bSLoGin let manager = video_refresh_manager(); 2481496ba7bSLoGin 2491496ba7bSLoGin let start_next_refresh = || { 2501496ba7bSLoGin //判断是否还需要刷新,若需要则继续分配下一次计时任务,否则不分配 2511496ba7bSLoGin if manager.running.load(Ordering::SeqCst) { 2521496ba7bSLoGin let timer = Timer::new(VideoRefreshExecutor::new(), REFRESH_INTERVAL); 2531496ba7bSLoGin //将新一次定时任务加入队列 2541496ba7bSLoGin timer.activate(); 2551496ba7bSLoGin } 2561496ba7bSLoGin }; 2571496ba7bSLoGin 2582755467cS曾俊 let mut refresh_target: Option<RwLockReadGuard<'_, Option<Arc<SpinLock<Box<[u8]>>>>>> = 2591496ba7bSLoGin None; 2601496ba7bSLoGin const TRY_TIMES: i32 = 2; 2611496ba7bSLoGin for i in 0..TRY_TIMES { 2621496ba7bSLoGin let g = manager.refresh_target.try_read(); 2631496ba7bSLoGin if g.is_none() { 2641496ba7bSLoGin if i == TRY_TIMES - 1 { 2651496ba7bSLoGin start_next_refresh(); 2661496ba7bSLoGin return Ok(()); 2671496ba7bSLoGin } 2681496ba7bSLoGin continue; 2691496ba7bSLoGin } 2701496ba7bSLoGin refresh_target = Some(g.unwrap()); 2711496ba7bSLoGin break; 2721496ba7bSLoGin } 2731496ba7bSLoGin 2741496ba7bSLoGin let refresh_target = refresh_target.unwrap(); 2751496ba7bSLoGin 2761496ba7bSLoGin if let ScmBuffer::DeviceBuffer(vaddr) = manager.device_buffer().buf { 277b5b571e0SLoGin let p: *mut u8 = vaddr.as_ptr(); 2781496ba7bSLoGin let mut target_guard = None; 2791496ba7bSLoGin for _ in 0..2 { 2801496ba7bSLoGin if let Ok(guard) = refresh_target.as_ref().unwrap().try_lock_irqsave() { 2811496ba7bSLoGin target_guard = Some(guard); 2821496ba7bSLoGin break; 2831496ba7bSLoGin } 2841496ba7bSLoGin } 2851496ba7bSLoGin if target_guard.is_none() { 2861496ba7bSLoGin start_next_refresh(); 2871496ba7bSLoGin return Ok(()); 2881496ba7bSLoGin } 2891496ba7bSLoGin let mut target_guard = target_guard.unwrap(); 2901496ba7bSLoGin unsafe { 2911496ba7bSLoGin p.copy_from_nonoverlapping( 2922755467cS曾俊 target_guard.as_mut_ptr(), 2931496ba7bSLoGin manager.device_buffer().buf_size() as usize, 2941496ba7bSLoGin ) 2951496ba7bSLoGin } 2961496ba7bSLoGin } 2971496ba7bSLoGin 2981496ba7bSLoGin start_next_refresh(); 2991496ba7bSLoGin 3001496ba7bSLoGin return Ok(()); 3011496ba7bSLoGin } 3021496ba7bSLoGin } 3031496ba7bSLoGin 304bacd691cSlogin #[no_mangle] 3051496ba7bSLoGin pub unsafe extern "C" fn rs_video_init() -> i32 { 3061496ba7bSLoGin return VideoRefreshManager::video_init() 3071496ba7bSLoGin .map(|_| 0) 3081496ba7bSLoGin .unwrap_or_else(|e| e.to_posix_errno()); 309bacd691cSlogin } 310