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