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