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 /** 174 * @brief 初始化显示驱动 175 * 176 * @return int 177 */ 178 pub unsafe fn video_init() -> Result<(), SystemError> { 179 static INIT: AtomicBool = AtomicBool::new(false); 180 181 if INIT 182 .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) 183 .is_err() 184 { 185 panic!("Try to init video twice!"); 186 } 187 188 let mut _reserved: u32 = 0; 189 190 let mut fb_info: MaybeUninit<multiboot_tag_framebuffer_info_t> = MaybeUninit::uninit(); 191 //从multiboot2中读取帧缓冲区信息至fb_info 192 multiboot2_iter( 193 Some(multiboot2_get_Framebuffer_info), 194 fb_info.as_mut_ptr() as usize as *mut c_void, 195 &mut _reserved as *mut c_uint, 196 ); 197 fb_info.assume_init(); 198 let fb_info: multiboot_tag_framebuffer_info_t = core::mem::transmute(fb_info); 199 200 let width = fb_info.framebuffer_width; 201 let height = fb_info.framebuffer_height; 202 203 //初始化帧缓冲区信息结构体 204 let (bit_depth, flags) = if fb_info.framebuffer_type == 2 { 205 //当type=2时,width与height用字符数表示,故depth=8 206 207 (8u32, ScmBufferFlag::SCM_BF_TEXT | ScmBufferFlag::SCM_BF_FB) 208 } else { 209 //否则为图像模式,depth应参照帧缓冲区信息里面的每个像素的位数 210 ( 211 fb_info.framebuffer_bpp as u32, 212 ScmBufferFlag::SCM_BF_PIXEL | ScmBufferFlag::SCM_BF_FB, 213 ) 214 }; 215 216 let buf_vaddr = VirtAddr::new(0xffff800003200000); 217 let device_buffer = ScmBufferInfo::new_device_buffer( 218 width, 219 height, 220 width * height * ((bit_depth + 7) / 8), 221 bit_depth, 222 flags, 223 buf_vaddr, 224 ) 225 .unwrap(); 226 227 let init_text = "Video driver to map.\n\0"; 228 send_to_default_serial8250_port(init_text.as_bytes()); 229 230 //地址映射 231 let paddr = PhysAddr::new(fb_info.framebuffer_addr as usize); 232 let count = PageFrameCount::new( 233 page_align_up(device_buffer.buf_size() as usize) / MMArch::PAGE_SIZE, 234 ); 235 pseudo_map_phys(buf_vaddr, paddr, count); 236 237 let result = Self { 238 fb_info, 239 device_buffer: RwLock::new(device_buffer), 240 refresh_target: RwLock::new(None), 241 running: AtomicBool::new(false), 242 }; 243 244 __MAMAGER = Some(result); 245 246 let init_text = "Video driver initialized.\n\0"; 247 send_to_default_serial8250_port(init_text.as_bytes()); 248 return Ok(()); 249 } 250 } 251 252 //刷新任务执行器 253 #[derive(Debug)] 254 struct VideoRefreshExecutor; 255 256 impl VideoRefreshExecutor { 257 fn new() -> Box<VideoRefreshExecutor> { 258 return Box::new(VideoRefreshExecutor); 259 } 260 } 261 262 impl TimerFunction for VideoRefreshExecutor { 263 /** 264 * @brief 交给定时器执行的任务,此方法不应手动调用 265 * @return Ok(()) 266 */ 267 fn run(&mut self) -> Result<(), SystemError> { 268 // 获得Manager 269 let manager = video_refresh_manager(); 270 271 let start_next_refresh = || { 272 //判断是否还需要刷新,若需要则继续分配下一次计时任务,否则不分配 273 if manager.running.load(Ordering::SeqCst) { 274 let timer = Timer::new(VideoRefreshExecutor::new(), REFRESH_INTERVAL); 275 //将新一次定时任务加入队列 276 timer.activate(); 277 } 278 }; 279 280 let mut refresh_target: Option<RwLockReadGuard<'_, Option<Arc<SpinLock<Box<[u32]>>>>>> = 281 None; 282 const TRY_TIMES: i32 = 2; 283 for i in 0..TRY_TIMES { 284 let g = manager.refresh_target.try_read(); 285 if g.is_none() { 286 if i == TRY_TIMES - 1 { 287 start_next_refresh(); 288 return Ok(()); 289 } 290 continue; 291 } 292 refresh_target = Some(g.unwrap()); 293 break; 294 } 295 296 let refresh_target = refresh_target.unwrap(); 297 298 if let ScmBuffer::DeviceBuffer(vaddr) = manager.device_buffer().buf { 299 let p = vaddr.as_ptr() as *mut u8; 300 let mut target_guard = None; 301 for _ in 0..2 { 302 if let Ok(guard) = refresh_target.as_ref().unwrap().try_lock_irqsave() { 303 target_guard = Some(guard); 304 break; 305 } 306 } 307 if target_guard.is_none() { 308 start_next_refresh(); 309 return Ok(()); 310 } 311 let mut target_guard = target_guard.unwrap(); 312 unsafe { 313 p.copy_from_nonoverlapping( 314 target_guard.as_mut_ptr() as *mut u8, 315 manager.device_buffer().buf_size() as usize, 316 ) 317 } 318 } 319 320 start_next_refresh(); 321 322 return Ok(()); 323 } 324 } 325 326 #[no_mangle] 327 pub unsafe extern "C" fn rs_video_init() -> i32 { 328 return VideoRefreshManager::video_init() 329 .map(|_| 0) 330 .unwrap_or_else(|e| e.to_posix_errno()); 331 } 332