xref: /DragonOS/kernel/src/driver/video/fbdev/base/fbmem.rs (revision e7071df6a47c100381a8bc2000022e82d422361a)
1 use core::intrinsics::unlikely;
2 
3 use alloc::{
4     string::{String, ToString},
5     sync::{Arc, Weak},
6 };
7 
8 use system_error::SystemError;
9 use unified_init::macros::unified_init;
10 
11 use crate::{
12     driver::base::{
13         class::{class_manager, Class},
14         device::{
15             bus::Bus,
16             device_manager,
17             device_number::{DeviceNumber, Major},
18             driver::Driver,
19             sys_dev_char_kset, Device, DeviceType, IdTable,
20         },
21         kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
22         kset::KSet,
23         subsys::SubSysPrivate,
24     },
25     filesystem::{kernfs::KernFSInode, sysfs::AttributeGroup},
26     init::initcall::INITCALL_SUBSYS,
27     libs::{
28         rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
29         spinlock::SpinLock,
30     },
31 };
32 
33 use super::{fbcon::fb_console_init, fbsysfs::FbDeviceAttrGroup, FbId, FrameBuffer};
34 
35 /// `/sys/class/graphics` 的 class 实例
36 static mut CLASS_GRAPHICS_INSTANCE: Option<Arc<GraphicsClass>> = None;
37 
38 lazy_static! {
39     /// 帧缓冲区管理器
40     static ref FRAME_BUFFER_MANAGER: FrameBufferManager = FrameBufferManager::new();
41 }
42 
43 /// 获取 `/sys/class/graphics` 的 class 实例
44 #[inline(always)]
45 #[allow(dead_code)]
46 pub fn sys_class_graphics_instance() -> Option<&'static Arc<GraphicsClass>> {
47     unsafe { CLASS_GRAPHICS_INSTANCE.as_ref() }
48 }
49 
50 #[inline(always)]
51 pub fn frame_buffer_manager() -> &'static FrameBufferManager {
52     &FRAME_BUFFER_MANAGER
53 }
54 
55 /// 初始化帧缓冲区子系统
56 #[unified_init(INITCALL_SUBSYS)]
57 pub fn fbmem_init() -> Result<(), SystemError> {
58     let graphics_class = GraphicsClass::new();
59     class_manager().class_register(&(graphics_class.clone() as Arc<dyn Class>))?;
60 
61     unsafe {
62         CLASS_GRAPHICS_INSTANCE = Some(graphics_class);
63     }
64 
65     fb_console_init()?;
66     return Ok(());
67 }
68 
69 /// `/sys/class/graphics` 类
70 #[derive(Debug)]
71 pub struct GraphicsClass {
72     subsystem: SubSysPrivate,
73 }
74 
75 impl GraphicsClass {
76     const NAME: &'static str = "graphics";
77     pub fn new() -> Arc<Self> {
78         let r = Self {
79             subsystem: SubSysPrivate::new(Self::NAME.to_string(), None, None, &[]),
80         };
81         let r = Arc::new(r);
82         r.subsystem()
83             .set_class(Some(Arc::downgrade(&r) as Weak<dyn Class>));
84 
85         return r;
86     }
87 }
88 
89 impl Class for GraphicsClass {
90     fn name(&self) -> &'static str {
91         return Self::NAME;
92     }
93 
94     fn dev_kobj(&self) -> Option<Arc<dyn KObject>> {
95         Some(sys_dev_char_kset() as Arc<dyn KObject>)
96     }
97 
98     fn set_dev_kobj(&self, _kobj: Arc<dyn KObject>) {
99         unimplemented!("GraphicsClass::set_dev_kobj");
100     }
101 
102     fn subsystem(&self) -> &SubSysPrivate {
103         return &self.subsystem;
104     }
105 }
106 
107 /// 帧缓冲区管理器
108 #[derive(Debug)]
109 pub struct FrameBufferManager {
110     inner: RwLock<InnerFrameBufferManager>,
111 }
112 
113 #[derive(Debug)]
114 struct InnerFrameBufferManager {
115     /// 已经注册的帧缓冲区
116     registered_fbs: [Option<Arc<dyn FrameBuffer>>; FrameBufferManager::FB_MAX],
117 }
118 
119 impl FrameBufferManager {
120     pub const FB_MAX: usize = 32;
121     pub fn new() -> Self {
122         Self {
123             inner: RwLock::new(InnerFrameBufferManager {
124                 registered_fbs: Default::default(),
125             }),
126         }
127     }
128 
129     /// 注册一个帧缓冲区
130     ///
131     /// # 参数
132     ///
133     /// - fb: 帧缓冲区
134     pub fn register_fb(&self, fb: Arc<dyn FrameBuffer>) -> Result<FbId, SystemError> {
135         let id = self.generate_fb_id().expect("no more fb id");
136         fb.set_fb_id(id);
137         let fb_device = FbDevice::new(Arc::downgrade(&fb) as Weak<dyn FrameBuffer>, id);
138         device_manager().device_default_initialize(&(fb_device.clone() as Arc<dyn Device>));
139         fb_device.set_parent(Some(Arc::downgrade(&(fb.clone() as Arc<dyn KObject>))));
140 
141         fb.set_fb_device(Some(fb_device.clone()));
142 
143         device_manager().add_device(fb_device.clone() as Arc<dyn Device>)?;
144 
145         // todo: 从Modedb中获取信息
146         // 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbmem.c#1584
147 
148         let mut inner = self.inner.write();
149         inner.registered_fbs[id.data() as usize] = Some(fb.clone() as Arc<dyn FrameBuffer>);
150 
151         // todo: 把fb跟fbcon关联起来
152         return Ok(id);
153     }
154 
155     /// 注销一个帧缓冲区
156     ///
157     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbmem.c#1726
158     #[allow(dead_code)]
159     pub fn unregister_fb(&self, _fb: Arc<dyn FrameBuffer>) -> Result<(), SystemError> {
160         todo!("unregister_fb")
161     }
162 
163     /// 根据id查找帧缓冲区
164     pub fn find_fb_by_id(&self, id: FbId) -> Result<Option<Arc<dyn FrameBuffer>>, SystemError> {
165         if unlikely(!id.is_valid()) {
166             return Err(SystemError::EINVAL);
167         }
168 
169         let inner = self.inner.read();
170         return Ok(inner.registered_fbs[id.data() as usize].clone());
171     }
172 
173     fn generate_fb_id(&self) -> Option<FbId> {
174         for i in 0..Self::FB_MAX {
175             if self.inner.read().registered_fbs[i].is_none() {
176                 return Some(FbId::new(i as u32));
177             }
178         }
179         return None;
180     }
181 }
182 
183 /// 抽象的帧缓冲区设备
184 ///
185 /// 对应于`/sys/class/graphics/fb(x)`目录下的设备, 其中`(x)`为帧缓冲区的id
186 ///
187 /// 该设备的父设备为真实的帧缓冲区设备
188 #[derive(Debug)]
189 #[cast_to([sync] Device)]
190 pub struct FbDevice {
191     inner: SpinLock<InnerFbDevice>,
192     kobj_state: LockedKObjectState,
193 }
194 
195 impl FbDevice {
196     pub const BASENAME: &'static str = "fb";
197     fn new(fb: Weak<dyn FrameBuffer>, id: FbId) -> Arc<Self> {
198         Arc::new(Self {
199             inner: SpinLock::new(InnerFbDevice {
200                 fb,
201                 kern_inode: None,
202                 parent: None,
203                 kset: None,
204                 ktype: None,
205                 fb_id: id,
206             }),
207             kobj_state: LockedKObjectState::new(None),
208         })
209     }
210 
211     pub fn framebuffer(&self) -> Option<Arc<dyn FrameBuffer>> {
212         self.inner.lock().fb.upgrade()
213     }
214 }
215 
216 #[derive(Debug)]
217 struct InnerFbDevice {
218     fb: Weak<dyn FrameBuffer>,
219     kern_inode: Option<Arc<KernFSInode>>,
220     parent: Option<Weak<dyn KObject>>,
221     kset: Option<Arc<KSet>>,
222     ktype: Option<&'static dyn KObjType>,
223     /// 帧缓冲区id
224     fb_id: FbId,
225 }
226 
227 impl KObject for FbDevice {
228     fn as_any_ref(&self) -> &dyn core::any::Any {
229         self
230     }
231 
232     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
233         self.inner.lock().kern_inode = inode;
234     }
235 
236     fn inode(&self) -> Option<Arc<KernFSInode>> {
237         self.inner.lock().kern_inode.clone()
238     }
239 
240     fn parent(&self) -> Option<Weak<dyn KObject>> {
241         self.inner.lock().parent.clone()
242     }
243 
244     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
245         self.inner.lock().parent = parent;
246     }
247 
248     fn kset(&self) -> Option<Arc<KSet>> {
249         self.inner.lock().kset.clone()
250     }
251 
252     fn set_kset(&self, kset: Option<Arc<KSet>>) {
253         self.inner.lock().kset = kset;
254     }
255 
256     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
257         self.inner.lock().ktype
258     }
259 
260     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
261         self.inner.lock().ktype = ktype;
262     }
263 
264     fn name(&self) -> String {
265         format!("{}{}", Self::BASENAME, self.inner.lock().fb_id.data())
266     }
267 
268     fn set_name(&self, _name: String) {
269         // do nothing
270     }
271 
272     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
273         self.kobj_state.read()
274     }
275 
276     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
277         self.kobj_state.write()
278     }
279 
280     fn set_kobj_state(&self, state: KObjectState) {
281         *self.kobj_state.write() = state;
282     }
283 }
284 
285 impl Device for FbDevice {
286     fn dev_type(&self) -> DeviceType {
287         DeviceType::Char
288     }
289 
290     fn id_table(&self) -> IdTable {
291         IdTable::new(
292             Self::BASENAME.to_string(),
293             Some(DeviceNumber::new(
294                 Major::FB_MAJOR,
295                 self.inner.lock().fb_id.data(),
296             )),
297         )
298     }
299 
300     fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
301         todo!()
302     }
303 
304     fn class(&self) -> Option<Arc<dyn Class>> {
305         sys_class_graphics_instance().map(|ins| ins.clone() as Arc<dyn Class>)
306     }
307     fn set_class(&self, _class: Option<Arc<dyn Class>>) {
308         // do nothing
309     }
310 
311     fn driver(&self) -> Option<Arc<dyn Driver>> {
312         None
313     }
314 
315     fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
316         // do nothing
317     }
318 
319     fn is_dead(&self) -> bool {
320         false
321     }
322 
323     fn can_match(&self) -> bool {
324         false
325     }
326 
327     fn set_can_match(&self, _can_match: bool) {
328         // do nothing
329     }
330 
331     fn state_synced(&self) -> bool {
332         true
333     }
334 
335     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
336         Some(&[&FbDeviceAttrGroup])
337     }
338 }
339