mod.rs 13 KB

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