mod.rs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. use core::sync::atomic::{AtomicBool, Ordering};
  2. use crate::{
  3. arch::MMArch,
  4. init::boot_params,
  5. libs::{
  6. align::page_align_up,
  7. lib_ui::screen_manager::{ScmBuffer, ScmBufferFlag, ScmBufferInfo},
  8. rwlock::{RwLock, RwLockReadGuard},
  9. spinlock::SpinLock,
  10. },
  11. mm::{
  12. allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, page::EntryFlags,
  13. MemoryManagementArch,
  14. },
  15. time::timer::{Timer, TimerFunction},
  16. };
  17. use alloc::{boxed::Box, sync::Arc};
  18. use log::info;
  19. use system_error::SystemError;
  20. pub mod console;
  21. pub mod fbdev;
  22. static mut __MAMAGER: Option<VideoRefreshManager> = None;
  23. pub fn video_refresh_manager() -> &'static VideoRefreshManager {
  24. return unsafe {
  25. __MAMAGER
  26. .as_ref()
  27. .expect("Video refresh manager has not been initialized yet!")
  28. };
  29. }
  30. #[allow(clippy::type_complexity)]
  31. ///管理显示刷新变量的结构体
  32. pub struct VideoRefreshManager {
  33. device_buffer: RwLock<ScmBufferInfo>,
  34. refresh_target: RwLock<Option<Arc<SpinLock<Box<[u8]>>>>>,
  35. running: AtomicBool,
  36. }
  37. const REFRESH_INTERVAL: u64 = 30;
  38. impl VideoRefreshManager {
  39. /**
  40. * @brief 启动定时刷新
  41. * @return 启动成功: true, 失败: false
  42. */
  43. pub fn run_video_refresh(&self) -> bool {
  44. //设置Manager运行标志
  45. let res = self.set_run();
  46. //设置成功则开始任务,否则直接返回false
  47. if res {
  48. //第一次将expire_jiffies设置小一点,使得这次刷新尽快开始,后续的刷新将按照REFRESH_INTERVAL间隔进行
  49. let timer = Timer::new(VideoRefreshExecutor::new(), 1);
  50. //将新一次定时任务加入队列
  51. timer.activate();
  52. }
  53. return res;
  54. }
  55. /// 停止定时刷新
  56. #[allow(dead_code)]
  57. pub fn stop_video_refresh(&self) {
  58. self.running.store(false, Ordering::SeqCst);
  59. }
  60. fn set_run(&self) -> bool {
  61. let res = self
  62. .running
  63. .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst);
  64. return res.is_ok();
  65. }
  66. /**
  67. * @brief VBE帧缓存区的地址重新映射
  68. * 将帧缓存区映射到地址SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE处
  69. */
  70. fn init_frame_buffer(&self) {
  71. info!("Re-mapping VBE frame buffer...");
  72. let buf_vaddr = boot_params()
  73. .read_irqsave()
  74. .screen_info
  75. .lfb_virt_base
  76. .unwrap();
  77. let mut frame_buffer_info_guard = self.device_buffer.write();
  78. if let ScmBuffer::DeviceBuffer(vaddr) = &mut (frame_buffer_info_guard).buf {
  79. *vaddr = buf_vaddr;
  80. }
  81. // 地址映射
  82. let mut paddr = boot_params().read().screen_info.lfb_base;
  83. let count = PageFrameCount::new(
  84. page_align_up(frame_buffer_info_guard.buf_size()) / MMArch::PAGE_SIZE,
  85. );
  86. let page_flags: EntryFlags<MMArch> = EntryFlags::new().set_execute(true).set_write(true);
  87. let mut kernel_mapper = KernelMapper::lock();
  88. let mut kernel_mapper = kernel_mapper.as_mut();
  89. assert!(kernel_mapper.is_some());
  90. let mut vaddr = buf_vaddr;
  91. unsafe {
  92. for _ in 0..count.data() {
  93. let flusher = kernel_mapper
  94. .as_mut()
  95. .unwrap()
  96. .map_phys(vaddr, paddr, page_flags)
  97. .unwrap();
  98. flusher.flush();
  99. vaddr += MMArch::PAGE_SIZE;
  100. paddr += MMArch::PAGE_SIZE;
  101. }
  102. }
  103. info!("VBE frame buffer successfully Re-mapped!");
  104. }
  105. /**
  106. * @brief 初始化显示模块,需先低级初始化才能高级初始化
  107. * @param level 初始化等级
  108. * false -> 低级初始化:不使用double buffer
  109. * true ->高级初始化:增加double buffer的支持
  110. * @return int
  111. */
  112. pub fn video_reinitialize(&self, level: bool) -> Result<(), SystemError> {
  113. if !level {
  114. self.init_frame_buffer();
  115. } else {
  116. // 开启屏幕计时刷新
  117. assert!(self.run_video_refresh());
  118. }
  119. return Ok(());
  120. }
  121. /**
  122. * @brief 设置帧缓冲区刷新目标
  123. *
  124. * @param buf
  125. * @return int
  126. */
  127. pub fn set_refresh_target(&self, buf_info: &ScmBufferInfo) -> Result<(), SystemError> {
  128. let mut refresh_target = self.refresh_target.write_irqsave();
  129. if let ScmBuffer::DoubleBuffer(double_buffer) = &buf_info.buf {
  130. *refresh_target = Some(double_buffer.clone());
  131. return Ok(());
  132. }
  133. return Err(SystemError::EINVAL);
  134. }
  135. #[allow(clippy::type_complexity)]
  136. #[allow(dead_code)]
  137. pub fn refresh_target(&self) -> RwLockReadGuard<'_, Option<Arc<SpinLock<Box<[u8]>>>>> {
  138. let x = self.refresh_target.read();
  139. return x;
  140. }
  141. pub fn device_buffer(&self) -> RwLockReadGuard<'_, ScmBufferInfo> {
  142. return self.device_buffer.read();
  143. }
  144. /// 在riscv64平台下暂时不支持
  145. #[cfg(target_arch = "riscv64")]
  146. pub unsafe fn video_init() -> Result<(), SystemError> {
  147. return Err(SystemError::ENOSYS);
  148. }
  149. /// 此函数用于初始化显示驱动,为后续的图形输出做好准备。
  150. #[cfg(target_arch = "x86_64")]
  151. pub unsafe fn video_init() -> Result<(), SystemError> {
  152. use crate::{
  153. arch::driver::video::arch_video_early_init,
  154. driver::{
  155. serial::serial8250::send_to_default_serial8250_port,
  156. video::fbdev::base::BootTimeVideoType,
  157. },
  158. };
  159. arch_video_early_init()?;
  160. let boot_params_guard = boot_params().read();
  161. let screen_info = &boot_params_guard.screen_info;
  162. let buf_vaddr = screen_info.lfb_virt_base.unwrap();
  163. let buf_flag: ScmBufferFlag;
  164. let device_buffer: ScmBufferInfo;
  165. if screen_info.video_type == BootTimeVideoType::Mda {
  166. buf_flag = ScmBufferFlag::SCM_BF_TEXT | ScmBufferFlag::SCM_BF_FB;
  167. device_buffer = ScmBufferInfo::new_device_buffer(
  168. screen_info.origin_video_cols.into(),
  169. screen_info.origin_video_lines.into(),
  170. screen_info.lfb_size as u32,
  171. screen_info.lfb_depth.into(),
  172. buf_flag,
  173. buf_vaddr,
  174. )
  175. .unwrap();
  176. } else {
  177. // 图形模式
  178. buf_flag = ScmBufferFlag::SCM_BF_PIXEL | ScmBufferFlag::SCM_BF_FB;
  179. device_buffer = ScmBufferInfo::new_device_buffer(
  180. screen_info.lfb_width,
  181. screen_info.lfb_height,
  182. screen_info.lfb_size as u32,
  183. screen_info.lfb_depth.into(),
  184. buf_flag,
  185. buf_vaddr,
  186. )
  187. .unwrap();
  188. }
  189. let result = Self {
  190. device_buffer: RwLock::new(device_buffer),
  191. refresh_target: RwLock::new(None),
  192. running: AtomicBool::new(false),
  193. };
  194. __MAMAGER = Some(result);
  195. let init_text = "Video driver initialized.\n\0";
  196. send_to_default_serial8250_port(init_text.as_bytes());
  197. return Ok(());
  198. }
  199. }
  200. //刷新任务执行器
  201. #[derive(Debug)]
  202. struct VideoRefreshExecutor;
  203. impl VideoRefreshExecutor {
  204. fn new() -> Box<VideoRefreshExecutor> {
  205. return Box::new(VideoRefreshExecutor);
  206. }
  207. }
  208. impl TimerFunction for VideoRefreshExecutor {
  209. /**
  210. * @brief 交给定时器执行的任务,此方法不应手动调用
  211. * @return Ok(())
  212. */
  213. #[allow(clippy::type_complexity)]
  214. fn run(&mut self) -> Result<(), SystemError> {
  215. // 获得Manager
  216. let manager = video_refresh_manager();
  217. let start_next_refresh = || {
  218. //判断是否还需要刷新,若需要则继续分配下一次计时任务,否则不分配
  219. if manager.running.load(Ordering::SeqCst) {
  220. let timer = Timer::new(VideoRefreshExecutor::new(), REFRESH_INTERVAL);
  221. //将新一次定时任务加入队列
  222. timer.activate();
  223. }
  224. };
  225. let mut refresh_target: Option<RwLockReadGuard<'_, Option<Arc<SpinLock<Box<[u8]>>>>>> =
  226. None;
  227. const TRY_TIMES: i32 = 2;
  228. for i in 0..TRY_TIMES {
  229. let g = manager.refresh_target.try_read();
  230. if g.is_none() {
  231. if i == TRY_TIMES - 1 {
  232. start_next_refresh();
  233. return Ok(());
  234. }
  235. continue;
  236. }
  237. refresh_target = Some(g.unwrap());
  238. break;
  239. }
  240. let refresh_target = refresh_target.unwrap();
  241. if let ScmBuffer::DeviceBuffer(vaddr) = manager.device_buffer().buf {
  242. let p: *mut u8 = vaddr.as_ptr();
  243. let mut target_guard = None;
  244. for _ in 0..2 {
  245. if let Ok(guard) = refresh_target.as_ref().unwrap().try_lock_irqsave() {
  246. target_guard = Some(guard);
  247. break;
  248. }
  249. }
  250. if target_guard.is_none() {
  251. start_next_refresh();
  252. return Ok(());
  253. }
  254. let mut target_guard = target_guard.unwrap();
  255. unsafe {
  256. p.copy_from_nonoverlapping(
  257. target_guard.as_mut_ptr(),
  258. manager.device_buffer().buf_size() as usize,
  259. )
  260. }
  261. }
  262. start_next_refresh();
  263. return Ok(());
  264. }
  265. }
  266. #[no_mangle]
  267. pub unsafe extern "C" fn rs_video_init() -> i32 {
  268. return VideoRefreshManager::video_init()
  269. .map(|_| 0)
  270. .unwrap_or_else(|e| e.to_posix_errno());
  271. }