xref: /DragonOS/kernel/src/driver/video/mod.rs (revision 78bf93f02f84bf5e024ddfb559f040e68ce39ccf)
1*78bf93f0SYJwu2023 use core::{
2*78bf93f0SYJwu2023     ptr::null_mut,
3*78bf93f0SYJwu2023     sync::atomic::{AtomicBool, Ordering},
4*78bf93f0SYJwu2023 };
5bacd691cSlogin 
6bacd691cSlogin use alloc::sync::Arc;
7bacd691cSlogin 
8bacd691cSlogin use crate::{
9*78bf93f0SYJwu2023     exception::softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
10bacd691cSlogin     include::bindings::bindings::video_refresh_framebuffer,
11bacd691cSlogin };
12bacd691cSlogin 
13bacd691cSlogin #[derive(Debug)]
14bacd691cSlogin pub struct VideoRefreshFramebuffer {
15*78bf93f0SYJwu2023     running: AtomicBool,
16bacd691cSlogin }
17bacd691cSlogin 
18bacd691cSlogin impl SoftirqVec for VideoRefreshFramebuffer {
19bacd691cSlogin     fn run(&self) {
20bacd691cSlogin         if self.set_run() == false {
21bacd691cSlogin             return;
22bacd691cSlogin         }
23bacd691cSlogin 
24bacd691cSlogin         unsafe {
25bacd691cSlogin             video_refresh_framebuffer(null_mut());
26bacd691cSlogin         }
27bacd691cSlogin 
28bacd691cSlogin         self.clear_run();
29bacd691cSlogin     }
30bacd691cSlogin }
31bacd691cSlogin impl VideoRefreshFramebuffer {
32bacd691cSlogin     pub fn new() -> VideoRefreshFramebuffer {
33bacd691cSlogin         VideoRefreshFramebuffer {
34*78bf93f0SYJwu2023             running: AtomicBool::new(false),
35bacd691cSlogin         }
36bacd691cSlogin     }
37bacd691cSlogin 
38bacd691cSlogin     fn set_run(&self) -> bool {
39bacd691cSlogin         let x = self
40bacd691cSlogin             .running
41bacd691cSlogin             .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed);
42bacd691cSlogin         if x.is_ok() {
43bacd691cSlogin             return true;
44bacd691cSlogin         } else {
45bacd691cSlogin             return false;
46bacd691cSlogin         }
47bacd691cSlogin     }
48bacd691cSlogin 
49bacd691cSlogin     fn clear_run(&self) {
50bacd691cSlogin         self.running.store(false, Ordering::Release);
51bacd691cSlogin     }
52bacd691cSlogin }
53bacd691cSlogin 
54bacd691cSlogin pub fn register_softirq_video() {
55bacd691cSlogin     // kdebug!("register_softirq_video");
56bacd691cSlogin     let handler = Arc::new(VideoRefreshFramebuffer::new());
57bacd691cSlogin     softirq_vectors()
58bacd691cSlogin         .register_softirq(SoftirqNumber::VideoRefresh, handler)
59bacd691cSlogin         .expect("register_softirq_video run failed");
60bacd691cSlogin }
61bacd691cSlogin // ======= 以下为给C提供的接口,video重构完后请删除 =======
62bacd691cSlogin #[no_mangle]
63bacd691cSlogin pub extern "C" fn rs_register_softirq_video() {
64bacd691cSlogin     register_softirq_video();
65bacd691cSlogin }
66