在虚拟机中,如果要passthrough pci设备,流程一般是这样的:VMM会分配一段MMIO空间给BAR。如果bar空间需要map,则需要避开需要trap的区域,比如msix cap的区域。OS初始化的时候,kernel可能会重新分配一段物理地址空间给BAR,然后通过写入BAR寄存器来改变寄存器的值,VMM这时候可能会重新map这段空间,称之为reprogram。
读取msix中断表的地址,table地址位于第bir个bar的table_offset位置 pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE, &table_offset); bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); //读取bir table_offset &= PCI_MSIX_TABLE_OFFSET; //读取table偏移 phys_addr = pci_resource_start...
请求者接收到的完成报文中的Request ID与请求者BDF不一致; 请求者接收到的完成报文中的Comleter ID与所有Outstanding请求中的Request ID不一致; 请求者接收到的完成报文,检查其中Tag,发现并无对应的Outstanding请求。 [17] Receiver Overflow Status (Optional) 接收端收到的TLP多于可用的接收缓冲空间。出现这种问题,要...
u16 aer_cap;/*AER capability offset*/#endifu8 pcie_cap;/*PCIe capability offset*/u8 msi_cap;/*MSI capability offset*/u8 msix_cap;/*MSI-X capability offset*/u8 pcie_mpss:3;/*PCIe Max Payload Size Supported*/u8 rom_base_reg;/*which config register controls the ROM*/u8 pin;/*which ...
1、pci_device_id: 在介绍该结构之前,让我们来看看PCI的地址空间:I/O空间,存储空间,配置空间。 CPU 可以访问PCI设备上的所有地址空间,其中I/O空间和存储空间提供给设备驱动程序使用,而配置空间则由Linux内核中的PCI初始化代码使用,内核在 启动时负责对所有PCI设备进行初始化,配置好所有的PCI设备,包括中断号以及I...
status = pci_msi_check_device(dev, 1, PCI_CAP_ID_MSI); if(status) returnstatus; WARN_ON(!!dev->msi_enabled); if(dev->msix_enabled) { dev_info(&dev->dev,"can't enable MSI " "(MSI-X already enabled)\n"); return-EINVAL; ...
void msix_set_message(PCIDevice *dev, int vector, struct MSIMessage msg) { uint8_t *table_entry = dev->msix_table + vector * PCI_MSIX_ENTRY_SIZE; pci_set_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR, msg.address); pci_set_long(table_entry + PCI_MSIX_ENTRY_DATA, msg.data)...
u8 msix_cap;/* MSI-X capability offset */ u8 pcie_mpss:3;/* PCI-E Max Payload Size Supported */ u8 rom_base_reg;/* which config register controls the ROM */ u8 pin;/* which interrupt pin this device uses */ u16 pcie_flags_reg;/* cached PCI-E Capabilities Register */ ...
msix pciexpress cap_listconfiguration: latency=0*-network:0description: Wireless interfacephysical id...
msix.lock() .unwrap() .notify(0, self.dev_id.load(Ordering::Acquire)); } else { error!("Failed to send interrupt: msix does not exist"); } } 1. 2. 3. 4. 5. 6. 7. 8. 9. 热拔实现 对于设备热拔请求的逻辑主要在 unplug_request 函数,该函数负责更新寄存器,并且通过调用 hotplug_...