memmap.rs 5.0 KB

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