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