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