xref: /DragonOS/kernel/src/driver/pci/pci.rs (revision 73c607aaddf6e4634cad179a81d3f1bc589f7220)
126d84a31SYJwu2023 use crate::include::bindings::bindings::{
226d84a31SYJwu2023     initial_mm, mm_map, mm_struct, pci_read_config, pci_write_config, VM_DONTCOPY, VM_IO,
326d84a31SYJwu2023 };
426d84a31SYJwu2023 use crate::mm::mmio_buddy::MMIO_POOL;
526d84a31SYJwu2023 use crate::{kdebug, kerror, kwarn};
626d84a31SYJwu2023 use bitflags::bitflags;
726d84a31SYJwu2023 use core::{
826d84a31SYJwu2023     convert::TryFrom,
926d84a31SYJwu2023     fmt::{self, Display, Formatter},
1026d84a31SYJwu2023 };
1126d84a31SYJwu2023 //Bar0寄存器的offset
1226d84a31SYJwu2023 const BAR0_OFFSET: u8 = 0x10;
1326d84a31SYJwu2023 //Status、Command寄存器的offset
1426d84a31SYJwu2023 const STATUS_COMMAND_OFFSET: u8 = 0x04;
1526d84a31SYJwu2023 /// ID for vendor-specific PCI capabilities.(Virtio Capabilities)
1626d84a31SYJwu2023 pub const PCI_CAP_ID_VNDR: u8 = 0x09;
1726d84a31SYJwu2023 
1826d84a31SYJwu2023 bitflags! {
1926d84a31SYJwu2023     /// The status register in PCI configuration space.
2026d84a31SYJwu2023     pub struct Status: u16 {
2126d84a31SYJwu2023         // Bits 0-2 are reserved.
2226d84a31SYJwu2023         /// The state of the device's INTx# signal.
2326d84a31SYJwu2023         const INTERRUPT_STATUS = 1 << 3;
2426d84a31SYJwu2023         /// The device has a linked list of capabilities.
2526d84a31SYJwu2023         const CAPABILITIES_LIST = 1 << 4;
2626d84a31SYJwu2023         /// The device is capabile of running at 66 MHz rather than 33 MHz.
2726d84a31SYJwu2023         const MHZ_66_CAPABLE = 1 << 5;
2826d84a31SYJwu2023         // Bit 6 is reserved.
2926d84a31SYJwu2023         /// The device can accept fast back-to-back transactions not from the same agent.
3026d84a31SYJwu2023         const FAST_BACK_TO_BACK_CAPABLE = 1 << 7;
3126d84a31SYJwu2023         /// The bus agent observed a parity error (if parity error handling is enabled).
3226d84a31SYJwu2023         const MASTER_DATA_PARITY_ERROR = 1 << 8;
3326d84a31SYJwu2023         // Bits 9-10 are DEVSEL timing.
3426d84a31SYJwu2023         /// A target device terminated a transaction with target-abort.
3526d84a31SYJwu2023         const SIGNALED_TARGET_ABORT = 1 << 11;
3626d84a31SYJwu2023         /// A master device transaction was terminated with target-abort.
3726d84a31SYJwu2023         const RECEIVED_TARGET_ABORT = 1 << 12;
3826d84a31SYJwu2023         /// A master device transaction was terminated with master-abort.
3926d84a31SYJwu2023         const RECEIVED_MASTER_ABORT = 1 << 13;
4026d84a31SYJwu2023         /// A device asserts SERR#.
4126d84a31SYJwu2023         const SIGNALED_SYSTEM_ERROR = 1 << 14;
4226d84a31SYJwu2023         /// The device detects a parity error, even if parity error handling is disabled.
4326d84a31SYJwu2023         const DETECTED_PARITY_ERROR = 1 << 15;
4426d84a31SYJwu2023     }
4526d84a31SYJwu2023 }
4626d84a31SYJwu2023 
4726d84a31SYJwu2023 bitflags! {
4826d84a31SYJwu2023     /// The command register in PCI configuration space.
49*73c607aaSYJwu2023     pub struct CommandRegister: u16 {
5026d84a31SYJwu2023         /// The device can respond to I/O Space accesses.
5126d84a31SYJwu2023         const IO_SPACE = 1 << 0;
5226d84a31SYJwu2023         /// The device can respond to Memory Space accesses.
5326d84a31SYJwu2023         const MEMORY_SPACE = 1 << 1;
5426d84a31SYJwu2023         /// The device can behave as a bus master.
5526d84a31SYJwu2023         const BUS_MASTER = 1 << 2;
5626d84a31SYJwu2023         /// The device can monitor Special Cycle operations.
5726d84a31SYJwu2023         const SPECIAL_CYCLES = 1 << 3;
5826d84a31SYJwu2023         /// The device can generate the Memory Write and Invalidate command.
5926d84a31SYJwu2023         const MEMORY_WRITE_AND_INVALIDATE_ENABLE = 1 << 4;
6026d84a31SYJwu2023         /// The device will snoop palette register data.
6126d84a31SYJwu2023         const VGA_PALETTE_SNOOP = 1 << 5;
6226d84a31SYJwu2023         /// The device should take its normal action when a parity error is detected.
6326d84a31SYJwu2023         const PARITY_ERROR_RESPONSE = 1 << 6;
6426d84a31SYJwu2023         // Bit 7 is reserved.
6526d84a31SYJwu2023         /// The SERR# driver is enabled.
6626d84a31SYJwu2023         const SERR_ENABLE = 1 << 8;
6726d84a31SYJwu2023         /// The device is allowed to generate fast back-to-back transactions.
6826d84a31SYJwu2023         const FAST_BACK_TO_BACK_ENABLE = 1 << 9;
6926d84a31SYJwu2023         /// Assertion of the device's INTx# signal is disabled.
7026d84a31SYJwu2023         const INTERRUPT_DISABLE = 1 << 10;
7126d84a31SYJwu2023     }
7226d84a31SYJwu2023 }
7326d84a31SYJwu2023 
7426d84a31SYJwu2023 /// Gets the capabilities 'pointer' for the device function, if any.
7526d84a31SYJwu2023 ///@brief 获取第一个capability 的offset
7626d84a31SYJwu2023 ///@param device_function PCI设备的唯一标识
7726d84a31SYJwu2023 ///@return Option<u8> offset
7826d84a31SYJwu2023 pub fn capabilities_offset(device_function: DeviceFunction) -> Option<u8> {
7926d84a31SYJwu2023     let status: Status = unsafe {
8026d84a31SYJwu2023         let temp = pci_read_config(
8126d84a31SYJwu2023             device_function.bus,
8226d84a31SYJwu2023             device_function.device,
8326d84a31SYJwu2023             device_function.function,
8426d84a31SYJwu2023             STATUS_COMMAND_OFFSET,
8526d84a31SYJwu2023         );
8626d84a31SYJwu2023         Status::from_bits_truncate((temp >> 16) as u16)
8726d84a31SYJwu2023     };
8826d84a31SYJwu2023     if status.contains(Status::CAPABILITIES_LIST) {
8926d84a31SYJwu2023         let cap_pointer = unsafe {
9026d84a31SYJwu2023             let temp = pci_read_config(
9126d84a31SYJwu2023                 device_function.bus,
9226d84a31SYJwu2023                 device_function.device,
9326d84a31SYJwu2023                 device_function.function,
9426d84a31SYJwu2023                 0x34,
9526d84a31SYJwu2023             );
9626d84a31SYJwu2023             temp as u8 & 0xFC
9726d84a31SYJwu2023         };
9826d84a31SYJwu2023         Some(cap_pointer)
9926d84a31SYJwu2023     } else {
10026d84a31SYJwu2023         None
10126d84a31SYJwu2023     }
10226d84a31SYJwu2023 }
10326d84a31SYJwu2023 /// An identifier for a PCI bus, device and function.
10426d84a31SYJwu2023 /// PCI设备的唯一标识
10526d84a31SYJwu2023 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
10626d84a31SYJwu2023 pub struct DeviceFunction {
10726d84a31SYJwu2023     /// The PCI bus number, between 0 and 255.
10826d84a31SYJwu2023     pub bus: u8,
10926d84a31SYJwu2023     /// The device number on the bus, between 0 and 31.
11026d84a31SYJwu2023     pub device: u8,
11126d84a31SYJwu2023     /// The function number of the device, between 0 and 7.
11226d84a31SYJwu2023     pub function: u8,
11326d84a31SYJwu2023 }
11426d84a31SYJwu2023 ///PCI的Error
11526d84a31SYJwu2023 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
11626d84a31SYJwu2023 pub enum PciError {
11726d84a31SYJwu2023     /// The device reported an invalid BAR type.
11826d84a31SYJwu2023     InvalidBarType,
11926d84a31SYJwu2023     CreateMmioError,
12026d84a31SYJwu2023 }
12126d84a31SYJwu2023 ///实现PciError的Display trait,使其可以直接输出
12226d84a31SYJwu2023 impl Display for PciError {
12326d84a31SYJwu2023     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
12426d84a31SYJwu2023         match self {
12526d84a31SYJwu2023             Self::InvalidBarType => write!(f, "Invalid PCI BAR type."),
12626d84a31SYJwu2023             Self::CreateMmioError => write!(f, "Error occurred while creating mmio"),
12726d84a31SYJwu2023         }
12826d84a31SYJwu2023     }
12926d84a31SYJwu2023 }
13026d84a31SYJwu2023 
13126d84a31SYJwu2023 impl DeviceFunction {
13226d84a31SYJwu2023     /// Returns whether the device and function numbers are valid, i.e. the device is between 0 and
13326d84a31SYJwu2023     /// 31, and the function is between 0 and 7.
13426d84a31SYJwu2023     /// @brief 检测DeviceFunction实例是否有效
13526d84a31SYJwu2023     /// @param self
13626d84a31SYJwu2023     /// @return bool 是否有效
137*73c607aaSYJwu2023     #[allow(dead_code)]
13826d84a31SYJwu2023     pub fn valid(&self) -> bool {
13926d84a31SYJwu2023         self.device < 32 && self.function < 8
14026d84a31SYJwu2023     }
14126d84a31SYJwu2023 }
14226d84a31SYJwu2023 ///实现DeviceFunction的Display trait,使其可以直接输出
14326d84a31SYJwu2023 impl Display for DeviceFunction {
14426d84a31SYJwu2023     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
14526d84a31SYJwu2023         write!(f, "{:02x}:{:02x}.{}", self.bus, self.device, self.function)
14626d84a31SYJwu2023     }
14726d84a31SYJwu2023 }
14826d84a31SYJwu2023 /// The location allowed for a memory BAR.
14926d84a31SYJwu2023 /// memory BAR的三种情况
15026d84a31SYJwu2023 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
15126d84a31SYJwu2023 pub enum MemoryBarType {
15226d84a31SYJwu2023     /// The BAR has a 32-bit address and can be mapped anywhere in 32-bit address space.
15326d84a31SYJwu2023     Width32,
15426d84a31SYJwu2023     /// The BAR must be mapped below 1MiB.
15526d84a31SYJwu2023     Below1MiB,
15626d84a31SYJwu2023     /// The BAR has a 64-bit address and can be mapped anywhere in 64-bit address space.
15726d84a31SYJwu2023     Width64,
15826d84a31SYJwu2023 }
15926d84a31SYJwu2023 ///实现MemoryBarType与u8的类型转换
16026d84a31SYJwu2023 impl From<MemoryBarType> for u8 {
16126d84a31SYJwu2023     fn from(bar_type: MemoryBarType) -> Self {
16226d84a31SYJwu2023         match bar_type {
16326d84a31SYJwu2023             MemoryBarType::Width32 => 0,
16426d84a31SYJwu2023             MemoryBarType::Below1MiB => 1,
16526d84a31SYJwu2023             MemoryBarType::Width64 => 2,
16626d84a31SYJwu2023         }
16726d84a31SYJwu2023     }
16826d84a31SYJwu2023 }
16926d84a31SYJwu2023 ///实现MemoryBarType与u8的类型转换
17026d84a31SYJwu2023 impl TryFrom<u8> for MemoryBarType {
17126d84a31SYJwu2023     type Error = PciError;
17226d84a31SYJwu2023     fn try_from(value: u8) -> Result<Self, Self::Error> {
17326d84a31SYJwu2023         match value {
17426d84a31SYJwu2023             0 => Ok(Self::Width32),
17526d84a31SYJwu2023             1 => Ok(Self::Below1MiB),
17626d84a31SYJwu2023             2 => Ok(Self::Width64),
17726d84a31SYJwu2023             _ => Err(PciError::InvalidBarType),
17826d84a31SYJwu2023         }
17926d84a31SYJwu2023     }
18026d84a31SYJwu2023 }
18126d84a31SYJwu2023 
18226d84a31SYJwu2023 /// Information about a PCI Base Address Register.
18326d84a31SYJwu2023 /// BAR的三种类型 Memory/IO/Unused
18426d84a31SYJwu2023 #[derive(Clone, Debug, Eq, PartialEq)]
18526d84a31SYJwu2023 pub enum BarInfo {
18626d84a31SYJwu2023     /// The BAR is for a memory region.
18726d84a31SYJwu2023     Memory {
18826d84a31SYJwu2023         /// The size of the BAR address and where it can be located.
18926d84a31SYJwu2023         address_type: MemoryBarType,
19026d84a31SYJwu2023         /// If true, then reading from the region doesn't have side effects. The CPU may cache reads
19126d84a31SYJwu2023         /// and merge repeated stores.
19226d84a31SYJwu2023         prefetchable: bool,
19326d84a31SYJwu2023         /// The memory address, always 16-byte aligned.
19426d84a31SYJwu2023         address: u64,
19526d84a31SYJwu2023         /// The size of the BAR in bytes.
19626d84a31SYJwu2023         size: u32,
19726d84a31SYJwu2023         /// The virtaddress for a memory bar(mapped).
19826d84a31SYJwu2023         virtaddress: u64,
19926d84a31SYJwu2023     },
20026d84a31SYJwu2023     /// The BAR is for an I/O region.
20126d84a31SYJwu2023     IO {
20226d84a31SYJwu2023         /// The I/O address, always 4-byte aligned.
20326d84a31SYJwu2023         address: u32,
20426d84a31SYJwu2023         /// The size of the BAR in bytes.
20526d84a31SYJwu2023         size: u32,
20626d84a31SYJwu2023     },
20726d84a31SYJwu2023     Unused,
20826d84a31SYJwu2023 }
20926d84a31SYJwu2023 
21026d84a31SYJwu2023 impl BarInfo {
21126d84a31SYJwu2023     /// Returns the address and size of this BAR if it is a memory bar, or `None` if it is an IO
21226d84a31SYJwu2023     /// BAR.
21326d84a31SYJwu2023     ///@brief 得到某个bar的memory_address与size(前提是他的类型为Memory Bar)
21426d84a31SYJwu2023     ///@param self
21526d84a31SYJwu2023     ///@return Option<(u64, u32) 是Memory Bar返回内存地址与大小,不是则返回None
21626d84a31SYJwu2023     pub fn memory_address_size(&self) -> Option<(u64, u32)> {
21726d84a31SYJwu2023         if let Self::Memory { address, size, .. } = self {
21826d84a31SYJwu2023             Some((*address, *size))
21926d84a31SYJwu2023         } else {
22026d84a31SYJwu2023             None
22126d84a31SYJwu2023         }
22226d84a31SYJwu2023     }
22326d84a31SYJwu2023     ///@brief 得到某个bar的virtaddress(前提是他的类型为Memory Bar)
22426d84a31SYJwu2023     ///@param self
22526d84a31SYJwu2023     ///@return Option<(u64) 是Memory Bar返回映射的虚拟地址,不是则返回None
22626d84a31SYJwu2023     pub fn virtual_address(&self) -> Option<u64> {
22726d84a31SYJwu2023         if let Self::Memory { virtaddress, .. } = self {
22826d84a31SYJwu2023             Some(*virtaddress)
22926d84a31SYJwu2023         } else {
23026d84a31SYJwu2023             None
23126d84a31SYJwu2023         }
23226d84a31SYJwu2023     }
23326d84a31SYJwu2023 }
23426d84a31SYJwu2023 ///实现BarInfo的Display trait,使其可以直接输出
23526d84a31SYJwu2023 impl Display for BarInfo {
23626d84a31SYJwu2023     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
23726d84a31SYJwu2023         match self {
23826d84a31SYJwu2023             Self::Memory {
23926d84a31SYJwu2023                 address_type,
24026d84a31SYJwu2023                 prefetchable,
24126d84a31SYJwu2023                 address,
24226d84a31SYJwu2023                 size,
24326d84a31SYJwu2023                 virtaddress,
24426d84a31SYJwu2023             } => write!(
24526d84a31SYJwu2023                 f,
24626d84a31SYJwu2023                 "Memory space at {:#010x}, size {}, type {:?}, prefetchable {},mapped at {:#x}",
24726d84a31SYJwu2023                 address, size, address_type, prefetchable, virtaddress
24826d84a31SYJwu2023             ),
24926d84a31SYJwu2023             Self::IO { address, size } => {
25026d84a31SYJwu2023                 write!(f, "I/O space at {:#010x}, size {}", address, size)
25126d84a31SYJwu2023             }
25226d84a31SYJwu2023             Self::Unused => {
25326d84a31SYJwu2023                 write!(f, "Unused bar")
25426d84a31SYJwu2023             }
25526d84a31SYJwu2023         }
25626d84a31SYJwu2023     }
25726d84a31SYJwu2023 }
25826d84a31SYJwu2023 ///一个PCI设备有6个BAR寄存器,PciDeviceBar存储其全部信息
25926d84a31SYJwu2023 #[derive(Clone, Debug, Eq, PartialEq)]
26026d84a31SYJwu2023 pub struct PciDeviceBar {
26126d84a31SYJwu2023     bar0: BarInfo,
26226d84a31SYJwu2023     bar1: BarInfo,
26326d84a31SYJwu2023     bar2: BarInfo,
26426d84a31SYJwu2023     bar3: BarInfo,
26526d84a31SYJwu2023     bar4: BarInfo,
26626d84a31SYJwu2023     bar5: BarInfo,
26726d84a31SYJwu2023 }
26826d84a31SYJwu2023 
26926d84a31SYJwu2023 impl PciDeviceBar {
27026d84a31SYJwu2023     ///@brief 得到某个bar的barinfo
27126d84a31SYJwu2023     ///@param self ,bar_index(0-5)
27226d84a31SYJwu2023     ///@return Result<&BarInfo, PciError> bar_index在0-5则返回对应的bar_info结构体,超出范围则返回错误
27326d84a31SYJwu2023     pub fn get_bar(&self, bar_index: u8) -> Result<&BarInfo, PciError> {
27426d84a31SYJwu2023         match bar_index {
27526d84a31SYJwu2023             0 => Ok(&self.bar0),
27626d84a31SYJwu2023             1 => Ok(&self.bar1),
27726d84a31SYJwu2023             2 => Ok(&self.bar2),
27826d84a31SYJwu2023             3 => Ok(&self.bar3),
27926d84a31SYJwu2023             4 => Ok(&self.bar4),
28026d84a31SYJwu2023             _ => Err(PciError::InvalidBarType),
28126d84a31SYJwu2023         }
28226d84a31SYJwu2023     }
28326d84a31SYJwu2023 }
28426d84a31SYJwu2023 ///实现PciDeviceBar的Display trait,使其可以直接输出
28526d84a31SYJwu2023 impl Display for PciDeviceBar {
28626d84a31SYJwu2023     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
28726d84a31SYJwu2023         write!(
28826d84a31SYJwu2023             f,
28926d84a31SYJwu2023             "\r\nBar0:{}\r\n Bar1:{}\r\n Bar2:{}\r\n Bar3:{}\r\nBar4:{}\r\nBar5:{}",
29026d84a31SYJwu2023             self.bar0, self.bar1, self.bar2, self.bar3, self.bar4, self.bar5
29126d84a31SYJwu2023         )
29226d84a31SYJwu2023     }
29326d84a31SYJwu2023 }
29426d84a31SYJwu2023 ///实现PciDeviceBar的Default trait,使其可以简单初始化
29526d84a31SYJwu2023 impl Default for PciDeviceBar {
29626d84a31SYJwu2023     fn default() -> Self {
29726d84a31SYJwu2023         PciDeviceBar {
29826d84a31SYJwu2023             bar0: BarInfo::Unused,
29926d84a31SYJwu2023             bar1: BarInfo::Unused,
30026d84a31SYJwu2023             bar2: BarInfo::Unused,
30126d84a31SYJwu2023             bar3: BarInfo::Unused,
30226d84a31SYJwu2023             bar4: BarInfo::Unused,
30326d84a31SYJwu2023             bar5: BarInfo::Unused,
30426d84a31SYJwu2023         }
30526d84a31SYJwu2023     }
30626d84a31SYJwu2023 }
30726d84a31SYJwu2023 
30826d84a31SYJwu2023 ///@brief 将某个pci设备的bar全部初始化,memory
30926d84a31SYJwu2023 ///@param self ,device_function PCI设备的唯一标识符
31026d84a31SYJwu2023 ///@return Result<PciDeviceBar, PciError> 成功则返回对应的PciDeviceBar结构体,失败则返回错误类型
31126d84a31SYJwu2023 pub fn pci_bar_init(device_function: DeviceFunction) -> Result<PciDeviceBar, PciError> {
31226d84a31SYJwu2023     let mut device_bar: PciDeviceBar = PciDeviceBar::default();
31326d84a31SYJwu2023     let mut bar_index_ignore: u8 = 255;
31426d84a31SYJwu2023     for bar_index in 0..6 {
31526d84a31SYJwu2023         if bar_index == bar_index_ignore {
31626d84a31SYJwu2023             continue;
31726d84a31SYJwu2023         }
31826d84a31SYJwu2023         let bar_info;
31926d84a31SYJwu2023         let mut virtaddress: u64 = 0;
32026d84a31SYJwu2023         let bar_orig = unsafe {
32126d84a31SYJwu2023             let bar_temp = pci_read_config(
32226d84a31SYJwu2023                 device_function.bus,
32326d84a31SYJwu2023                 device_function.device,
32426d84a31SYJwu2023                 device_function.function,
32526d84a31SYJwu2023                 BAR0_OFFSET + 4 * bar_index,
32626d84a31SYJwu2023             );
32726d84a31SYJwu2023             bar_temp
32826d84a31SYJwu2023         };
32926d84a31SYJwu2023         unsafe {
33026d84a31SYJwu2023             pci_write_config(
33126d84a31SYJwu2023                 device_function.bus,
33226d84a31SYJwu2023                 device_function.device,
33326d84a31SYJwu2023                 device_function.function,
33426d84a31SYJwu2023                 BAR0_OFFSET + 4 * bar_index,
33526d84a31SYJwu2023                 0xffffffff,
33626d84a31SYJwu2023             );
33726d84a31SYJwu2023         }
33826d84a31SYJwu2023         let size_mask = unsafe {
33926d84a31SYJwu2023             let bar_temp = pci_read_config(
34026d84a31SYJwu2023                 device_function.bus,
34126d84a31SYJwu2023                 device_function.device,
34226d84a31SYJwu2023                 device_function.function,
34326d84a31SYJwu2023                 BAR0_OFFSET + 4 * bar_index,
34426d84a31SYJwu2023             );
34526d84a31SYJwu2023             bar_temp
34626d84a31SYJwu2023         };
34726d84a31SYJwu2023         // A wrapping add is necessary to correctly handle the case of unused BARs, which read back
34826d84a31SYJwu2023         // as 0, and should be treated as size 0.
34926d84a31SYJwu2023         let size = (!(size_mask & 0xfffffff0)).wrapping_add(1);
35026d84a31SYJwu2023         //kdebug!("bar_orig:{:#x},size: {:#x}", bar_orig,size);
35126d84a31SYJwu2023         // Restore the original value.
35226d84a31SYJwu2023         unsafe {
35326d84a31SYJwu2023             pci_write_config(
35426d84a31SYJwu2023                 device_function.bus,
35526d84a31SYJwu2023                 device_function.device,
35626d84a31SYJwu2023                 device_function.function,
35726d84a31SYJwu2023                 BAR0_OFFSET + 4 * bar_index,
35826d84a31SYJwu2023                 bar_orig,
35926d84a31SYJwu2023             );
36026d84a31SYJwu2023         }
36126d84a31SYJwu2023         if size == 0 {
36226d84a31SYJwu2023             continue;
36326d84a31SYJwu2023         }
36426d84a31SYJwu2023         if bar_orig & 0x00000001 == 0x00000001 {
36526d84a31SYJwu2023             // I/O space
36626d84a31SYJwu2023             let address = bar_orig & 0xfffffffc;
36726d84a31SYJwu2023             bar_info = BarInfo::IO { address, size };
36826d84a31SYJwu2023         } else {
36926d84a31SYJwu2023             // Memory space
37026d84a31SYJwu2023             let mut address = u64::from(bar_orig & 0xfffffff0);
37126d84a31SYJwu2023             let prefetchable = bar_orig & 0x00000008 != 0;
37226d84a31SYJwu2023             let address_type = MemoryBarType::try_from(((bar_orig & 0x00000006) >> 1) as u8)?;
37326d84a31SYJwu2023             if address_type == MemoryBarType::Width64 {
37426d84a31SYJwu2023                 if bar_index >= 5 {
37526d84a31SYJwu2023                     return Err(PciError::InvalidBarType);
37626d84a31SYJwu2023                 }
37726d84a31SYJwu2023                 let address_top = unsafe {
37826d84a31SYJwu2023                     let bar_temp = pci_read_config(
37926d84a31SYJwu2023                         device_function.bus,
38026d84a31SYJwu2023                         device_function.device,
38126d84a31SYJwu2023                         device_function.function,
38226d84a31SYJwu2023                         BAR0_OFFSET + 4 * (bar_index + 1),
38326d84a31SYJwu2023                     );
38426d84a31SYJwu2023                     bar_temp
38526d84a31SYJwu2023                 };
38626d84a31SYJwu2023                 address |= u64::from(address_top) << 32;
38726d84a31SYJwu2023                 bar_index_ignore = bar_index + 1; //下个bar跳过,因为64位的memory bar覆盖了两个bar
38826d84a31SYJwu2023             }
38926d84a31SYJwu2023             //kdebug!("address={:#x},size={:#x}",address,size);
39026d84a31SYJwu2023             unsafe {
39126d84a31SYJwu2023                 let vaddr_ptr = &mut virtaddress as *mut u64;
39226d84a31SYJwu2023                 let mut virtsize: u64 = 0;
39326d84a31SYJwu2023                 let virtsize_ptr = &mut virtsize as *mut u64;
39426d84a31SYJwu2023                 let initial_mm_ptr = &mut initial_mm as *mut mm_struct;
39526d84a31SYJwu2023                 //kdebug!("size want={:#x}", size);
39626d84a31SYJwu2023                 if let Err(_) = MMIO_POOL.create_mmio(
39726d84a31SYJwu2023                     size,
39826d84a31SYJwu2023                     (VM_IO | VM_DONTCOPY) as u64,
39926d84a31SYJwu2023                     vaddr_ptr,
40026d84a31SYJwu2023                     virtsize_ptr,
40126d84a31SYJwu2023                 ) {
40226d84a31SYJwu2023                     kerror!("Create mmio failed when initing pci bar");
40326d84a31SYJwu2023                     return Err(PciError::CreateMmioError);
40426d84a31SYJwu2023                 };
40526d84a31SYJwu2023                 //kdebug!("virtaddress={:#x},virtsize={:#x}",virtaddress,virtsize);
40626d84a31SYJwu2023                 mm_map(initial_mm_ptr, virtaddress, size as u64, address);
40726d84a31SYJwu2023             }
40826d84a31SYJwu2023             bar_info = BarInfo::Memory {
40926d84a31SYJwu2023                 address_type,
41026d84a31SYJwu2023                 prefetchable,
41126d84a31SYJwu2023                 address,
41226d84a31SYJwu2023                 size,
41326d84a31SYJwu2023                 virtaddress,
41426d84a31SYJwu2023             };
41526d84a31SYJwu2023         }
41626d84a31SYJwu2023         match bar_index {
41726d84a31SYJwu2023             0 => {
41826d84a31SYJwu2023                 device_bar.bar0 = bar_info;
41926d84a31SYJwu2023             }
42026d84a31SYJwu2023             1 => {
42126d84a31SYJwu2023                 device_bar.bar1 = bar_info;
42226d84a31SYJwu2023             }
42326d84a31SYJwu2023             2 => {
42426d84a31SYJwu2023                 device_bar.bar2 = bar_info;
42526d84a31SYJwu2023             }
42626d84a31SYJwu2023             3 => {
42726d84a31SYJwu2023                 device_bar.bar3 = bar_info;
42826d84a31SYJwu2023             }
42926d84a31SYJwu2023             4 => {
43026d84a31SYJwu2023                 device_bar.bar4 = bar_info;
43126d84a31SYJwu2023             }
43226d84a31SYJwu2023             5 => {
43326d84a31SYJwu2023                 device_bar.bar5 = bar_info;
43426d84a31SYJwu2023             }
43526d84a31SYJwu2023             _ => {}
43626d84a31SYJwu2023         }
43726d84a31SYJwu2023     }
43826d84a31SYJwu2023     kdebug!("pci_device_bar:{}", device_bar);
43926d84a31SYJwu2023     return Ok(device_bar);
44026d84a31SYJwu2023 }
44126d84a31SYJwu2023 
44226d84a31SYJwu2023 /// Information about a PCI device capability.
44326d84a31SYJwu2023 /// PCI设备的capability的信息
44426d84a31SYJwu2023 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
44526d84a31SYJwu2023 pub struct CapabilityInfo {
44626d84a31SYJwu2023     /// The offset of the capability in the PCI configuration space of the device function.
44726d84a31SYJwu2023     pub offset: u8,
44826d84a31SYJwu2023     /// The ID of the capability.
44926d84a31SYJwu2023     pub id: u8,
45026d84a31SYJwu2023     /// The third and fourth bytes of the capability, to save reading them again.
45126d84a31SYJwu2023     pub private_header: u16,
45226d84a31SYJwu2023 }
453*73c607aaSYJwu2023 
45426d84a31SYJwu2023 /// Iterator over capabilities for a device.
45526d84a31SYJwu2023 /// 创建迭代器以遍历PCI设备的capability
45626d84a31SYJwu2023 #[derive(Debug)]
45726d84a31SYJwu2023 pub struct CapabilityIterator {
45826d84a31SYJwu2023     pub device_function: DeviceFunction,
45926d84a31SYJwu2023     pub next_capability_offset: Option<u8>,
46026d84a31SYJwu2023 }
46126d84a31SYJwu2023 
46226d84a31SYJwu2023 impl Iterator for CapabilityIterator {
46326d84a31SYJwu2023     type Item = CapabilityInfo;
46426d84a31SYJwu2023     fn next(&mut self) -> Option<Self::Item> {
46526d84a31SYJwu2023         let offset = self.next_capability_offset?;
46626d84a31SYJwu2023 
46726d84a31SYJwu2023         // Read the first 4 bytes of the capability.
46826d84a31SYJwu2023         let capability_header = unsafe {
46926d84a31SYJwu2023             let temp = pci_read_config(
47026d84a31SYJwu2023                 self.device_function.bus,
47126d84a31SYJwu2023                 self.device_function.device,
47226d84a31SYJwu2023                 self.device_function.function,
47326d84a31SYJwu2023                 offset,
47426d84a31SYJwu2023             );
47526d84a31SYJwu2023             temp
47626d84a31SYJwu2023         };
47726d84a31SYJwu2023         let id = capability_header as u8;
47826d84a31SYJwu2023         let next_offset = (capability_header >> 8) as u8;
47926d84a31SYJwu2023         let private_header = (capability_header >> 16) as u16;
48026d84a31SYJwu2023 
48126d84a31SYJwu2023         self.next_capability_offset = if next_offset == 0 {
48226d84a31SYJwu2023             None
48326d84a31SYJwu2023         } else if next_offset < 64 || next_offset & 0x3 != 0 {
48426d84a31SYJwu2023             kwarn!("Invalid next capability offset {:#04x}", next_offset);
48526d84a31SYJwu2023             None
48626d84a31SYJwu2023         } else {
48726d84a31SYJwu2023             Some(next_offset)
48826d84a31SYJwu2023         };
48926d84a31SYJwu2023 
49026d84a31SYJwu2023         Some(CapabilityInfo {
49126d84a31SYJwu2023             offset,
49226d84a31SYJwu2023             id,
49326d84a31SYJwu2023             private_header,
49426d84a31SYJwu2023         })
49526d84a31SYJwu2023     }
49626d84a31SYJwu2023 }
497*73c607aaSYJwu2023 
498*73c607aaSYJwu2023 /// @brief 设置PCI Config Space里面的Command Register
499*73c607aaSYJwu2023 ///
500*73c607aaSYJwu2023 /// @param device_function 设备
501*73c607aaSYJwu2023 /// @param value command register要被设置成的值
502*73c607aaSYJwu2023 pub fn set_command_register(device_function: &DeviceFunction, value: CommandRegister) {
503*73c607aaSYJwu2023     unsafe {
504*73c607aaSYJwu2023         pci_write_config(
505*73c607aaSYJwu2023             device_function.bus,
506*73c607aaSYJwu2023             device_function.device,
507*73c607aaSYJwu2023             device_function.function,
508*73c607aaSYJwu2023             STATUS_COMMAND_OFFSET,
509*73c607aaSYJwu2023             value.bits().into(),
510*73c607aaSYJwu2023         );
511*73c607aaSYJwu2023     }
512*73c607aaSYJwu2023 }
513*73c607aaSYJwu2023 /// @brief 使能对PCI Memory/IO空间的写入,使能PCI设备作为主设备(主动进行Memory的写入等,msix中断使用到)
514*73c607aaSYJwu2023 ///
515*73c607aaSYJwu2023 /// @param device_function 设备
516*73c607aaSYJwu2023 pub fn pci_enable_master(device_function: DeviceFunction) {
517*73c607aaSYJwu2023     set_command_register(
518*73c607aaSYJwu2023         &device_function,
519*73c607aaSYJwu2023         CommandRegister::IO_SPACE | CommandRegister::MEMORY_SPACE | CommandRegister::BUS_MASTER,
520*73c607aaSYJwu2023     );
521*73c607aaSYJwu2023 }
522