1 use alloc::{
2     string::{String, ToString},
3     sync::{Arc, Weak},
4     vec::Vec,
5 };
6 use system_error::SystemError;
7 
8 use crate::{
9     driver::{
10         base::{
11             class::Class,
12             device::{bus::Bus, device_manager, driver::Driver, Device, DeviceType, IdTable},
13             kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
14             kset::KSet,
15         },
16         tty::virtual_terminal::virtual_console::{CursorOperation, VcCursor, VirtualConsoleData},
17     },
18     filesystem::{
19         kernfs::KernFSInode,
20         sysfs::{file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport},
21         vfs::syscall::ModeType,
22     },
23     libs::{
24         rwlock::{RwLockReadGuard, RwLockWriteGuard},
25         spinlock::{SpinLock, SpinLockGuard},
26     },
27 };
28 
29 use super::{fbmem::sys_class_graphics_instance, FbCursor, ScrollMode};
30 
31 pub mod framebuffer_console;
32 
33 /// framebuffer console设备管理器实例
34 static mut FB_CONSOLE_MANAGER: Option<FbConsoleManager> = None;
35 
fb_console_manager() -> &'static FbConsoleManager36 pub fn fb_console_manager() -> &'static FbConsoleManager {
37     unsafe { FB_CONSOLE_MANAGER.as_ref().unwrap() }
38 }
39 
40 /// 初始化framebuffer console
fb_console_init() -> Result<(), SystemError>41 pub(super) fn fb_console_init() -> Result<(), SystemError> {
42     // todo: 对全局的console信号量加锁(linux中是console_lock)
43 
44     let fbcon_device: Arc<FbConsoleDevice> = FbConsoleDevice::new();
45 
46     {
47         let fbcon_manager = FbConsoleManager::new(fbcon_device.clone());
48         unsafe { FB_CONSOLE_MANAGER = Some(fbcon_manager) };
49     }
50 
51     device_manager().register(fbcon_device.clone() as Arc<dyn Device>)?;
52     fb_console_manager().init_device()?;
53 
54     return Ok(());
55 }
56 
57 /// framebuffer console设备管理器
58 #[derive(Debug)]
59 pub struct FbConsoleManager {
60     _inner: SpinLock<InnerFbConsoleManager>,
61     /// framebuffer console设备实例
62     /// (对应`/sys/class/graphics/fbcon`)
63     device: Arc<FbConsoleDevice>,
64 }
65 
66 impl FbConsoleManager {
new(device: Arc<FbConsoleDevice>) -> Self67     pub fn new(device: Arc<FbConsoleDevice>) -> Self {
68         return Self {
69             _inner: SpinLock::new(InnerFbConsoleManager {}),
70             device,
71         };
72     }
73 
74     #[allow(dead_code)]
75     #[inline(always)]
device(&self) -> &Arc<FbConsoleDevice>76     pub fn device(&self) -> &Arc<FbConsoleDevice> {
77         &self.device
78     }
79 
80     /// 初始化设备
init_device(&self) -> Result<(), SystemError>81     fn init_device(&self) -> Result<(), SystemError> {
82         return Ok(()); // todo
83     }
84 }
85 
86 #[derive(Debug)]
87 struct InnerFbConsoleManager {}
88 
89 #[derive(Debug)]
90 struct InnerFbConsoleDevice {
91     kernfs_inode: Option<Arc<KernFSInode>>,
92     parent: Option<Weak<dyn KObject>>,
93     kset: Option<Arc<KSet>>,
94     bus: Option<Weak<dyn Bus>>,
95     driver: Option<Weak<dyn Driver>>,
96     ktype: Option<&'static dyn KObjType>,
97 }
98 
99 /// `/sys/class/graphics/fbcon`代表的 framebuffer console 设备
100 #[derive(Debug)]
101 #[cast_to([sync] Device)]
102 pub struct FbConsoleDevice {
103     inner: SpinLock<InnerFbConsoleDevice>,
104     kobj_state: LockedKObjectState,
105 }
106 
107 impl FbConsoleDevice {
108     const NAME: &'static str = "fbcon";
109 
new() -> Arc<Self>110     pub fn new() -> Arc<Self> {
111         return Arc::new(Self {
112             inner: SpinLock::new(InnerFbConsoleDevice {
113                 kernfs_inode: None,
114                 parent: None,
115                 kset: None,
116                 bus: None,
117                 ktype: None,
118                 driver: None,
119             }),
120             kobj_state: LockedKObjectState::new(None),
121         });
122     }
123 }
124 
125 impl KObject for FbConsoleDevice {
as_any_ref(&self) -> &dyn core::any::Any126     fn as_any_ref(&self) -> &dyn core::any::Any {
127         self
128     }
129 
set_inode(&self, inode: Option<Arc<KernFSInode>>)130     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
131         self.inner.lock().kernfs_inode = inode;
132     }
133 
inode(&self) -> Option<Arc<KernFSInode>>134     fn inode(&self) -> Option<Arc<KernFSInode>> {
135         self.inner.lock().kernfs_inode.clone()
136     }
137 
parent(&self) -> Option<Weak<dyn KObject>>138     fn parent(&self) -> Option<Weak<dyn KObject>> {
139         self.inner.lock().parent.clone()
140     }
141 
set_parent(&self, parent: Option<Weak<dyn KObject>>)142     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
143         self.inner.lock().parent = parent;
144     }
145 
kset(&self) -> Option<Arc<KSet>>146     fn kset(&self) -> Option<Arc<KSet>> {
147         self.inner.lock().kset.clone()
148     }
149 
set_kset(&self, kset: Option<Arc<KSet>>)150     fn set_kset(&self, kset: Option<Arc<KSet>>) {
151         self.inner.lock().kset = kset;
152     }
153 
kobj_type(&self) -> Option<&'static dyn KObjType>154     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
155         self.inner.lock().ktype
156     }
157 
set_kobj_type(&self, ktype: Option<&'static dyn KObjType>)158     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
159         self.inner.lock().ktype = ktype;
160     }
161 
name(&self) -> String162     fn name(&self) -> String {
163         Self::NAME.to_string()
164     }
165 
set_name(&self, _name: String)166     fn set_name(&self, _name: String) {
167         // 不允许修改
168         kwarn!("fbcon name can not be changed");
169     }
170 
kobj_state(&self) -> RwLockReadGuard<KObjectState>171     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
172         self.kobj_state.read()
173     }
174 
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>175     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
176         self.kobj_state.write()
177     }
178 
set_kobj_state(&self, state: KObjectState)179     fn set_kobj_state(&self, state: KObjectState) {
180         *self.kobj_state.write() = state;
181     }
182 }
183 impl Device for FbConsoleDevice {
dev_type(&self) -> DeviceType184     fn dev_type(&self) -> DeviceType {
185         DeviceType::Char
186     }
187 
id_table(&self) -> IdTable188     fn id_table(&self) -> IdTable {
189         IdTable::new(Self::NAME.to_string(), None)
190     }
191 
set_bus(&self, bus: Option<Weak<dyn Bus>>)192     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
193         self.inner.lock().bus = bus;
194     }
195 
bus(&self) -> Option<Weak<dyn Bus>>196     fn bus(&self) -> Option<Weak<dyn Bus>> {
197         self.inner.lock().bus.clone()
198     }
199 
set_class(&self, _class: Option<Arc<dyn Class>>)200     fn set_class(&self, _class: Option<Arc<dyn Class>>) {
201         // 不允许修改
202         kwarn!("fbcon's class can not be changed");
203     }
204 
class(&self) -> Option<Arc<dyn Class>>205     fn class(&self) -> Option<Arc<dyn Class>> {
206         sys_class_graphics_instance().map(|ins| ins.clone() as Arc<dyn Class>)
207     }
208 
driver(&self) -> Option<Arc<dyn Driver>>209     fn driver(&self) -> Option<Arc<dyn Driver>> {
210         self.inner
211             .lock()
212             .driver
213             .clone()
214             .and_then(|driver| driver.upgrade())
215     }
216 
set_driver(&self, driver: Option<Weak<dyn Driver>>)217     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
218         self.inner.lock().driver = driver;
219     }
220 
is_dead(&self) -> bool221     fn is_dead(&self) -> bool {
222         todo!()
223     }
224 
can_match(&self) -> bool225     fn can_match(&self) -> bool {
226         todo!()
227     }
228 
set_can_match(&self, _can_match: bool)229     fn set_can_match(&self, _can_match: bool) {
230         todo!()
231     }
232 
state_synced(&self) -> bool233     fn state_synced(&self) -> bool {
234         todo!()
235     }
236 
attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>237     fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
238         return Some(&[&AnonymousAttributeGroup]);
239     }
240 }
241 
242 /// framebuffer console设备的匿名属性组
243 #[derive(Debug)]
244 struct AnonymousAttributeGroup;
245 
246 impl AttributeGroup for AnonymousAttributeGroup {
name(&self) -> Option<&str>247     fn name(&self) -> Option<&str> {
248         None
249     }
250 
attrs(&self) -> &[&'static dyn Attribute]251     fn attrs(&self) -> &[&'static dyn Attribute] {
252         return &[&AttrRotate, &AttrRotateAll, &AttrCursorBlink];
253     }
254 
is_visible( &self, _kobj: Arc<dyn KObject>, attr: &'static dyn Attribute, ) -> Option<ModeType>255     fn is_visible(
256         &self,
257         _kobj: Arc<dyn KObject>,
258         attr: &'static dyn Attribute,
259     ) -> Option<ModeType> {
260         return Some(attr.mode());
261     }
262 }
263 
264 #[derive(Debug)]
265 struct AttrRotate;
266 
267 impl Attribute for AttrRotate {
name(&self) -> &str268     fn name(&self) -> &str {
269         "rotate"
270     }
271 
mode(&self) -> ModeType272     fn mode(&self) -> ModeType {
273         ModeType::S_IRUGO | ModeType::S_IWUSR
274     }
275 
support(&self) -> SysFSOpsSupport276     fn support(&self) -> SysFSOpsSupport {
277         SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE
278     }
279 
280     /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3226
show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError>281     fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
282         kwarn!("fbcon rotate show not implemented");
283         return sysfs_emit_str(buf, "0\n");
284     }
285 
286     /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3182
store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError>287     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
288         kwarn!("fbcon rotate store not implemented");
289         return Err(SystemError::ENOSYS);
290     }
291 }
292 
293 #[derive(Debug)]
294 struct AttrRotateAll;
295 
296 impl Attribute for AttrRotateAll {
name(&self) -> &str297     fn name(&self) -> &str {
298         "rotate_all"
299     }
300 
mode(&self) -> ModeType301     fn mode(&self) -> ModeType {
302         ModeType::S_IWUSR
303     }
304 
support(&self) -> SysFSOpsSupport305     fn support(&self) -> SysFSOpsSupport {
306         SysFSOpsSupport::ATTR_STORE
307     }
308 
309     /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3204
store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError>310     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
311         kwarn!("fbcon rotate_all store not implemented");
312         return Err(SystemError::ENOSYS);
313     }
314 }
315 
316 #[derive(Debug)]
317 struct AttrCursorBlink;
318 
319 impl Attribute for AttrCursorBlink {
name(&self) -> &str320     fn name(&self) -> &str {
321         "cursor_blink"
322     }
323 
mode(&self) -> ModeType324     fn mode(&self) -> ModeType {
325         ModeType::S_IRUGO | ModeType::S_IWUSR
326     }
327 
support(&self) -> SysFSOpsSupport328     fn support(&self) -> SysFSOpsSupport {
329         SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE
330     }
331 
332     /// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbcon.c#3245
show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError>333     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
334         todo!()
335     }
336 
store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError>337     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
338         todo!()
339     }
340 }
341 
342 #[derive(Debug, Default)]
343 pub struct FrameBufferConsoleData {
344     /// 光标闪烁间隔
345     pub cursor_blink_jiffies: i64,
346     /// 是否刷新光标
347     pub cursor_flash: bool,
348     ///
349     pub display: FbConsoleDisplay,
350     /// 光标状态
351     pub cursor_state: FbCursor,
352     /// 重设光标?
353     pub cursor_reset: bool,
354     /// cursor 位图数据
355     pub cursor_data: Vec<u8>,
356 }
357 
358 pub trait FrameBufferConsole {
fbcon_data(&self) -> SpinLockGuard<FrameBufferConsoleData>359     fn fbcon_data(&self) -> SpinLockGuard<FrameBufferConsoleData>;
360 
361     /// ## 将位块移动到目标位置
362     /// 坐标均以字体为单位而不是pixel
363     /// ### 参数
364     /// ### sy: 起始位置的y坐标
365     /// ### sx: 起始位置的x坐标、
366     /// ### dy: 目标位置的y坐标
367     /// ### dx: 目标位置的x坐标
368     /// ### height: 位图高度
369     /// ### width: 位图宽度
bmove( &self, vc_data: &VirtualConsoleData, sy: i32, sx: i32, dy: i32, dx: i32, height: u32, width: u32, ) -> Result<(), SystemError>370     fn bmove(
371         &self,
372         vc_data: &VirtualConsoleData,
373         sy: i32,
374         sx: i32,
375         dy: i32,
376         dx: i32,
377         height: u32,
378         width: u32,
379     ) -> Result<(), SystemError>;
380 
381     /// ## 清除位图
382     ///
383     /// ### 参数
384     /// ### sy: 原位置的y坐标
385     /// ### sx: 原位置的x坐标、
386     /// ### height: 位图高度
387     /// ### width: 位图宽度
clear( &self, vc_data: &VirtualConsoleData, sy: u32, sx: u32, height: u32, width: u32, ) -> Result<(), SystemError>388     fn clear(
389         &self,
390         vc_data: &VirtualConsoleData,
391         sy: u32,
392         sx: u32,
393         height: u32,
394         width: u32,
395     ) -> Result<(), SystemError>;
396 
397     /// ## 显示字符串
398     ///
399     /// ### 参数
400     /// ### y: 起始位置y坐标
401     /// ### x: 起始位置的x坐标、
402     /// ### fg: 前景色
403     /// ### bg: 背景色
put_string( &self, vc_data: &VirtualConsoleData, data: &[u16], count: u32, y: u32, x: u32, fg: u32, bg: u32, ) -> Result<(), SystemError>404     fn put_string(
405         &self,
406         vc_data: &VirtualConsoleData,
407         data: &[u16],
408         count: u32,
409         y: u32,
410         x: u32,
411         fg: u32,
412         bg: u32,
413     ) -> Result<(), SystemError>;
414 
cursor(&self, vc_data: &VirtualConsoleData, op: CursorOperation, fg: u32, bg: u32)415     fn cursor(&self, vc_data: &VirtualConsoleData, op: CursorOperation, fg: u32, bg: u32);
416 }
417 
418 /// 表示 framebuffer 控制台与低级帧缓冲设备之间接口的数据结构
419 #[derive(Debug, Default)]
420 pub struct FbConsoleDisplay {
421     /// 硬件滚动的行数
422     pub yscroll: u32,
423     /// 光标
424     pub cursor_shape: VcCursor,
425     /// 滚动模式
426     pub scroll_mode: ScrollMode,
427     virt_rows: u32,
428 }
429 
430 impl FbConsoleDisplay {
real_y(&self, mut ypos: u32) -> u32431     pub fn real_y(&self, mut ypos: u32) -> u32 {
432         let rows = self.virt_rows;
433         ypos += self.yscroll;
434         if ypos < rows {
435             return ypos;
436         } else {
437             return ypos - rows;
438         }
439     }
440 }
441 
442 bitflags! {
443     pub struct FbConAttr:u8 {
444         const UNDERLINE = 1;
445         const REVERSE   = 2;
446         const BOLD      = 4;
447     }
448 }
449 
450 impl FbConAttr {
get_attr(c: u16, color_depth: u32) -> Self451     pub fn get_attr(c: u16, color_depth: u32) -> Self {
452         let mut attr = Self::empty();
453         if color_depth == 1 {
454             if Self::underline(c) {
455                 attr.insert(Self::UNDERLINE);
456             }
457             if Self::reverse(c) {
458                 attr.intersects(Self::REVERSE);
459             }
460             if Self::blod(c) {
461                 attr.insert(Self::BOLD);
462             }
463         }
464         attr
465     }
466 
update_attr(&self, dst: &mut [u8], src: &[u8], vc_data: &VirtualConsoleData)467     pub fn update_attr(&self, dst: &mut [u8], src: &[u8], vc_data: &VirtualConsoleData) {
468         let mut offset = if vc_data.font.height < 10 { 1 } else { 2 } as usize;
469 
470         let width = (vc_data.font.width + 7) / 8;
471         let cellsize = (vc_data.font.height * width) as usize;
472 
473         // 大于offset的部分就是下划线
474         offset = cellsize - (offset * width as usize);
475         for i in 0..cellsize {
476             let mut c = src[i];
477             if self.contains(Self::UNDERLINE) && i >= offset {
478                 // 下划线
479                 c = 0xff;
480             }
481             if self.contains(Self::BOLD) {
482                 c |= c >> 1;
483             }
484             if self.contains(Self::REVERSE) {
485                 c = !c;
486             }
487 
488             dst[i] = c;
489         }
490     }
491 
underline(c: u16) -> bool492     pub fn underline(c: u16) -> bool {
493         c & 0x400 != 0
494     }
495 
blod(c: u16) -> bool496     pub fn blod(c: u16) -> bool {
497         c & 0x200 != 0
498     }
499 
reverse(c: u16) -> bool500     pub fn reverse(c: u16) -> bool {
501         c & 0x800 != 0
502     }
503 }
504