ARM Cortex A9中的处理器间中断 (在Linux中如何编写一个软件生成的中断处理程序?)。

5

我读到ARM中生成的软件中断被用作处理器间中断。我也可以看到其中5个中断已经在使用中。我还知道ARM提供了16个软件生成的中断。

在我的应用程序中,我在一个ARM Cortex核心上运行裸机应用程序,在另一个核心上运行Linux。我想要将一些数据从运行裸机应用程序的核心通信到运行Linux的核心。我计划将数据复制到芯片上的内存(共享内存),并触发一个SGI中断(在运行Linux的核心上)来指示有一些可用于处理的数据。现在我能够从运行裸机应用程序的核心生成SGI中断。但是对于在Linux方面处理中断,我不确定哪些SGI IRQ号码是空闲的,也不确定是否可以直接使用IRQ号码(通常SGI为0-15)。有没有人知道如何在Linux中编写SGI处理程序?

编辑:由于 SSCE原因,上述文本进行了重新措辞。Cortex-A CPU用于多CPU系统。ARM 通用中断控制器(GIC)监视所有全局中断并将它们分派到特定的CPU。为了使各个CPU相互信号,从一个核心发送软件生成的中断(SGI)到另一个核心;这使用外围专用中断(PPI)。这个问题是,

如何实现一个Linux内核驱动程序,可以作为PPI接收SGI?

2个回答

7

有人知道如何在Linux中编写SGI的处理程序吗?

由于您没有提供Linux版本,因此我将假设您使用最新(或至少近期)的版本。ARM GIC具有设备树绑定。通常,您需要在设备树节点中指定SGI中断号。

 ipc: ipc@address {
        compatible = "company,board-ipc"; /* Your driver */
        reg = <address range>;
        interrupts = <1 SGI 0x02>;  /* SGI is your CPU interrupt. */
        status = "enabled";
 };
< p >“中断”章节中的第一个数字表示“PPI”(外围私有中断)。对于Cortex-A5,SGI(软件生成中断)可能在0-15之间,因为这是SGI中断路由的范围。

然后,您可以在驱动程序中使用platform_get_irq()来获取“PPI”。 我猜“address”是您希望进行通信的共享内存(物理内存),也许“reg”不是很合适,但我认为它能够正常工作。 该区域将被Linux MMU重新映射,并且您可以使用它。

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mem = devm_ioremap_resource(dev, res);

设备树中的地址是物理地址的十六进制值。 platform_get_irq() 应该返回一个可用于 request_irq() 函数族的 中断号 。将其与您的例程连接即可。 编辑:不幸的是,在Linux的 irq-gic.c 下,中断16以下是禁止的。例如,gic_handle_irq() 将处理程序限制为16到1020之间的中断。如果启用了SMP,则对感兴趣的中断调用 handle_IPI() 。可以使用gic_raise_softirq()来发出中断信号。要处理当前Linux的 SGI ,则在 handle_IPI() 中,smp.c 需要添加其他enum ipi_msg_type 值和处理这些值的代码。看起来更新的内核(可能是3.14+?)可以在smp.c中添加set_ipi_handler()以使不需要进行此类修改。

谢谢您的回答。我有几个问题。如何填充pdev和dev结构?我想我不能使用探测函数来填充它,因为它没有硬件中断。而且设备树条目中的<reg>字段将是共享物理内存(reg)的起始地址和要访问的字节数(range)。我是正确的吗? - Nuetrino
1
pdevdev都被发送到probe()函数。static int probe(struct platform_device *pdev)...static struct platform_driver driver = { .probe = probe };以及module_platform_driver(driver);dev = &pdev->dev - artless noise
参见 ARM Cortex 中断源和类型。GIC 文档的 4.3.15 节给出了 ICDSGIRNSATT 指定了 trustzone 是否安全。您可以选择任何未使用的中断 (0-15)。 - artless noise
1
@artlessnoise 谢谢。我解决了这个问题。当我尝试在 request_irq 函数中使用 irq 号码(对于所有 SgI irq 号码)时,出现了一个错误(EINVaL = -22 无效参数),因此我使用了另一个函数 set_ipi_handlers(arch/arm/kernel/smp.c)来注册我的 irq 处理程序。我想 request_irq 不能在这种情况下使用。 - Nuetrino

2
我想补充一下,这种内核间通信的例子可以在TI多核SoC(即OMAP3530)中找到。在我使用这种机制的时候,TI提供了相应的手段。具体来说,是DSPLink Linux设备驱动程序提供了这种功能。当时,不幸的是,它不是一个开源的解决方案,但也许有一些TI的技术论文描述了它的工作原理...只是一个你可以进一步调查的方向:)
编辑:与此同时,他们似乎已经将其开源。所以,如果这就是你要找的东西,你可以看看:DSPLinkSysLink (DSPLink的继任者)

谢谢。我会看一下的。 :) - Nuetrino

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接