【问题标题】:Does UIO generic PCI support interrupts?UIO 通用 PCI 是否支持中断?
【发布时间】:2020-03-26 05:58:41
【问题描述】:

我使用 uio 通用驱动程序,硬件由连接到 Intel ATOM cpu 的 PCIe 设备 (FPGA) 组成。

但是,在测试中,虽然在驱动程序中看到了中断,但它并没有传递到用户空间。

这些是我正在做的步骤:

echo "10ee 0007" > /sys/bus/pci/drivers/uio_pci_generic/new_id

我使用等待中断的用户空间应用程序,正如代码示例here 中所述。

我从 FPGA 触发了一个中断,但是没有从用户空间应用程序打印出来,并且出现了异常:

irq 23: nobody cared (try booting with the "irqpoll" option)
[ 91.030760] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.18.16 #6
[ 91.037037] Hardware name: /conga-MA5, BIOS MA50R000 10/30/2019
[ 91.043302] Call Trace:
[ 91.045881] <IRQ>
[ 91.048002] dump_stack+0x5c/0x80
[ 91.051464] __report_bad_irq+0x35/0xaf
[ 91.055465] note_interrupt.cold.9+0xa/0x63
[ 91.059823] handle_irq_event_percpu+0x68/0x70
[ 91.064470] handle_irq_event+0x37/0x57
[ 91.068481] handle_fasteoi_irq+0x97/0x150
...
[ 91.176043] handlers:
[ 91.178419] [<00000000ec05b056>] uio_interrupt
[ 91.183054] Disabling IRQ #23

我开始调试 uio 驱动程序,我看到中断处理程序被调用,但没有被处理:

static irqreturn_t irqhandler(int irq, struct uio_info *info)
{
        struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
printk("here 1\n");    <<--- we get here interrupt is catched here
        if (!pci_check_and_mask_intx(gdev->pdev))
                return IRQ_NONE;
printk("here 2\n");    <<--- But we never get here
        /* UIO core will signal the user process. */
        return IRQ_HANDLED;
}

pci_check_and_mask_intx() 似乎没有将其检测为来自我们设备的中断!

设备显示如下:

02:00.0 RAM memory: Xilinx Corporation Default PCIe endpoint ID
        Subsystem: Xilinx Corporation Default PCIe endpoint ID
        Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Interrupt: pin A routed to IRQ 23
        Region 0: Memory at 91200000 (32-bit, non-prefetchable) [size=1M]
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+
                Address: 0000000000000000  Data: 0000
        Capabilities: [58] Express (v1) Endpoint, MSI 00
                DevCap: MaxPayload 256 bytes, PhantFunc 1, Latency L0s <64ns, L1 <1us
                        ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 10.000W
                DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
                        RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+
                        MaxPayload 256 bytes, MaxReadReq 512 bytes
                DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
                LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s, Exit Latency L0s unlimited
                        ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
                LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
                LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
        Capabilities: [100 v1] Device Serial Number 00-00-00-00-00-00-00-00
        Kernel driver in use: uio_pci_generic

是 FPGA 设备的问题吗?还是 UIO 通用 PCI 不支持中断?

【问题讨论】:

  • 您错过了请求中断的部分。
  • 什么意思? PCI 通用处理程序请求中断作为通用驱动程序代码的一部分。
  • 是的,你调查过吗?它似乎使用默认标志(仅在顶部添加了共享)。您的情况更有可能显示错误的极性设置。您可以将apic=debug 添加到内核命令行以查看如何路由 IRQ #23 以及正在使用哪些标志。作为测试,您还可以将gdev-&gt;info.irq_flags = IRQF_SHARED; 替换为gdev-&gt;info.irq_flags = IRQF_SHARED | IRQF_TRIGGER_LOW;(如果默认为高电平有效)或gdev-&gt;info.irq_flags = IRQF_SHARED | IRQF_TRIGGER_HIGH;,否则。如果是这种情况,您需要找到一种方法来修复您的默认极性,无论是在 FPGA 级别还是通过软件。
  • 但是 irqhandler 被调用了,正如我上面提到的(这意味着 irq 可能被正确地请求了)。只有对 pci_check_and_mask_intx 的调用返回 false。
  • 请再仔细阅读我在上面评论中写的内容。

标签: linux-kernel interrupt pci pci-e


【解决方案1】:

最终在为 irqhandler 注释以下行之后,

我能够接收来自 FPGA 的中断

static irqreturn_t irqhandler(int irq, struct uio_info *info)
 {
      struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
-        if (!pci_check_and_mask_intx(gdev->pdev))
-                return IRQ_NONE;
    /* UIO core will signal the user process. */
    return IRQ_HANDLED;
}

然而,显然它仍然是一种变通方法,我们需要稍后研究为什么 FPGA 没有将 PCIe 配置空间中的状态寄存器中的位状态更改与 irq 一起传递。

【讨论】:

    猜你喜欢
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多