1 #![allow(dead_code)] 2 // 目前仅支持单主桥单Segment 3 4 use super::pci_irq::{IrqType, PciIrqError}; 5 use crate::arch::{PciArch, TraitPciArch}; 6 use crate::exception::IrqNumber; 7 use crate::include::bindings::bindings::PAGE_2M_SIZE; 8 use crate::libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; 9 10 use crate::mm::mmio_buddy::{mmio_pool, MMIOSpaceGuard}; 11 12 use crate::mm::{PhysAddr, VirtAddr}; 13 use crate::{kdebug, kerror, kinfo, kwarn}; 14 use alloc::sync::Arc; 15 use alloc::vec::Vec; 16 use alloc::{boxed::Box, collections::LinkedList}; 17 use bitflags::bitflags; 18 19 use core::{ 20 convert::TryFrom, 21 fmt::{self, Debug, Display, Formatter}, 22 }; 23 // PCI_DEVICE_LINKEDLIST 添加了读写锁的全局链表,里面存储了检索到的PCI设备结构体 24 // PCI_ROOT_0 Segment为0的全局PciRoot 25 lazy_static! { 26 pub static ref PCI_DEVICE_LINKEDLIST: PciDeviceLinkedList = PciDeviceLinkedList::new(); 27 pub static ref PCI_ROOT_0: Option<PciRoot> = { 28 match PciRoot::new(0, PciCam::Ecam) { 29 Ok(root) => Some(root), 30 Err(err) => { 31 kerror!("Pci_root init failed because of error: {}", err); 32 None 33 } 34 } 35 }; 36 } 37 38 #[inline(always)] 39 pub fn pci_root_0() -> &'static PciRoot { 40 PCI_ROOT_0.as_ref().unwrap() 41 } 42 43 /// PCI域地址 44 #[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)] 45 #[repr(transparent)] 46 pub struct PciAddr(usize); 47 48 impl PciAddr { 49 #[inline(always)] 50 pub const fn new(address: usize) -> Self { 51 Self(address) 52 } 53 54 /// @brief 获取PCI域地址的值 55 #[inline(always)] 56 pub fn data(&self) -> usize { 57 self.0 58 } 59 60 /// @brief 将PCI域地址加上一个偏移量 61 #[inline(always)] 62 pub fn add(self, offset: usize) -> Self { 63 Self(self.0 + offset) 64 } 65 66 /// @brief 判断PCI域地址是否按照指定要求对齐 67 #[inline(always)] 68 pub fn check_aligned(&self, align: usize) -> bool { 69 return self.0 & (align - 1) == 0; 70 } 71 } 72 impl Debug for PciAddr { 73 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 74 write!(f, "PciAddr({:#x})", self.0) 75 } 76 } 77 78 /// 添加了读写锁的链表,存储PCI设备结构体 79 pub struct PciDeviceLinkedList { 80 list: RwLock<LinkedList<Box<dyn PciDeviceStructure>>>, 81 } 82 83 impl PciDeviceLinkedList { 84 /// @brief 初始化结构体 85 fn new() -> Self { 86 PciDeviceLinkedList { 87 list: RwLock::new(LinkedList::new()), 88 } 89 } 90 /// @brief 获取可读的linkedlist(读锁守卫) 91 /// @return RwLockReadGuard<LinkedList<Box<dyn PciDeviceStructure>>> 读锁守卫 92 pub fn read(&self) -> RwLockReadGuard<LinkedList<Box<dyn PciDeviceStructure>>> { 93 self.list.read() 94 } 95 /// @brief 获取可写的linkedlist(写锁守卫) 96 /// @return RwLockWriteGuard<LinkedList<Box<dyn PciDeviceStructure>>> 写锁守卫 97 pub fn write(&self) -> RwLockWriteGuard<LinkedList<Box<dyn PciDeviceStructure>>> { 98 self.list.write() 99 } 100 /// @brief 获取链表中PCI结构体数目 101 /// @return usize 链表中PCI结构体数目 102 pub fn num(&self) -> usize { 103 let list = self.list.read(); 104 list.len() 105 } 106 /// @brief 添加Pci设备结构体到链表中 107 pub fn add(&self, device: Box<dyn PciDeviceStructure>) { 108 let mut list = self.list.write(); 109 list.push_back(device); 110 } 111 } 112 113 /// @brief 在链表中寻找满足条件的PCI设备结构体并返回其可变引用 114 /// @param list 链表的写锁守卫 115 /// @param class_code 寄存器值 116 /// @param subclass 寄存器值,与class_code一起确定设备类型 117 /// @return Vec<&'a mut Box<(dyn PciDeviceStructure) 包含链表中所有满足条件的PCI结构体的可变引用的容器 118 pub fn get_pci_device_structure_mut<'a>( 119 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, 120 class_code: u8, 121 subclass: u8, 122 ) -> Vec<&'a mut Box<(dyn PciDeviceStructure)>> { 123 let mut result = Vec::new(); 124 for box_pci_device_structure in list.iter_mut() { 125 let common_header = (*box_pci_device_structure).common_header(); 126 if (common_header.class_code == class_code) && (common_header.subclass == subclass) { 127 result.push(box_pci_device_structure); 128 } 129 } 130 result 131 } 132 /// @brief 在链表中寻找满足条件的PCI设备结构体并返回其不可变引用 133 /// @param list 链表的读锁守卫 134 /// @param class_code 寄存器值 135 /// @param subclass 寄存器值,与class_code一起确定设备类型 136 /// @return Vec<&'a Box<(dyn PciDeviceStructure) 包含链表中所有满足条件的PCI结构体的不可变引用的容器 137 #[allow(clippy::borrowed_box)] 138 pub fn get_pci_device_structure<'a>( 139 list: &'a mut RwLockReadGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, 140 class_code: u8, 141 subclass: u8, 142 ) -> Vec<&'a Box<(dyn PciDeviceStructure)>> { 143 let mut result = Vec::new(); 144 for box_pci_device_structure in list.iter() { 145 let common_header = (*box_pci_device_structure).common_header(); 146 if (common_header.class_code == class_code) && (common_header.subclass == subclass) { 147 result.push(box_pci_device_structure); 148 } 149 } 150 result 151 } 152 153 //Bar0寄存器的offset 154 const BAR0_OFFSET: u8 = 0x10; 155 //Status、Command寄存器的offset 156 const STATUS_COMMAND_OFFSET: u8 = 0x04; 157 /// ID for vendor-specific PCI capabilities.(Virtio Capabilities) 158 pub const PCI_CAP_ID_VNDR: u8 = 0x09; 159 pub const PCI_CAP_ID_MSI: u8 = 0x05; 160 pub const PCI_CAP_ID_MSIX: u8 = 0x11; 161 pub const PORT_PCI_CONFIG_ADDRESS: u16 = 0xcf8; 162 pub const PORT_PCI_CONFIG_DATA: u16 = 0xcfc; 163 // pci设备分组的id 164 pub type SegmentGroupNumber = u16; //理论上最多支持65535个Segment_Group 165 166 bitflags! { 167 /// The status register in PCI configuration space. 168 pub struct Status: u16 { 169 // Bits 0-2 are reserved. 170 /// The state of the device's INTx# signal. 171 const INTERRUPT_STATUS = 1 << 3; 172 /// The device has a linked list of capabilities. 173 const CAPABILITIES_LIST = 1 << 4; 174 /// The device is capabile of running at 66 MHz rather than 33 MHz. 175 const MHZ_66_CAPABLE = 1 << 5; 176 // Bit 6 is reserved. 177 /// The device can accept fast back-to-back transactions not from the same agent. 178 const FAST_BACK_TO_BACK_CAPABLE = 1 << 7; 179 /// The bus agent observed a parity error (if parity error handling is enabled). 180 const MASTER_DATA_PARITY_ERROR = 1 << 8; 181 // Bits 9-10 are DEVSEL timing. 182 /// A target device terminated a transaction with target-abort. 183 const SIGNALED_TARGET_ABORT = 1 << 11; 184 /// A master device transaction was terminated with target-abort. 185 const RECEIVED_TARGET_ABORT = 1 << 12; 186 /// A master device transaction was terminated with master-abort. 187 const RECEIVED_MASTER_ABORT = 1 << 13; 188 /// A device asserts SERR#. 189 const SIGNALED_SYSTEM_ERROR = 1 << 14; 190 /// The device detects a parity error, even if parity error handling is disabled. 191 const DETECTED_PARITY_ERROR = 1 << 15; 192 } 193 } 194 195 bitflags! { 196 /// The command register in PCI configuration space. 197 pub struct Command: u16 { 198 /// The device can respond to I/O Space accesses. 199 const IO_SPACE = 1 << 0; 200 /// The device can respond to Memory Space accesses. 201 const MEMORY_SPACE = 1 << 1; 202 /// The device can behave as a bus master. 203 const BUS_MASTER = 1 << 2; 204 /// The device can monitor Special Cycle operations. 205 const SPECIAL_CYCLES = 1 << 3; 206 /// The device can generate the Memory Write and Invalidate command. 207 const MEMORY_WRITE_AND_INVALIDATE_ENABLE = 1 << 4; 208 /// The device will snoop palette register data. 209 const VGA_PALETTE_SNOOP = 1 << 5; 210 /// The device should take its normal action when a parity error is detected. 211 const PARITY_ERROR_RESPONSE = 1 << 6; 212 // Bit 7 is reserved. 213 /// The SERR# driver is enabled. 214 const SERR_ENABLE = 1 << 8; 215 /// The device is allowed to generate fast back-to-back transactions. 216 const FAST_BACK_TO_BACK_ENABLE = 1 << 9; 217 /// Assertion of the device's INTx# signal is disabled. 218 const INTERRUPT_DISABLE = 1 << 10; 219 } 220 } 221 222 /// The type of a PCI device function header. 223 /// 标头类型/设备类型 224 #[derive(Copy, Clone, Debug, Eq, PartialEq)] 225 pub enum HeaderType { 226 /// A normal PCI device. 227 Standard, 228 /// A PCI to PCI bridge. 229 PciPciBridge, 230 /// A PCI to CardBus bridge. 231 PciCardbusBridge, 232 /// Unrecognised header type. 233 Unrecognised(u8), 234 } 235 /// u8到HeaderType的转换 236 impl From<u8> for HeaderType { 237 fn from(value: u8) -> Self { 238 match value { 239 0x00 => Self::Standard, 240 0x01 => Self::PciPciBridge, 241 0x02 => Self::PciCardbusBridge, 242 _ => Self::Unrecognised(value), 243 } 244 } 245 } 246 /// Pci可能触发的各种错误 247 #[derive(Copy, Clone, Debug, Eq, PartialEq)] 248 pub enum PciError { 249 /// The device reported an invalid BAR type. 250 InvalidBarType, 251 CreateMmioError, 252 InvalidBusDeviceFunction, 253 SegmentNotFound, 254 McfgTableNotFound, 255 GetWrongHeader, 256 UnrecognisedHeaderType, 257 PciDeviceStructureTransformError, 258 PciIrqError(PciIrqError), 259 } 260 ///实现PciError的Display trait,使其可以直接输出 261 impl Display for PciError { 262 fn fmt(&self, f: &mut Formatter) -> fmt::Result { 263 match self { 264 Self::InvalidBarType => write!(f, "Invalid PCI BAR type."), 265 Self::CreateMmioError => write!(f, "Error occurred while creating mmio."), 266 Self::InvalidBusDeviceFunction => write!(f, "Found invalid BusDeviceFunction."), 267 Self::SegmentNotFound => write!(f, "Target segment not found"), 268 Self::McfgTableNotFound => write!(f, "ACPI MCFG Table not found"), 269 Self::GetWrongHeader => write!(f, "GetWrongHeader with vendor id 0xffff"), 270 Self::UnrecognisedHeaderType => write!(f, "Found device with unrecognised header type"), 271 Self::PciDeviceStructureTransformError => { 272 write!(f, "Found None When transform Pci device structure") 273 } 274 Self::PciIrqError(err) => write!(f, "Error occurred while setting irq :{:?}.", err), 275 } 276 } 277 } 278 279 /// trait类型Pci_Device_Structure表示pci设备,动态绑定三种具体设备类型:Pci_Device_Structure_General_Device、Pci_Device_Structure_Pci_to_Pci_Bridge、Pci_Device_Structure_Pci_to_Cardbus_Bridge 280 pub trait PciDeviceStructure: Send + Sync { 281 /// @brief 获取设备类型 282 /// @return HeaderType 设备类型 283 fn header_type(&self) -> HeaderType; 284 /// @brief 当其为standard设备时返回&Pci_Device_Structure_General_Device,其余情况返回None 285 #[inline(always)] 286 fn as_standard_device(&self) -> Option<&PciDeviceStructureGeneralDevice> { 287 None 288 } 289 /// @brief 当其为pci to pci bridge设备时返回&Pci_Device_Structure_Pci_to_Pci_Bridge,其余情况返回None 290 #[inline(always)] 291 fn as_pci_to_pci_bridge_device(&self) -> Option<&PciDeviceStructurePciToPciBridge> { 292 None 293 } 294 /// @brief 当其为pci to cardbus bridge设备时返回&Pci_Device_Structure_Pci_to_Cardbus_Bridge,其余情况返回None 295 #[inline(always)] 296 fn as_pci_to_carbus_bridge_device(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> { 297 None 298 } 299 /// @brief 获取Pci设备共有的common_header 300 /// @return 返回其不可变引用 301 fn common_header(&self) -> &PciDeviceStructureHeader; 302 /// @brief 当其为standard设备时返回&mut Pci_Device_Structure_General_Device,其余情况返回None 303 #[inline(always)] 304 fn as_standard_device_mut(&mut self) -> Option<&mut PciDeviceStructureGeneralDevice> { 305 None 306 } 307 /// @brief 当其为pci to pci bridge设备时返回&mut Pci_Device_Structure_Pci_to_Pci_Bridge,其余情况返回None 308 #[inline(always)] 309 fn as_pci_to_pci_bridge_device_mut(&mut self) -> Option<&mut PciDeviceStructurePciToPciBridge> { 310 None 311 } 312 /// @brief 当其为pci to cardbus bridge设备时返回&mut Pci_Device_Structure_Pci_to_Cardbus_Bridge,其余情况返回None 313 #[inline(always)] 314 fn as_pci_to_carbus_bridge_device_mut( 315 &mut self, 316 ) -> Option<&mut PciDeviceStructurePciToCardbusBridge> { 317 None 318 } 319 /// @brief 返回迭代器,遍历capabilities 320 fn capabilities(&self) -> Option<CapabilityIterator> { 321 None 322 } 323 /// @brief 获取Status、Command寄存器的值 324 fn status_command(&self) -> (Status, Command) { 325 let common_header = self.common_header(); 326 let status = Status::from_bits_truncate(common_header.status); 327 let command = Command::from_bits_truncate(common_header.command); 328 (status, command) 329 } 330 /// @brief 设置Command寄存器的值 331 fn set_command(&mut self, command: Command) { 332 let common_header = self.common_header_mut(); 333 let command = command.bits(); 334 common_header.command = command; 335 pci_root_0().write_config( 336 common_header.bus_device_function, 337 STATUS_COMMAND_OFFSET.into(), 338 command as u32, 339 ); 340 } 341 /// @brief 获取Pci设备共有的common_header 342 /// @return 返回其可变引用 343 fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader; 344 345 /// @brief 读取standard设备的bar寄存器,映射后将结果加入结构体的standard_device_bar变量 346 /// @return 只有standard设备才返回成功或者错误,其余返回None 347 #[inline(always)] 348 fn bar_ioremap(&mut self) -> Option<Result<u8, PciError>> { 349 None 350 } 351 /// @brief 获取PCI设备的bar寄存器的引用 352 /// @return 353 #[inline(always)] 354 fn bar(&mut self) -> Option<&PciStandardDeviceBar> { 355 None 356 } 357 /// @brief 通过设置该pci设备的command 358 fn enable_master(&mut self) { 359 self.set_command(Command::IO_SPACE | Command::MEMORY_SPACE | Command::BUS_MASTER); 360 } 361 /// @brief 寻找设备的msix空间的offset 362 fn msix_capability_offset(&self) -> Option<u8> { 363 for capability in self.capabilities()? { 364 if capability.id == PCI_CAP_ID_MSIX { 365 return Some(capability.offset); 366 } 367 } 368 None 369 } 370 /// @brief 寻找设备的msi空间的offset 371 fn msi_capability_offset(&self) -> Option<u8> { 372 for capability in self.capabilities()? { 373 if capability.id == PCI_CAP_ID_MSI { 374 return Some(capability.offset); 375 } 376 } 377 None 378 } 379 /// @brief 返回结构体中的irq_type的可变引用 380 fn irq_type_mut(&mut self) -> Option<&mut IrqType>; 381 /// @brief 返回结构体中的irq_vector的可变引用 382 fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>>; 383 } 384 385 /// Pci_Device_Structure_Header PCI设备结构体共有的头部 386 #[derive(Clone, Debug)] 387 pub struct PciDeviceStructureHeader { 388 // ==== busdevicefunction变量表示该结构体所处的位置 389 pub bus_device_function: BusDeviceFunction, 390 pub vendor_id: u16, // 供应商ID 0xffff是一个无效值,在读取访问不存在的设备的配置空间寄存器时返回 391 pub device_id: u16, // 设备ID,标志特定设备 392 pub command: u16, // 提供对设备生成和响应pci周期的能力的控制 向该寄存器写入0时,设备与pci总线断开除配置空间访问以外的所有连接 393 pub status: u16, // 用于记录pci总线相关时间的状态信息寄存器 394 pub revision_id: u8, // 修订ID,指定特定设备的修订标志符 395 pub prog_if: u8, // 编程接口字节,一个只读寄存器,指定设备具有的寄存器级别的编程接口(如果有的话) 396 pub subclass: u8, // 子类。指定设备执行的特定功能的只读寄存器 397 pub class_code: u8, // 类代码,一个只读寄存器,指定设备执行的功能类型 398 pub cache_line_size: u8, // 缓存线大小:以 32 位为单位指定系统缓存线大小。设备可以限制它可以支持的缓存线大小的数量,如果不支持的值写入该字段,设备将表现得好像写入了 0 值 399 pub latency_timer: u8, // 延迟计时器:以 PCI 总线时钟为单位指定延迟计时器。 400 pub header_type: u8, // 标头类型 a value of 0x0 specifies a general device, a value of 0x1 specifies a PCI-to-PCI bridge, and a value of 0x2 specifies a CardBus bridge. If bit 7 of this register is set, the device has multiple functions; otherwise, it is a single function device. 401 pub bist: u8, // Represents that status and allows control of a devices BIST (built-in self test). 402 // Here is the layout of the BIST register: 403 // | bit7 | bit6 | Bits 5-4 | Bits 3-0 | 404 // | BIST Capable | Start BIST | Reserved | Completion Code | 405 // for more details, please visit https://wiki.osdev.org/PCI 406 } 407 408 /// Pci_Device_Structure_General_Device PCI标准设备结构体 409 #[derive(Clone, Debug)] 410 pub struct PciDeviceStructureGeneralDevice { 411 pub common_header: PciDeviceStructureHeader, 412 // 中断结构体,包括legacy,msi,msix三种情况 413 pub irq_type: IrqType, 414 // 使用的中断号的vec集合 415 pub irq_vector: Vec<IrqNumber>, 416 pub standard_device_bar: PciStandardDeviceBar, 417 pub cardbus_cis_pointer: u32, // 指向卡信息结构,供在 CardBus 和 PCI 之间共享芯片的设备使用。 418 pub subsystem_vendor_id: u16, 419 pub subsystem_id: u16, 420 pub expansion_rom_base_address: u32, 421 pub capabilities_pointer: u8, 422 pub reserved0: u8, 423 pub reserved1: u16, 424 pub reserved2: u32, 425 pub interrupt_line: u8, // 指定设备的中断引脚连接到系统中断控制器的哪个输入,并由任何使用中断引脚的设备实现。对于 x86 架构,此寄存器对应于 PIC IRQ 编号 0-15(而不是 I/O APIC IRQ 编号),并且值0xFF定义为无连接。 426 pub interrupt_pin: u8, // 指定设备使用的中断引脚。其中值为0x1INTA#、0x2INTB#、0x3INTC#、0x4INTD#,0x0表示设备不使用中断引脚。 427 pub min_grant: u8, // 一个只读寄存器,用于指定设备所需的突发周期长度(以 1/4 微秒为单位)(假设时钟速率为 33 MHz) 428 pub max_latency: u8, // 一个只读寄存器,指定设备需要多长时间访问一次 PCI 总线(以 1/4 微秒为单位)。 429 } 430 impl PciDeviceStructure for PciDeviceStructureGeneralDevice { 431 #[inline(always)] 432 fn header_type(&self) -> HeaderType { 433 HeaderType::Standard 434 } 435 #[inline(always)] 436 fn as_standard_device(&self) -> Option<&PciDeviceStructureGeneralDevice> { 437 Some(self) 438 } 439 #[inline(always)] 440 fn as_standard_device_mut(&mut self) -> Option<&mut PciDeviceStructureGeneralDevice> { 441 Some(self) 442 } 443 #[inline(always)] 444 fn common_header(&self) -> &PciDeviceStructureHeader { 445 &self.common_header 446 } 447 #[inline(always)] 448 fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader { 449 &mut self.common_header 450 } 451 fn capabilities(&self) -> Option<CapabilityIterator> { 452 Some(CapabilityIterator { 453 bus_device_function: self.common_header.bus_device_function, 454 next_capability_offset: Some(self.capabilities_pointer), 455 }) 456 } 457 fn bar_ioremap(&mut self) -> Option<Result<u8, PciError>> { 458 let common_header = &self.common_header; 459 match pci_bar_init(common_header.bus_device_function) { 460 Ok(bar) => { 461 self.standard_device_bar = bar; 462 Some(Ok(0)) 463 } 464 Err(e) => Some(Err(e)), 465 } 466 } 467 fn bar(&mut self) -> Option<&PciStandardDeviceBar> { 468 Some(&self.standard_device_bar) 469 } 470 #[inline(always)] 471 fn irq_type_mut(&mut self) -> Option<&mut IrqType> { 472 Some(&mut self.irq_type) 473 } 474 #[inline(always)] 475 fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>> { 476 Some(&mut self.irq_vector) 477 } 478 } 479 480 /// Pci_Device_Structure_Pci_to_Pci_Bridge pci-to-pci桥设备结构体 481 #[derive(Clone, Debug)] 482 pub struct PciDeviceStructurePciToPciBridge { 483 pub common_header: PciDeviceStructureHeader, 484 // 中断结构体,包括legacy,msi,msix三种情况 485 pub irq_type: IrqType, 486 // 使用的中断号的vec集合 487 pub irq_vector: Vec<IrqNumber>, 488 pub bar0: u32, 489 pub bar1: u32, 490 pub primary_bus_number: u8, 491 pub secondary_bus_number: u8, 492 pub subordinate_bus_number: u8, 493 pub secondary_latency_timer: u8, 494 pub io_base: u8, 495 pub io_limit: u8, 496 pub secondary_status: u16, 497 pub memory_base: u16, 498 pub memory_limit: u16, 499 pub prefetchable_memory_base: u16, 500 pub prefetchable_memory_limit: u16, 501 pub prefetchable_base_upper_32_bits: u32, 502 pub prefetchable_limit_upper_32_bits: u32, 503 pub io_base_upper_16_bits: u16, 504 pub io_limit_upper_16_bits: u16, 505 pub capability_pointer: u8, 506 pub reserved0: u8, 507 pub reserved1: u16, 508 pub expansion_rom_base_address: u32, 509 pub interrupt_line: u8, 510 pub interrupt_pin: u8, 511 pub bridge_control: u16, 512 } 513 impl PciDeviceStructure for PciDeviceStructurePciToPciBridge { 514 #[inline(always)] 515 fn header_type(&self) -> HeaderType { 516 HeaderType::PciPciBridge 517 } 518 #[inline(always)] 519 fn as_pci_to_pci_bridge_device(&self) -> Option<&PciDeviceStructurePciToPciBridge> { 520 Some(self) 521 } 522 #[inline(always)] 523 fn as_pci_to_pci_bridge_device_mut(&mut self) -> Option<&mut PciDeviceStructurePciToPciBridge> { 524 Some(self) 525 } 526 #[inline(always)] 527 fn common_header(&self) -> &PciDeviceStructureHeader { 528 &self.common_header 529 } 530 #[inline(always)] 531 fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader { 532 &mut self.common_header 533 } 534 #[inline(always)] 535 fn irq_type_mut(&mut self) -> Option<&mut IrqType> { 536 Some(&mut self.irq_type) 537 } 538 #[inline(always)] 539 fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>> { 540 Some(&mut self.irq_vector) 541 } 542 } 543 /// Pci_Device_Structure_Pci_to_Cardbus_Bridge Pci_to_Cardbus桥设备结构体 544 #[derive(Clone, Debug)] 545 pub struct PciDeviceStructurePciToCardbusBridge { 546 pub common_header: PciDeviceStructureHeader, 547 pub cardbus_socket_ex_ca_base_address: u32, 548 pub offset_of_capabilities_list: u8, 549 pub reserved: u8, 550 pub secondary_status: u16, 551 pub pci_bus_number: u8, 552 pub card_bus_bus_number: u8, 553 pub subordinate_bus_number: u8, 554 pub card_bus_latency_timer: u8, 555 pub memory_base_address0: u32, 556 pub memory_limit0: u32, 557 pub memory_base_address1: u32, 558 pub memory_limit1: u32, 559 pub io_base_address0: u32, 560 pub io_limit0: u32, 561 pub io_base_address1: u32, 562 pub io_limit1: u32, 563 pub interrupt_line: u8, 564 pub interrupt_pin: u8, 565 pub bridge_control: u16, 566 pub subsystem_device_id: u16, 567 pub subsystem_vendor_id: u16, 568 pub pc_card_legacy_mode_base_address_16_bit: u32, 569 } 570 impl PciDeviceStructure for PciDeviceStructurePciToCardbusBridge { 571 #[inline(always)] 572 fn header_type(&self) -> HeaderType { 573 HeaderType::PciCardbusBridge 574 } 575 #[inline(always)] 576 fn as_pci_to_carbus_bridge_device(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> { 577 Some(self) 578 } 579 #[inline(always)] 580 fn as_pci_to_carbus_bridge_device_mut( 581 &mut self, 582 ) -> Option<&mut PciDeviceStructurePciToCardbusBridge> { 583 Some(self) 584 } 585 #[inline(always)] 586 fn common_header(&self) -> &PciDeviceStructureHeader { 587 &self.common_header 588 } 589 #[inline(always)] 590 fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader { 591 &mut self.common_header 592 } 593 #[inline(always)] 594 fn irq_type_mut(&mut self) -> Option<&mut IrqType> { 595 None 596 } 597 #[inline(always)] 598 fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>> { 599 None 600 } 601 } 602 603 /// 代表一个PCI segement greoup. 604 #[derive(Clone, Debug)] 605 pub struct PciRoot { 606 pub physical_address_base: PhysAddr, //物理地址,acpi获取 607 pub mmio_guard: Option<Arc<MMIOSpaceGuard>>, //映射后的虚拟地址,为方便访问数据这里转化成指针 608 pub segement_group_number: SegmentGroupNumber, //segement greoup的id 609 pub bus_begin: u8, //该分组中的最小bus 610 pub bus_end: u8, //该分组中的最大bus 611 /// 配置空间访问机制 612 pub cam: PciCam, 613 } 614 615 /// PCI配置空间访问机制 616 /// 617 /// 用于访问PCI设备的功能配置空间的一组机制。 618 #[derive(Copy, Clone, Debug, Eq, PartialEq)] 619 pub enum PciCam { 620 /// PCI内存映射配置访问机制 621 /// 622 /// 为每个设备功能提供256字节的配置空间访问。 623 MmioCam, 624 /// PCIe内存映射增强配置访问机制 625 /// 626 /// 为每个设备功能提供4千字节(4096字节)的配置空间访问。 627 Ecam, 628 } 629 630 impl PciCam { 631 /// Returns the total size in bytes of the memory-mapped region. 632 pub const fn size(self) -> u32 { 633 match self { 634 Self::MmioCam => 0x1000000, 635 Self::Ecam => 0x10000000, 636 } 637 } 638 } 639 640 ///线程间共享需要,该结构体只需要在初始化时写入数据,无需读写锁保证线程安全 641 unsafe impl Send for PciRoot {} 642 unsafe impl Sync for PciRoot {} 643 ///实现PciRoot的Display trait,自定义输出 644 impl Display for PciRoot { 645 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 646 write!( 647 f, 648 "PCI Root with segement:{}, bus begin at {}, bus end at {}, physical address at {:?},mapped at {:?}", 649 self.segement_group_number, self.bus_begin, self.bus_end, self.physical_address_base, self.mmio_guard 650 ) 651 } 652 } 653 654 impl PciRoot { 655 /// 此函数用于初始化一个PciRoot结构体实例, 656 /// 该结构体基于ECAM根的物理地址,将其映射到虚拟地址 657 /// 658 /// ## 参数 659 /// 660 /// - segment_group_number: ECAM根的段组号。 661 /// - cam: PCI配置空间访问机制 662 /// 663 /// ## 返回值 664 /// 665 /// - Ok(Self): 初始化成功,返回一个新的结构体实例。 666 /// - Err(PciError): 初始化过程中发生错误,返回错误信息。 667 /// 668 /// ## 副作用 669 /// 670 /// - 成功执行后,结构体的内部状态将被初始化为包含映射后的虚拟地址。 671 pub fn new(segment_group_number: SegmentGroupNumber, cam: PciCam) -> Result<Self, PciError> { 672 assert_eq!(cam, PciCam::Ecam); 673 let mut pci_root = PciArch::ecam_root(segment_group_number)?; 674 pci_root.map()?; 675 Ok(pci_root) 676 } 677 /// @brief 完成物理地址到虚拟地址的映射,并将虚拟地址加入mmio_base变量 678 /// @return 返回错误或Ok(0) 679 fn map(&mut self) -> Result<u8, PciError> { 680 //kdebug!("bus_begin={},bus_end={}", self.bus_begin,self.bus_end); 681 let bus_number = (self.bus_end - self.bus_begin) as u32 + 1; 682 let bus_number_double = (bus_number - 1) / 2 + 1; //一个bus占据1MB空间,计算全部bus占据空间相对于2MB空间的个数 683 684 let size = (bus_number_double as usize) * (PAGE_2M_SIZE as usize); 685 unsafe { 686 let space_guard = mmio_pool() 687 .create_mmio(size) 688 .map_err(|_| PciError::CreateMmioError)?; 689 let space_guard = Arc::new(space_guard); 690 self.mmio_guard = Some(space_guard.clone()); 691 692 assert!(space_guard 693 .map_phys(self.physical_address_base, size) 694 .is_ok()); 695 } 696 return Ok(0); 697 } 698 699 /// # cam_offset - 获得要操作的寄存器相对于mmio_offset的偏移量 700 /// 701 /// 此函数用于计算一个PCI设备中特定寄存器相对于该设备的MMIO基地址的偏移量。 702 /// 703 /// ## 参数 704 /// 705 /// - `bus_device_function`: BusDeviceFunction,用于标识在同一组中的PCI设备。 706 /// - `register_offset`: u16,寄存器在设备中的偏移量。 707 /// 708 /// ## 返回值 709 /// 710 /// - `u32`: 成功时,返回要操作的寄存器相对于mmio_offset的偏移量。 711 /// 712 /// ## Panic 713 /// 714 /// - 此函数在参数有效性方面进行了断言,如果传入的`bus_device_function`无效,将panic。 715 /// - 此函数计算出的地址需要是字对齐的(即地址与0x3对齐)。如果不是,将panic。 716 fn cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 { 717 assert!(bus_device_function.valid()); 718 let bdf = ((bus_device_function.bus - self.bus_begin) as u32) << 8 719 | (bus_device_function.device as u32) << 3 720 | bus_device_function.function as u32; 721 let address = 722 bdf << match self.cam { 723 PciCam::MmioCam => 8, 724 PciCam::Ecam => 12, 725 } | register_offset as u32; 726 // Ensure that address is word-aligned. 727 assert!(address & 0x3 == 0); 728 address 729 } 730 /// @brief 通过bus_device_function和offset读取相应位置寄存器的值(32位) 731 /// @param bus_device_function 在同一个group中pci设备的唯一标识符 732 /// @param register_offset 寄存器在设备中的offset 733 /// @return u32 寄存器读值结果 734 pub fn read_config(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 { 735 let address = self.cam_offset(bus_device_function, register_offset); 736 unsafe { 737 // Right shift to convert from byte offset to word offset. 738 ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32) 739 .add((address >> 2) as usize)) 740 .read_volatile() 741 } 742 } 743 744 /// @brief 通过bus_device_function和offset写入相应位置寄存器值(32位) 745 /// @param bus_device_function 在同一个group中pci设备的唯一标识符 746 /// @param register_offset 寄存器在设备中的offset 747 /// @param data 要写入的值 748 pub fn write_config( 749 &self, 750 bus_device_function: BusDeviceFunction, 751 register_offset: u16, 752 data: u32, 753 ) { 754 let address = self.cam_offset(bus_device_function, register_offset); 755 // Safe because both the `mmio_base` and the address offset are properly aligned, and the 756 // resulting pointer is within the MMIO range of the CAM. 757 unsafe { 758 // Right shift to convert from byte offset to word offset. 759 ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32) 760 .add((address >> 2) as usize)) 761 .write_volatile(data) 762 } 763 } 764 /// @brief 返回迭代器,遍历pcie设备的external_capabilities 765 pub fn external_capabilities( 766 &self, 767 bus_device_function: BusDeviceFunction, 768 ) -> ExternalCapabilityIterator { 769 ExternalCapabilityIterator { 770 root: self, 771 bus_device_function, 772 next_capability_offset: Some(0x100), 773 } 774 } 775 } 776 /// Gets the capabilities 'pointer' for the device function, if any. 777 /// @brief 获取第一个capability 的offset 778 /// @param bus_device_function PCI设备的唯一标识 779 /// @return Option<u8> offset 780 pub fn capabilities_offset(bus_device_function: BusDeviceFunction) -> Option<u8> { 781 let result = pci_root_0().read_config(bus_device_function, STATUS_COMMAND_OFFSET.into()); 782 let status: Status = Status::from_bits_truncate((result >> 16) as u16); 783 if status.contains(Status::CAPABILITIES_LIST) { 784 let cap_pointer = pci_root_0().read_config(bus_device_function, 0x34) as u8 & 0xFC; 785 Some(cap_pointer) 786 } else { 787 None 788 } 789 } 790 791 /// @brief 读取pci设备头部 792 /// @param bus_device_function PCI设备的唯一标识 793 /// @param add_to_list 是否添加到链表 794 /// @return 返回的header(trait 类型) 795 fn pci_read_header( 796 bus_device_function: BusDeviceFunction, 797 add_to_list: bool, 798 ) -> Result<Box<dyn PciDeviceStructure>, PciError> { 799 // 先读取公共header 800 let result = pci_root_0().read_config(bus_device_function, 0x00); 801 let vendor_id = result as u16; 802 let device_id = (result >> 16) as u16; 803 804 let result = pci_root_0().read_config(bus_device_function, 0x04); 805 let command = result as u16; 806 let status = (result >> 16) as u16; 807 808 let result = pci_root_0().read_config(bus_device_function, 0x08); 809 let revision_id = result as u8; 810 let prog_if = (result >> 8) as u8; 811 let subclass = (result >> 16) as u8; 812 let class_code = (result >> 24) as u8; 813 814 let result = pci_root_0().read_config(bus_device_function, 0x0c); 815 let cache_line_size = result as u8; 816 let latency_timer = (result >> 8) as u8; 817 let header_type = (result >> 16) as u8; 818 let bist = (result >> 24) as u8; 819 if vendor_id == 0xffff { 820 return Err(PciError::GetWrongHeader); 821 } 822 let header = PciDeviceStructureHeader { 823 bus_device_function, 824 vendor_id, 825 device_id, 826 command, 827 status, 828 revision_id, 829 prog_if, 830 subclass, 831 class_code, 832 cache_line_size, 833 latency_timer, 834 header_type, 835 bist, 836 }; 837 match HeaderType::from(header_type & 0x7f) { 838 HeaderType::Standard => { 839 let general_device = pci_read_general_device_header(header, &bus_device_function); 840 let box_general_device = Box::new(general_device); 841 let box_general_device_clone = box_general_device.clone(); 842 if add_to_list { 843 PCI_DEVICE_LINKEDLIST.add(box_general_device); 844 } 845 Ok(box_general_device_clone) 846 } 847 HeaderType::PciPciBridge => { 848 let pci_to_pci_bridge = pci_read_pci_to_pci_bridge_header(header, &bus_device_function); 849 let box_pci_to_pci_bridge = Box::new(pci_to_pci_bridge); 850 let box_pci_to_pci_bridge_clone = box_pci_to_pci_bridge.clone(); 851 if add_to_list { 852 PCI_DEVICE_LINKEDLIST.add(box_pci_to_pci_bridge); 853 } 854 Ok(box_pci_to_pci_bridge_clone) 855 } 856 HeaderType::PciCardbusBridge => { 857 let pci_cardbus_bridge = 858 pci_read_pci_to_cardbus_bridge_header(header, &bus_device_function); 859 let box_pci_cardbus_bridge = Box::new(pci_cardbus_bridge); 860 let box_pci_cardbus_bridge_clone = box_pci_cardbus_bridge.clone(); 861 if add_to_list { 862 PCI_DEVICE_LINKEDLIST.add(box_pci_cardbus_bridge); 863 } 864 Ok(box_pci_cardbus_bridge_clone) 865 } 866 HeaderType::Unrecognised(_) => Err(PciError::UnrecognisedHeaderType), 867 } 868 } 869 870 /// @brief 读取type为0x0的pci设备的header 871 /// 本函数只应被 pci_read_header()调用 872 /// @param common_header 共有头部 873 /// @param bus_device_function PCI设备的唯一标识 874 /// @return Pci_Device_Structure_General_Device 标准设备头部 875 fn pci_read_general_device_header( 876 common_header: PciDeviceStructureHeader, 877 bus_device_function: &BusDeviceFunction, 878 ) -> PciDeviceStructureGeneralDevice { 879 let standard_device_bar = PciStandardDeviceBar::default(); 880 let cardbus_cis_pointer = pci_root_0().read_config(*bus_device_function, 0x28); 881 882 let result = pci_root_0().read_config(*bus_device_function, 0x2c); 883 let subsystem_vendor_id = result as u16; 884 let subsystem_id = (result >> 16) as u16; 885 886 let expansion_rom_base_address = pci_root_0().read_config(*bus_device_function, 0x30); 887 888 let result = pci_root_0().read_config(*bus_device_function, 0x34); 889 let capabilities_pointer = result as u8; 890 let reserved0 = (result >> 8) as u8; 891 let reserved1 = (result >> 16) as u16; 892 893 let reserved2 = pci_root_0().read_config(*bus_device_function, 0x38); 894 895 let result = pci_root_0().read_config(*bus_device_function, 0x3c); 896 let interrupt_line = result as u8; 897 let interrupt_pin = (result >> 8) as u8; 898 let min_grant = (result >> 16) as u8; 899 let max_latency = (result >> 24) as u8; 900 PciDeviceStructureGeneralDevice { 901 common_header, 902 irq_type: IrqType::Unused, 903 irq_vector: Vec::new(), 904 standard_device_bar, 905 cardbus_cis_pointer, 906 subsystem_vendor_id, 907 subsystem_id, 908 expansion_rom_base_address, 909 capabilities_pointer, 910 reserved0, 911 reserved1, 912 reserved2, 913 interrupt_line, 914 interrupt_pin, 915 min_grant, 916 max_latency, 917 } 918 } 919 920 /// @brief 读取type为0x1的pci设备的header 921 /// 本函数只应被 pci_read_header()调用 922 /// @param common_header 共有头部 923 /// @param bus_device_function PCI设备的唯一标识 924 /// @return Pci_Device_Structure_Pci_to_Pci_Bridge pci-to-pci 桥设备头部 925 fn pci_read_pci_to_pci_bridge_header( 926 common_header: PciDeviceStructureHeader, 927 bus_device_function: &BusDeviceFunction, 928 ) -> PciDeviceStructurePciToPciBridge { 929 let bar0 = pci_root_0().read_config(*bus_device_function, 0x10); 930 let bar1 = pci_root_0().read_config(*bus_device_function, 0x14); 931 932 let result = pci_root_0().read_config(*bus_device_function, 0x18); 933 934 let primary_bus_number = result as u8; 935 let secondary_bus_number = (result >> 8) as u8; 936 let subordinate_bus_number = (result >> 16) as u8; 937 let secondary_latency_timer = (result >> 24) as u8; 938 939 let result = pci_root_0().read_config(*bus_device_function, 0x1c); 940 let io_base = result as u8; 941 let io_limit = (result >> 8) as u8; 942 let secondary_status = (result >> 16) as u16; 943 944 let result = pci_root_0().read_config(*bus_device_function, 0x20); 945 let memory_base = result as u16; 946 let memory_limit = (result >> 16) as u16; 947 948 let result = pci_root_0().read_config(*bus_device_function, 0x24); 949 let prefetchable_memory_base = result as u16; 950 let prefetchable_memory_limit = (result >> 16) as u16; 951 952 let prefetchable_base_upper_32_bits = pci_root_0().read_config(*bus_device_function, 0x28); 953 let prefetchable_limit_upper_32_bits = pci_root_0().read_config(*bus_device_function, 0x2c); 954 955 let result = pci_root_0().read_config(*bus_device_function, 0x30); 956 let io_base_upper_16_bits = result as u16; 957 let io_limit_upper_16_bits = (result >> 16) as u16; 958 959 let result = pci_root_0().read_config(*bus_device_function, 0x34); 960 let capability_pointer = result as u8; 961 let reserved0 = (result >> 8) as u8; 962 let reserved1 = (result >> 16) as u16; 963 964 let expansion_rom_base_address = pci_root_0().read_config(*bus_device_function, 0x38); 965 966 let result = pci_root_0().read_config(*bus_device_function, 0x3c); 967 let interrupt_line = result as u8; 968 let interrupt_pin = (result >> 8) as u8; 969 let bridge_control = (result >> 16) as u16; 970 PciDeviceStructurePciToPciBridge { 971 common_header, 972 irq_type: IrqType::Unused, 973 irq_vector: Vec::new(), 974 bar0, 975 bar1, 976 primary_bus_number, 977 secondary_bus_number, 978 subordinate_bus_number, 979 secondary_latency_timer, 980 io_base, 981 io_limit, 982 secondary_status, 983 memory_base, 984 memory_limit, 985 prefetchable_memory_base, 986 prefetchable_memory_limit, 987 prefetchable_base_upper_32_bits, 988 prefetchable_limit_upper_32_bits, 989 io_base_upper_16_bits, 990 io_limit_upper_16_bits, 991 capability_pointer, 992 reserved0, 993 reserved1, 994 expansion_rom_base_address, 995 interrupt_line, 996 interrupt_pin, 997 bridge_control, 998 } 999 } 1000 1001 /// @brief 读取type为0x2的pci设备的header 1002 /// 本函数只应被 pci_read_header()调用 1003 /// @param common_header 共有头部 1004 /// @param bus_device_function PCI设备的唯一标识 1005 /// @return Pci_Device_Structure_Pci_to_Cardbus_Bridge pci-to-cardbus 桥设备头部 1006 fn pci_read_pci_to_cardbus_bridge_header( 1007 common_header: PciDeviceStructureHeader, 1008 busdevicefunction: &BusDeviceFunction, 1009 ) -> PciDeviceStructurePciToCardbusBridge { 1010 let cardbus_socket_ex_ca_base_address = pci_root_0().read_config(*busdevicefunction, 0x10); 1011 1012 let result = pci_root_0().read_config(*busdevicefunction, 0x14); 1013 let offset_of_capabilities_list = result as u8; 1014 let reserved = (result >> 8) as u8; 1015 let secondary_status = (result >> 16) as u16; 1016 1017 let result = pci_root_0().read_config(*busdevicefunction, 0x18); 1018 let pci_bus_number = result as u8; 1019 let card_bus_bus_number = (result >> 8) as u8; 1020 let subordinate_bus_number = (result >> 16) as u8; 1021 let card_bus_latency_timer = (result >> 24) as u8; 1022 1023 let memory_base_address0 = pci_root_0().read_config(*busdevicefunction, 0x1c); 1024 let memory_limit0 = pci_root_0().read_config(*busdevicefunction, 0x20); 1025 let memory_base_address1 = pci_root_0().read_config(*busdevicefunction, 0x24); 1026 let memory_limit1 = pci_root_0().read_config(*busdevicefunction, 0x28); 1027 1028 let io_base_address0 = pci_root_0().read_config(*busdevicefunction, 0x2c); 1029 let io_limit0 = pci_root_0().read_config(*busdevicefunction, 0x30); 1030 let io_base_address1 = pci_root_0().read_config(*busdevicefunction, 0x34); 1031 let io_limit1 = pci_root_0().read_config(*busdevicefunction, 0x38); 1032 let result = pci_root_0().read_config(*busdevicefunction, 0x3c); 1033 let interrupt_line = result as u8; 1034 let interrupt_pin = (result >> 8) as u8; 1035 let bridge_control = (result >> 16) as u16; 1036 1037 let result = pci_root_0().read_config(*busdevicefunction, 0x40); 1038 let subsystem_device_id = result as u16; 1039 let subsystem_vendor_id = (result >> 16) as u16; 1040 1041 let pc_card_legacy_mode_base_address_16_bit = 1042 pci_root_0().read_config(*busdevicefunction, 0x44); 1043 PciDeviceStructurePciToCardbusBridge { 1044 common_header, 1045 cardbus_socket_ex_ca_base_address, 1046 offset_of_capabilities_list, 1047 reserved, 1048 secondary_status, 1049 pci_bus_number, 1050 card_bus_bus_number, 1051 subordinate_bus_number, 1052 card_bus_latency_timer, 1053 memory_base_address0, 1054 memory_limit0, 1055 memory_base_address1, 1056 memory_limit1, 1057 io_base_address0, 1058 io_limit0, 1059 io_base_address1, 1060 io_limit1, 1061 interrupt_line, 1062 interrupt_pin, 1063 bridge_control, 1064 subsystem_device_id, 1065 subsystem_vendor_id, 1066 pc_card_legacy_mode_base_address_16_bit, 1067 } 1068 } 1069 1070 /// @brief 检查所有bus上的设备并将其加入链表 1071 /// @return 成功返回ok(),失败返回失败原因 1072 fn pci_check_all_buses() -> Result<u8, PciError> { 1073 kinfo!("Checking all devices in PCI bus..."); 1074 let busdevicefunction = BusDeviceFunction { 1075 bus: 0, 1076 device: 0, 1077 function: 0, 1078 }; 1079 let header = pci_read_header(busdevicefunction, false)?; 1080 let common_header = header.common_header(); 1081 pci_check_bus(0)?; 1082 if common_header.header_type & 0x80 != 0 { 1083 for function in 1..8 { 1084 pci_check_bus(function)?; 1085 } 1086 } 1087 Ok(0) 1088 } 1089 /// @brief 检查特定设备并将其加入链表 1090 /// @return 成功返回ok(),失败返回失败原因 1091 fn pci_check_function(busdevicefunction: BusDeviceFunction) -> Result<u8, PciError> { 1092 //kdebug!("PCI check function {}", busdevicefunction.function); 1093 let header = match pci_read_header(busdevicefunction, true) { 1094 Ok(header) => header, 1095 Err(PciError::GetWrongHeader) => { 1096 return Ok(255); 1097 } 1098 Err(e) => { 1099 return Err(e); 1100 } 1101 }; 1102 let common_header = header.common_header(); 1103 if (common_header.class_code == 0x06) 1104 && (common_header.subclass == 0x04 || common_header.subclass == 0x09) 1105 { 1106 let pci_to_pci_bridge = header 1107 .as_pci_to_pci_bridge_device() 1108 .ok_or(PciError::PciDeviceStructureTransformError)?; 1109 let secondary_bus = pci_to_pci_bridge.secondary_bus_number; 1110 pci_check_bus(secondary_bus)?; 1111 } 1112 Ok(0) 1113 } 1114 1115 /// @brief 检查device上的设备并将其加入链表 1116 /// @return 成功返回ok(),失败返回失败原因 1117 fn pci_check_device(bus: u8, device: u8) -> Result<u8, PciError> { 1118 //kdebug!("PCI check device {}", device); 1119 let busdevicefunction = BusDeviceFunction { 1120 bus, 1121 device, 1122 function: 0, 1123 }; 1124 let header = match pci_read_header(busdevicefunction, false) { 1125 Ok(header) => header, 1126 Err(PciError::GetWrongHeader) => { 1127 //设备不存在,直接返回即可,不用终止遍历 1128 return Ok(255); 1129 } 1130 Err(e) => { 1131 return Err(e); 1132 } 1133 }; 1134 pci_check_function(busdevicefunction)?; 1135 let common_header = header.common_header(); 1136 if common_header.header_type & 0x80 != 0 { 1137 kdebug!( 1138 "Detected multi func device in bus{},device{}", 1139 busdevicefunction.bus, 1140 busdevicefunction.device 1141 ); 1142 // 这是一个多function的设备,因此查询剩余的function 1143 for function in 1..8 { 1144 let busdevicefunction = BusDeviceFunction { 1145 bus, 1146 device, 1147 function, 1148 }; 1149 pci_check_function(busdevicefunction)?; 1150 } 1151 } 1152 Ok(0) 1153 } 1154 /// @brief 检查该bus上的设备并将其加入链表 1155 /// @return 成功返回ok(),失败返回失败原因 1156 fn pci_check_bus(bus: u8) -> Result<u8, PciError> { 1157 //kdebug!("PCI check bus {}", bus); 1158 for device in 0..32 { 1159 pci_check_device(bus, device)?; 1160 } 1161 Ok(0) 1162 } 1163 1164 /// pci初始化函数 1165 #[inline(never)] 1166 pub fn pci_init() { 1167 kinfo!("Initializing PCI bus..."); 1168 if let Err(e) = pci_check_all_buses() { 1169 kerror!("pci init failed when checking bus because of error: {}", e); 1170 return; 1171 } 1172 kinfo!( 1173 "Total pci device and function num = {}", 1174 PCI_DEVICE_LINKEDLIST.num() 1175 ); 1176 let list = PCI_DEVICE_LINKEDLIST.read(); 1177 for box_pci_device in list.iter() { 1178 let common_header = box_pci_device.common_header(); 1179 match box_pci_device.header_type() { 1180 HeaderType::Standard if common_header.status & 0x10 != 0 => { 1181 kinfo!("Found pci standard device with class code ={} subclass={} status={:#x} cap_pointer={:#x} vendor={:#x}, device id={:#x},bdf={}", common_header.class_code, common_header.subclass, common_header.status, box_pci_device.as_standard_device().unwrap().capabilities_pointer,common_header.vendor_id, common_header.device_id,common_header.bus_device_function); 1182 } 1183 HeaderType::Standard => { 1184 kinfo!( 1185 "Found pci standard device with class code ={} subclass={} status={:#x} ", 1186 common_header.class_code, 1187 common_header.subclass, 1188 common_header.status 1189 ); 1190 } 1191 HeaderType::PciPciBridge if common_header.status & 0x10 != 0 => { 1192 kinfo!("Found pci-to-pci bridge device with class code ={} subclass={} status={:#x} cap_pointer={:#x}", common_header.class_code, common_header.subclass, common_header.status, box_pci_device.as_standard_device().unwrap().capabilities_pointer); 1193 } 1194 HeaderType::PciPciBridge => { 1195 kinfo!( 1196 "Found pci-to-pci bridge device with class code ={} subclass={} status={:#x} ", 1197 common_header.class_code, 1198 common_header.subclass, 1199 common_header.status 1200 ); 1201 } 1202 HeaderType::PciCardbusBridge => { 1203 kinfo!( 1204 "Found pcicardbus bridge device with class code ={} subclass={} status={:#x} ", 1205 common_header.class_code, 1206 common_header.subclass, 1207 common_header.status 1208 ); 1209 } 1210 HeaderType::Unrecognised(_) => {} 1211 } 1212 } 1213 kinfo!("PCI bus initialized."); 1214 } 1215 1216 /// An identifier for a PCI bus, device and function. 1217 /// PCI设备的唯一标识 1218 #[derive(Copy, Clone, Debug, Eq, PartialEq)] 1219 pub struct BusDeviceFunction { 1220 /// The PCI bus number, between 0 and 255. 1221 pub bus: u8, 1222 /// The device number on the bus, between 0 and 31. 1223 pub device: u8, 1224 /// The function number of the device, between 0 and 7. 1225 pub function: u8, 1226 } 1227 impl BusDeviceFunction { 1228 /// Returns whether the device and function numbers are valid, i.e. the device is between 0 and 1229 ///@brief 检测BusDeviceFunction实例是否有效 1230 ///@param self 1231 ///@return bool 是否有效 1232 #[allow(dead_code)] 1233 pub fn valid(&self) -> bool { 1234 self.device < 32 && self.function < 8 1235 } 1236 } 1237 ///实现BusDeviceFunction的Display trait,使其可以直接输出 1238 impl Display for BusDeviceFunction { 1239 fn fmt(&self, f: &mut Formatter) -> fmt::Result { 1240 write!( 1241 f, 1242 "bus {} device {} function{}", 1243 self.bus, self.device, self.function 1244 ) 1245 } 1246 } 1247 /// The location allowed for a memory BAR. 1248 /// memory BAR的三种情况 1249 #[derive(Copy, Clone, Debug, Eq, PartialEq)] 1250 pub enum MemoryBarType { 1251 /// The BAR has a 32-bit address and can be mapped anywhere in 32-bit address space. 1252 Width32, 1253 /// The BAR must be mapped below 1MiB. 1254 Below1MiB, 1255 /// The BAR has a 64-bit address and can be mapped anywhere in 64-bit address space. 1256 Width64, 1257 } 1258 ///实现MemoryBarType与u8的类型转换 1259 impl From<MemoryBarType> for u8 { 1260 fn from(bar_type: MemoryBarType) -> Self { 1261 match bar_type { 1262 MemoryBarType::Width32 => 0, 1263 MemoryBarType::Below1MiB => 1, 1264 MemoryBarType::Width64 => 2, 1265 } 1266 } 1267 } 1268 ///实现MemoryBarType与u8的类型转换 1269 impl TryFrom<u8> for MemoryBarType { 1270 type Error = PciError; 1271 fn try_from(value: u8) -> Result<Self, Self::Error> { 1272 match value { 1273 0 => Ok(Self::Width32), 1274 1 => Ok(Self::Below1MiB), 1275 2 => Ok(Self::Width64), 1276 _ => Err(PciError::InvalidBarType), 1277 } 1278 } 1279 } 1280 1281 /// Information about a PCI Base Address Register. 1282 /// BAR的三种类型 Memory/IO/Unused 1283 #[derive(Clone, Debug)] 1284 pub enum BarInfo { 1285 /// The BAR is for a memory region. 1286 Memory { 1287 /// The size of the BAR address and where it can be located. 1288 address_type: MemoryBarType, 1289 /// If true, then reading from the region doesn't have side effects. The CPU may cache reads 1290 /// and merge repeated stores. 1291 prefetchable: bool, 1292 /// The memory address, always 16-byte aligned. 1293 address: u64, 1294 /// The size of the BAR in bytes. 1295 size: u32, 1296 /// The virtaddress for a memory bar(mapped). 1297 mmio_guard: Arc<MMIOSpaceGuard>, 1298 }, 1299 /// The BAR is for an I/O region. 1300 IO { 1301 /// The I/O address, always 4-byte aligned. 1302 address: u32, 1303 /// The size of the BAR in bytes. 1304 size: u32, 1305 }, 1306 Unused, 1307 } 1308 1309 impl BarInfo { 1310 /// Returns the address and size of this BAR if it is a memory bar, or `None` if it is an IO 1311 /// BAR. 1312 ///@brief 得到某个bar的memory_address与size(前提是他的类型为Memory Bar) 1313 ///@param self 1314 ///@return Option<(u64, u32) 是Memory Bar返回内存地址与大小,不是则返回None 1315 pub fn memory_address_size(&self) -> Option<(u64, u32)> { 1316 if let Self::Memory { address, size, .. } = self { 1317 Some((*address, *size)) 1318 } else { 1319 None 1320 } 1321 } 1322 ///@brief 得到某个bar的virtaddress(前提是他的类型为Memory Bar) 1323 ///@param self 1324 ///@return Option<(u64) 是Memory Bar返回映射的虚拟地址,不是则返回None 1325 pub fn virtual_address(&self) -> Option<VirtAddr> { 1326 if let Self::Memory { mmio_guard, .. } = self { 1327 Some(mmio_guard.vaddr()) 1328 } else { 1329 None 1330 } 1331 } 1332 } 1333 ///实现BarInfo的Display trait,自定义输出 1334 impl Display for BarInfo { 1335 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 1336 match self { 1337 Self::Memory { 1338 address_type, 1339 prefetchable, 1340 address, 1341 size, 1342 mmio_guard, 1343 } => write!( 1344 f, 1345 "Memory space at {:#010x}, size {}, type {:?}, prefetchable {}, mmio_guard: {:?}", 1346 address, size, address_type, prefetchable, mmio_guard 1347 ), 1348 Self::IO { address, size } => { 1349 write!(f, "I/O space at {:#010x}, size {}", address, size) 1350 } 1351 Self::Unused => { 1352 write!(f, "Unused bar") 1353 } 1354 } 1355 } 1356 } 1357 // todo 增加对桥的bar的支持 1358 pub trait PciDeviceBar {} 1359 1360 ///一个普通PCI设备(非桥)有6个BAR寄存器,PciStandardDeviceBar存储其全部信息 1361 #[derive(Clone, Debug)] 1362 pub struct PciStandardDeviceBar { 1363 bar0: BarInfo, 1364 bar1: BarInfo, 1365 bar2: BarInfo, 1366 bar3: BarInfo, 1367 bar4: BarInfo, 1368 bar5: BarInfo, 1369 } 1370 1371 impl PciStandardDeviceBar { 1372 ///@brief 得到某个bar的barinfo 1373 ///@param self ,bar_index(0-5) 1374 ///@return Result<&BarInfo, PciError> bar_index在0-5则返回对应的bar_info结构体,超出范围则返回错误 1375 pub fn get_bar(&self, bar_index: u8) -> Result<&BarInfo, PciError> { 1376 match bar_index { 1377 0 => Ok(&self.bar0), 1378 1 => Ok(&self.bar1), 1379 2 => Ok(&self.bar2), 1380 3 => Ok(&self.bar3), 1381 4 => Ok(&self.bar4), 1382 5 => Ok(&self.bar5), 1383 _ => Err(PciError::InvalidBarType), 1384 } 1385 } 1386 } 1387 ///实现PciStandardDeviceBar的Display trait,使其可以直接输出 1388 impl Display for PciStandardDeviceBar { 1389 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 1390 write!( 1391 f, 1392 "\r\nBar0:{}\r\nBar1:{}\r\nBar2:{}\r\nBar3:{}\r\nBar4:{}\r\nBar5:{}", 1393 self.bar0, self.bar1, self.bar2, self.bar3, self.bar4, self.bar5 1394 ) 1395 } 1396 } 1397 ///实现PciStandardDeviceBar的Default trait,使其可以简单初始化 1398 impl Default for PciStandardDeviceBar { 1399 fn default() -> Self { 1400 PciStandardDeviceBar { 1401 bar0: BarInfo::Unused, 1402 bar1: BarInfo::Unused, 1403 bar2: BarInfo::Unused, 1404 bar3: BarInfo::Unused, 1405 bar4: BarInfo::Unused, 1406 bar5: BarInfo::Unused, 1407 } 1408 } 1409 } 1410 1411 ///@brief 将某个pci设备的bar寄存器读取值后映射到虚拟地址 1412 ///@param self ,bus_device_function PCI设备的唯一标识符 1413 ///@return Result<PciStandardDeviceBar, PciError> 成功则返回对应的PciStandardDeviceBar结构体,失败则返回错误类型 1414 pub fn pci_bar_init( 1415 bus_device_function: BusDeviceFunction, 1416 ) -> Result<PciStandardDeviceBar, PciError> { 1417 let mut device_bar: PciStandardDeviceBar = PciStandardDeviceBar::default(); 1418 let mut bar_index_ignore: u8 = 255; 1419 for bar_index in 0..6 { 1420 if bar_index == bar_index_ignore { 1421 continue; 1422 } 1423 let bar_info; 1424 let bar_orig = 1425 pci_root_0().read_config(bus_device_function, (BAR0_OFFSET + 4 * bar_index).into()); 1426 pci_root_0().write_config( 1427 bus_device_function, 1428 (BAR0_OFFSET + 4 * bar_index).into(), 1429 0xffffffff, 1430 ); 1431 let size_mask = 1432 pci_root_0().read_config(bus_device_function, (BAR0_OFFSET + 4 * bar_index).into()); 1433 // A wrapping add is necessary to correctly handle the case of unused BARs, which read back 1434 // as 0, and should be treated as size 0. 1435 let size = (!(size_mask & 0xfffffff0)).wrapping_add(1); 1436 //kdebug!("bar_orig:{:#x},size: {:#x}", bar_orig,size); 1437 // Restore the original value. 1438 pci_root_0().write_config( 1439 bus_device_function, 1440 (BAR0_OFFSET + 4 * bar_index).into(), 1441 bar_orig, 1442 ); 1443 if size == 0 { 1444 continue; 1445 } 1446 if bar_orig & 0x00000001 == 0x00000001 { 1447 // I/O space 1448 let address = bar_orig & 0xfffffffc; 1449 bar_info = BarInfo::IO { address, size }; 1450 } else { 1451 // Memory space 1452 let mut address = u64::from(bar_orig & 0xfffffff0); 1453 let prefetchable = bar_orig & 0x00000008 != 0; 1454 let address_type = MemoryBarType::try_from(((bar_orig & 0x00000006) >> 1) as u8)?; 1455 if address_type == MemoryBarType::Width64 { 1456 if bar_index >= 5 { 1457 return Err(PciError::InvalidBarType); 1458 } 1459 let address_top = pci_root_0().read_config( 1460 bus_device_function, 1461 (BAR0_OFFSET + 4 * (bar_index + 1)).into(), 1462 ); 1463 address |= u64::from(address_top) << 32; 1464 bar_index_ignore = bar_index + 1; //下个bar跳过,因为64位的memory bar覆盖了两个bar 1465 } 1466 let pci_address = PciAddr::new(address as usize); 1467 let paddr = PciArch::address_pci_to_physical(pci_address); //PCI总线域物理地址转换为存储器域物理地址 1468 1469 let space_guard: Arc<MMIOSpaceGuard>; 1470 unsafe { 1471 let size_want = size as usize; 1472 let tmp = mmio_pool() 1473 .create_mmio(size_want) 1474 .map_err(|_| PciError::CreateMmioError)?; 1475 space_guard = Arc::new(tmp); 1476 //kdebug!("Pci bar init: mmio space: {space_guard:?}, paddr={paddr:?}, size_want={size_want}"); 1477 assert!( 1478 space_guard.map_phys(paddr, size_want).is_ok(), 1479 "pci_bar_init: map_phys failed" 1480 ); 1481 } 1482 bar_info = BarInfo::Memory { 1483 address_type, 1484 prefetchable, 1485 address, 1486 size, 1487 mmio_guard: space_guard, 1488 }; 1489 } 1490 match bar_index { 1491 0 => { 1492 device_bar.bar0 = bar_info; 1493 } 1494 1 => { 1495 device_bar.bar1 = bar_info; 1496 } 1497 2 => { 1498 device_bar.bar2 = bar_info; 1499 } 1500 3 => { 1501 device_bar.bar3 = bar_info; 1502 } 1503 4 => { 1504 device_bar.bar4 = bar_info; 1505 } 1506 5 => { 1507 device_bar.bar5 = bar_info; 1508 } 1509 _ => {} 1510 } 1511 } 1512 //kdebug!("pci_device_bar:{}", device_bar); 1513 return Ok(device_bar); 1514 } 1515 1516 /// Information about a PCI device capability. 1517 /// PCI设备的capability的信息 1518 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 1519 pub struct CapabilityInfo { 1520 /// The offset of the capability in the PCI configuration space of the device function. 1521 pub offset: u8, 1522 /// The ID of the capability. 1523 pub id: u8, 1524 /// The third and fourth bytes of the capability, to save reading them again. 1525 pub private_header: u16, 1526 } 1527 1528 /// Iterator over capabilities for a device. 1529 /// 创建迭代器以遍历PCI设备的capability 1530 #[derive(Debug)] 1531 pub struct CapabilityIterator { 1532 pub bus_device_function: BusDeviceFunction, 1533 pub next_capability_offset: Option<u8>, 1534 } 1535 1536 impl Iterator for CapabilityIterator { 1537 type Item = CapabilityInfo; 1538 fn next(&mut self) -> Option<Self::Item> { 1539 let offset = self.next_capability_offset?; 1540 1541 // Read the first 4 bytes of the capability. 1542 let capability_header = pci_root_0().read_config(self.bus_device_function, offset.into()); 1543 let id = capability_header as u8; 1544 let next_offset = (capability_header >> 8) as u8; 1545 let private_header = (capability_header >> 16) as u16; 1546 1547 self.next_capability_offset = if next_offset == 0 { 1548 None 1549 } else if next_offset < 64 || next_offset & 0x3 != 0 { 1550 kwarn!("Invalid next capability offset {:#04x}", next_offset); 1551 None 1552 } else { 1553 Some(next_offset) 1554 }; 1555 1556 Some(CapabilityInfo { 1557 offset, 1558 id, 1559 private_header, 1560 }) 1561 } 1562 } 1563 1564 /// Information about a PCIe device capability. 1565 /// PCIe设备的external capability的信息 1566 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 1567 pub struct ExternalCapabilityInfo { 1568 /// The offset of the capability in the PCI configuration space of the device function. 1569 pub offset: u16, 1570 /// The ID of the capability. 1571 pub id: u16, 1572 /// The third and fourth bytes of the capability, to save reading them again. 1573 pub capability_version: u8, 1574 } 1575 1576 /// Iterator over capabilities for a device. 1577 /// 创建迭代器以遍历PCIe设备的external capability 1578 #[derive(Debug)] 1579 pub struct ExternalCapabilityIterator<'a> { 1580 pub root: &'a PciRoot, 1581 pub bus_device_function: BusDeviceFunction, 1582 pub next_capability_offset: Option<u16>, 1583 } 1584 impl<'a> Iterator for ExternalCapabilityIterator<'a> { 1585 type Item = ExternalCapabilityInfo; 1586 fn next(&mut self) -> Option<Self::Item> { 1587 let offset = self.next_capability_offset?; 1588 1589 // Read the first 4 bytes of the capability. 1590 let capability_header = self.root.read_config(self.bus_device_function, offset); 1591 let id = capability_header as u16; 1592 let next_offset = (capability_header >> 20) as u16; 1593 let capability_version = ((capability_header >> 16) & 0xf) as u8; 1594 1595 self.next_capability_offset = if next_offset == 0 { 1596 None 1597 } else if next_offset < 0x100 || next_offset & 0x3 != 0 { 1598 kwarn!("Invalid next capability offset {:#04x}", next_offset); 1599 None 1600 } else { 1601 Some(next_offset) 1602 }; 1603 1604 Some(ExternalCapabilityInfo { 1605 offset, 1606 id, 1607 capability_version, 1608 }) 1609 } 1610 } 1611