1 use core::{intrinsics::unlikely, mem::size_of}; 2 3 use log::error; 4 use system_error::SystemError; 5 6 use crate::{ 7 driver::firmware::efi::EFIInitFlags, 8 libs::align::page_align_down, 9 mm::{early_ioremap::EarlyIoRemap, PhysAddr, VirtAddr}, 10 }; 11 12 use super::{fdt::EFIFdtParams, tables::MemoryDescriptor, EFIManager}; 13 14 #[derive(Debug)] 15 pub struct EFIMemoryMapInfo { 16 /// EFI Memory Map的物理地址 17 pub(super) paddr: Option<PhysAddr>, 18 /// EFI Memory Map的虚拟地址 19 pub(super) vaddr: Option<VirtAddr>, 20 /// EFI Memory Map的大小 21 pub(super) size: usize, 22 /// 映射的描述信息的数量 23 pub(super) nr_map: usize, 24 /// EFI Memory Map的描述信息的大小 25 pub(super) desc_size: usize, 26 /// EFI Memory Map的描述信息的版本 27 pub(super) desc_version: usize, 28 /// 当前是否在内存管理已经完成初始化后,对该结构体进行操作 29 /// 30 /// true: 内存管理已经完成初始化 31 /// false: 内存管理还未完成初始化 32 pub(super) late: bool, 33 } 34 35 impl EFIMemoryMapInfo { 36 pub const DEFAULT: Self = EFIMemoryMapInfo { 37 paddr: None, 38 vaddr: None, 39 size: 0, 40 nr_map: 0, 41 desc_size: 0, 42 desc_version: 0, 43 late: false, 44 }; 45 46 /// 获取EFI Memory Map的虚拟的结束地址 47 #[allow(dead_code)] 48 pub fn map_end_vaddr(&self) -> Option<VirtAddr> { 49 return self.vaddr.map(|v| v + self.size); 50 } 51 52 /// 迭代所有的内存描述符 53 pub fn iter(&self) -> EFIMemoryDescIter { 54 EFIMemoryDescIter::new(self) 55 } 56 } 57 58 /// UEFI 内存描述符的迭代器 59 pub struct EFIMemoryDescIter<'a> { 60 inner: &'a EFIMemoryMapInfo, 61 offset: usize, 62 } 63 64 impl<'a> EFIMemoryDescIter<'a> { 65 fn new(inner: &'a EFIMemoryMapInfo) -> Self { 66 Self { inner, offset: 0 } 67 } 68 } 69 70 impl<'a> Iterator for EFIMemoryDescIter<'a> { 71 type Item = MemoryDescriptor; 72 73 fn next(&mut self) -> Option<Self::Item> { 74 if self.offset + size_of::<Self::Item>() > self.inner.size { 75 return None; 76 } 77 78 // 如果是空指针,返回None 79 if unlikely(self.inner.vaddr.unwrap_or(VirtAddr::new(0)).is_null()) { 80 return None; 81 } 82 83 let vaddr = self.inner.vaddr? + self.offset; 84 self.offset += size_of::<Self::Item>(); 85 let res = unsafe { *(vaddr.data() as *const Self::Item) }; 86 return Some(res); 87 } 88 } 89 90 impl EFIManager { 91 /// Map the EFI memory map data structure 92 /// 93 /// 进入当前函数前,不应持有efi_manager.inner的锁 94 #[inline(never)] 95 pub(super) fn memmap_init_early(&self, data: &EFIFdtParams) -> Result<(), SystemError> { 96 return self.do_efi_memmap_init(data, true); 97 } 98 99 /// 映射 EFI memory map 100 /// 101 /// 该函数在内核启动过程中使用 102 /// 103 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/firmware/efi/memmap.c?fi=efi_memmap_init_early#104 104 #[inline(never)] 105 fn do_efi_memmap_init(&self, data: &EFIFdtParams, early: bool) -> Result<(), SystemError> { 106 let paddr = data.mmap_base.expect("mmap_base is not set"); 107 let paddr = PhysAddr::new(paddr as usize); 108 109 let mut inner_guard = self.inner.write(); 110 if early { 111 let offset = paddr.data() - page_align_down(paddr.data()); 112 let map_size = data.mmap_size.unwrap() as usize + offset; 113 114 // debug!("do_efi_memmap_init: map_size={map_size:#x}"); 115 116 // 映射内存 117 let mut vaddr = EarlyIoRemap::map( 118 PhysAddr::new(page_align_down(paddr.data())), 119 map_size, 120 false, 121 ) 122 .map(|(vaddr, _)| vaddr)?; 123 124 vaddr += offset; 125 126 inner_guard.mmap.vaddr = Some(vaddr); 127 inner_guard.mmap.late = false; 128 } else { 129 inner_guard.mmap.late = true; 130 unimplemented!("efi_memmap_init_late") 131 } 132 133 if inner_guard.mmap.vaddr.is_none() { 134 error!("Cannot map the EFI memory map!"); 135 return Err(SystemError::ENOMEM); 136 } 137 138 inner_guard.mmap.paddr = Some(paddr); 139 inner_guard.mmap.size = data.mmap_size.unwrap() as usize; 140 inner_guard.mmap.nr_map = 141 data.mmap_size.unwrap() as usize / data.mmap_desc_size.unwrap() as usize; 142 inner_guard.mmap.desc_size = data.mmap_desc_size.unwrap() as usize; 143 inner_guard.mmap.desc_version = data.mmap_desc_version.unwrap() as usize; 144 145 inner_guard.init_flags.set(EFIInitFlags::MEMMAP, true); 146 147 return Ok(()); 148 } 149 150 /// 清除EFI Memory Table在内存中的映射 151 pub fn efi_memmap_unmap(&self) { 152 let mut inner_guard = self.inner.write_irqsave(); 153 154 // 没有启用memmap 155 if !inner_guard.init_flags.contains(EFIInitFlags::MEMMAP) { 156 return; 157 } 158 159 if !inner_guard.mmap.late { 160 EarlyIoRemap::unmap(inner_guard.mmap.vaddr.take().unwrap()).unwrap(); 161 } else { 162 unimplemented!("efi_memmap_unmap"); 163 } 164 inner_guard.init_flags.set(EFIInitFlags::MEMMAP, false); 165 } 166 } 167