xref: /DragonOS/kernel/src/driver/video/fbdev/base/mod.rs (revision 5b59005f930266d0e9c0092373e894826150f862)
1 use alloc::{string::String, sync::Arc};
2 use system_error::SystemError;
3 
4 use crate::{
5     driver::base::device::Device,
6     mm::{ucontext::LockedVMA, PhysAddr, VirtAddr},
7 };
8 
9 use self::fbmem::{FbDevice, FrameBufferManager};
10 
11 pub mod fbcon;
12 pub mod fbmem;
13 pub mod fbsysfs;
14 pub mod modedb;
15 
16 // 帧缓冲区id
17 int_like!(FbId, u32);
18 
19 impl FbId {
20     /// 帧缓冲区id的初始值(无效值)
21     pub const INIT: Self = Self::new(u32::MAX);
22 
23     /// 判断是否为无效的帧缓冲区id
24     #[allow(dead_code)]
25     pub const fn is_valid(&self) -> bool {
26         if self.0 == Self::INIT.0 || self.0 >= FrameBufferManager::FB_MAX as u32 {
27             return false;
28         }
29         return true;
30     }
31 }
32 
33 /// 帧缓冲区应该实现的接口
34 pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
35     /// 获取帧缓冲区的id
36     fn fb_id(&self) -> FbId;
37 
38     /// 设置帧缓冲区的id
39     fn set_fb_id(&self, id: FbId);
40 }
41 
42 /// 帧缓冲区信息
43 pub trait FrameBufferInfo {
44     /// Amount of ioremapped VRAM or 0
45     fn screen_size(&self) -> usize;
46 
47     /// 获取当前的可变帧缓冲信息
48     fn current_fb_var(&self) -> FbVarScreenInfo;
49 
50     /// 获取当前的固定帧缓冲信息
51     fn current_fb_fix(&self) -> FixedScreenInfo;
52 
53     /// 获取当前的视频模式
54     fn video_mode(&self) -> Option<&FbVideoMode>;
55 
56     /// 获取当前帧缓冲区对应的`/sys/class/graphics/fb0`或者`/sys/class/graphics/fb1`等的设备结构体
57     fn fb_device(&self) -> Option<Arc<FbDevice>>;
58 
59     /// 设置当前帧缓冲区对应的`/sys/class/graphics/fb0`或者`/sys/class/graphics/fb1`等的设备结构体
60     fn set_fb_device(&self, device: Option<Arc<FbDevice>>);
61 
62     /// 获取帧缓冲区的状态
63     fn state(&self) -> FbState;
64 }
65 
66 /// 帧缓冲区操作
67 ///
68 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/fb.h#237
69 pub trait FrameBufferOps {
70     fn fb_open(&self, user: bool);
71     fn fb_release(&self, user: bool);
72 
73     /// 读取帧缓冲区的内容。
74     ///
75     /// 对于具有奇特非线性布局的帧缓冲区或正常内存映射访问无法工作的帧缓冲区,可以使用此方法。
76     fn fb_read(&self, _buf: &mut [u8], _pos: usize) -> Result<usize, SystemError> {
77         Err(SystemError::ENOSYS)
78     }
79 
80     /// 将帧缓冲区的内容写入。
81     ///
82     /// 对于具有奇特非线性布局的帧缓冲区或正常内存映射访问无法工作的帧缓冲区,可以使用此方法。
83     fn fb_write(&self, _buf: &[u8], _pos: usize) -> Result<usize, SystemError> {
84         Err(SystemError::ENOSYS)
85     }
86 
87     /// 设置帧缓冲区的颜色寄存器。
88     ///
89     /// 颜色寄存器的数量和含义取决于帧缓冲区的硬件。
90     ///
91     /// ## 参数
92     ///
93     /// - `regno`:寄存器编号。
94     /// - `red`:红色分量。
95     /// - `green`:绿色分量。
96     /// - `blue`:蓝色分量。
97     fn fb_set_color_register(
98         &self,
99         regno: u16,
100         red: u16,
101         green: u16,
102         blue: u16,
103     ) -> Result<(), SystemError>;
104 
105     /// 设置帧缓冲区的黑屏模式
106     fn fb_blank(&self, blank_mode: BlankMode) -> Result<(), SystemError>;
107 
108     /// 在帧缓冲区中绘制一个矩形。
109     fn fb_fillrect(&self, _data: FillRectData) -> Result<(), SystemError> {
110         Err(SystemError::ENOSYS)
111     }
112 
113     /// 将数据从一处复制到另一处。
114     fn fb_copyarea(&self, _data: CopyAreaData) -> Result<(), SystemError> {
115         Err(SystemError::ENOSYS)
116     }
117 
118     /// 将帧缓冲区的内容映射到用户空间。
119     fn fb_mmap(&self, _vma: &Arc<LockedVMA>) -> Result<(), SystemError> {
120         Err(SystemError::ENOSYS)
121     }
122 
123     /// 卸载与该帧缓冲区相关的所有资源
124     fn fb_destroy(&self);
125 }
126 
127 /// 帧缓冲区的状态
128 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
129 pub enum FbState {
130     Running = 0,
131     Suspended = 1,
132 }
133 
134 /// 屏幕黑屏模式。
135 #[allow(dead_code)]
136 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
137 pub enum BlankMode {
138     /// 取消屏幕黑屏, 垂直同步和水平同步均打开
139     Unblank,
140     /// 屏幕黑屏, 垂直同步和水平同步均打开
141     Normal,
142     /// 屏幕黑屏, 水平同步打开, 垂直同步关闭
143     HSync,
144     /// 屏幕黑屏, 水平同步关闭, 垂直同步打开
145     VSync,
146     /// 屏幕黑屏, 水平同步和垂直同步均关闭
147     Powerdown,
148 }
149 
150 /// `FillRectData` 结构体用于表示一个矩形区域并填充特定颜色。
151 ///
152 /// # 结构体字段
153 /// * `dx`:
154 /// * `dy`:
155 /// * `width`:
156 /// * `height`: 矩形的高度
157 /// * `color`: 用于填充矩形的颜色,是一个32位无符号整数
158 /// * `rop`: 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
159 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
160 pub struct FillRectData {
161     /// 矩形左上角的x坐标(相对于屏幕)
162     pub dx: u32,
163     /// 矩形左上角的y坐标(相对于屏幕)
164     pub dy: u32,
165     /// 矩形的宽度
166     pub width: u32,
167     /// 矩形的高度
168     pub height: u32,
169     /// 用于填充矩形的颜色,是一个32位无符号整数
170     pub color: u32,
171     /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
172     pub rop: FillRectROP,
173 }
174 
175 impl FillRectData {
176     #[allow(dead_code)]
177     pub fn new(dx: u32, dy: u32, width: u32, height: u32, color: u32, rop: FillRectROP) -> Self {
178         Self {
179             dx,
180             dy,
181             width,
182             height,
183             color,
184             rop,
185         }
186     }
187 }
188 
189 /// 光栅操作(Raster Operation),用于定义如何将颜色应用到矩形区域
190 #[allow(dead_code)]
191 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
192 pub enum FillRectROP {
193     /// 复制操作,即直接将指定颜色应用到矩形区域,覆盖原有颜色。
194     Copy,
195     /// 异或操作,即将指定颜色与矩形区域原有颜色进行异或操作,结果颜色应用到矩形区域。
196     Xor,
197 }
198 
199 /// `CopyAreaData` 结构体用于表示一个矩形区域,并指定从哪个源位置复制数据。
200 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
201 pub struct CopyAreaData {
202     /// 目标矩形左上角的x坐标
203     pub dx: u32,
204     /// 目标矩形左上角的y坐标
205     pub dy: u32,
206     /// 矩形的宽度
207     pub width: u32,
208     /// 矩形的高度
209     pub height: u32,
210     /// 源矩形左上角的x坐标
211     pub sx: u32,
212     /// 源矩形左上角的y坐标
213     pub sy: u32,
214 }
215 
216 impl CopyAreaData {
217     #[allow(dead_code)]
218     pub fn new(dx: u32, dy: u32, width: u32, height: u32, sx: u32, sy: u32) -> Self {
219         Self {
220             dx,
221             dy,
222             width,
223             height,
224             sx,
225             sy,
226         }
227     }
228 }
229 
230 /// `FbVarScreenInfo` 结构体用于描述屏幕的各种属性。
231 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
232 pub struct FbVarScreenInfo {
233     /// 可见分辨率的宽度
234     pub xres: u32,
235     /// 可见分辨率的高度
236     pub yres: u32,
237     /// 虚拟分辨率的宽度
238     pub xres_virtual: u32,
239     /// 虚拟分辨率的高度
240     pub yres_virtual: u32,
241     /// 从虚拟到可见分辨率的偏移量(宽度方向)
242     pub xoffset: u32,
243     /// 从虚拟到可见分辨率的偏移量(高度方向)
244     pub yoffset: u32,
245     /// 每像素的位数
246     pub bits_per_pixel: u32,
247     /// 颜色模式
248     pub color_mode: FbColorMode,
249     /// 红色位域
250     pub red: FbBitfield,
251     /// 绿色位域
252     pub green: FbBitfield,
253     /// 蓝色位域
254     pub blue: FbBitfield,
255     /// 透明度位域
256     pub transp: FbBitfield,
257     /// 像素格式
258     pub pixel_format: FbPixelFormat,
259     /// 激活标志(参见FB_ACTIVATE_*)
260     pub activate: FbActivateFlags,
261     /// 帧缓冲区的高度(像素) None表示未知
262     pub height: Option<u32>,
263     /// 帧缓冲区的宽度(像素) None表示未知
264     pub width: Option<u32>,
265     /// 像素时钟(皮秒)
266     pub pixclock: u32,
267     /// 左边距
268     pub left_margin: u32,
269     /// 右边距
270     pub right_margin: u32,
271     /// 上边距
272     pub upper_margin: u32,
273     /// 下边距
274     pub lower_margin: u32,
275     /// 水平同步的长度
276     pub hsync_len: u32,
277     /// 垂直同步的长度
278     pub vsync_len: u32,
279     /// 同步标志(参见FB_SYNC_*)
280     pub sync: FbSyncFlags,
281     /// 视频模式(参见FB_VMODE_*)
282     pub vmode: FbVModeFlags,
283     /// 逆时针旋转的角度
284     pub rotate_angle: u32,
285     /// 颜色空间
286     pub colorspace: V4l2Colorspace,
287 }
288 
289 impl Default for FbVarScreenInfo {
290     fn default() -> Self {
291         Self {
292             xres: Default::default(),
293             yres: Default::default(),
294             xres_virtual: Default::default(),
295             yres_virtual: Default::default(),
296             xoffset: Default::default(),
297             yoffset: Default::default(),
298             bits_per_pixel: Default::default(),
299             color_mode: Default::default(),
300             red: Default::default(),
301             green: Default::default(),
302             blue: Default::default(),
303             transp: Default::default(),
304             pixel_format: Default::default(),
305             activate: Default::default(),
306             height: None,
307             width: None,
308             pixclock: Default::default(),
309             left_margin: Default::default(),
310             right_margin: Default::default(),
311             upper_margin: Default::default(),
312             lower_margin: Default::default(),
313             hsync_len: Default::default(),
314             vsync_len: Default::default(),
315             sync: FbSyncFlags::empty(),
316             vmode: FbVModeFlags::empty(),
317             rotate_angle: Default::default(),
318             colorspace: Default::default(),
319         }
320     }
321 }
322 
323 /// 帧缓冲区的颜色模式
324 ///
325 /// 默认为彩色
326 #[allow(dead_code)]
327 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
328 pub enum FbColorMode {
329     /// 灰度
330     GrayScale,
331     /// 彩色
332     Color,
333     /// FOURCC
334     FourCC,
335 }
336 
337 impl Default for FbColorMode {
338     fn default() -> Self {
339         FbColorMode::Color
340     }
341 }
342 
343 /// `FbBitfield` 结构体用于描述颜色字段的位域。
344 ///
345 /// 所有的偏移量都是从右边开始,位于一个精确为'bits_per_pixel'宽度的"像素"值内。
346 /// 一个像素之后是一个位流,并且未经修改地写入视频内存。
347 ///
348 /// 对于伪颜色:所有颜色组件的偏移和长度应该相同。
349 /// 偏移指定了调色板索引在像素值中的最低有效位的位置。
350 /// 长度表示可用的调色板条目的数量(即条目数 = 1 << 长度)。
351 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
352 pub struct FbBitfield {
353     /// 位域的起始位置
354     pub offset: u32,
355     /// 位域的长度
356     pub length: u32,
357     /// 最高有效位是否在右边
358     pub msb_right: bool,
359 }
360 
361 impl FbBitfield {
362     #[allow(dead_code)]
363     pub fn new(offset: u32, length: u32, msb_right: bool) -> Self {
364         Self {
365             offset,
366             length,
367             msb_right,
368         }
369     }
370 }
371 
372 impl Default for FbBitfield {
373     fn default() -> Self {
374         Self {
375             offset: Default::default(),
376             length: Default::default(),
377             msb_right: Default::default(),
378         }
379     }
380 }
381 
382 bitflags! {
383     /// `FbActivateFlags` 用于描述帧缓冲区的激活标志。
384     ///
385     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/fb.h#198
386     pub struct FbActivateFlags: u32 {
387         /// 立即设置值(或vbl)
388         const FB_ACTIVATE_NOW = 0;
389         /// 在下一次打开时激活
390         const FB_ACTIVATE_NXTOPEN = 1;
391         /// don't set, round up impossible values
392         const FB_ACTIVATE_TEST = 2;
393         const FB_ACTIVATE_MASK = 15;
394 
395         /// 在下一个vbl上激活值
396         const FB_ACTIVATE_VBL = 16;
397         /// 在vbl上更改色彩映射
398         const FB_ACTIVATE_CHANGE_CMAP_VBL = 32;
399         /// 更改此fb上的所有VC
400         const FB_ACTIVATE_ALL = 64;
401         /// 即使没有变化也强制应用
402         const FB_ACTIVATE_FORCE = 128;
403         /// 使视频模式无效
404         const FB_ACTIVATE_INV_MODE = 256;
405         /// 用于KDSET vt ioctl
406         const FB_ACTIVATE_KD_TEXT = 512;
407     }
408 }
409 
410 impl Default for FbActivateFlags {
411     fn default() -> Self {
412         FbActivateFlags::FB_ACTIVATE_NOW
413     }
414 }
415 
416 #[allow(dead_code)]
417 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
418 pub enum FbPixelFormat {
419     Standard,
420     /// Hold And Modify
421     HAM,
422     /// order of pixels in each byte is reversed
423     Reserved,
424 }
425 
426 impl Default for FbPixelFormat {
427     fn default() -> Self {
428         FbPixelFormat::Standard
429     }
430 }
431 
432 bitflags! {
433     pub struct FbSyncFlags: u32 {
434         /// 水平同步高电平有效
435         const FB_SYNC_HOR_HIGH_ACT = 1;
436         /// 垂直同步高电平有效
437         const FB_SYNC_VERT_HIGH_ACT = 2;
438         /// 外部同步
439         const FB_SYNC_EXT = 4;
440         /// 复合同步高电平有效
441         const FB_SYNC_COMP_HIGH_ACT = 8;
442         /// 广播视频时序
443         const FB_SYNC_BROADCAST = 16;
444         /// sync on green
445         const FB_SYNC_ON_GREEN = 32;
446     }
447 }
448 
449 bitflags! {
450     /// `FbVModeFlags` 用于描述帧缓冲区的视频模式。
451     pub struct FbVModeFlags: u32 {
452         /// 非交错
453         const FB_VMODE_NONINTERLACED = 0;
454         /// 交错
455         const FB_VMODE_INTERLACED = 1;
456         /// 双扫描
457         const FB_VMODE_DOUBLE = 2;
458         /// 交错:首先是顶行
459         const FB_VMODE_ODD_FLD_FIRST = 4;
460         /// 掩码
461         const FB_VMODE_MASK = 255;
462         /// ywrap代替平移
463         const FB_VMODE_YWRAP = 256;
464         /// 平滑xpan可能(内部使用)
465         const FB_VMODE_SMOOTH_XPAN = 512;
466         /// 不更新x/yoffset
467         const FB_VMODE_CONUPDATE = 512;
468     }
469 }
470 
471 /// 视频颜色空间
472 #[allow(dead_code)]
473 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
474 pub enum V4l2Colorspace {
475     /// 默认颜色空间,即让驱动程序自行判断。只能用于视频捕获。
476     Default = 0,
477     /// SMPTE 170M:用于广播NTSC/PAL SDTV
478     Smpte170m = 1,
479     /// 过时的1998年前的SMPTE 240M HDTV标准,已被Rec 709取代
480     Smpte240m = 2,
481     /// Rec.709:用于HDTV
482     Rec709 = 3,
483     /// 已弃用,不要使用。没有驱动程序会返回这个。这是基于对bt878数据表的误解。
484     Bt878 = 4,
485     /// NTSC 1953颜色空间。只有在处理非常非常旧的NTSC录音时才有意义。已被SMPTE 170M取代。
486     System470M = 5,
487     /// EBU Tech 3213 PAL/SECAM颜色空间。
488     System470Bg = 6,
489     /// 实际上是V4L2_COLORSPACE_SRGB,V4L2_YCBCR_ENC_601和V4L2_QUANTIZATION_FULL_RANGE的简写。用于(Motion-)JPEG。
490     Jpeg = 7,
491     /// 用于RGB颜色空间,如大多数网络摄像头所产生的。
492     Srgb = 8,
493     /// opRGB颜色空间
494     Oprgb = 9,
495     /// BT.2020颜色空间,用于UHDTV。
496     Bt2020 = 10,
497     /// Raw颜色空间:用于RAW未处理的图像
498     Raw = 11,
499     /// DCI-P3颜色空间,用于电影投影机
500     DciP3 = 12,
501 
502     /// Largest supported colorspace value, assigned by the compiler, used
503     /// by the framework to check for invalid values.
504     Last,
505 }
506 
507 impl Default for V4l2Colorspace {
508     fn default() -> Self {
509         V4l2Colorspace::Default
510     }
511 }
512 
513 /// `FixedScreenInfo` 结构体用于描述屏幕的固定属性。
514 #[allow(dead_code)]
515 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
516 pub struct FixedScreenInfo {
517     // 字符串,用于标识屏幕,例如 "TT Builtin"
518     pub id: [char; 16],
519     // 帧缓冲区的起始物理地址
520     pub smem_start: Option<PhysAddr>,
521     // 帧缓冲区的长度
522     pub smem_len: usize,
523     // 屏幕类型,参考 FB_TYPE_
524     pub fb_type: FbType,
525     // 用于表示交错平面的小端辅助类型
526     pub type_aux: u32,
527     // 视觉类型,参考 FB_VISUAL_
528     pub visual: FbVisual,
529     // 水平缩放步长,如果无硬件缩放,则为0
530     pub xpanstep: u16,
531     // 垂直缩放步长,如果无硬件缩放,则为0
532     pub ypanstep: u16,
533     // 垂直环绕步长,如果无硬件环绕,则为0
534     pub ywrapstep: u16,
535     // 一行的大小(以字节为单位)
536     pub line_length: u32,
537     // 内存映射I/O端口的起始物理地址
538     pub mmio_start: Option<PhysAddr>,
539     // 内存映射I/O的长度
540     pub mmio_len: usize,
541     // 表示驱动器拥有的特定芯片/卡片类型
542     pub accel: FbAccel,
543     // 表示支持的特性,参考 FB_CAP_
544     pub capabilities: FbCapability,
545 }
546 
547 impl FixedScreenInfo {
548     /// 将字符串转换为长度为16的字符数组(包含结尾的`\0`)
549     ///
550     /// ## 参数
551     ///
552     /// - `name`: 字符串,长度不超过15,超过的部分将被截断
553     ///
554     /// ## 返回
555     ///
556     /// 长度为16的字符数组
557     pub const fn name2id(name: &str) -> [char; 16] {
558         let mut id = [0 as char; 16];
559         let mut i = 0;
560 
561         while i < 15 && i < name.len() {
562             id[i] = name.as_bytes()[i] as char;
563             i += 1;
564         }
565 
566         id[i] = '\0';
567         return id;
568     }
569 }
570 
571 impl Default for FixedScreenInfo {
572     fn default() -> Self {
573         Self {
574             id: Default::default(),
575             smem_start: None,
576             smem_len: Default::default(),
577             fb_type: FbType::PackedPixels,
578             type_aux: Default::default(),
579             visual: FbVisual::Mono10,
580             xpanstep: Default::default(),
581             ypanstep: Default::default(),
582             ywrapstep: Default::default(),
583             line_length: Default::default(),
584             mmio_start: None,
585             mmio_len: Default::default(),
586             accel: Default::default(),
587             capabilities: Default::default(),
588         }
589     }
590 }
591 
592 /// 帧缓冲类型
593 #[allow(dead_code)]
594 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
595 pub enum FbType {
596     /// 压缩像素
597     PackedPixels = 0,
598     /// 非交错平面
599     Planes = 1,
600     /// 交错平面
601     InterleavedPlanes = 2,
602     /// 文本/属性
603     Text = 3,
604     /// EGA/VGA平面
605     VgaPlanes = 4,
606     /// 由V4L2 FOURCC标识的类型
607     FourCC = 5,
608 }
609 
610 /// 帧缓冲视觉类型
611 #[allow(dead_code)]
612 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
613 pub enum FbVisual {
614     /// 单色。1=黑色 0=白色
615     Mono01 = 0,
616     /// 单色。1=白色 0=黑色
617     Mono10 = 1,
618     /// 真彩色
619     TrueColor = 2,
620     /// 伪彩色(如Atari)
621     PseudoColor = 3,
622     /// 直接颜色
623     DirectColor = 4,
624     /// 只读的伪彩色
625     StaticPseudoColor = 5,
626     /// 由FOURCC标识的类型
627     FourCC,
628 }
629 
630 #[allow(dead_code)]
631 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
632 pub enum FbCapability {
633     Default = 0,
634     /// 设备支持基于FOURCC的格式。
635     FourCC,
636 }
637 
638 impl Default for FbCapability {
639     fn default() -> Self {
640         FbCapability::Default
641     }
642 }
643 
644 /// 视频模式
645 #[allow(dead_code)]
646 #[derive(Debug, Clone, Eq, PartialEq)]
647 pub struct FbVideoMode {
648     /// 可选的名称
649     pub name: Option<String>,
650     /// 可选的刷新率
651     pub refresh: Option<u32>,
652     /// 水平分辨率
653     pub xres: u32,
654     /// 垂直分辨率
655     pub yres: u32,
656     /// 像素时钟
657     pub pixclock: u32,
658     /// 左边距
659     pub left_margin: u32,
660     /// 右边距
661     pub right_margin: u32,
662     /// 上边距
663     pub upper_margin: u32,
664     /// 下边距
665     pub lower_margin: u32,
666     /// 水平同步长度
667     pub hsync_len: u32,
668     /// 垂直同步长度
669     pub vsync_len: u32,
670     /// 同步
671     pub sync: FbSyncFlags,
672     /// 视频模式
673     pub vmode: FbVModeFlags,
674     /// 标志
675     pub flag: u32,
676 }
677 
678 #[allow(dead_code)]
679 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
680 pub enum FbAccel {
681     /// 没有硬件加速器
682     None,
683 
684     AtariBlitter = 1,
685     AmigaBlitter = 2,
686     S3Trio64 = 3,
687     NCR77C32BLT = 4,
688     S3Virge = 5,
689     AtiMach64GX = 6,
690     DECTGA = 7,
691     AtiMach64CT = 8,
692     AtiMach64VT = 9,
693     AtiMach64GT = 10,
694     SunCreator = 11,
695     SunCGSix = 12,
696     SunLeo = 13,
697     IMSTwinTurbo = 14,
698     Acc3DLabsPermedia2 = 15,
699     MatroxMGA2064W = 16,
700     MatroxMGA1064SG = 17,
701     MatroxMGA2164W = 18,
702     MatroxMGA2164WAGP = 19,
703     MatroxMGAG400 = 20,
704     NV3 = 21,
705     NV4 = 22,
706     NV5 = 23,
707     NV6 = 24,
708     XGIVolariV = 25,
709     XGIVolariZ = 26,
710     Omap1610 = 27,
711     TridentTGUI = 28,
712     Trident3DImage = 29,
713     TridentBlade3D = 30,
714     TridentBladeXP = 31,
715     CirrusAlpine = 32,
716     NeoMagicNM2070 = 90,
717     NeoMagicNM2090 = 91,
718     NeoMagicNM2093 = 92,
719     NeoMagicNM2097 = 93,
720     NeoMagicNM2160 = 94,
721     NeoMagicNM2200 = 95,
722     NeoMagicNM2230 = 96,
723     NeoMagicNM2360 = 97,
724     NeoMagicNM2380 = 98,
725     PXA3XX = 99,
726 
727     Savage4 = 0x80,
728     Savage3D = 0x81,
729     Savage3DMV = 0x82,
730     Savage2000 = 0x83,
731     SavageMXMV = 0x84,
732     SavageMX = 0x85,
733     SavageIXMV = 0x86,
734     SavageIX = 0x87,
735     ProSavagePM = 0x88,
736     ProSavageKM = 0x89,
737     S3Twister = 0x8a,
738     S3TwisterK = 0x8b,
739     SuperSavage = 0x8c,
740     ProSavageDDR = 0x8d,
741     ProSavageDDRK = 0x8e,
742     // Add other accelerators here
743 }
744 
745 impl Default for FbAccel {
746     fn default() -> Self {
747         FbAccel::None
748     }
749 }
750 
751 #[derive(Debug, Copy, Clone)]
752 pub struct BootTimeScreenInfo {
753     pub origin_x: u8,
754     pub origin_y: u8,
755     /// text mode时,每行的字符数
756     pub origin_video_cols: u8,
757     /// text mode时,行数
758     pub origin_video_lines: u8,
759     /// 标记屏幕是否为VGA类型
760     pub is_vga: bool,
761     /// video mode type
762     pub video_type: BootTimeVideoType,
763 
764     // 以下字段用于线性帧缓冲区
765     /// 线性帧缓冲区的起始物理地址
766     pub lfb_base: PhysAddr,
767     /// 线性帧缓冲区在初始化阶段被映射到的起始虚拟地址
768     ///
769     /// 这个值可能会被设置2次:
770     ///
771     /// - 内存管理初始化之前,early init阶段,临时映射
772     /// - 内存管理初始化完毕,重新映射时被设置
773     pub lfb_virt_base: Option<VirtAddr>,
774     /// 线性帧缓冲区的长度
775     pub lfb_size: usize,
776     /// 线性帧缓冲区的宽度(像素)
777     pub lfb_width: u32,
778     /// 线性帧缓冲区的高度(像素)
779     pub lfb_height: u32,
780     /// 线性帧缓冲区的深度(位数)
781     pub lfb_depth: u8,
782     /// 红色位域的大小
783     pub red_size: u8,
784     /// 红色位域的偏移量(左移位数)
785     pub red_pos: u8,
786     /// 绿色位域的大小
787     pub green_size: u8,
788     /// 绿色位域的偏移量(左移位数)
789     pub green_pos: u8,
790     /// 蓝色位域的大小
791     pub blue_size: u8,
792     /// 蓝色位域的偏移量(左移位数)
793     pub blue_pos: u8,
794 }
795 
796 impl BootTimeScreenInfo {
797     pub const DEFAULT: Self = Self {
798         origin_x: 0,
799         origin_y: 0,
800         is_vga: false,
801         lfb_base: PhysAddr::new(0),
802         lfb_size: 0,
803         lfb_width: 0,
804         lfb_height: 0,
805         red_size: 0,
806         red_pos: 0,
807         green_size: 0,
808         green_pos: 0,
809         blue_size: 0,
810         blue_pos: 0,
811         video_type: BootTimeVideoType::UnDefined,
812         origin_video_cols: 0,
813         origin_video_lines: 0,
814         lfb_virt_base: None,
815         lfb_depth: 0,
816     };
817 }
818 
819 /// Video types for different display hardware
820 #[allow(dead_code)]
821 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
822 pub enum BootTimeVideoType {
823     UnDefined,
824     /// Monochrome Text Display
825     Mda,
826     /// CGA Display
827     Cga,
828     /// EGA/VGA in Monochrome Mode
829     EgaM,
830     /// EGA in Color Mode
831     EgaC,
832     /// VGA+ in Color Mode
833     VgaC,
834     /// VESA VGA in graphic mode
835     Vlfb,
836     /// ACER PICA-61 local S3 video
837     PicaS3,
838     /// MIPS Magnum 4000 G364 video
839     MipsG364,
840     /// Various SGI graphics hardware
841     Sgi,
842     /// DEC TGA
843     TgaC,
844     /// Sun frame buffer
845     Sun,
846     /// Sun PCI based frame buffer
847     SunPci,
848     /// PowerMacintosh frame buffer
849     Pmac,
850     /// EFI graphic mode
851     Efi,
852 }
853