文章目录
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 int做
4.
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>
};
};