暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

pcie(六)- Linux PCI 驱动程序

囧囧妹 2022-08-12
208

点击上方蓝字【囧囧妹】一起学习,一起成长!

三,设置 DMA 掩码大小

虽然所有驱动程序都应明确指示 PCI 总线主控器的 DMA 功能(例如 32 位或 64 位),但具有超过 32 位总线主控器功能的设备需要驱动程序通过调用 dma_set_mask() 来“注册”此功能适当的参数。通常,这允许在系统 RAM 存在于 4G  _physical_ 以上的系统上进行更有效的 DMA。

所有 PCI-X 和 PCIe 兼容设备的驱动程序必须调用 dma_set_mask(),因为它们是 64 位 DMA 设备。

同样,如果设备可以通过调用 dma_set_coherent_mask() 直接寻址 4G 物理地址以上的系统 RAM 中的“相干内存”,驱动程序也必须“注册”此功能。同样,这包括所有 PCI-X 和 PCIe 兼容设备的驱动程序。许多 64 位“PCI”设备(在 PCI-X 之前)和一些 PCI-X 设备是 64 位 DMA,能够处理有效负载(“流式传输”)数据,但不能控制(“一致性”)数据。

   这里刨个坑后面再来具体了解linux的dma机制以及dma动态映射,一致性和流式dma区别和使用。

四,设置共享控制数据

一旦设置了 DMA 掩码,驱动程序就可以分配“一致”(也称为共享)内存。这样就可以直接操作物理地址。



五,初始化设备寄存器

当内存映射完成之后就可以通过程序来修改寄存器相关字段以及初始化和重置寄存器。


六,注册IRQ处理程序

虽然调用request_irq()是最后一步,但此步骤也可以推迟到设备打开使用。

IRQ 线的所有中断处理程序都应注册到 IRQF_SHARED 并使用 devid 将 IRQ 映射到设备(请记住,所有 PCI IRQ 线都可以共享)。

request_irq()将中断处理程序和设备句柄与中断号相关联。中断号代表从 PCI 设备到中断控制器的 IRQ 线。request_irq()也使能中断,在注册中断处理程序之前,确保设备处于静止状态并且没有任何未决中断。

MSI 和 MSI-X 是 PCI 功能,两者都是“消息信号中断”,通过对本地 APIC 的 DMA 写入向 CPU 提供中断,MSI 和 MSI-X 之间的根本区别在于如何分配多个“向量”。MSI 需要连续的向量块,而 MSI-X 可以分配多个单独的向量。

MSI 功能可以通过调用 pci_alloc_irq_vectors() 再调用request_irq(). 这会导致 PCI 支持将 CPU 向量数据编程到 PCI 设备功能寄存器中。许多架构、芯片组或 BIOS 不支持 MSI 或 MSI-X,并且仅使用 PCI_IRQ_MSI 和 PCI_IRQ_MSIX 标志调用 pci_alloc_irq_vectors 将失败,可以尝试指定 PCI_IRQ_LEGACY。

对 MSI/MSI-X 和传统 INTx 具有不同中断处理程序的驱动程序应在调用 pci_alloc_irq_vectors 后根据 pci_dev 结构中的 msi_enabled 和 msix_enabled 标志选择正确的处理程序。

使用 MSI 有(至少)两个非常好的理由:

1,根据定义,MSI 是一个独占中断向量。这意味着中断处理程序不必验证其设备是否导致了中断。

2,MSI 避免了 DMA/IRQ 竞争条件。传送 MSI 时,主机 CPU 可以看到 DMA 到主机内存。这对于数据一致性和避免过时的控制数据都很重要。此保证允许驱动程序省略 MMIO 读取以刷新 DMA 流。

有关 MSI/MSI-X 用法的示例,请参阅 drivers/infiniband/hw/mthca/ 或 drivers/net/tg3.c。


到此,pci设备的初始化就完成了,下面来看下关闭pci设备的每一步都做了什么。


觉得不错,点击“分享”,“赞”,“在看”传播给更多热爱嵌入式的小伙伴吧!
文章转载自囧囧妹,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论