1 use alloc::{
2 string::{String, ToString},
3 sync::{Arc, Weak},
4 vec::Vec,
5 };
6 use log::warn;
7 use system_error::SystemError;
8
9 use crate::{
10 driver::{
11 base::{
12 class::Class,
13 device::{
14 bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceType,
15 IdTable,
16 },
17 kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
18 kset::KSet,
19 },
20 tty::virtual_terminal::virtual_console::{CursorOperation, VcCursor, VirtualConsoleData},
21 },
22 filesystem::{
23 kernfs::KernFSInode,
24 sysfs::{file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport},
25 vfs::syscall::ModeType,
26 },
27 libs::{
28 rwlock::{RwLockReadGuard, RwLockWriteGuard},
29 spinlock::{SpinLock, SpinLockGuard},
30 },
31 };
32
33 use super::{fbmem::sys_class_graphics_instance, FbCursor, ScrollMode};
34
35 pub mod framebuffer_console;
36
37 /// framebuffer console设备管理器实例
38 static mut FB_CONSOLE_MANAGER: Option<FbConsoleManager> = None;
39
fb_console_manager() -> &'static FbConsoleManager40 pub fn fb_console_manager() -> &'static FbConsoleManager {
41 unsafe { FB_CONSOLE_MANAGER.as_ref().unwrap() }
42 }
43
44 /// 初始化framebuffer console
fb_console_init() -> Result<(), SystemError>45 pub(super) fn fb_console_init() -> Result<(), SystemError> {
46 // todo: 对全局的console信号量加锁(linux中是console_lock)
47
48 let fbcon_device: Arc<FbConsoleDevice> = FbConsoleDevice::new();
49
50 {
51 let fbcon_manager = FbConsoleManager::new(fbcon_device.clone());
52 unsafe { FB_CONSOLE_MANAGER = Some(fbcon_manager) };
53 }
54
55 device_manager().register(fbcon_device.clone() as Arc<dyn Device>)?;
56 fb_console_manager().init_device()?;
57
58 return Ok(());
59 }
60
61 /// framebuffer console设备管理器
62 #[derive(Debug)]
63 pub struct FbConsoleManager {
64 _inner: SpinLock<InnerFbConsoleManager>,
65 /// framebuffer console设备实例
66 /// (对应`/sys/class/graphics/fbcon`)
67 device: Arc<FbConsoleDevice>,
68 }
69
70 impl FbConsoleManager {
new(device: Arc<FbConsoleDevice>) -> Self71 pub fn new(device: Arc<FbConsoleDevice>) -> Self {
72 return Self {
73 _inner: SpinLock::new(InnerFbConsoleManager {}),
74 device,
75 };
76 }
77
78 #[allow(dead_code)]
79 #[inline(always)]
device(&self) -> &Arc<FbConsoleDevice>80 pub fn device(&self) -> &Arc<FbConsoleDevice> {
81 &self.device
82 }
83
84 /// 初始化设备
init_device(&self) -> Result<(), SystemError>85 fn init_device(&self) -> Result<(), SystemError> {
86 return Ok(()); // todo
87 }
88 }
89
90 #[derive(Debug)]
91 struct InnerFbConsoleManager {}
92
93 #[derive(Debug)]
94 struct InnerFbConsoleDevice {
95 device_common: DeviceCommonData,
96 kobject_common: KObjectCommonData,
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 device_common: DeviceCommonData::default(),
114 kobject_common: KObjectCommonData::default(),
115 }),
116 kobj_state: LockedKObjectState::new(None),
117 });
118 }
119
inner(&self) -> SpinLockGuard<InnerFbConsoleDevice>120 fn inner(&self) -> SpinLockGuard<InnerFbConsoleDevice> {
121 self.inner.lock()
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().kobject_common.kern_inode = inode;
132 }
133
inode(&self) -> Option<Arc<KernFSInode>>134 fn inode(&self) -> Option<Arc<KernFSInode>> {
135 self.inner().kobject_common.kern_inode.clone()
136 }
137
parent(&self) -> Option<Weak<dyn KObject>>138 fn parent(&self) -> Option<Weak<dyn KObject>> {
139 self.inner().kobject_common.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().kobject_common.parent = parent;
144 }
145
kset(&self) -> Option<Arc<KSet>>146 fn kset(&self) -> Option<Arc<KSet>> {
147 self.inner().kobject_common.kset.clone()
148 }
149
set_kset(&self, kset: Option<Arc<KSet>>)150 fn set_kset(&self, kset: Option<Arc<KSet>>) {
151 self.inner().kobject_common.kset = kset;
152 }
153
kobj_type(&self) -> Option<&'static dyn KObjType>154 fn kobj_type(&self) -> Option<&'static dyn KObjType> {
155 self.inner().kobject_common.kobj_type
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().kobject_common.kobj_type = 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 warn!("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().device_common.bus = bus;
194 }
195
bus(&self) -> Option<Weak<dyn Bus>>196 fn bus(&self) -> Option<Weak<dyn Bus>> {
197 self.inner().device_common.bus.clone()
198 }
199
set_class(&self, _class: Option<Weak<dyn Class>>)200 fn set_class(&self, _class: Option<Weak<dyn Class>>) {
201 // 不允许修改
202 warn!("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 .device_common
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().device_common.driver = driver;
219 }
220
is_dead(&self) -> bool221 fn is_dead(&self) -> bool {
222 self.inner().device_common.dead
223 }
224
can_match(&self) -> bool225 fn can_match(&self) -> bool {
226 self.inner().device_common.can_match
227 }
228
set_can_match(&self, can_match: bool)229 fn set_can_match(&self, can_match: bool) {
230 self.inner().device_common.can_match = can_match;
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
dev_parent(&self) -> Option<Weak<dyn Device>>241 fn dev_parent(&self) -> Option<Weak<dyn Device>> {
242 self.inner().device_common.get_parent_weak_or_clear()
243 }
244
set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>)245 fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
246 self.inner().device_common.parent = dev_parent;
247 }
248 }
249
250 /// framebuffer console设备的匿名属性组
251 #[derive(Debug)]
252 struct AnonymousAttributeGroup;
253
254 impl AttributeGroup for AnonymousAttributeGroup {
name(&self) -> Option<&str>255 fn name(&self) -> Option<&str> {
256 None
257 }
258
attrs(&self) -> &[&'static dyn Attribute]259 fn attrs(&self) -> &[&'static dyn Attribute] {
260 return &[&AttrRotate, &AttrRotateAll, &AttrCursorBlink];
261 }
262
is_visible( &self, _kobj: Arc<dyn KObject>, attr: &'static dyn Attribute, ) -> Option<ModeType>263 fn is_visible(
264 &self,
265 _kobj: Arc<dyn KObject>,
266 attr: &'static dyn Attribute,
267 ) -> Option<ModeType> {
268 return Some(attr.mode());
269 }
270 }
271
272 #[derive(Debug)]
273 struct AttrRotate;
274
275 impl Attribute for AttrRotate {
name(&self) -> &str276 fn name(&self) -> &str {
277 "rotate"
278 }
279
mode(&self) -> ModeType280 fn mode(&self) -> ModeType {
281 ModeType::S_IRUGO | ModeType::S_IWUSR
282 }
283
support(&self) -> SysFSOpsSupport284 fn support(&self) -> SysFSOpsSupport {
285 SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE
286 }
287
288 /// 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>289 fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
290 warn!("fbcon rotate show not implemented");
291 return sysfs_emit_str(buf, "0\n");
292 }
293
294 /// 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>295 fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
296 warn!("fbcon rotate store not implemented");
297 return Err(SystemError::ENOSYS);
298 }
299 }
300
301 #[derive(Debug)]
302 struct AttrRotateAll;
303
304 impl Attribute for AttrRotateAll {
name(&self) -> &str305 fn name(&self) -> &str {
306 "rotate_all"
307 }
308
mode(&self) -> ModeType309 fn mode(&self) -> ModeType {
310 ModeType::S_IWUSR
311 }
312
support(&self) -> SysFSOpsSupport313 fn support(&self) -> SysFSOpsSupport {
314 SysFSOpsSupport::ATTR_STORE
315 }
316
317 /// 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>318 fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
319 warn!("fbcon rotate_all store not implemented");
320 return Err(SystemError::ENOSYS);
321 }
322 }
323
324 #[derive(Debug)]
325 struct AttrCursorBlink;
326
327 impl Attribute for AttrCursorBlink {
name(&self) -> &str328 fn name(&self) -> &str {
329 "cursor_blink"
330 }
331
mode(&self) -> ModeType332 fn mode(&self) -> ModeType {
333 ModeType::S_IRUGO | ModeType::S_IWUSR
334 }
335
support(&self) -> SysFSOpsSupport336 fn support(&self) -> SysFSOpsSupport {
337 SysFSOpsSupport::ATTR_SHOW | SysFSOpsSupport::ATTR_STORE
338 }
339
340 /// 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>341 fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
342 todo!()
343 }
344
store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError>345 fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
346 todo!()
347 }
348 }
349
350 #[derive(Debug, Default)]
351 #[allow(dead_code)]
352 pub struct FrameBufferConsoleData {
353 /// 光标闪烁间隔
354 pub cursor_blink_jiffies: i64,
355 /// 是否刷新光标
356 pub cursor_flash: bool,
357 pub display: FbConsoleDisplay,
358 /// 光标状态
359 pub cursor_state: FbCursor,
360 /// 重设光标?
361 pub cursor_reset: bool,
362 /// cursor 位图数据
363 pub cursor_data: Vec<u8>,
364 }
365
366 pub trait FrameBufferConsole {
fbcon_data(&self) -> SpinLockGuard<FrameBufferConsoleData>367 fn fbcon_data(&self) -> SpinLockGuard<FrameBufferConsoleData>;
368
369 /// ## 将位块移动到目标位置
370 /// 坐标均以字体为单位而不是pixel
371 /// ### 参数
372 /// ### sy: 起始位置的y坐标
373 /// ### sx: 起始位置的x坐标、
374 /// ### dy: 目标位置的y坐标
375 /// ### dx: 目标位置的x坐标
376 /// ### height: 位图高度
377 /// ### width: 位图宽度
378 #[allow(clippy::too_many_arguments)]
bmove( &self, vc_data: &VirtualConsoleData, sy: i32, sx: i32, dy: i32, dx: i32, height: u32, width: u32, ) -> Result<(), SystemError>379 fn bmove(
380 &self,
381 vc_data: &VirtualConsoleData,
382 sy: i32,
383 sx: i32,
384 dy: i32,
385 dx: i32,
386 height: u32,
387 width: u32,
388 ) -> Result<(), SystemError>;
389
390 /// ## 清除位图
391 ///
392 /// ### 参数
393 /// ### sy: 原位置的y坐标
394 /// ### sx: 原位置的x坐标、
395 /// ### height: 位图高度
396 /// ### width: 位图宽度
clear( &self, vc_data: &VirtualConsoleData, sy: u32, sx: u32, height: u32, width: u32, ) -> Result<(), SystemError>397 fn clear(
398 &self,
399 vc_data: &VirtualConsoleData,
400 sy: u32,
401 sx: u32,
402 height: u32,
403 width: u32,
404 ) -> Result<(), SystemError>;
405
406 /// ## 显示字符串
407 ///
408 /// ### 参数
409 /// ### y: 起始位置y坐标
410 /// ### x: 起始位置的x坐标、
411 /// ### fg: 前景色
412 /// ### bg: 背景色
413 #[allow(clippy::too_many_arguments)]
put_string( &self, vc_data: &VirtualConsoleData, data: &[u16], count: u32, y: u32, x: u32, fg: u32, bg: u32, ) -> Result<(), SystemError>414 fn put_string(
415 &self,
416 vc_data: &VirtualConsoleData,
417 data: &[u16],
418 count: u32,
419 y: u32,
420 x: u32,
421 fg: u32,
422 bg: u32,
423 ) -> Result<(), SystemError>;
424
cursor(&self, vc_data: &VirtualConsoleData, op: CursorOperation, fg: u32, bg: u32)425 fn cursor(&self, vc_data: &VirtualConsoleData, op: CursorOperation, fg: u32, bg: u32);
426 }
427
428 /// 表示 framebuffer 控制台与低级帧缓冲设备之间接口的数据结构
429 #[derive(Debug, Default)]
430 pub struct FbConsoleDisplay {
431 /// 硬件滚动的行数
432 pub yscroll: u32,
433 /// 光标
434 pub cursor_shape: VcCursor,
435 /// 滚动模式
436 pub scroll_mode: ScrollMode,
437 virt_rows: u32,
438 }
439
440 impl FbConsoleDisplay {
real_y(&self, mut ypos: u32) -> u32441 pub fn real_y(&self, mut ypos: u32) -> u32 {
442 let rows = self.virt_rows;
443 ypos += self.yscroll;
444 if ypos < rows {
445 return ypos;
446 } else {
447 return ypos - rows;
448 }
449 }
450 }
451
452 bitflags! {
453 pub struct FbConAttr:u8 {
454 const UNDERLINE = 1;
455 const REVERSE = 2;
456 const BOLD = 4;
457 }
458 }
459
460 impl FbConAttr {
get_attr(c: u16, color_depth: u32) -> Self461 pub fn get_attr(c: u16, color_depth: u32) -> Self {
462 let mut attr = Self::empty();
463 if color_depth == 1 {
464 if Self::underline(c) {
465 attr.insert(Self::UNDERLINE);
466 }
467 if Self::reverse(c) {
468 attr.intersects(Self::REVERSE);
469 }
470 if Self::blod(c) {
471 attr.insert(Self::BOLD);
472 }
473 }
474 attr
475 }
476
update_attr(&self, dst: &mut [u8], src: &[u8], vc_data: &VirtualConsoleData)477 pub fn update_attr(&self, dst: &mut [u8], src: &[u8], vc_data: &VirtualConsoleData) {
478 let mut offset = if vc_data.font.height < 10 { 1 } else { 2 } as usize;
479
480 let width = (vc_data.font.width + 7) / 8;
481 let cellsize = (vc_data.font.height * width) as usize;
482
483 // 大于offset的部分就是下划线
484 offset = cellsize - (offset * width as usize);
485 for i in 0..cellsize {
486 let mut c = src[i];
487 if self.contains(Self::UNDERLINE) && i >= offset {
488 // 下划线
489 c = 0xff;
490 }
491 if self.contains(Self::BOLD) {
492 c |= c >> 1;
493 }
494 if self.contains(Self::REVERSE) {
495 c = !c;
496 }
497
498 dst[i] = c;
499 }
500 }
501
underline(c: u16) -> bool502 pub fn underline(c: u16) -> bool {
503 c & 0x400 != 0
504 }
505
blod(c: u16) -> bool506 pub fn blod(c: u16) -> bool {
507 c & 0x200 != 0
508 }
509
reverse(c: u16) -> bool510 pub fn reverse(c: u16) -> bool {
511 c & 0x800 != 0
512 }
513 }
514