通常在 PCIe RC 侧,S/W 应该在 PCIe 核心前面的电路中设置 MSI(消息信号中断)基址寄存器地址,我猜这样 PCIe 核心(或连接到它的桥)可以提取软件中断消息并将其传递给中断控制器(然后在arm64情况下将其转换为LPI)。我正在关注 RC 端的 Xilinx PCIe 驱动程序。在这段代码中
/* Setup MSI */
if (IS_ENABLED(CONFIG_PCI_MSI)) {
phys_addr_t pa = ALIGN_DOWN(virt_to_phys(port), SZ_4K);
ret = xilinx_allocate_msi_domains(port);
if (ret)
return ret;
pcie_write(port, upper_32_bits(pa), XILINX_PCIE_REG_MSIBASE1);
pcie_write(port, lower_32_bits(pa), XILINX_PCIE_REG_MSIBASE2);
}
这里,获得了结构体
port
的物理地址并用于设置MSIBASE寄存器。 Xilinx PCIe 桥手册对此寄存器的说明:
此范围内地址的 MemWr TLP 被解释为 MSI 中断。 MSI TLP 根据编程的地址进行解释 在此寄存器中。
我认为MSI基地址应该是硬件寄存器地址(如arm gic-v3 ITS的翻译寄存器),但是如何在桥中设置结构体的这个地址以将MWr TLP转移到中断控制器?
当您将 TLP 写入特定内存区域时,MSI 由 PCIe RC 识别。
MSI基地址是该内存区域的基地址(该基地址存储在RC的HW寄存器中)。
下一节更多地依赖于架构/系统/配置:
该内存区域通常映射到中断控制器内部的地址空间。 因此,每当有东西写入该区域时,RC 都会识别它,并将其发送到中断控制器内部地址空间。
中断控制器读取写入的TLP,解析TLP中写入的数据,并将中断分配(根据TLP的数据,可能还有额外的路由表或配置)到相关的核或任何需要的单元来处理它。
分配中断通常意味着将其写入内存中的循环缓冲区,并递增该缓冲区的写指针。此增量之后是相关单元的中断。
同样,最后一部分是非常特定于架构/系统/配置的。有些架构甚至没有中断控制器、路由表、多核或其他我没有想到的东西。
您可以在这个 PPT 中找到一个相当好的示例(从第 8 页开始):
还有另一个基本描述:
http://fundasbykrishna.blogspot.com/2013/05/message-signaled-interrupt.html
希望它能表达你想知道的内容。