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