xref: /DragonOS/kernel/src/driver/firmware/efi/init.rs (revision 7a29d4fcbcd89a226289c7bf541c2c78623de3ad)
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