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