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 36 pub fn fb_console_manager() -> &'static FbConsoleManager { 37 unsafe { FB_CONSOLE_MANAGER.as_ref().unwrap() } 38 } 39 40 /// 初始化framebuffer console 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 { 67 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)] 76 pub fn device(&self) -> &Arc<FbConsoleDevice> { 77 &self.device 78 } 79 80 /// 初始化设备 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 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 { 126 fn as_any_ref(&self) -> &dyn core::any::Any { 127 self 128 } 129 130 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 131 self.inner.lock().kernfs_inode = inode; 132 } 133 134 fn inode(&self) -> Option<Arc<KernFSInode>> { 135 self.inner.lock().kernfs_inode.clone() 136 } 137 138 fn parent(&self) -> Option<Weak<dyn KObject>> { 139 self.inner.lock().parent.clone() 140 } 141 142 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 143 self.inner.lock().parent = parent; 144 } 145 146 fn kset(&self) -> Option<Arc<KSet>> { 147 self.inner.lock().kset.clone() 148 } 149 150 fn set_kset(&self, kset: Option<Arc<KSet>>) { 151 self.inner.lock().kset = kset; 152 } 153 154 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 155 self.inner.lock().ktype 156 } 157 158 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 159 self.inner.lock().ktype = ktype; 160 } 161 162 fn name(&self) -> String { 163 Self::NAME.to_string() 164 } 165 166 fn set_name(&self, _name: String) { 167 // 不允许修改 168 kwarn!("fbcon name can not be changed"); 169 } 170 171 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 172 self.kobj_state.read() 173 } 174 175 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 176 self.kobj_state.write() 177 } 178 179 fn set_kobj_state(&self, state: KObjectState) { 180 *self.kobj_state.write() = state; 181 } 182 } 183 impl Device for FbConsoleDevice { 184 fn dev_type(&self) -> DeviceType { 185 DeviceType::Char 186 } 187 188 fn id_table(&self) -> IdTable { 189 IdTable::new(Self::NAME.to_string(), None) 190 } 191 192 fn set_bus(&self, bus: Option<Weak<dyn Bus>>) { 193 self.inner.lock().bus = bus; 194 } 195 196 fn bus(&self) -> Option<Weak<dyn Bus>> { 197 self.inner.lock().bus.clone() 198 } 199 200 fn set_class(&self, _class: Option<Arc<dyn Class>>) { 201 // 不允许修改 202 kwarn!("fbcon's class can not be changed"); 203 } 204 205 fn class(&self) -> Option<Arc<dyn Class>> { 206 sys_class_graphics_instance().map(|ins| ins.clone() as Arc<dyn Class>) 207 } 208 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 217 fn set_driver(&self, driver: Option<Weak<dyn Driver>>) { 218 self.inner.lock().driver = driver; 219 } 220 221 fn is_dead(&self) -> bool { 222 todo!() 223 } 224 225 fn can_match(&self) -> bool { 226 todo!() 227 } 228 229 fn set_can_match(&self, _can_match: bool) { 230 todo!() 231 } 232 233 fn state_synced(&self) -> bool { 234 todo!() 235 } 236 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 { 247 fn name(&self) -> Option<&str> { 248 None 249 } 250 251 fn attrs(&self) -> &[&'static dyn Attribute] { 252 return &[&AttrRotate, &AttrRotateAll, &AttrCursorBlink]; 253 } 254 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 { 268 fn name(&self) -> &str { 269 "rotate" 270 } 271 272 fn mode(&self) -> ModeType { 273 ModeType::S_IRUGO | ModeType::S_IWUSR 274 } 275 276 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 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 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 { 297 fn name(&self) -> &str { 298 "rotate_all" 299 } 300 301 fn mode(&self) -> ModeType { 302 ModeType::S_IWUSR 303 } 304 305 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 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 { 320 fn name(&self) -> &str { 321 "cursor_blink" 322 } 323 324 fn mode(&self) -> ModeType { 325 ModeType::S_IRUGO | ModeType::S_IWUSR 326 } 327 328 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 333 fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> { 334 todo!() 335 } 336 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 { 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: 位图宽度 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: 位图宽度 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: 背景色 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 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 { 431 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 { 451 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 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 492 pub fn underline(c: u16) -> bool { 493 c & 0x400 != 0 494 } 495 496 pub fn blod(c: u16) -> bool { 497 c & 0x200 != 0 498 } 499 500 pub fn reverse(c: u16) -> bool { 501 c & 0x800 != 0 502 } 503 } 504