xref: /DragonOS/kernel/src/driver/video/mod.rs (revision 40314b30ab2a7e1fd06a05a00f693e644e446035)
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