1 use log::{error, warn}; 2 use system_error::SystemError; 3 4 use crate::{ 5 libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, 6 mm::PhysAddr, 7 }; 8 9 use self::{guid::DragonStubPayloadEFI, memmap::EFIMemoryMapInfo}; 10 11 pub mod esrt; 12 mod fdt; 13 pub mod guid; 14 pub mod init; 15 pub mod memmap; 16 pub mod tables; 17 18 static EFI_MANAGER: EFIManager = EFIManager::new(); 19 20 /// EFI管理器 21 /// 22 /// 数据成员可参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/efi.h#620 23 #[derive(Debug)] 24 pub struct EFIManager { 25 inner: RwLock<InnerEFIManager>, 26 } 27 28 #[inline(always)] 29 pub fn efi_manager() -> &'static EFIManager { 30 &EFI_MANAGER 31 } 32 33 #[derive(Debug)] 34 struct InnerEFIManager { 35 pub mmap: EFIMemoryMapInfo, 36 /// EFI模块启动时状态的标识 37 pub init_flags: EFIInitFlags, 38 /// runtime services的物理地址 39 pub runtime_paddr: Option<PhysAddr>, 40 /// runtime services的版本号 41 pub runtime_service_version: Option<uefi_raw::table::Revision>, 42 pub dragonstub_load_info: Option<DragonStubPayloadEFI>, 43 /// uefi 内存属性表的物理地址 44 pub memory_attribute_table_paddr: Option<PhysAddr>, 45 /// uefi 内存保留表的物理地址 46 pub memreserve_table_paddr: Option<PhysAddr>, 47 /// uefi esrt表的物理地址 48 pub esrt_table_paddr: Option<PhysAddr>, 49 } 50 51 impl EFIManager { 52 const fn new() -> Self { 53 EFIManager { 54 inner: RwLock::new(InnerEFIManager { 55 mmap: EFIMemoryMapInfo::DEFAULT, 56 init_flags: EFIInitFlags::empty(), 57 runtime_paddr: None, 58 runtime_service_version: None, 59 dragonstub_load_info: None, 60 memory_attribute_table_paddr: None, 61 memreserve_table_paddr: None, 62 esrt_table_paddr: None, 63 }), 64 } 65 } 66 67 pub fn desc_version(&self) -> usize { 68 return self.inner.read().mmap.desc_version; 69 } 70 71 /// 内核加载的地址、大小的信息 72 #[allow(dead_code)] 73 pub fn kernel_load_info(&self) -> Option<DragonStubPayloadEFI> { 74 return self.inner.read().dragonstub_load_info; 75 } 76 77 /// 检查是否为有效的system table表头 78 /// 79 /// ## 参数 80 /// 81 /// - header: system table表头 82 /// - min_major: 最小的major版本号。如果不满足,则会输出Warning,并返回Ok 83 /// 84 /// ## 返回 85 /// 86 /// - Ok(()): 检查通过 87 /// - Err(SystemError::EINVAL): header无效 88 pub fn check_system_table_header( 89 &self, 90 header: &uefi_raw::table::Header, 91 min_major: u16, 92 ) -> Result<(), SystemError> { 93 if header.signature != uefi_raw::table::system::SystemTable::SIGNATURE { 94 error!("System table signature mismatch!"); 95 return Err(SystemError::EINVAL); 96 } 97 98 if header.revision.major() < min_major { 99 warn!( 100 "System table version: {:?}, expected {}.00 or greater!", 101 header.revision, 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