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