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