Articles of pci

Linux如何testingPCIe驱动程序?

我写了一个简单的PCIe驱动程序,我想testing它是否工作。 例如,如果可以写入和读取从设备使用的内存。 我怎样才能做到这一点? 哪些东西应该被certificate呢?

PCI枚举hack以数据中止exception结束

我正在一个arm-linux板上有几个PCI插槽。 我想检查UBoot中PCI模块的供应商ID /设备ID。 所以我将PCI驱动程序的初始化部分从linux移植到UBoot。 Hack:由于我的主板上的PCI拓扑结构是固定的,所以我在UBoot中自由地对总线编号(pirmary,secondary,subordinate)进行了硬编码,所以我不需要将枚举代码移植到UBoot中。 为了获得总线数字,我编写了一个小型可装载内核模块,一旦内核完成枚举PCI总线上的设备 ,就可以获取设备总线编号。 问题:现在,如果模块存在于PCI插槽中,我可以成功读取它们的ID。 但是,如果一个模块不存在,我尝试读取它的ID,我被ARM的数据中止处理程序击中。 这是否是解决这个数据中止exception的方法,或者在尝试读取ID之前预先知道插槽是否被填充。 更新1:我根据auselen的input修改了UBoot源码,如下所示: start.S中 / /添加以下macros .macro irq_restore_user_regs_mod ldmia sp, {r0 – lr}^ @ Calling r0 – lr mov r0, r0 ldr lr, [sp, #S_PC] @ Get PC add sp, sp, #S_FRAME_SIZE mov pc, lr @ return & move spsr_svc into cpsr .endm 更改data_abort代码如下 data_abort: get_bad_stack irq_save_user_regs […]

如何在Linux中发送PCIe读取请求TLP

就像标题一样,我想知道是否可以在Linux中手动向设备发送PCIe读取请求TLP。 对于这个读取请求TLP有没有可能,我的驱动程序将定义TLP大小和TLP标记?

Linux PCI驱动程序,mmap预取

我有一个PCI设备,它的Linux驱动程序和一个用户空间应用程序。 应用程序mmap是通过驱动程序的PCI设备的第一个BAR。 所有的访问都是通过32位整数完成的,这是很重要的,因为读/写寄存器可能有副作用(启动操作等)。 在x86平台上,这工作得很好。 不过,我刚刚搬到了ARM平台,而且我有一个奇怪的行为: 从驱动程序读取/写入行为正确 从用户空间读取触发一个64字节的PCI读取请求,这是我的设备无法实现的,因为它只接受32位访问(+因为副作用,我不想那么做)。 我认为问题是,mmap想要预取一些数据,并发出这64字节的读取。 我是否错过了一个标志或可能会禁用某种mmap预取? 我目前在驱动程序方面的mmap实现很简单 vma->vm_flags |= VM_RESERVED; remap_pfn_range(vma,vma->vm_start, pfn, Size_UL, vma->vm_page_prot)

如何在Linux中读取扩展的PCIEconfiguration空间?

我已经尝试读取/ proc / bus / pci目录下的用户空间pci条目,并在驱动程序中调用内核空间API pci_read_config_word()。 但似乎两者只能读取基本的configuration空间,偏移量小于0x100。 我想要读取的偏移量超出了0x100,谁能告诉我如何在Linux中做到这一点? 如果在内核空间中完成,告诉哪个API来调用将非常赞赏。 非常感谢你!

从用户空间程序访问PCI设备

我有一个将通过pcie与我的处理器接口的设备。 我已经使用现有的pci文件操作为它编写了驱动程序。 现在我的问题是如何从用户空间程序访问它? PCI文件操作没有IOCTL支持,因此我不能做一个ioctl调用不像其他字符设备。 我不能使用pci_config_read_byte等函数,因为它们是用于内核空间的(包含在linux / pci.h中)。

Linux:request_mem_region返回不可用的范围

我目前正在从2.6到3.16移植一个VME桥的内核模块。 该设备能够将VME地址空间映射到PCI,映射到的地址范围可由驱动程序设置。 因此,内核模块首先尝试通过这样的循环来在地址空间中查找可用区域 for (pciAddr=MEM_START; pciAddr<MEM_STOP; pciAddr+=STEP) { if (check_mem_region(pci_Addr, size)==0) break; } request_mem_region(pciAddr, size, modulename); 应该更改为 for (pciAddr=MEM_START; pciAddr<MEM_STOP; pciAddr+=STEP) { if (request_mem_region(pciAddr, size, modulename)!=0) break; } 为更新的内核。 这对2.6内核工作正常,但对于较新的3.16,这两个变体都返回第一个区域(从MEM_START开始),但后续读取的地址范围失败,总是返回0xff。 MEM_START被定义为0x40000000,并且/ proc / iomem显示 40000000-401fffff : PCI Bus 0000:01 在其中之一。 当根据/ proc / iomem将MEM_START更改为另一个空闲的地址时,一切正常。 所以看起来request_mem_region()返回一个不可用的区域的成功,并且只为较新的内核做这个。 什么可能是这种行为的原因?

基地址寄存器如何获取地址?

我已经完成了在linux下的FPGA开发FPGA的pcie驱动程序。 一切工作正常。 但是我想知道FPGA的PCI端点的基地址寄存器在哪里得到基地址。 当我生成PCIe端点时,我可以设置BAR的长度,但不是更多。 在PCIe驱动程序中,我执行像pci_enable_device这样的标准function,但是我没有专门设置基地址。 那么操作系统在启动过程中是否设置了基地址? 或者它是如何工作的? 就我而言,我想知道如果一个pcie设备连接,操作系统一般会做什么初始化。 因为我确实在卸载驱动程序的时候在lspci中看到了我的pci设备。 亲爱的托马斯

我如何读取数据从条形码0,从用户空间,在Linux的PCIE卡?

在Windows上有这个程序叫做pcitree ,它允许你在不写设备驱动程序的情况下设置和读取内存。 是否有一个Linux的替代pcitree,将允许我读取我的pcie卡的块0内存? 一个简单的用例是我使用驱动程序代码在我的pci-e卡的第零块的第一个内存地址上写入一个32位整数。 然后,我使用pcitree替代读取块的第一个内存地址的值,并看到我的整数。 谢谢

如何强制内核重新读取/重新初始化PCI设备ID?

我的机器(运行Linux内核3.2.38)在启动时有一个PCI设备的子系统ID(子设备和子供应商ID)错误。 如果在系统仍然运行的情况下(例如热插拔)拔出PCI设备并重新插入,则会得到正确的ID。 请注意,它获取的错误子设备和子供应商ID与设备的设备和供应商ID相同(请参阅下面的lspci输出中的前两行)。 以下是热插拔设备前后lspci -vvnn的输出: 热插拔之前: 0b:0f.0 Bridge [0680]: Device [1a88:4d45] (rev 05) Subsystem: Device [1a88:4d45] Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap- 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 32 (250ns min, 63750ns max) Interrupt: pin A routed to IRQ 10 Region […]