xref: /DragonOS/kernel/src/driver/firmware/efi/mod.rs (revision 0102d69fdd231e472d7bb3d609a41ae56a3799ee)
1 use system_error::SystemError;
2 
3 use crate::{
4     libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
5     mm::PhysAddr,
6 };
7 
8 use self::{guid::DragonStubPayloadEFI, memmap::EFIMemoryMapInfo};
9 
10 pub mod esrt;
11 mod fdt;
12 pub mod guid;
13 pub mod init;
14 pub mod memmap;
15 pub mod tables;
16 
17 static EFI_MANAGER: EFIManager = EFIManager::new();
18 
19 /// EFI管理器
20 ///
21 /// 数据成员可参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/efi.h#620
22 #[derive(Debug)]
23 pub struct EFIManager {
24     inner: RwLock<InnerEFIManager>,
25 }
26 
27 #[inline(always)]
28 pub fn efi_manager() -> &'static EFIManager {
29     &EFI_MANAGER
30 }
31 
32 #[derive(Debug)]
33 struct InnerEFIManager {
34     pub mmap: EFIMemoryMapInfo,
35     /// EFI模块启动时状态的标识
36     pub init_flags: EFIInitFlags,
37     /// runtime services的物理地址
38     pub runtime_paddr: Option<PhysAddr>,
39     /// runtime services的版本号
40     pub runtime_service_version: Option<uefi_raw::table::Revision>,
41     pub dragonstub_load_info: Option<DragonStubPayloadEFI>,
42     /// uefi 内存属性表的物理地址
43     pub memory_attribute_table_paddr: Option<PhysAddr>,
44     /// uefi 内存保留表的物理地址
45     pub memreserve_table_paddr: Option<PhysAddr>,
46     /// uefi esrt表的物理地址
47     pub esrt_table_paddr: Option<PhysAddr>,
48 }
49 
50 impl EFIManager {
51     const fn new() -> Self {
52         EFIManager {
53             inner: RwLock::new(InnerEFIManager {
54                 mmap: EFIMemoryMapInfo::DEFAULT,
55                 init_flags: EFIInitFlags::empty(),
56                 runtime_paddr: None,
57                 runtime_service_version: None,
58                 dragonstub_load_info: None,
59                 memory_attribute_table_paddr: None,
60                 memreserve_table_paddr: None,
61                 esrt_table_paddr: None,
62             }),
63         }
64     }
65 
66     pub fn desc_version(&self) -> usize {
67         return self.inner.read().mmap.desc_version;
68     }
69 
70     /// 内核加载的地址、大小的信息
71     #[allow(dead_code)]
72     pub fn kernel_load_info(&self) -> Option<DragonStubPayloadEFI> {
73         return self.inner.read().dragonstub_load_info;
74     }
75 
76     /// 检查是否为有效的system table表头
77     ///
78     /// ## 参数
79     ///
80     /// - header: system table表头
81     /// - min_major: 最小的major版本号。如果不满足,则会输出Warning,并返回Ok
82     ///
83     /// ## 返回
84     ///
85     /// - Ok(()): 检查通过
86     /// - Err(SystemError::EINVAL): header无效
87     pub fn check_system_table_header(
88         &self,
89         header: &uefi_raw::table::Header,
90         min_major: u16,
91     ) -> Result<(), SystemError> {
92         if header.signature != uefi_raw::table::system::SystemTable::SIGNATURE {
93             kerror!("System table signature mismatch!");
94             return Err(SystemError::EINVAL);
95         }
96 
97         if header.revision.major() < min_major {
98             kwarn!(
99                 "System table version: {:?}, expected {}.00 or greater!",
100                 header.revision,
101                 min_major
102             );
103         }
104 
105         return Ok(());
106     }
107 
108     fn inner_read(&self) -> RwLockReadGuard<InnerEFIManager> {
109         self.inner.read()
110     }
111 
112     fn inner_write(&self) -> RwLockWriteGuard<InnerEFIManager> {
113         self.inner.write()
114     }
115 
116     /// 是否存在ESRT表
117     fn esrt_table_exists(&self) -> bool {
118         self.inner_read().esrt_table_paddr.is_some()
119     }
120 }
121 
122 // 在Rust中,我们使用枚举和bitflags来表示这些宏
123 bitflags! {
124     pub struct EFIInitFlags: u32 {
125         /// 当前使用EFI启动
126         const BOOT = 1 << 0;
127         /// 是否可以使用EFI配置表
128         const CONFIG_TABLES = 1 << 1;
129         /// 是否可以使用运行时服务
130         const RUNTIME_SERVICES = 1 << 2;
131         /// 是否可以使用EFI内存映射
132         const MEMMAP = 1 << 3;
133         /// 固件是否为64位
134         const EFI_64BIT = 1 << 4;
135         /// 访问是否通过虚拟化接口
136         const PARAVIRT = 1 << 5;
137         /// 第一架构特定位
138         const ARCH_1 = 1 << 6;
139         /// 打印附加运行时调试信息
140         const DBG = 1 << 7;
141         /// 是否可以在运行时数据区域映射非可执行
142         const NX_PE_DATA = 1 << 8;
143         /// 固件是否发布了一个EFI_MEMORY_ATTRIBUTES表
144         const MEM_ATTR = 1 << 9;
145         /// 内核是否配置为忽略软保留
146         const MEM_NO_SOFT_RESERVE = 1 << 10;
147         /// 是否可以使用EFI引导服务内存段
148         const PRESERVE_BS_REGIONS = 1 << 11;
149 
150     }
151 }
152