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