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