1 use core::{intrinsics::unlikely, mem::size_of}; 2 3 use system_error::SystemError; 4 5 use crate::{ 6 driver::firmware::efi::EFIInitFlags, 7 libs::align::page_align_down, 8 mm::{early_ioremap::EarlyIoRemap, PhysAddr, VirtAddr}, 9 }; 10 11 use super::efi_manager; 12 13 #[allow(dead_code)] 14 #[inline(never)] 15 pub fn efi_init() { 16 let data_from_fdt = efi_manager() 17 .get_fdt_params() 18 .expect("Failed to get fdt params"); 19 20 if data_from_fdt.systable.is_none() { 21 kerror!("Failed to get systable from fdt"); 22 return; 23 } 24 25 kdebug!("to map memory table"); 26 27 // 映射mmap table 28 if efi_manager().memmap_init_early(&data_from_fdt).is_err() { 29 // 如果我们通过UEFI进行引导, 30 // 那么 UEFI memory map 就是我们拥有的关于内存的唯一描述, 31 // 所以如果我们无法访问它,那么继续进行下去就没有什么意义了 32 33 kerror!("Failed to initialize early memory map"); 34 loop {} 35 } 36 // kdebug!("NNNN"); 37 // kwarn!("BBBB, e:{:?}", SystemError::EINVAL); 38 39 let desc_version = efi_manager().desc_version(); 40 41 if unlikely(desc_version != 1) { 42 kwarn!("Unexpected EFI memory map version: {}", desc_version); 43 } 44 45 // todo: 映射table,初始化runtime services 46 47 let r = uefi_init(PhysAddr::new(data_from_fdt.systable.unwrap() as usize)); 48 49 if let Err(r) = r { 50 kerror!("Failed to initialize UEFI: {:?}", r); 51 } 52 53 loop {} 54 } 55 56 #[inline(never)] 57 fn uefi_init(system_table: PhysAddr) -> Result<(), SystemError> { 58 // 定义错误处理函数 59 60 // 错误处理:取消systable的映射 61 let err_unmap_systable = |st_vaddr: VirtAddr| { 62 EarlyIoRemap::unmap(st_vaddr) 63 .map_err(|e| { 64 kerror!("Failed to unmap system table: {e:?}"); 65 }) 66 .ok(); 67 }; 68 69 // 映射system table 70 71 let st_size = size_of::<uefi_raw::table::system::SystemTable>(); 72 kdebug!("system table: {system_table:?}, size: {st_size}"); 73 let st_map_phy_base = PhysAddr::new(page_align_down(system_table.data())); 74 75 let st_map_offset = system_table.data() - st_map_phy_base.data(); 76 let st_map_size = st_size + st_map_offset; 77 let (st_vaddr, _st_map_size) = 78 EarlyIoRemap::map(st_map_phy_base, st_map_size, true).map_err(|e| { 79 kwarn!("Unable to map EFI system table, e:{e:?}"); 80 e 81 })?; 82 83 let st_vaddr = st_vaddr + st_map_offset; 84 85 efi_manager() 86 .inner 87 .write() 88 .init_flags 89 .set(EFIInitFlags::BOOT, true); 90 91 efi_manager() 92 .inner 93 .write() 94 .init_flags 95 .set(EFIInitFlags::EFI_64BIT, true); 96 97 kdebug!("to parse EFI system table: p: {st_vaddr:?}"); 98 99 if st_vaddr.is_null() { 100 return Err(SystemError::EINVAL); 101 } 102 103 // 解析system table 104 let st_ptr = st_vaddr.data() as *const uefi_raw::table::system::SystemTable; 105 efi_manager() 106 .check_system_table_header(unsafe { &st_ptr.as_ref().unwrap().header }, 2) 107 .map_err(|e| { 108 err_unmap_systable(st_vaddr); 109 e 110 })?; 111 112 kdebug!("parse ok!"); 113 let mut inner_write_guard = efi_manager().inner.write(); 114 let st_ref = unsafe { st_ptr.as_ref().unwrap() }; 115 inner_write_guard.runtime_paddr = Some(PhysAddr::new(st_ref.runtime_services as usize)); 116 inner_write_guard.runtime_service_version = Some(st_ref.header.revision); 117 118 kdebug!( 119 "runtime service paddr: {:?}", 120 inner_write_guard.runtime_paddr.unwrap() 121 ); 122 kdebug!( 123 "runtime service version: {}", 124 inner_write_guard.runtime_service_version.unwrap() 125 ); 126 127 unimplemented!("report header"); 128 // return Ok(()); 129 } 130