1 use core::sync::atomic::{AtomicBool, Ordering}; 2 3 use crate::{ 4 arch::MMArch, 5 init::boot_params, 6 libs::{ 7 align::page_align_up, 8 lib_ui::screen_manager::{ScmBuffer, ScmBufferFlag, ScmBufferInfo}, 9 rwlock::{RwLock, RwLockReadGuard}, 10 spinlock::SpinLock, 11 }, 12 mm::{mmio_buddy::mmio_pool, page::EntryFlags}, 13 time::timer::{Timer, TimerFunction}, 14 }; 15 use alloc::{boxed::Box, sync::Arc}; 16 use log::info; 17 use system_error::SystemError; 18 19 pub mod console; 20 pub mod fbdev; 21 22 static mut __MAMAGER: Option<VideoRefreshManager> = None; 23 24 #[inline] 25 pub fn has_video_refresh_manager() -> bool { 26 return unsafe { __MAMAGER.is_some() }; 27 } 28 pub fn video_refresh_manager() -> &'static VideoRefreshManager { 29 return unsafe { 30 __MAMAGER 31 .as_ref() 32 .expect("Video refresh manager has not been initialized yet!") 33 }; 34 } 35 #[allow(clippy::type_complexity)] 36 ///管理显示刷新变量的结构体 37 pub struct VideoRefreshManager { 38 device_buffer: RwLock<ScmBufferInfo>, 39 refresh_target: RwLock<Option<Arc<SpinLock<Box<[u8]>>>>>, 40 running: AtomicBool, 41 } 42 43 const REFRESH_INTERVAL: u64 = 30; 44 45 impl VideoRefreshManager { 46 /** 47 * @brief 启动定时刷新 48 * @return 启动成功: true, 失败: false 49 */ 50 pub fn run_video_refresh(&self) -> bool { 51 //设置Manager运行标志 52 let res = self.set_run(); 53 54 //设置成功则开始任务,否则直接返回false 55 if res { 56 //第一次将expire_jiffies设置小一点,使得这次刷新尽快开始,后续的刷新将按照REFRESH_INTERVAL间隔进行 57 let timer = Timer::new(VideoRefreshExecutor::new(), 1); 58 //将新一次定时任务加入队列 59 timer.activate(); 60 } 61 return res; 62 } 63 64 /// 停止定时刷新 65 #[allow(dead_code)] 66 pub fn stop_video_refresh(&self) { 67 self.running.store(false, Ordering::SeqCst); 68 } 69 70 fn set_run(&self) -> bool { 71 let res = self 72 .running 73 .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst); 74 return res.is_ok(); 75 } 76 77 /** 78 * VBE帧缓存区的地址重新映射 79 */ 80 fn init_frame_buffer(&self) -> Result<(), SystemError> { 81 let mut bp = boot_params().write_irqsave(); 82 // 没有VBE 83 if bp.screen_info.lfb_base.data() == 0 { 84 return Err(SystemError::ENODEV); 85 } 86 info!("Re-mapping VBE frame buffer..."); 87 let buf_size = bp.screen_info.lfb_size; 88 89 let mmio_guard = mmio_pool().create_mmio(page_align_up(buf_size)).unwrap(); 90 let mmio_guard = Arc::new(mmio_guard); 91 let buf_vaddr = mmio_guard.vaddr(); 92 bp.screen_info.lfb_virt_base = Some(buf_vaddr); 93 94 let mut frame_buffer_info_guard: crate::libs::rwlock::RwLockWriteGuard<ScmBufferInfo> = 95 self.device_buffer.write(); 96 unsafe { frame_buffer_info_guard.set_device_buffer_mmio_guard(mmio_guard.clone()) }; 97 if let ScmBuffer::DeviceBuffer(vaddr) = &mut (frame_buffer_info_guard).buf { 98 *vaddr = buf_vaddr; 99 } 100 // 地址映射 101 let paddr = bp.screen_info.lfb_base; 102 let page_flags: EntryFlags<MMArch> = EntryFlags::new().set_execute(true).set_write(true); 103 104 unsafe { 105 mmio_guard 106 .map_phys_with_flags(paddr, page_align_up(buf_size), page_flags) 107 .expect("Failed to map VBE frame buffer!") 108 }; 109 110 info!("VBE frame buffer successfully Re-mapped!"); 111 Ok(()) 112 } 113 114 /** 115 * @brief 初始化显示模块,需先低级初始化才能高级初始化 116 * @param level 初始化等级 117 * false -> 低级初始化:不使用double buffer 118 * true ->高级初始化:增加double buffer的支持 119 * @return int 120 */ 121 pub fn video_reinitialize(&self, level: bool) -> Result<(), SystemError> { 122 if !level { 123 self.init_frame_buffer()?; 124 } else { 125 // 开启屏幕计时刷新 126 assert!(self.run_video_refresh()); 127 } 128 return Ok(()); 129 } 130 131 /** 132 * @brief 设置帧缓冲区刷新目标 133 * 134 * @param buf 135 * @return int 136 */ 137 pub fn set_refresh_target(&self, buf_info: &ScmBufferInfo) -> Result<(), SystemError> { 138 let mut refresh_target = self.refresh_target.write_irqsave(); 139 if let ScmBuffer::DoubleBuffer(double_buffer) = &buf_info.buf { 140 *refresh_target = Some(double_buffer.clone()); 141 return Ok(()); 142 } 143 return Err(SystemError::EINVAL); 144 } 145 #[allow(clippy::type_complexity)] 146 #[allow(dead_code)] 147 pub fn refresh_target(&self) -> RwLockReadGuard<'_, Option<Arc<SpinLock<Box<[u8]>>>>> { 148 let x = self.refresh_target.read(); 149 150 return x; 151 } 152 153 pub fn device_buffer(&self) -> RwLockReadGuard<'_, ScmBufferInfo> { 154 return self.device_buffer.read(); 155 } 156 157 /// 在riscv64平台下暂时不支持 158 #[cfg(target_arch = "riscv64")] 159 pub unsafe fn video_init() -> Result<(), SystemError> { 160 return Err(SystemError::ENOSYS); 161 } 162 163 /// 此函数用于初始化显示驱动,为后续的图形输出做好准备。 164 #[cfg(target_arch = "x86_64")] 165 pub unsafe fn video_init() -> Result<(), SystemError> { 166 use crate::{ 167 arch::driver::video::arch_video_early_init, 168 driver::{ 169 serial::serial8250::send_to_default_serial8250_port, 170 video::fbdev::base::BootTimeVideoType, 171 }, 172 }; 173 174 arch_video_early_init()?; 175 176 let boot_params_guard = boot_params().read(); 177 let screen_info = &boot_params_guard.screen_info; 178 let buf_vaddr = screen_info.lfb_virt_base.unwrap(); 179 180 let buf_flag: ScmBufferFlag; 181 let device_buffer: ScmBufferInfo; 182 183 if screen_info.video_type == BootTimeVideoType::Mda { 184 buf_flag = ScmBufferFlag::SCM_BF_TEXT | ScmBufferFlag::SCM_BF_FB; 185 device_buffer = ScmBufferInfo::new_device_buffer( 186 screen_info.origin_video_cols.into(), 187 screen_info.origin_video_lines.into(), 188 screen_info.lfb_size as u32, 189 screen_info.lfb_depth.into(), 190 buf_flag, 191 buf_vaddr, 192 None, 193 ) 194 .unwrap(); 195 } else { 196 // 图形模式 197 buf_flag = ScmBufferFlag::SCM_BF_PIXEL | ScmBufferFlag::SCM_BF_FB; 198 device_buffer = ScmBufferInfo::new_device_buffer( 199 screen_info.lfb_width, 200 screen_info.lfb_height, 201 screen_info.lfb_size as u32, 202 screen_info.lfb_depth.into(), 203 buf_flag, 204 buf_vaddr, 205 None, 206 ) 207 .unwrap(); 208 } 209 210 let result = Self { 211 device_buffer: RwLock::new(device_buffer), 212 refresh_target: RwLock::new(None), 213 running: AtomicBool::new(false), 214 }; 215 216 __MAMAGER = Some(result); 217 218 let init_text = "Video driver initialized.\n\0"; 219 send_to_default_serial8250_port(init_text.as_bytes()); 220 return Ok(()); 221 } 222 } 223 224 //刷新任务执行器 225 #[derive(Debug)] 226 struct VideoRefreshExecutor; 227 228 impl VideoRefreshExecutor { 229 fn new() -> Box<VideoRefreshExecutor> { 230 return Box::new(VideoRefreshExecutor); 231 } 232 } 233 234 impl TimerFunction for VideoRefreshExecutor { 235 /** 236 * @brief 交给定时器执行的任务,此方法不应手动调用 237 * @return Ok(()) 238 */ 239 #[allow(clippy::type_complexity)] 240 fn run(&mut self) -> Result<(), SystemError> { 241 // 获得Manager 242 let manager = video_refresh_manager(); 243 244 let start_next_refresh = || { 245 //判断是否还需要刷新,若需要则继续分配下一次计时任务,否则不分配 246 if manager.running.load(Ordering::SeqCst) { 247 let timer = Timer::new(VideoRefreshExecutor::new(), REFRESH_INTERVAL); 248 //将新一次定时任务加入队列 249 timer.activate(); 250 } 251 }; 252 253 let mut refresh_target: Option<RwLockReadGuard<'_, Option<Arc<SpinLock<Box<[u8]>>>>>> = 254 None; 255 const TRY_TIMES: i32 = 2; 256 for i in 0..TRY_TIMES { 257 let g = manager.refresh_target.try_read(); 258 if g.is_none() { 259 if i == TRY_TIMES - 1 { 260 start_next_refresh(); 261 return Ok(()); 262 } 263 continue; 264 } 265 refresh_target = Some(g.unwrap()); 266 break; 267 } 268 269 let refresh_target = refresh_target.unwrap(); 270 271 if let ScmBuffer::DeviceBuffer(vaddr) = manager.device_buffer().buf { 272 let p: *mut u8 = vaddr.as_ptr(); 273 let mut target_guard = None; 274 for _ in 0..2 { 275 if let Ok(guard) = refresh_target.as_ref().unwrap().try_lock_irqsave() { 276 target_guard = Some(guard); 277 break; 278 } 279 } 280 if target_guard.is_none() { 281 start_next_refresh(); 282 return Ok(()); 283 } 284 let mut target_guard = target_guard.unwrap(); 285 unsafe { 286 p.copy_from_nonoverlapping( 287 target_guard.as_mut_ptr(), 288 manager.device_buffer().buf_size() as usize, 289 ) 290 } 291 } 292 293 start_next_refresh(); 294 295 return Ok(()); 296 } 297 } 298 299 #[no_mangle] 300 pub unsafe extern "C" fn rs_video_init() -> i32 { 301 return VideoRefreshManager::video_init() 302 .map(|_| 0) 303 .unwrap_or_else(|e| e.to_posix_errno()); 304 } 305