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