xref: /DragonOS/kernel/src/driver/firmware/efi/memmap.rs (revision 9284987850c1da2ce607a539eeae8a353a8f6df9)
1*92849878SLoGin use core::{intrinsics::unlikely, mem::size_of};
2*92849878SLoGin 
37a29d4fcSLoGin use system_error::SystemError;
47a29d4fcSLoGin 
57a29d4fcSLoGin use crate::{
67a29d4fcSLoGin     driver::firmware::efi::EFIInitFlags,
77a29d4fcSLoGin     libs::align::page_align_down,
87a29d4fcSLoGin     mm::{early_ioremap::EarlyIoRemap, PhysAddr, VirtAddr},
97a29d4fcSLoGin };
107a29d4fcSLoGin 
11*92849878SLoGin use super::{fdt::EFIFdtParams, tables::MemoryDescriptor, EFIManager};
127a29d4fcSLoGin 
137a29d4fcSLoGin #[derive(Debug)]
147a29d4fcSLoGin pub struct EFIMemoryMapInfo {
157a29d4fcSLoGin     /// EFI Memory Map的物理地址
167a29d4fcSLoGin     pub(super) paddr: Option<PhysAddr>,
177a29d4fcSLoGin     /// EFI Memory Map的虚拟地址
187a29d4fcSLoGin     pub(super) vaddr: Option<VirtAddr>,
197a29d4fcSLoGin     /// EFI Memory Map的大小
207a29d4fcSLoGin     pub(super) size: usize,
217a29d4fcSLoGin     /// 映射的描述信息的数量
227a29d4fcSLoGin     pub(super) nr_map: usize,
237a29d4fcSLoGin     /// EFI Memory Map的描述信息的大小
247a29d4fcSLoGin     pub(super) desc_size: usize,
257a29d4fcSLoGin     /// EFI Memory Map的描述信息的版本
267a29d4fcSLoGin     pub(super) desc_version: usize,
27*92849878SLoGin     /// 当前是否在内存管理已经完成初始化后,对该结构体进行操作
28*92849878SLoGin     ///
29*92849878SLoGin     /// true: 内存管理已经完成初始化
30*92849878SLoGin     /// false: 内存管理还未完成初始化
31*92849878SLoGin     pub(super) late: bool,
327a29d4fcSLoGin }
337a29d4fcSLoGin 
347a29d4fcSLoGin impl EFIMemoryMapInfo {
357a29d4fcSLoGin     pub const DEFAULT: Self = EFIMemoryMapInfo {
367a29d4fcSLoGin         paddr: None,
377a29d4fcSLoGin         vaddr: None,
387a29d4fcSLoGin         size: 0,
397a29d4fcSLoGin         nr_map: 0,
407a29d4fcSLoGin         desc_size: 0,
417a29d4fcSLoGin         desc_version: 0,
42*92849878SLoGin         late: false,
437a29d4fcSLoGin     };
447a29d4fcSLoGin 
457a29d4fcSLoGin     /// 获取EFI Memory Map的虚拟的结束地址
467a29d4fcSLoGin     #[allow(dead_code)]
477a29d4fcSLoGin     pub fn map_end_vaddr(&self) -> Option<VirtAddr> {
487a29d4fcSLoGin         return self.vaddr.map(|v| v + self.size);
497a29d4fcSLoGin     }
50*92849878SLoGin 
51*92849878SLoGin     /// 迭代所有的内存描述符
52*92849878SLoGin     pub fn iter(&self) -> EFIMemoryDescIter {
53*92849878SLoGin         EFIMemoryDescIter::new(self)
54*92849878SLoGin     }
55*92849878SLoGin }
56*92849878SLoGin 
57*92849878SLoGin /// UEFI 内存描述符的迭代器
58*92849878SLoGin pub struct EFIMemoryDescIter<'a> {
59*92849878SLoGin     inner: &'a EFIMemoryMapInfo,
60*92849878SLoGin     offset: usize,
61*92849878SLoGin }
62*92849878SLoGin 
63*92849878SLoGin impl<'a> EFIMemoryDescIter<'a> {
64*92849878SLoGin     fn new(inner: &'a EFIMemoryMapInfo) -> Self {
65*92849878SLoGin         Self { inner, offset: 0 }
66*92849878SLoGin     }
67*92849878SLoGin }
68*92849878SLoGin 
69*92849878SLoGin impl<'a> Iterator for EFIMemoryDescIter<'a> {
70*92849878SLoGin     type Item = MemoryDescriptor;
71*92849878SLoGin 
72*92849878SLoGin     fn next(&mut self) -> Option<Self::Item> {
73*92849878SLoGin         if self.offset + size_of::<Self::Item>() > self.inner.size {
74*92849878SLoGin             return None;
75*92849878SLoGin         }
76*92849878SLoGin 
77*92849878SLoGin         // 如果是空指针,返回None
78*92849878SLoGin         if unlikely(self.inner.vaddr.unwrap_or(VirtAddr::new(0)).is_null()) {
79*92849878SLoGin             return None;
80*92849878SLoGin         }
81*92849878SLoGin 
82*92849878SLoGin         let vaddr = self.inner.vaddr? + self.offset;
83*92849878SLoGin         self.offset += size_of::<Self::Item>();
84*92849878SLoGin         let res = unsafe { *(vaddr.data() as *const Self::Item) };
85*92849878SLoGin         return Some(res);
86*92849878SLoGin     }
877a29d4fcSLoGin }
887a29d4fcSLoGin 
897a29d4fcSLoGin impl EFIManager {
907a29d4fcSLoGin     /// Map the EFI memory map data structure
917a29d4fcSLoGin     ///
927a29d4fcSLoGin     /// 进入当前函数前,不应持有efi_manager.inner的锁
937a29d4fcSLoGin     #[inline(never)]
947a29d4fcSLoGin     pub(super) fn memmap_init_early(&self, data: &EFIFdtParams) -> Result<(), SystemError> {
957a29d4fcSLoGin         return self.do_efi_memmap_init(data, true);
967a29d4fcSLoGin     }
977a29d4fcSLoGin 
987a29d4fcSLoGin     /// 映射 EFI memory map
997a29d4fcSLoGin     ///
1007a29d4fcSLoGin     /// 该函数在内核启动过程中使用
1017a29d4fcSLoGin     ///
1027a29d4fcSLoGin     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/firmware/efi/memmap.c?fi=efi_memmap_init_early#104
1037a29d4fcSLoGin     #[inline(never)]
1047a29d4fcSLoGin     fn do_efi_memmap_init(&self, data: &EFIFdtParams, early: bool) -> Result<(), SystemError> {
1057a29d4fcSLoGin         let paddr = data.mmap_base.expect("mmap_base is not set");
1067a29d4fcSLoGin         let paddr = PhysAddr::new(paddr as usize);
107*92849878SLoGin 
1087a29d4fcSLoGin         let mut inner_guard = self.inner.write();
1097a29d4fcSLoGin         if early {
1107a29d4fcSLoGin             let offset = paddr.data() - page_align_down(paddr.data());
1117a29d4fcSLoGin             let map_size = data.mmap_size.unwrap() as usize + offset;
1127a29d4fcSLoGin 
113*92849878SLoGin             // kdebug!("do_efi_memmap_init: map_size={map_size:#x}");
114*92849878SLoGin 
1157a29d4fcSLoGin             // 映射内存
1167a29d4fcSLoGin             let mut vaddr = EarlyIoRemap::map(
1177a29d4fcSLoGin                 PhysAddr::new(page_align_down(paddr.data())),
1187a29d4fcSLoGin                 map_size,
1197a29d4fcSLoGin                 false,
1207a29d4fcSLoGin             )
1217a29d4fcSLoGin             .map(|(vaddr, _)| vaddr)?;
1227a29d4fcSLoGin 
1237a29d4fcSLoGin             vaddr += offset;
1247a29d4fcSLoGin 
1257a29d4fcSLoGin             inner_guard.mmap.vaddr = Some(vaddr);
126*92849878SLoGin             inner_guard.mmap.late = false;
1277a29d4fcSLoGin         } else {
128*92849878SLoGin             inner_guard.mmap.late = true;
1297a29d4fcSLoGin             unimplemented!("efi_memmap_init_late")
1307a29d4fcSLoGin         }
1317a29d4fcSLoGin 
1327a29d4fcSLoGin         if inner_guard.mmap.vaddr.is_none() {
1337a29d4fcSLoGin             kerror!("Cannot map the EFI memory map!");
1347a29d4fcSLoGin             return Err(SystemError::ENOMEM);
1357a29d4fcSLoGin         }
1367a29d4fcSLoGin 
1377a29d4fcSLoGin         inner_guard.mmap.paddr = Some(paddr);
1387a29d4fcSLoGin         inner_guard.mmap.size = data.mmap_size.unwrap() as usize;
1397a29d4fcSLoGin         inner_guard.mmap.nr_map =
1407a29d4fcSLoGin             data.mmap_size.unwrap() as usize / data.mmap_desc_size.unwrap() as usize;
1417a29d4fcSLoGin         inner_guard.mmap.desc_size = data.mmap_desc_size.unwrap() as usize;
1427a29d4fcSLoGin         inner_guard.mmap.desc_version = data.mmap_desc_version.unwrap() as usize;
1437a29d4fcSLoGin 
1447a29d4fcSLoGin         inner_guard.init_flags.set(EFIInitFlags::MEMMAP, true);
1457a29d4fcSLoGin 
1467a29d4fcSLoGin         return Ok(());
1477a29d4fcSLoGin     }
148*92849878SLoGin 
149*92849878SLoGin     /// 清除EFI Memory Table在内存中的映射
150*92849878SLoGin     pub fn efi_memmap_unmap(&self) {
151*92849878SLoGin         let mut inner_guard = self.inner.write_irqsave();
152*92849878SLoGin 
153*92849878SLoGin         // 没有启用memmap
154*92849878SLoGin         if !inner_guard.init_flags.contains(EFIInitFlags::MEMMAP) {
155*92849878SLoGin             return;
156*92849878SLoGin         }
157*92849878SLoGin 
158*92849878SLoGin         if !inner_guard.mmap.late {
159*92849878SLoGin             EarlyIoRemap::unmap(inner_guard.mmap.vaddr.take().unwrap()).unwrap();
160*92849878SLoGin         } else {
161*92849878SLoGin             unimplemented!("efi_memmap_unmap");
162*92849878SLoGin         }
163*92849878SLoGin         inner_guard.init_flags.set(EFIInitFlags::MEMMAP, false);
164*92849878SLoGin     }
1657a29d4fcSLoGin }
166