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