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