1 use core::fmt::Formatter; 2 3 use alloc::sync::Arc; 4 use hashbrown::HashMap; 5 6 use crate::{ 7 arch::{PciArch, TraitPciArch}, 8 libs::spinlock::{SpinLock, SpinLockGuard}, 9 mm::{ 10 mmio_buddy::{mmio_pool, MMIOSpaceGuard}, 11 page::PAGE_2M_SIZE, 12 }, 13 }; 14 15 use super::{ 16 ecam::EcamRootInfo, 17 pci::{BusDeviceFunction, ExternalCapabilityIterator, PciCam, PciError, SegmentGroupNumber}, 18 }; 19 20 lazy_static! { 21 static ref PCI_ROOT_MANAGER: PciRootManager = PciRootManager::new(); 22 } 23 24 #[inline(always)] 25 pub fn pci_root_manager() -> &'static PciRootManager { 26 &PCI_ROOT_MANAGER 27 } 28 29 /// 代表一个PCI segement greoup. 30 #[derive(Clone, Debug)] 31 pub struct PciRoot { 32 pub ecam_root_info: Option<EcamRootInfo>, 33 pub mmio_guard: Option<Arc<MMIOSpaceGuard>>, //映射后的虚拟地址,为方便访问数据这里转化成指针 34 /// 配置空间访问机制 35 pub cam: PciCam, 36 /// bus起始位置 37 pub bus_begin: u8, 38 /// bus结束位置 39 pub bus_end: u8, 40 } 41 42 ///线程间共享需要,该结构体只需要在初始化时写入数据,无需读写锁保证线程安全 43 unsafe impl Send for PciRoot {} 44 unsafe impl Sync for PciRoot {} 45 ///实现PciRoot的Display trait,自定义输出 46 impl core::fmt::Display for PciRoot { 47 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { 48 if let Some(ecam_root_info) = &self.ecam_root_info { 49 write!( 50 f, 51 "PCI Eacm Root with segment:{}, bus begin at {}, bus end at {}, physical address at {:?},mapped at {:?}", 52 ecam_root_info.segment_group_number, ecam_root_info.bus_begin, ecam_root_info.bus_end, ecam_root_info.physical_address_base, self.mmio_guard 53 ) 54 } else { 55 write!(f, "PCI Root cam is {:?}", self.cam,) 56 } 57 } 58 } 59 60 impl PciRoot { 61 /// 此函数用于初始化一个PciRoot结构体实例, 62 /// 该结构体基于ECAM根的物理地址,将其映射到虚拟地址 63 /// 64 /// ## 参数 65 /// 66 /// - segment_group_number: ECAM根的段组号。 67 /// - cam: PCI配置空间访问机制 68 /// 69 /// ## 返回值 70 /// 71 /// - Ok(Self): 初始化成功,返回一个新的结构体实例。 72 /// - Err(PciError): 初始化过程中发生错误,返回错误信息。 73 /// 74 /// ## 副作用 75 /// 76 /// - 成功执行后,结构体的内部状态将被初始化为包含映射后的虚拟地址。 77 pub fn new( 78 ecam_root_info: Option<EcamRootInfo>, 79 cam: PciCam, 80 bus_begin: u8, 81 bus_end: u8, 82 ) -> Result<Arc<Self>, PciError> { 83 let mut pci_root = Self { 84 ecam_root_info, 85 mmio_guard: None, 86 cam, 87 bus_begin, 88 bus_end, 89 }; 90 91 if ecam_root_info.is_some() { 92 pci_root.map()?; 93 } 94 95 Ok(Arc::new(pci_root)) 96 } 97 98 /// # 完成物理地址到虚拟地址的映射,并将虚拟地址加入mmio_base变量 99 /// ## return 返回错误或Ok(0) 100 fn map(&mut self) -> Result<u8, PciError> { 101 //debug!("bus_begin={},bus_end={}", self.bus_begin,self.bus_end); 102 let bus_number = (self.bus_end - self.bus_begin) as u32 + 1; 103 let bus_number_double = (bus_number - 1) / 2 + 1; //一个bus占据1MB空间,计算全部bus占据空间相对于2MB空间的个数 104 105 let size = (bus_number_double as usize) * PAGE_2M_SIZE; 106 unsafe { 107 let space_guard = mmio_pool() 108 .create_mmio(size) 109 .map_err(|_| PciError::CreateMmioError)?; 110 let space_guard = Arc::new(space_guard); 111 self.mmio_guard = Some(space_guard.clone()); 112 113 assert!(space_guard 114 .map_phys(self.ecam_root_info.unwrap().physical_address_base, size) 115 .is_ok()); 116 } 117 return Ok(0); 118 } 119 120 /// # cam_offset - 获得要操作的寄存器相对于mmio_offset的偏移量 121 /// 122 /// 此函数用于计算一个PCI设备中特定寄存器相对于该设备的MMIO基地址的偏移量。 123 /// 124 /// ## 参数 125 /// 126 /// - `bus_device_function`: BusDeviceFunction,用于标识在同一组中的PCI设备。 127 /// - `register_offset`: u16,寄存器在设备中的偏移量。 128 /// 129 /// ## 返回值 130 /// 131 /// - `u32`: 成功时,返回要操作的寄存器相对于mmio_offset的偏移量。 132 /// 133 /// ## Panic 134 /// 135 /// - 此函数在参数有效性方面进行了断言,如果传入的`bus_device_function`无效,将panic。 136 /// - 此函数计算出的地址需要是字对齐的(即地址与0x3对齐)。如果不是,将panic。 137 fn cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 { 138 assert!(bus_device_function.valid()); 139 let bdf = ((bus_device_function.bus - self.ecam_root_info.unwrap().bus_begin) as u32) << 8 140 | (bus_device_function.device as u32) << 3 141 | bus_device_function.function as u32; 142 let address = 143 bdf << match self.cam { 144 PciCam::Portiocam => 4, 145 PciCam::MmioCam => 8, 146 PciCam::Ecam => 12, 147 } | register_offset as u32; 148 // Ensure that address is word-aligned. 149 assert!(address & 0x3 == 0); 150 address 151 } 152 153 /// # read_config - 通过bus_device_function和offset读取相应位置寄存器的值(32位) 154 /// 155 /// 此函数用于通过指定的bus_device_function和register_offset读取PCI设备中相应位置的寄存器值。 156 /// 157 /// ## 参数 158 /// 159 /// - `bus_device_function`: 在同一个group中pci设备的唯一标识符 160 /// - `register_offset`: 寄存器在设备中的offset 161 /// 162 /// ## 返回值 163 /// 164 /// - `u32`: 寄存器读值结果 165 pub fn read_config(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 { 166 if self.ecam_root_info.is_some() { 167 let address = self.cam_offset(bus_device_function, register_offset); 168 unsafe { 169 // Right shift to convert from byte offset to word offset. 170 ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32) 171 .add((address >> 2) as usize)) 172 .read_volatile() 173 } 174 } else { 175 PciArch::read_config(&bus_device_function, register_offset as u8) 176 } 177 } 178 179 /// # write_config - 通过bus_device_function和offset写入相应位置寄存器值(32位) 180 /// 181 /// 此函数用于通过指定的bus_device_function和register_offset,向PCI设备写入一个32位的寄存器值。 182 /// 183 /// ## 参数 184 /// 185 /// - `bus_device_function`: 在同一个group中pci设备的唯一标识符 186 /// - `register_offset`: 寄存器在设备中的offset 187 /// - `data`: 要写入的数据 188 pub fn write_config( 189 &self, 190 bus_device_function: BusDeviceFunction, 191 register_offset: u16, 192 data: u32, 193 ) { 194 if self.ecam_root_info.is_some() { 195 let address = self.cam_offset(bus_device_function, register_offset); 196 // Safe because both the `mmio_base` and the address offset are properly aligned, and the 197 // resulting pointer is within the MMIO range of the CAM. 198 unsafe { 199 // Right shift to convert from byte offset to word offset. 200 ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32) 201 .add((address >> 2) as usize)) 202 .write_volatile(data) 203 } 204 } else { 205 PciArch::write_config(&bus_device_function, register_offset as u8, data); 206 } 207 } 208 209 /// 返回迭代器,遍历pcie设备的external_capabilities 210 #[allow(dead_code)] 211 pub fn external_capabilities( 212 &self, 213 bus_device_function: BusDeviceFunction, 214 ) -> ExternalCapabilityIterator { 215 ExternalCapabilityIterator { 216 root: self, 217 bus_device_function, 218 next_capability_offset: Some(0x100), 219 } 220 } 221 } 222 223 #[inline(always)] 224 pub fn pci_root_0() -> Arc<PciRoot> { 225 pci_root_manager().get_pci_root(0).unwrap() 226 } 227 228 pub struct PciRootManager { 229 inner: SpinLock<InnerPciRootManager>, 230 } 231 232 struct InnerPciRootManager { 233 pci_root: HashMap<SegmentGroupNumber, Arc<PciRoot>>, 234 } 235 236 impl PciRootManager { 237 pub fn new() -> Self { 238 Self { 239 inner: SpinLock::new(InnerPciRootManager { 240 pci_root: HashMap::new(), 241 }), 242 } 243 } 244 245 /// # 添加PciRoot - 向PciRootManager中添加一个PciRoot 246 /// 247 /// 向PciRootManager中添加一个新的PciRoot,通过其segment_group_number进行标识。 248 /// 249 /// ## 参数 250 /// 251 /// - `pci_root`: Arc<PciRoot>,要添加的PciRoot的Arc指针 252 pub fn add_pci_root(&self, pci_root: Arc<PciRoot>) { 253 let mut inner = self.inner.lock(); 254 255 if let Some(ecam_root_info) = pci_root.ecam_root_info { 256 inner 257 .pci_root 258 .insert(ecam_root_info.segment_group_number, pci_root); 259 } else { 260 inner.pci_root.insert(pci_root.bus_begin as u16, pci_root); 261 } 262 } 263 264 /// # 检查是否存在PciRoot - 检查PciRootManager中是否存在指定segment_group_number的PciRoot 265 /// 266 /// 检查PciRootManager中是否存在segment_group_number对应的PciRoot。 267 /// 268 /// ## 参数 269 /// 270 /// - `segement_group_number`: SegmentGroupNumber,要检查的segment_group_number。 271 /// 272 /// ## 返回值 273 /// 274 /// - `true`: 如果存在对应的PciRoot。 275 /// - `false`: 如果不存在对应的PciRoot。 276 pub fn has_root(&self, segement_group_number: SegmentGroupNumber) -> bool { 277 self.inner 278 .lock() 279 .pci_root 280 .contains_key(&segement_group_number) 281 } 282 283 /// # 获取PciRoot - 从PciRootManager中获取指定segment_group_number的PciRoot 284 /// 285 /// 从PciRootManager中获取segment_group_number对应的PciRoot。 286 /// 287 /// ## 参数 288 /// 289 /// - `segement_group_number`: SegmentGroupNumber,要获取的PciRoot的segment_group_number。 290 /// 291 /// ## 返回值 292 /// 293 /// - `Some(Arc<PciRoot>)`: 如果找到对应的PciRoot,返回其引用。 294 /// - `None`: 如果没有找到对应的PciRoot。 295 pub fn get_pci_root(&self, segement_group_number: SegmentGroupNumber) -> Option<Arc<PciRoot>> { 296 self.inner 297 .lock() 298 .pci_root 299 .get(&segement_group_number) 300 .cloned() 301 } 302 303 /// # PciRoot迭代器 - 创建一个新的PciRoot迭代器 304 /// 305 /// 创建一个新的迭代器,用于遍历PciRootManager中的所有PciRoot。 306 #[allow(dead_code)] 307 pub fn iter(&self) -> PciRootIterator<'_> { 308 PciRootIterator { 309 inner: self.inner.lock(), 310 index: 0, 311 } 312 } 313 } 314 315 pub struct PciRootIterator<'a> { 316 inner: SpinLockGuard<'a, InnerPciRootManager>, 317 index: usize, 318 } 319 320 impl<'a> Iterator for PciRootIterator<'a> { 321 type Item = Arc<PciRoot>; 322 323 fn next(&mut self) -> Option<Self::Item> { 324 self.inner.pci_root.values().nth(self.index).cloned() 325 } 326 } 327