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