123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- use core::intrinsics::unlikely;
- use alloc::{
- string::{String, ToString},
- sync::{Arc, Weak},
- };
- use system_error::SystemError;
- use unified_init::macros::unified_init;
- use crate::{
- driver::base::{
- class::{class_manager, Class},
- device::{
- bus::Bus,
- device_manager,
- device_number::{DeviceNumber, Major},
- driver::Driver,
- sys_dev_char_kset, Device, DeviceType, IdTable,
- },
- kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
- kset::KSet,
- subsys::SubSysPrivate,
- },
- filesystem::{kernfs::KernFSInode, sysfs::AttributeGroup},
- init::initcall::INITCALL_SUBSYS,
- libs::{
- rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
- spinlock::SpinLock,
- },
- };
- use super::{fbcon::fb_console_init, fbsysfs::FbDeviceAttrGroup, FbId, FrameBuffer};
- /// `/sys/class/graphics` 的 class 实例
- static mut CLASS_GRAPHICS_INSTANCE: Option<Arc<GraphicsClass>> = None;
- lazy_static! {
- /// 帧缓冲区管理器
- static ref FRAME_BUFFER_MANAGER: FrameBufferManager = FrameBufferManager::new();
- }
- /// 获取 `/sys/class/graphics` 的 class 实例
- #[inline(always)]
- #[allow(dead_code)]
- pub fn sys_class_graphics_instance() -> Option<&'static Arc<GraphicsClass>> {
- unsafe { CLASS_GRAPHICS_INSTANCE.as_ref() }
- }
- #[inline(always)]
- pub fn frame_buffer_manager() -> &'static FrameBufferManager {
- &FRAME_BUFFER_MANAGER
- }
- /// 初始化帧缓冲区子系统
- #[unified_init(INITCALL_SUBSYS)]
- pub fn fbmem_init() -> Result<(), SystemError> {
- let graphics_class = GraphicsClass::new();
- class_manager().class_register(&(graphics_class.clone() as Arc<dyn Class>))?;
- unsafe {
- CLASS_GRAPHICS_INSTANCE = Some(graphics_class);
- }
- fb_console_init()?;
- return Ok(());
- }
- /// `/sys/class/graphics` 类
- #[derive(Debug)]
- pub struct GraphicsClass {
- subsystem: SubSysPrivate,
- }
- impl GraphicsClass {
- const NAME: &'static str = "graphics";
- pub fn new() -> Arc<Self> {
- let r = Self {
- subsystem: SubSysPrivate::new(Self::NAME.to_string(), None, None, &[]),
- };
- let r = Arc::new(r);
- r.subsystem()
- .set_class(Some(Arc::downgrade(&r) as Weak<dyn Class>));
- return r;
- }
- }
- impl Class for GraphicsClass {
- fn name(&self) -> &'static str {
- return Self::NAME;
- }
- fn dev_kobj(&self) -> Option<Arc<dyn KObject>> {
- Some(sys_dev_char_kset() as Arc<dyn KObject>)
- }
- fn set_dev_kobj(&self, _kobj: Arc<dyn KObject>) {
- unimplemented!("GraphicsClass::set_dev_kobj");
- }
- fn subsystem(&self) -> &SubSysPrivate {
- return &self.subsystem;
- }
- }
- /// 帧缓冲区管理器
- #[derive(Debug)]
- pub struct FrameBufferManager {
- inner: RwLock<InnerFrameBufferManager>,
- }
- #[derive(Debug)]
- struct InnerFrameBufferManager {
- /// 已经注册的帧缓冲区
- registered_fbs: [Option<Arc<dyn FrameBuffer>>; FrameBufferManager::FB_MAX],
- }
- impl FrameBufferManager {
- pub const FB_MAX: usize = 32;
- pub fn new() -> Self {
- Self {
- inner: RwLock::new(InnerFrameBufferManager {
- registered_fbs: Default::default(),
- }),
- }
- }
- /// 注册一个帧缓冲区
- ///
- /// # 参数
- ///
- /// - fb: 帧缓冲区
- pub fn register_fb(&self, fb: Arc<dyn FrameBuffer>) -> Result<FbId, SystemError> {
- let id = self.generate_fb_id().expect("no more fb id");
- fb.set_fb_id(id);
- let fb_device = FbDevice::new(Arc::downgrade(&fb) as Weak<dyn FrameBuffer>, id);
- device_manager().device_default_initialize(&(fb_device.clone() as Arc<dyn Device>));
- fb_device.set_parent(Some(Arc::downgrade(&(fb.clone() as Arc<dyn KObject>))));
- fb.set_fb_device(Some(fb_device.clone()));
- device_manager().add_device(fb_device.clone() as Arc<dyn Device>)?;
- // todo: 从Modedb中获取信息
- // 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbmem.c#1584
- let mut inner = self.inner.write();
- inner.registered_fbs[id.data() as usize] = Some(fb.clone() as Arc<dyn FrameBuffer>);
- // todo: 把fb跟fbcon关联起来
- return Ok(id);
- }
- /// 注销一个帧缓冲区
- ///
- /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbmem.c#1726
- #[allow(dead_code)]
- pub fn unregister_fb(&self, _fb: Arc<dyn FrameBuffer>) -> Result<(), SystemError> {
- todo!("unregister_fb")
- }
- /// 根据id查找帧缓冲区
- pub fn find_fb_by_id(&self, id: FbId) -> Result<Option<Arc<dyn FrameBuffer>>, SystemError> {
- if unlikely(!id.is_valid()) {
- return Err(SystemError::EINVAL);
- }
- let inner = self.inner.read();
- return Ok(inner.registered_fbs[id.data() as usize].clone());
- }
- fn generate_fb_id(&self) -> Option<FbId> {
- for i in 0..Self::FB_MAX {
- if self.inner.read().registered_fbs[i].is_none() {
- return Some(FbId::new(i as u32));
- }
- }
- return None;
- }
- }
- /// 抽象的帧缓冲区设备
- ///
- /// 对应于`/sys/class/graphics/fb(x)`目录下的设备, 其中`(x)`为帧缓冲区的id
- ///
- /// 该设备的父设备为真实的帧缓冲区设备
- #[derive(Debug)]
- #[cast_to([sync] Device)]
- pub struct FbDevice {
- inner: SpinLock<InnerFbDevice>,
- kobj_state: LockedKObjectState,
- }
- impl FbDevice {
- pub const BASENAME: &'static str = "fb";
- fn new(fb: Weak<dyn FrameBuffer>, id: FbId) -> Arc<Self> {
- Arc::new(Self {
- inner: SpinLock::new(InnerFbDevice {
- fb,
- kern_inode: None,
- parent: None,
- kset: None,
- ktype: None,
- fb_id: id,
- }),
- kobj_state: LockedKObjectState::new(None),
- })
- }
- pub fn framebuffer(&self) -> Option<Arc<dyn FrameBuffer>> {
- self.inner.lock().fb.upgrade()
- }
- }
- #[derive(Debug)]
- struct InnerFbDevice {
- fb: Weak<dyn FrameBuffer>,
- kern_inode: Option<Arc<KernFSInode>>,
- parent: Option<Weak<dyn KObject>>,
- kset: Option<Arc<KSet>>,
- ktype: Option<&'static dyn KObjType>,
- /// 帧缓冲区id
- fb_id: FbId,
- }
- impl KObject for FbDevice {
- fn as_any_ref(&self) -> &dyn core::any::Any {
- self
- }
- fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
- self.inner.lock().kern_inode = inode;
- }
- fn inode(&self) -> Option<Arc<KernFSInode>> {
- self.inner.lock().kern_inode.clone()
- }
- fn parent(&self) -> Option<Weak<dyn KObject>> {
- self.inner.lock().parent.clone()
- }
- fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
- self.inner.lock().parent = parent;
- }
- fn kset(&self) -> Option<Arc<KSet>> {
- self.inner.lock().kset.clone()
- }
- fn set_kset(&self, kset: Option<Arc<KSet>>) {
- self.inner.lock().kset = kset;
- }
- fn kobj_type(&self) -> Option<&'static dyn KObjType> {
- self.inner.lock().ktype
- }
- fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
- self.inner.lock().ktype = ktype;
- }
- fn name(&self) -> String {
- format!("{}{}", Self::BASENAME, self.inner.lock().fb_id.data())
- }
- fn set_name(&self, _name: String) {
- // do nothing
- }
- fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
- self.kobj_state.read()
- }
- fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
- self.kobj_state.write()
- }
- fn set_kobj_state(&self, state: KObjectState) {
- *self.kobj_state.write() = state;
- }
- }
- impl Device for FbDevice {
- fn dev_type(&self) -> DeviceType {
- DeviceType::Char
- }
- fn id_table(&self) -> IdTable {
- IdTable::new(
- Self::BASENAME.to_string(),
- Some(DeviceNumber::new(
- Major::FB_MAJOR,
- self.inner.lock().fb_id.data(),
- )),
- )
- }
- fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
- todo!()
- }
- fn class(&self) -> Option<Arc<dyn Class>> {
- sys_class_graphics_instance().map(|ins| ins.clone() as Arc<dyn Class>)
- }
- fn set_class(&self, _class: Option<Arc<dyn Class>>) {
- // do nothing
- }
- fn driver(&self) -> Option<Arc<dyn Driver>> {
- None
- }
- fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
- // do nothing
- }
- fn is_dead(&self) -> bool {
- false
- }
- fn can_match(&self) -> bool {
- false
- }
- fn set_can_match(&self, _can_match: bool) {
- // do nothing
- }
- fn state_synced(&self) -> bool {
- true
- }
- fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
- Some(&[&FbDeviceAttrGroup])
- }
- }
|