xref: /DragonOS/kernel/src/driver/firmware/efi/memmap.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
192849878SLoGin use core::{intrinsics::unlikely, mem::size_of};
292849878SLoGin 
3*2eab6dd7S曾俊 use log::error;
47a29d4fcSLoGin use system_error::SystemError;
57a29d4fcSLoGin 
67a29d4fcSLoGin use crate::{
77a29d4fcSLoGin     driver::firmware::efi::EFIInitFlags,
87a29d4fcSLoGin     libs::align::page_align_down,
97a29d4fcSLoGin     mm::{early_ioremap::EarlyIoRemap, PhysAddr, VirtAddr},
107a29d4fcSLoGin };
117a29d4fcSLoGin 
1292849878SLoGin use super::{fdt::EFIFdtParams, tables::MemoryDescriptor, EFIManager};
137a29d4fcSLoGin 
147a29d4fcSLoGin #[derive(Debug)]
157a29d4fcSLoGin pub struct EFIMemoryMapInfo {
167a29d4fcSLoGin     /// EFI Memory Map的物理地址
177a29d4fcSLoGin     pub(super) paddr: Option<PhysAddr>,
187a29d4fcSLoGin     /// EFI Memory Map的虚拟地址
197a29d4fcSLoGin     pub(super) vaddr: Option<VirtAddr>,
207a29d4fcSLoGin     /// EFI Memory Map的大小
217a29d4fcSLoGin     pub(super) size: usize,
227a29d4fcSLoGin     /// 映射的描述信息的数量
237a29d4fcSLoGin     pub(super) nr_map: usize,
247a29d4fcSLoGin     /// EFI Memory Map的描述信息的大小
257a29d4fcSLoGin     pub(super) desc_size: usize,
267a29d4fcSLoGin     /// EFI Memory Map的描述信息的版本
277a29d4fcSLoGin     pub(super) desc_version: usize,
2892849878SLoGin     /// 当前是否在内存管理已经完成初始化后,对该结构体进行操作
2992849878SLoGin     ///
3092849878SLoGin     /// true: 内存管理已经完成初始化
3192849878SLoGin     /// false: 内存管理还未完成初始化
3292849878SLoGin     pub(super) late: bool,
337a29d4fcSLoGin }
347a29d4fcSLoGin 
357a29d4fcSLoGin impl EFIMemoryMapInfo {
367a29d4fcSLoGin     pub const DEFAULT: Self = EFIMemoryMapInfo {
377a29d4fcSLoGin         paddr: None,
387a29d4fcSLoGin         vaddr: None,
397a29d4fcSLoGin         size: 0,
407a29d4fcSLoGin         nr_map: 0,
417a29d4fcSLoGin         desc_size: 0,
427a29d4fcSLoGin         desc_version: 0,
4392849878SLoGin         late: false,
447a29d4fcSLoGin     };
457a29d4fcSLoGin 
467a29d4fcSLoGin     /// 获取EFI Memory Map的虚拟的结束地址
477a29d4fcSLoGin     #[allow(dead_code)]
map_end_vaddr(&self) -> Option<VirtAddr>487a29d4fcSLoGin     pub fn map_end_vaddr(&self) -> Option<VirtAddr> {
497a29d4fcSLoGin         return self.vaddr.map(|v| v + self.size);
507a29d4fcSLoGin     }
5192849878SLoGin 
5292849878SLoGin     /// 迭代所有的内存描述符
iter(&self) -> EFIMemoryDescIter5392849878SLoGin     pub fn iter(&self) -> EFIMemoryDescIter {
5492849878SLoGin         EFIMemoryDescIter::new(self)
5592849878SLoGin     }
5692849878SLoGin }
5792849878SLoGin 
5892849878SLoGin /// UEFI 内存描述符的迭代器
5992849878SLoGin pub struct EFIMemoryDescIter<'a> {
6092849878SLoGin     inner: &'a EFIMemoryMapInfo,
6192849878SLoGin     offset: usize,
6292849878SLoGin }
6392849878SLoGin 
6492849878SLoGin impl<'a> EFIMemoryDescIter<'a> {
new(inner: &'a EFIMemoryMapInfo) -> Self6592849878SLoGin     fn new(inner: &'a EFIMemoryMapInfo) -> Self {
6692849878SLoGin         Self { inner, offset: 0 }
6792849878SLoGin     }
6892849878SLoGin }
6992849878SLoGin 
7092849878SLoGin impl<'a> Iterator for EFIMemoryDescIter<'a> {
7192849878SLoGin     type Item = MemoryDescriptor;
7292849878SLoGin 
next(&mut self) -> Option<Self::Item>7392849878SLoGin     fn next(&mut self) -> Option<Self::Item> {
7492849878SLoGin         if self.offset + size_of::<Self::Item>() > self.inner.size {
7592849878SLoGin             return None;
7692849878SLoGin         }
7792849878SLoGin 
7892849878SLoGin         // 如果是空指针,返回None
7992849878SLoGin         if unlikely(self.inner.vaddr.unwrap_or(VirtAddr::new(0)).is_null()) {
8092849878SLoGin             return None;
8192849878SLoGin         }
8292849878SLoGin 
8392849878SLoGin         let vaddr = self.inner.vaddr? + self.offset;
8492849878SLoGin         self.offset += size_of::<Self::Item>();
8592849878SLoGin         let res = unsafe { *(vaddr.data() as *const Self::Item) };
8692849878SLoGin         return Some(res);
8792849878SLoGin     }
887a29d4fcSLoGin }
897a29d4fcSLoGin 
907a29d4fcSLoGin impl EFIManager {
917a29d4fcSLoGin     /// Map the EFI memory map data structure
927a29d4fcSLoGin     ///
937a29d4fcSLoGin     /// 进入当前函数前,不应持有efi_manager.inner的锁
947a29d4fcSLoGin     #[inline(never)]
memmap_init_early(&self, data: &EFIFdtParams) -> Result<(), SystemError>957a29d4fcSLoGin     pub(super) fn memmap_init_early(&self, data: &EFIFdtParams) -> Result<(), SystemError> {
967a29d4fcSLoGin         return self.do_efi_memmap_init(data, true);
977a29d4fcSLoGin     }
987a29d4fcSLoGin 
997a29d4fcSLoGin     /// 映射 EFI memory map
1007a29d4fcSLoGin     ///
1017a29d4fcSLoGin     /// 该函数在内核启动过程中使用
1027a29d4fcSLoGin     ///
1037a29d4fcSLoGin     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/firmware/efi/memmap.c?fi=efi_memmap_init_early#104
1047a29d4fcSLoGin     #[inline(never)]
do_efi_memmap_init(&self, data: &EFIFdtParams, early: bool) -> Result<(), SystemError>1057a29d4fcSLoGin     fn do_efi_memmap_init(&self, data: &EFIFdtParams, early: bool) -> Result<(), SystemError> {
1067a29d4fcSLoGin         let paddr = data.mmap_base.expect("mmap_base is not set");
1077a29d4fcSLoGin         let paddr = PhysAddr::new(paddr as usize);
10892849878SLoGin 
1097a29d4fcSLoGin         let mut inner_guard = self.inner.write();
1107a29d4fcSLoGin         if early {
1117a29d4fcSLoGin             let offset = paddr.data() - page_align_down(paddr.data());
1127a29d4fcSLoGin             let map_size = data.mmap_size.unwrap() as usize + offset;
1137a29d4fcSLoGin 
114*2eab6dd7S曾俊             // debug!("do_efi_memmap_init: map_size={map_size:#x}");
11592849878SLoGin 
1167a29d4fcSLoGin             // 映射内存
1177a29d4fcSLoGin             let mut vaddr = EarlyIoRemap::map(
1187a29d4fcSLoGin                 PhysAddr::new(page_align_down(paddr.data())),
1197a29d4fcSLoGin                 map_size,
1207a29d4fcSLoGin                 false,
1217a29d4fcSLoGin             )
1227a29d4fcSLoGin             .map(|(vaddr, _)| vaddr)?;
1237a29d4fcSLoGin 
1247a29d4fcSLoGin             vaddr += offset;
1257a29d4fcSLoGin 
1267a29d4fcSLoGin             inner_guard.mmap.vaddr = Some(vaddr);
12792849878SLoGin             inner_guard.mmap.late = false;
1287a29d4fcSLoGin         } else {
12992849878SLoGin             inner_guard.mmap.late = true;
1307a29d4fcSLoGin             unimplemented!("efi_memmap_init_late")
1317a29d4fcSLoGin         }
1327a29d4fcSLoGin 
1337a29d4fcSLoGin         if inner_guard.mmap.vaddr.is_none() {
134*2eab6dd7S曾俊             error!("Cannot map the EFI memory map!");
1357a29d4fcSLoGin             return Err(SystemError::ENOMEM);
1367a29d4fcSLoGin         }
1377a29d4fcSLoGin 
1387a29d4fcSLoGin         inner_guard.mmap.paddr = Some(paddr);
1397a29d4fcSLoGin         inner_guard.mmap.size = data.mmap_size.unwrap() as usize;
1407a29d4fcSLoGin         inner_guard.mmap.nr_map =
1417a29d4fcSLoGin             data.mmap_size.unwrap() as usize / data.mmap_desc_size.unwrap() as usize;
1427a29d4fcSLoGin         inner_guard.mmap.desc_size = data.mmap_desc_size.unwrap() as usize;
1437a29d4fcSLoGin         inner_guard.mmap.desc_version = data.mmap_desc_version.unwrap() as usize;
1447a29d4fcSLoGin 
1457a29d4fcSLoGin         inner_guard.init_flags.set(EFIInitFlags::MEMMAP, true);
1467a29d4fcSLoGin 
1477a29d4fcSLoGin         return Ok(());
1487a29d4fcSLoGin     }
14992849878SLoGin 
15092849878SLoGin     /// 清除EFI Memory Table在内存中的映射
efi_memmap_unmap(&self)15192849878SLoGin     pub fn efi_memmap_unmap(&self) {
15292849878SLoGin         let mut inner_guard = self.inner.write_irqsave();
15392849878SLoGin 
15492849878SLoGin         // 没有启用memmap
15592849878SLoGin         if !inner_guard.init_flags.contains(EFIInitFlags::MEMMAP) {
15692849878SLoGin             return;
15792849878SLoGin         }
15892849878SLoGin 
15992849878SLoGin         if !inner_guard.mmap.late {
16092849878SLoGin             EarlyIoRemap::unmap(inner_guard.mmap.vaddr.take().unwrap()).unwrap();
16192849878SLoGin         } else {
16292849878SLoGin             unimplemented!("efi_memmap_unmap");
16392849878SLoGin         }
16492849878SLoGin         inner_guard.init_flags.set(EFIInitFlags::MEMMAP, false);
16592849878SLoGin     }
1667a29d4fcSLoGin }
167