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