【发布时间】: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->info.irq_flags = IRQF_SHARED;替换为gdev->info.irq_flags = IRQF_SHARED | IRQF_TRIGGER_LOW;(如果默认为高电平有效)或gdev->info.irq_flags = IRQF_SHARED | IRQF_TRIGGER_HIGH;,否则。如果是这种情况,您需要找到一种方法来修复您的默认极性,无论是在 FPGA 级别还是通过软件。 -
但是 irqhandler 被调用了,正如我上面提到的(这意味着 irq 可能被正确地请求了)。只有对 pci_check_and_mask_intx 的调用返回 false。
-
请再仔细阅读我在上面评论中写的内容。
标签: linux-kernel interrupt pci pci-e