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