文章目录
- 如何创建一个 irq_domain
- 如何创建一个 msi_domain
- irq domain 和 msi domain 的关系
- MSI对IRQdomain打的补丁
- 变量
- 结构体
- API
- 初始化时的API
- 申请IRQ时的API
- 实例 GICV3-ITS & GICV3-ITS-PCI 相关结构体变量所在文件
如何创建一个 irq_domain
内核文档说,我们可以调用如下的API 来创建domain
irq_domain_add_linear/irq_domain_create_linear
irq_domain_add_tree/irq_domain_create_tree
irq_domain_add_nomap
irq_domain_add_simple/irq_domain_add_legacy/irq_domain_add_legacy_isa
注意 : create_ 和 add_ 都是调用了 __irq_domain_add
注意 : 现在好像都用 irq_domain_create_ 了
如何创建一个 msi_domain
- 参考 GICV3-ITS-PCI
- 参考 GICV3-ITS-PLATFORM
- 参考 GICV3-ITS
irq domain 和 msi domain 的关系
- msi domain 是 irq domain的一个user
host_data: private data pointer for use by owner. Not touched by irq_domain core code
很明显msi irq domain就是那个user
还有其他的user : gpiolib 中的 gpio_chip 等等,可用用以下命令搜索
// grep "host_data;" * -nr |grep " = "
- msi domain 只是粘在 irq domain的一个结构体,并没有父子关系
msi irq domain跟irq domain的关系是什么,是irq domain 的user?
也就是附着在狼身上的一个狈,狼有等级制度(parent),但是狈没有。
但是狈利用了这个等级制度。
所以我们一般说 msi-domain 或者 msi-irq-domain 的时候,就默认指 msi-domain + irq_domain , 即狈 和狼
但是我们一般说 irq-domain 的时候, 特指 狼,没有狈
- msi domain 是 irq domain 的一个补丁
msi domain其实是基于irqdomain的一个补丁,这个补丁不太好看
在结构体上,
1.msi irq domain 使用了 host_data,实现了flag和prepare。
2.新增了一系列 结构体
在变量上,
1. 新增了一些 static 变量,供MSI系统私用
在API上,
实现了一些内部函数,以驱使流程
新增了一系列api,供用户使用
在流程观感上
在普通流程的基础上增加了prepare(准备硬件中断号)的动作
msi irq的流程 相对于 普通的irq 的流程,多了一个硬件中断号的获取
普通irq的hwirq是写到设备树中的
但是msi的hwirq是系统分配的。
如果一个plicsw要支持这两种,就必须 在系统中管理好这两种索取hwirq的途径
MSI对IRQdomain打的补丁
变量
MSI层的 结构体变量
// 被用作 ITS irq domain 的 子 irq domain 的ops
// 例如 GICV3-ITS-PCI irq domain的 ops 就使用了它
static const struct irq_domain_ops msi_domain_ops = {
.alloc = msi_domain_alloc,
.free = msi_domain_free,
.activate = msi_domain_activate,
.deactivate = msi_domain_deactivate,
};
// 被用作 填充 ITS irq domain 的 子 irq domain 的ops 中的未定义的指针
// 例如 GICV3-ITS-PCI msi domain的 ops : its_msi_domain_ops ,其中的一些字段被它填充了
// msi_create_irq_domain->msi_domain_update_dom_ops
static struct msi_domain_ops msi_domain_ops_default = {
.get_hwirq = msi_domain_ops_get_hwirq,
.msi_init = msi_domain_ops_init,
.msi_check = msi_domain_ops_check,
.msi_prepare = msi_domain_ops_prepare,
.set_desc = msi_domain_ops_set_desc,
.domain_alloc_irqs = __msi_domain_alloc_irqs,
.domain_free_irqs = __msi_domain_free_irqs,
};
结构体
MSI层的结构体,待用户填充
// 被用作 ITS irq domain 的 host_data
337 struct msi_domain_info {
338 u32 flags;
339 struct msi_domain_ops *ops;
340 struct irq_chip *chip;
341 void *chip_data;
342 irq_flow_handler_t handler;
343 void *handler_data;
344 const char *handler_name;
345 void *data;
346 };
// 被用作 ITS irq domain 的 host_data 的 ops
// 里面的 msi_prepare 用于 准备硬件中断号
static struct msi_domain_ops its_pci_msi_ops = {
.msi_prepare = its_pci_msi_prepare,
};
API
初始化时的API
MSI层 的API
msi_create_irq_domain
MSI-PCI 层的API
platform_msi_create_irq_domain
MSI-PLATFORM 层的API
platform_msi_create_irq_domain
申请IRQ时的API
MSI层 的API
msi_domain_alloc_irqs
__msi_domain_alloc_irqs
msi_domain_prepare_irqs
MSI-PCI 层的API
__pci_enable_msix_range
__pci_enable_msix
msix_capability_init
pci_msi_setup_msi_irqs
MSI-PLATFORM 层的API
platform_msi_domain_alloc_irqs
实例 GICV3-ITS & GICV3-ITS-PCI 相关结构体变量所在文件
GICV3-ITS
irq-domain
its_domain_ops drivers/irqchip/irq-gic-v3-its.c
its_irq_chip drivers/irqchip/irq-gic-v3-its.c
msi-domain
局部变量info
its_msi_domain_ops drivers/irqchip/irq-gic-v3-its.c
its_msi_prepare drivers/irqchip/irq-gic-v3-its.c
GICV3-ITS-PCI
irq-domain
msi_domain_ops kernel/irq/msi.c
its_msi_irq_chip drivers/irqchip/irq-gic-v3-its-pci-msi.c
msi-domain
its_pci_msi_domain_info drivers/irqchip/irq-gic-v3-its-pci-msi.c
its_pci_msi_ops drivers/irqchip/irq-gic-v3-its-pci-msi.c
its_pci_msi_prepare drivers/irqchip/irq-gic-v3-its-pci-msi.c
msi_domain_ops_default kernel/irq/msi.c