xref: /DragonOS/kernel/src/driver/video/mod.rs (revision 1496ba7b24a5e6954291ca9643b9f3cec567479a)
178bf93f0SYJwu2023 use core::{
2*1496ba7bSLoGin     ffi::{c_uint, c_void},
3*1496ba7bSLoGin     mem::MaybeUninit,
478bf93f0SYJwu2023     sync::atomic::{AtomicBool, Ordering},
578bf93f0SYJwu2023 };
6bacd691cSlogin 
7*1496ba7bSLoGin use alloc::{boxed::Box, sync::Arc};
8bacd691cSlogin 
9bacd691cSlogin use crate::{
10*1496ba7bSLoGin     arch::MMArch,
11*1496ba7bSLoGin     driver::uart::uart_device::c_uart_send_str,
12*1496ba7bSLoGin     driver::uart::uart_device::UartPort::COM1,
13*1496ba7bSLoGin     include::bindings::bindings::{
14*1496ba7bSLoGin         multiboot2_get_Framebuffer_info, multiboot2_iter, multiboot_tag_framebuffer_info_t,
15*1496ba7bSLoGin         FRAME_BUFFER_MAPPING_OFFSET, SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE,
16*1496ba7bSLoGin     },
17*1496ba7bSLoGin     kinfo,
18*1496ba7bSLoGin     libs::{
19*1496ba7bSLoGin         align::page_align_up,
20*1496ba7bSLoGin         lib_ui::screen_manager::{ScmBuffer, ScmBufferFlag, ScmBufferInfo},
21*1496ba7bSLoGin         rwlock::{RwLock, RwLockReadGuard},
22*1496ba7bSLoGin         spinlock::SpinLock,
23*1496ba7bSLoGin     },
24*1496ba7bSLoGin     mm::{
25*1496ba7bSLoGin         allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper,
26*1496ba7bSLoGin         no_init::pseudo_map_phys, page::PageFlags, MemoryManagementArch, PhysAddr, VirtAddr,
27*1496ba7bSLoGin     },
28*1496ba7bSLoGin     syscall::SystemError,
29*1496ba7bSLoGin     time::timer::{Timer, TimerFunction},
30bacd691cSlogin };
31bacd691cSlogin 
32*1496ba7bSLoGin static mut __MAMAGER: Option<VideoRefreshManager> = None;
33*1496ba7bSLoGin 
34*1496ba7bSLoGin pub fn video_refresh_manager() -> &'static VideoRefreshManager {
35*1496ba7bSLoGin     return unsafe {
36*1496ba7bSLoGin         &__MAMAGER
37*1496ba7bSLoGin             .as_ref()
38*1496ba7bSLoGin             .expect("Video refresh manager has not been initialized yet!")
39*1496ba7bSLoGin     };
40*1496ba7bSLoGin }
41*1496ba7bSLoGin 
42*1496ba7bSLoGin ///管理显示刷新变量的结构体
43*1496ba7bSLoGin pub struct VideoRefreshManager {
44*1496ba7bSLoGin     device_buffer: RwLock<ScmBufferInfo>,
45*1496ba7bSLoGin     fb_info: multiboot_tag_framebuffer_info_t,
46*1496ba7bSLoGin     refresh_target: RwLock<Option<Arc<SpinLock<Box<[u32]>>>>>,
4778bf93f0SYJwu2023     running: AtomicBool,
48bacd691cSlogin }
49bacd691cSlogin 
50*1496ba7bSLoGin const REFRESH_INTERVAL: u64 = 30;
51*1496ba7bSLoGin 
52*1496ba7bSLoGin impl VideoRefreshManager {
53*1496ba7bSLoGin     /**
54*1496ba7bSLoGin      * @brief 启动定时刷新
55*1496ba7bSLoGin      * @return 启动成功: true, 失败: false
56*1496ba7bSLoGin      */
57*1496ba7bSLoGin     pub fn run_video_refresh(&self) -> bool {
58*1496ba7bSLoGin         //设置Manager运行标志
59*1496ba7bSLoGin         let res = self.set_run();
60*1496ba7bSLoGin 
61*1496ba7bSLoGin         //设置成功则开始任务,否则直接返回false
62*1496ba7bSLoGin         if res {
63*1496ba7bSLoGin             //第一次将expire_jiffies设置小一点,使得这次刷新尽快开始,后续的刷新将按照REFRESH_INTERVAL间隔进行
64*1496ba7bSLoGin             let timer = Timer::new(VideoRefreshExecutor::new(), 1);
65*1496ba7bSLoGin             //将新一次定时任务加入队列
66*1496ba7bSLoGin             timer.activate();
67*1496ba7bSLoGin         }
68*1496ba7bSLoGin         return res;
69bacd691cSlogin     }
70bacd691cSlogin 
71*1496ba7bSLoGin     /// 停止定时刷新
72*1496ba7bSLoGin     #[allow(dead_code)]
73*1496ba7bSLoGin     pub fn stop_video_refresh(&self) {
74*1496ba7bSLoGin         self.running.store(false, Ordering::SeqCst);
75bacd691cSlogin     }
76bacd691cSlogin 
77bacd691cSlogin     fn set_run(&self) -> bool {
78*1496ba7bSLoGin         let res = self
79bacd691cSlogin             .running
80*1496ba7bSLoGin             .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst);
81*1496ba7bSLoGin         if res.is_ok() {
82bacd691cSlogin             return true;
83bacd691cSlogin         } else {
84bacd691cSlogin             return false;
85bacd691cSlogin         }
86bacd691cSlogin     }
87bacd691cSlogin 
88*1496ba7bSLoGin     /**
89*1496ba7bSLoGin      * @brief VBE帧缓存区的地址重新映射
90*1496ba7bSLoGin      * 将帧缓存区映射到地址SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE处
91*1496ba7bSLoGin      */
92*1496ba7bSLoGin     fn init_frame_buffer(&self) {
93*1496ba7bSLoGin         kinfo!("Re-mapping VBE frame buffer...");
94*1496ba7bSLoGin         let buf_vaddr = VirtAddr::new(
95*1496ba7bSLoGin             SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE as usize + FRAME_BUFFER_MAPPING_OFFSET as usize,
96*1496ba7bSLoGin         );
97*1496ba7bSLoGin 
98*1496ba7bSLoGin         let mut frame_buffer_info_graud = self.device_buffer.write();
99*1496ba7bSLoGin         if let ScmBuffer::DeviceBuffer(vaddr) = &mut (frame_buffer_info_graud).buf {
100*1496ba7bSLoGin             *vaddr = buf_vaddr;
101*1496ba7bSLoGin         }
102*1496ba7bSLoGin 
103*1496ba7bSLoGin         // 地址映射
104*1496ba7bSLoGin         let mut paddr = PhysAddr::new(self.fb_info.framebuffer_addr as usize);
105*1496ba7bSLoGin         let count = PageFrameCount::new(
106*1496ba7bSLoGin             page_align_up(frame_buffer_info_graud.buf_size()) / MMArch::PAGE_SIZE,
107*1496ba7bSLoGin         );
108*1496ba7bSLoGin         let page_flags: PageFlags<MMArch> = PageFlags::new().set_execute(true).set_write(true);
109*1496ba7bSLoGin 
110*1496ba7bSLoGin         let mut kernel_mapper = KernelMapper::lock();
111*1496ba7bSLoGin         let mut kernel_mapper = kernel_mapper.as_mut();
112*1496ba7bSLoGin         assert!(kernel_mapper.is_some());
113*1496ba7bSLoGin         let mut vaddr = buf_vaddr;
114*1496ba7bSLoGin         unsafe {
115*1496ba7bSLoGin             for _ in 0..count.data() {
116*1496ba7bSLoGin                 let flusher = kernel_mapper
117*1496ba7bSLoGin                     .as_mut()
118*1496ba7bSLoGin                     .unwrap()
119*1496ba7bSLoGin                     .map_phys(vaddr, paddr, page_flags)
120*1496ba7bSLoGin                     .unwrap();
121*1496ba7bSLoGin 
122*1496ba7bSLoGin                 flusher.flush();
123*1496ba7bSLoGin                 vaddr += MMArch::PAGE_SIZE;
124*1496ba7bSLoGin                 paddr += MMArch::PAGE_SIZE;
125bacd691cSlogin             }
126bacd691cSlogin         }
127bacd691cSlogin 
128*1496ba7bSLoGin         kinfo!("VBE frame buffer successfully Re-mapped!");
129bacd691cSlogin     }
130*1496ba7bSLoGin 
131*1496ba7bSLoGin     /**
132*1496ba7bSLoGin      * @brief 初始化显示模块,需先低级初始化才能高级初始化
133*1496ba7bSLoGin      * @param level 初始化等级
134*1496ba7bSLoGin      * false -> 低级初始化:不使用double buffer
135*1496ba7bSLoGin      * true ->高级初始化:增加double buffer的支持
136*1496ba7bSLoGin      * @return int
137*1496ba7bSLoGin      */
138*1496ba7bSLoGin     pub fn video_reinitialize(&self, level: bool) -> Result<(), SystemError> {
139*1496ba7bSLoGin         if !level {
140*1496ba7bSLoGin             self.init_frame_buffer();
141*1496ba7bSLoGin         } else {
142*1496ba7bSLoGin             // 开启屏幕计时刷新
143*1496ba7bSLoGin             assert!(self.run_video_refresh());
144*1496ba7bSLoGin         }
145*1496ba7bSLoGin         return Ok(());
146*1496ba7bSLoGin     }
147*1496ba7bSLoGin 
148*1496ba7bSLoGin     /**
149*1496ba7bSLoGin      * @brief 设置帧缓冲区刷新目标
150*1496ba7bSLoGin      *
151*1496ba7bSLoGin      * @param buf
152*1496ba7bSLoGin      * @return int
153*1496ba7bSLoGin      */
154*1496ba7bSLoGin     pub fn set_refresh_target(&self, buf_info: &ScmBufferInfo) -> Result<(), SystemError> {
155*1496ba7bSLoGin         let mut refresh_target = self.refresh_target.write_irqsave();
156*1496ba7bSLoGin         if let ScmBuffer::DoubleBuffer(double_buffer) = &buf_info.buf {
157*1496ba7bSLoGin             *refresh_target = Some(double_buffer.clone());
158*1496ba7bSLoGin             return Ok(());
159*1496ba7bSLoGin         }
160*1496ba7bSLoGin         return Err(SystemError::EINVAL);
161*1496ba7bSLoGin     }
162*1496ba7bSLoGin 
163*1496ba7bSLoGin     #[allow(dead_code)]
164*1496ba7bSLoGin     pub fn refresh_target(&self) -> RwLockReadGuard<'_, Option<Arc<SpinLock<Box<[u32]>>>>> {
165*1496ba7bSLoGin         let x = self.refresh_target.read();
166*1496ba7bSLoGin 
167*1496ba7bSLoGin         return x;
168*1496ba7bSLoGin     }
169*1496ba7bSLoGin 
170*1496ba7bSLoGin     pub fn device_buffer(&self) -> RwLockReadGuard<'_, ScmBufferInfo> {
171*1496ba7bSLoGin         return self.device_buffer.read();
172*1496ba7bSLoGin     }
173*1496ba7bSLoGin 
174*1496ba7bSLoGin     /**
175*1496ba7bSLoGin      * @brief 初始化显示驱动
176*1496ba7bSLoGin      *
177*1496ba7bSLoGin      * @return int
178*1496ba7bSLoGin      */
179*1496ba7bSLoGin     pub unsafe fn video_init() -> Result<(), SystemError> {
180*1496ba7bSLoGin         static INIT: AtomicBool = AtomicBool::new(false);
181*1496ba7bSLoGin 
182*1496ba7bSLoGin         if INIT
183*1496ba7bSLoGin             .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
184*1496ba7bSLoGin             .is_err()
185*1496ba7bSLoGin         {
186*1496ba7bSLoGin             panic!("Try to init video twice!");
187*1496ba7bSLoGin         }
188*1496ba7bSLoGin 
189*1496ba7bSLoGin         let mut _reserved: u32 = 0;
190*1496ba7bSLoGin 
191*1496ba7bSLoGin         let mut fb_info: MaybeUninit<multiboot_tag_framebuffer_info_t> = MaybeUninit::uninit();
192*1496ba7bSLoGin         //从multiboot2中读取帧缓冲区信息至fb_info
193*1496ba7bSLoGin         multiboot2_iter(
194*1496ba7bSLoGin             Some(multiboot2_get_Framebuffer_info),
195*1496ba7bSLoGin             fb_info.as_mut_ptr() as usize as *mut c_void,
196*1496ba7bSLoGin             &mut _reserved as *mut c_uint,
197*1496ba7bSLoGin         );
198*1496ba7bSLoGin         fb_info.assume_init();
199*1496ba7bSLoGin         let fb_info: multiboot_tag_framebuffer_info_t = core::mem::transmute(fb_info);
200*1496ba7bSLoGin 
201*1496ba7bSLoGin         let width = fb_info.framebuffer_width;
202*1496ba7bSLoGin         let height = fb_info.framebuffer_height;
203*1496ba7bSLoGin 
204*1496ba7bSLoGin         //初始化帧缓冲区信息结构体
205*1496ba7bSLoGin         let (bit_depth, flags) = if fb_info.framebuffer_type == 2 {
206*1496ba7bSLoGin             //当type=2时,width与height用字符数表示,故depth=8
207*1496ba7bSLoGin 
208*1496ba7bSLoGin             (8u32, ScmBufferFlag::SCM_BF_TEXT | ScmBufferFlag::SCM_BF_FB)
209*1496ba7bSLoGin         } else {
210*1496ba7bSLoGin             //否则为图像模式,depth应参照帧缓冲区信息里面的每个像素的位数
211*1496ba7bSLoGin             (
212*1496ba7bSLoGin                 fb_info.framebuffer_bpp as u32,
213*1496ba7bSLoGin                 ScmBufferFlag::SCM_BF_PIXEL | ScmBufferFlag::SCM_BF_FB,
214*1496ba7bSLoGin             )
215*1496ba7bSLoGin         };
216*1496ba7bSLoGin 
217*1496ba7bSLoGin         let buf_vaddr = VirtAddr::new(0xffff800003200000);
218*1496ba7bSLoGin         let device_buffer = ScmBufferInfo::new_device_buffer(
219*1496ba7bSLoGin             width,
220*1496ba7bSLoGin             height,
221*1496ba7bSLoGin             width * height * ((bit_depth + 7) / 8),
222*1496ba7bSLoGin             bit_depth,
223*1496ba7bSLoGin             flags,
224*1496ba7bSLoGin             buf_vaddr,
225*1496ba7bSLoGin         )
226*1496ba7bSLoGin         .unwrap();
227*1496ba7bSLoGin 
228*1496ba7bSLoGin         let init_text = "Video driver to map.\n\0";
229*1496ba7bSLoGin         c_uart_send_str(COM1 as u16, init_text.as_ptr());
230*1496ba7bSLoGin 
231*1496ba7bSLoGin         //地址映射
232*1496ba7bSLoGin         let paddr = PhysAddr::new(fb_info.framebuffer_addr as usize);
233*1496ba7bSLoGin         let count = PageFrameCount::new(
234*1496ba7bSLoGin             page_align_up(device_buffer.buf_size() as usize) / MMArch::PAGE_SIZE,
235*1496ba7bSLoGin         );
236*1496ba7bSLoGin         pseudo_map_phys(buf_vaddr, paddr, count);
237*1496ba7bSLoGin 
238*1496ba7bSLoGin         let result = Self {
239*1496ba7bSLoGin             fb_info,
240*1496ba7bSLoGin             device_buffer: RwLock::new(device_buffer),
241*1496ba7bSLoGin             refresh_target: RwLock::new(None),
242*1496ba7bSLoGin             running: AtomicBool::new(false),
243*1496ba7bSLoGin         };
244*1496ba7bSLoGin 
245*1496ba7bSLoGin         __MAMAGER = Some(result);
246*1496ba7bSLoGin 
247*1496ba7bSLoGin         let init_text = "Video driver initialized.\n\0";
248*1496ba7bSLoGin         c_uart_send_str(COM1 as u16, init_text.as_ptr());
249*1496ba7bSLoGin         return Ok(());
250*1496ba7bSLoGin     }
251*1496ba7bSLoGin }
252*1496ba7bSLoGin 
253*1496ba7bSLoGin //刷新任务执行器
254*1496ba7bSLoGin #[derive(Debug)]
255*1496ba7bSLoGin struct VideoRefreshExecutor;
256*1496ba7bSLoGin 
257*1496ba7bSLoGin impl VideoRefreshExecutor {
258*1496ba7bSLoGin     fn new() -> Box<VideoRefreshExecutor> {
259*1496ba7bSLoGin         return Box::new(VideoRefreshExecutor);
260*1496ba7bSLoGin     }
261*1496ba7bSLoGin }
262*1496ba7bSLoGin 
263*1496ba7bSLoGin impl TimerFunction for VideoRefreshExecutor {
264*1496ba7bSLoGin     /**
265*1496ba7bSLoGin      * @brief 交给定时器执行的任务,此方法不应手动调用
266*1496ba7bSLoGin      * @return Ok(())
267*1496ba7bSLoGin      */
268*1496ba7bSLoGin     fn run(&mut self) -> Result<(), SystemError> {
269*1496ba7bSLoGin         // 获得Manager
270*1496ba7bSLoGin         let manager = video_refresh_manager();
271*1496ba7bSLoGin 
272*1496ba7bSLoGin         let start_next_refresh = || {
273*1496ba7bSLoGin             //判断是否还需要刷新,若需要则继续分配下一次计时任务,否则不分配
274*1496ba7bSLoGin             if manager.running.load(Ordering::SeqCst) {
275*1496ba7bSLoGin                 let timer = Timer::new(VideoRefreshExecutor::new(), REFRESH_INTERVAL);
276*1496ba7bSLoGin                 //将新一次定时任务加入队列
277*1496ba7bSLoGin                 timer.activate();
278*1496ba7bSLoGin             }
279*1496ba7bSLoGin         };
280*1496ba7bSLoGin 
281*1496ba7bSLoGin         let mut refresh_target: Option<RwLockReadGuard<'_, Option<Arc<SpinLock<Box<[u32]>>>>>> =
282*1496ba7bSLoGin             None;
283*1496ba7bSLoGin         const TRY_TIMES: i32 = 2;
284*1496ba7bSLoGin         for i in 0..TRY_TIMES {
285*1496ba7bSLoGin             let g = manager.refresh_target.try_read();
286*1496ba7bSLoGin             if g.is_none() {
287*1496ba7bSLoGin                 if i == TRY_TIMES - 1 {
288*1496ba7bSLoGin                     start_next_refresh();
289*1496ba7bSLoGin                     return Ok(());
290*1496ba7bSLoGin                 }
291*1496ba7bSLoGin                 continue;
292*1496ba7bSLoGin             }
293*1496ba7bSLoGin             refresh_target = Some(g.unwrap());
294*1496ba7bSLoGin             break;
295*1496ba7bSLoGin         }
296*1496ba7bSLoGin 
297*1496ba7bSLoGin         let refresh_target = refresh_target.unwrap();
298*1496ba7bSLoGin 
299*1496ba7bSLoGin         if let ScmBuffer::DeviceBuffer(vaddr) = manager.device_buffer().buf {
300*1496ba7bSLoGin             let p = vaddr.as_ptr() as *mut u8;
301*1496ba7bSLoGin             let mut target_guard = None;
302*1496ba7bSLoGin             for _ in 0..2 {
303*1496ba7bSLoGin                 if let Ok(guard) = refresh_target.as_ref().unwrap().try_lock_irqsave() {
304*1496ba7bSLoGin                     target_guard = Some(guard);
305*1496ba7bSLoGin                     break;
306*1496ba7bSLoGin                 }
307*1496ba7bSLoGin             }
308*1496ba7bSLoGin             if target_guard.is_none() {
309*1496ba7bSLoGin                 start_next_refresh();
310*1496ba7bSLoGin                 return Ok(());
311*1496ba7bSLoGin             }
312*1496ba7bSLoGin             let mut target_guard = target_guard.unwrap();
313*1496ba7bSLoGin             unsafe {
314*1496ba7bSLoGin                 p.copy_from_nonoverlapping(
315*1496ba7bSLoGin                     target_guard.as_mut_ptr() as *mut u8,
316*1496ba7bSLoGin                     manager.device_buffer().buf_size() as usize,
317*1496ba7bSLoGin                 )
318*1496ba7bSLoGin             }
319*1496ba7bSLoGin         }
320*1496ba7bSLoGin 
321*1496ba7bSLoGin         start_next_refresh();
322*1496ba7bSLoGin 
323*1496ba7bSLoGin         return Ok(());
324*1496ba7bSLoGin     }
325*1496ba7bSLoGin }
326*1496ba7bSLoGin 
327bacd691cSlogin #[no_mangle]
328*1496ba7bSLoGin pub unsafe extern "C" fn rs_video_init() -> i32 {
329*1496ba7bSLoGin     return VideoRefreshManager::video_init()
330*1496ba7bSLoGin         .map(|_| 0)
331*1496ba7bSLoGin         .unwrap_or_else(|e| e.to_posix_errno());
332bacd691cSlogin }
333