Tim*_*ler 5 interrupt linux-kernel pci-bus
我和我的同事正在使用我们的一个基于PCIe的产品,我们发现某种平台/芯片组依赖性阻止了中断被传送到我们的Linux内核驱动程序(rapafp).我们必须继续在该领域支持的该产品的一个旧版本是从旧的PCI设计改造而来.所以我们得到的是一些FPGA,其中一个具有66MHz PCI-32接口,并且连接到Texas Instruments XIO PCI-to-PCIe桥接器.我应该注意到,我已经孜孜不倦地研究了几天,我只是没有到达任何地方.我们已经明确地考虑过我们自己设备的硬件问题,但是我们换掉了多张卡,并没有任何区别.
我们有一个运行RHEL6.5的系统运行良好,因此我们将其用作参考.以下是有关该平台的一些信息.我不知道你需要什么程度的细节,我不想写一个垃圾问题.请让我知道提供什么以及如何(内联问题,pastebin等)将有用.
来自uname -a:
Linux DL-2-107.localdomain 2.6.32-431.el6.i686 #1 SMP Fri Nov 22 00:26:36 UTC 2013 i686 i686 i386 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
来自/ proc/interrupts:
CPU0 CPU1
...
16: 609672457 1344098703 IO-APIC-fasteoi uhci_hcd:usb3, pata_jmicron, rapafp
Run Code Online (Sandbox Code Playgroud)
来自dmesg的信息:
rapafp driver version 3.3.0.5
rapafp: Requesting IRQ 16
TSI: rapafp0 (BusID 2:0:0) is RAPTOR 4000 @ 2048x2048
TSI: rapafp1 (BusID 2:0:0) is RAPTOR 4000 @ 1280x1024
Run Code Online (Sandbox Code Playgroud)
来自lspci:
# lspci -t
-[0000:00]-+-00.0
+-01.0-[01-02]----00.0-[02]----00.0
00:01.0 PCI bridge: Intel Corporation 82Q35 Express PCI Express Root Port (rev 02) (prog-if 00 [Normal decode])
01:00.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200A PCI Express-to-PCI Bridge (rev 03) (prog-if 00 [Normal decode])
02:00.0 Display controller: Tech-Source Device 0042
Run Code Online (Sandbox Code Playgroud)
安装的CPU是:型号名称:Intel(R)Core(TM)2 CPU E8400 @ 3.00GHz
来自dmidecode的一些BIOS信息:
Vendor: Phoenix Technologies, LTD
Version: 6.00 PG
Release Date: 12/12/2008
Run Code Online (Sandbox Code Playgroud)
请注意,驱动程序从未用fasteoi编写,因此它永远不会进行任何中断结束调用.然而,它在该机器上完美运行.
我们有两个系统在接收中断时遇到问题.一个是运行RHEL6.5(2.6.32-431.el6.i686),另一个是RHEL7.4(3.10.0-693.17.1.el7.x86_64).
RHEL6系统能够中断我们的驱动程序,但只能间歇性地中断.这可能是由于内核将设备连接到边沿触发的中断线(尽管驱动程序另有请求!)并且驱动程序未被编写为与边沿触发兼容.
RHEL7系统根本无法中断我们的驱动程序. 我们目前的目标是将驱动程序移植到RHEL7,因此我将专注于该机器.主机彼此之间有很多相似之处,并且与参考系统存在差异.重要的主要区别是内核版本,32位与64位,可能还有BIOS.首先,下面是一些系统信息.
来自uname -a:
Linux rhel74.techsource.com 3.10.0-693.17.1.el7.x86_64 #1 SMP Thu Jan 25 20:13:58 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
的/ proc /中断:
10: 0 0 IO-APIC-edge rapafp
Run Code Online (Sandbox Code Playgroud)
来自dmesg:
[321790.744110] raptor_attach: irq_set_irq_type(10,8) succeeded!
[321790.744111] raptor_attach: calling request_irq.
[321790.744239] raptor_attach: request_irq(10) succeeded!
[321790.744240] raptor_attach: done
[321790.744342] TSI: rapafp0 (BusID 2:0:0) is RAPTOR 4000 @ 2048x2048
...
[321807.840300] PCI Config Register dump:
[321807.840405] vendor id 0x1227
[321807.840508] device id 0x43
[321807.840611] command register 0x202
[321807.840715] status register 0x2a0
[321807.840818] revision id 0x0
[321807.840921] programming class code 0x0
[321807.841025] sub-class code 0x80
[321807.841129] basic class code 0x3
[321807.841232] header type 0x0
[321807.841335] base register 0 0xbfff0008
[321807.841439] base register 1 0xa0000008
[321807.841542] base register 2 0xb8000008
[321807.841645] base register 3 0x0
[321807.841749] base register 4 0xbffc0008
[321807.841852] base register 5 0x0
[321807.841955] Cardbus CIS Pointer 0x0
[321807.842059] Subsystem Vendor ID 0x1227
[321807.842162] Subsystem ID 0x43
[321807.842266] ROM base register 0x0
[321807.842369] interrupt line 0xa
[321807.842472] interrupt pin 0x1
[321807.842576] minimum grant 0x0
[321807.842679] maximum grant 0x0
Run Code Online (Sandbox Code Playgroud)
来自lspci的信息:
# lspci -t
-[0000:00]-+-00.0
+-01.0-[01-02]----00.0-[02]----00.0
00:00.0 Host bridge: Intel Corporation 82X38/X48 Express DRAM Controller (rev 01)
Subsystem: Holco Enterprise Co, Ltd/Shuttle Computer Device 3111
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-
...
00:01.0 PCI bridge: Intel Corporation 82X38/X48 Express Host-Primary PCI Express Bridge (rev 01) (prog-if 00 [Normal decode])
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-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 24
...
01:00.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200A PCI Express-to-PCI Bridge (rev 03) (prog-if 00 [Normal decode])
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-
...
02:00.0 Display controller: Tech-Source Device 0043
Subsystem: Tech-Source Device 0043
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-
Interrupt: pin A routed to IRQ 10
Run Code Online (Sandbox Code Playgroud)
我尝试了一系列修复.我做的第一件事是通过中断处理代码并重写它,以便它对边缘触发的中断线更友好,但这没有任何影响.我做的其他事情包括:
SA_,所以我用更新的标记替换它们IRQF_.我尝试了各种各样的旗帜组合.IRQF_TRIGGER_RISING,IRQF_TRIGGER_FALLING,IRQF_TRIGGER_HIGH,IRQF_TRIGGER_LOW,这些组合,有和没有IRQF_SHARED等.这些都没有对IRQ传递,/ proc/interrupts报告的内容或lspci报告的网桥配置产生任何影响.尽管如此,request_irq从未返回任何错误代码.最后我注意到PCI桥00:01.0有遗留中断(DisINTx +).我去寻找某种预先存在的函数,它将遍历桥层次结构并修复所有这些函数的中断,但我找不到任何东西.所以我决定尝试一下.
首先,我编写了自己的函数来提升桥接层次结构:
static int raptor_enable_intx(struct pci_dev *dev, TspciPtr pTspci) {
int num_en = 0;
int result;
u16 cmd, old_cmd;
while (dev) {
pci_read_config_word(dev, PCI_COMMAND, &old_cmd);
pci_intx(dev, true);
pci_read_config_word(dev, PCI_COMMAND, &cmd);
if (cmd & PCI_COMMAND_INTX_DISABLE) {
printk (KERN_INFO "raptor_enable_intx: Could not clear DisINTx for device %s\n", pci_name(dev));
} else {
printk (KERN_INFO "raptor_enable_intx: Successfully cleared DisINTx for device %s\n", pci_name(dev));
if ((old_cmd & PCI_COMMAND_INTX_DISABLE)) num_en++;
}
dev = pci_upstream_bridge(dev);
}
return num_en;
}
Run Code Online (Sandbox Code Playgroud)
这种情况的主要影响是导致机器挂起,虽然不是马上就能挂起.我试过在raptor_enable_intx之前或之后调用request_irq.IIRC,一个没有效果,而另一个导致系统挂起,虽然没有立即.
我还发现pci_common_swizzle有一些关于它是PCI标准要求的评论,所以我在上述函数之后调用它.在我做完这些事情后,我再调用request_irq.通过这些更改,系统会立即挂起insmod.
当然,我意识到迭代桥接并强制关闭PCI_COMMAND_INTX_DISABLE是一个令人恶心的黑客攻击,如果是那个或者导致系统挂起的混乱,我也不会感到惊讶.
无论如何,所以我迷失了,并在这里感到困惑.有谁知道我做错了什么?我怎么能得到那个允许遗留中断通过的系统桥?
在此先感谢您的帮助!