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