PCIe MSI-X 机制 实例

文章详细阐述了MessageSignaledInterrupt技术在PCIeMSI-X中的应用,以及在ARMGICv3和RISC-VPLIC-SW架构下的实现方式。在ARMGICv3中,PCIe设备写入特定地址触发中断,经过一系列处理后由GIC转发至核心。而在RISC-V环境中,目前Linux内核尚无PLIC的MSI实现,提出了关于中断控制器和PCIeIP中断的探讨。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Message Signaled Interrupt 技术 与 PCIe MSI-X 的关系

PCIe 提供了 MSI/MSI-X 中断, 这个东西基于某个技术
	PCIe 只说了 向某个地址 写入某个值,就会产生一个 中断号唯一的中断,但是没说这个地址,写了值之后,怎么产生中断的.
	所以需要依赖具体的架构,例如让arm提供,例如让x64提供,例如让risv 提供
	arm 架构中 , GICv3 实现了 MSI
	x64 架构中 , TODO
	risc v 中  , plic-sw 实现了 MSI

基于 ARM GICv3 提供的 Message Signaled Interrupt

本质上pcie设备向地址写了值之后,中断就发生了
	写了地址值之后,发生了一些列事情 : its 根据 初始化设置 找到对应的 intid , 发出中断
	另外,地址值也是一开始初始化好的, 

	所以在pcie 设备发出中断前, 我们需要做一些初始化
	其中包括的初始化包括  pcie 控制器 驱动, 和 pcie 设备驱动

pcie控制器 驱动要做
	1. 初始化 MSI-X Table
		1. 解析 msi-map = <0x0 &its 0x0 0x1000>
		2. 获取地址 GITS_TRANSLATER
		3. 获取 值 (device id + event id) // 哪个设备 + 设备的哪个中断
		4. 将键值对 写入 MSI-X Table

	2. 在its 中建立 Table中键值对 与 INTID 的映射关系 , 即 向上申请了 X个 中断号 (8192 - 8192+X) // GICv3 GIC-500 最大到 57344+8192-1
		1. 初始化 its 的配置
			键值对 x <---> 8192+x

pcie 设备驱动要做
	1.获取到 控制器预留的 硬件中断号 , 和其对应的软件中断号
		// 注意 此时硬件中断号是 its的,不是 pcie的
		// 实现msi时,pcie 没有实现  irq domain
	2.拿软件中断号 来 注册中断处理函数


pcie设备 中断如何 发生
	1. 设备 写 its ,gic 产生中断,给核心

pcie 设备的中断处理函数如何被调用
	1. 核心调用gic,gic 调用its
	2. its 获取到 硬件中断号 为 8192 的 中断源 发生了中断
	3. its 的 中断处理函数 调用  8192 对应的 软件中断号对应的 中断处理函数
		// 因为 实现msi时,pcie 没有实现  irq domain
		// 所以 发生时,没有 pcie 控制器的函数什么事情

基于 RISC V PLIC-SW 提供的 Message Signaled Interrupt

  • 目前 linux upstream 还没有 这种实现 2023-5-1 15:12:15
  • pci-msi.txt
1.确认 cadence 有没有提供 msi 中断控制器
2.确认 pcie ip的中断都是干啥的
3.确认是否可以先用legacy int4.
Bits [15:8] are the Bus number
Bits [7:3] are the Device number
Bits [2:0] are the Function number
如果需要全部映射,1个function 一个 msi 中断, 那么 需要 65536// 一个bus 256个
但是 plic-sw 提供了 1023 个中断  : 1-1023
1个bus需要用到 msi 256个中断
2个bus需要用到 msi 512个中断
1023最大支持3个bus...我操!

所以从 bus 0 开始提供,最多到 bus2 .

哪些 中断源被用了 , TODO
msi-map = <0x0 &msi_xxx 0x0 0x10000>,
bus-range = <0x0 0xff>; 弄少点, cfg mem 对应弄 , msi 也对应弄
那就2个bus 吧 , 如果rc是最简rc(TODO 确认)的话

/ {                                                                              
    #address-cells = <1>;                                                           
    #size-cells = <1>;                                                              
                                                                                    
    msi: msi-controller@a {                                                         
        reg = <0xa 0x1>;                                                            
        compatible = "vendor,some-controller";                                      
        msi-controller;                                                             
        #msi-cells = <1>;                                                           
    };                                                                              
                                                                                    
    pci: pci@f {                                                                    
        reg = <0xf 0x1>;                                                            
        compatible = "vendor,pcie-root-complex";                                    
        device_type = "pci";         
                                                       
		bus-range = <0x0 0x1>;
		reg = <0x00 0x0d000000 0x00 0x00800000>,
		<0x00 0x68000000 0x00 0x00200000>; // 2M
		reg-names = "reg", "cfg";   
		                                                                         
        /*                                                                          
         * The sideband data provided to the MSI controller is                      
         * the RID, masked to only the device and function bits.                    
         */                                                                         
        msi-map = <0x0 &msi_a 0x0 0x200>,                                           
        msi-map-mask = <0x1ff>                                                       
    };                                                                              
};
3 个bus 吧

/ {                                                                              
    #address-cells = <1>;                                                           
    #size-cells = <1>;                                                              
                                                                                    
    msi: msi-controller@a {                                                         
        reg = <0xa 0x1>;                                                            
        compatible = "vendor,some-controller";                                      
        msi-controller;                                                             
        #msi-cells = <1>;                                                           
    };                                                                              
                                                                                    
    pci: pci@f {                                                                    
        reg = <0xf 0x1>;                                                            
        compatible = "vendor,pcie-root-complex";                                    
        device_type = "pci";         
                                                       
		bus-range = <0x0 0x2>;
		reg = <0x00 0x0d000000 0x00 0x00800000>,
		<0x00 0x68000000 0x00 0x00300000>; // 2M
		reg-names = "reg", "cfg";   
		                                                                         
        /*                                                                          
         * The sideband data provided to the MSI controller is                      
         * the RID, masked to only the device and function bits.                    
         */                                                                         
        msi-map = <0x0 &msi_a 0x0 0x300>,                                           
        msi-map-mask = <0x3ff>                                                       
    };                                                                              
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值