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