免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: chishanmingshen

[硬件及驱动] pci dev的interrupte line register的疑问。。。 [复制链接]

论坛徽章:
0
发表于 2014-07-07 10:13 |显示全部楼层
回复 8# chishanmingshen


  
请教下:msi+多个中断号的设备,中断时该设备怎么知道应该提交msi capability list里的哪一个?

    类比legacy时,一个网卡设备在“收到报文完毕”时应该触发intA还是intB,我觉得这个应该是设备内部设置的。
    但是msi时如何实现?因为msi时的中断号那时还不确定!


pci 去enable msi的时候会初始化msi capability,这时会给Msi分配irq。请参考native_setup_msi_irqs 或者fsl_setup_msi_irqs。

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2014-07-07 10:30 |显示全部楼层
回复 11# xs3c

我的意思是手册怎么描述这个绑定?(网卡的话,手册中称为Mapping of Interrupt Causes)
如果legacy方式的,我觉得可以这么写“如果是收包中断,触发INTA脚。”
如果是msi方式的话,咋写?

论坛徽章:
0
发表于 2014-07-07 10:30 |显示全部楼层
回复 10# chishanmingshen
这个可能说明你的PCIE设备也支持legacy interrupt,使用INTA。


   

论坛徽章:
0
发表于 2014-07-07 10:35 |显示全部楼层
回复 12# chishanmingshen
msi 都是通过message ,X86是I/O APIC收到MSI中断请求后,会想local APIC发送interrupt message,最终local APIC通过IRTR向CPU提交中断。


   

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2014-07-07 10:40 |显示全部楼层
回复 14# xs3c

是啊,就是这种msix场景。
比如,给这个设备的收包中断分配了中断向量44, 发包中断分配了45.
当设备收包中断时怎么知道将44写到总线里(msix场景)?

因为我感觉仅仅是分配了,但是没明白怎么映射的。

指点啊,谢谢!

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2014-07-08 08:05 |显示全部楼层
不明决顶

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
发表于 2014-07-08 11:45 |显示全部楼层
回复 15# chishanmingshen

如果我记得不错的话,应该是在:

arch_setup_msi_irqs()
        native_setup_msi_irqs()
                setup_msi_irq()
                        write_msi_msg()
                                __write_msi_msg()


void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
        if (entry->dev->current_state != PCI_D0) {
                /* Don't touch the hardware now */
        } else if (entry->msi_attrib.is_msix) {
                void __iomem *base;
                base = entry->mask_base +
                        entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;

                writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR);
                writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR);
                writel(msg->data, base + PCI_MSIX_ENTRY_DATA);
        } else {
                struct pci_dev *dev = entry->dev;
                int pos = dev->msi_cap;
                u16 msgctl;

                pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl);
                msgctl &= ~PCI_MSI_FLAGS_QSIZE;
                msgctl |= entry->msi_attrib.multiple << 4;
                pci_write_config_word(dev, pos + PCI_MSI_FLAGS, msgctl);

                pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
                                       msg->address_lo);
                if (entry->msi_attrib.is_64) {
                        pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
                                               msg->address_hi);
                        pci_write_config_word(dev, pos + PCI_MSI_DATA_64,
                                              msg->data);
                } else {
                        pci_write_config_word(dev, pos + PCI_MSI_DATA_32,
                                              msg->data);
                }
        }
        entry->msg = *msg;
}

写入的数据实际上是特定的编码信息:

void native_compose_msi_msg(struct pci_dev *pdev,
                            unsigned int irq, unsigned int dest,
                            struct msi_msg *msg, u8 hpet_id)
{
        struct irq_cfg *cfg = irq_cfg(irq);

        msg->address_hi = MSI_ADDR_BASE_HI;

        if (x2apic_enabled())
                msg->address_hi |= MSI_ADDR_EXT_DEST_ID(dest);

        msg->address_lo =
                MSI_ADDR_BASE_LO |
                ((apic->irq_dest_mode == 0) ?
                        MSI_ADDR_DEST_MODE_PHYSICAL:
                        MSI_ADDR_DEST_MODE_LOGICAL) |
                ((apic->irq_delivery_mode != dest_LowestPrio) ?
                        MSI_ADDR_REDIRECTION_CPU:
                        MSI_ADDR_REDIRECTION_LOWPRI) |
                MSI_ADDR_DEST_ID(dest);

        msg->data =
                MSI_DATA_TRIGGER_EDGE |
                MSI_DATA_LEVEL_ASSERT |
                ((apic->irq_delivery_mode != dest_LowestPrio) ?
                        MSI_DATA_DELIVERY_FIXED:
                        MSI_DATA_DELIVERY_LOWPRI) |
                MSI_DATA_VECTOR(cfg->vector);

}

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
发表于 2014-07-08 11:59 |显示全部楼层
回复 17# asuka2001

MSI的介绍,MSI capability structure的定义之类的详细信息你可以查看 pci spec,实在有点多不好直接摘抄出来。

我看的是 PCI.Local.Bus.Specification.Revision.3.0.pdf,应该在第 6.8章,P237


   

论坛徽章:
4
酉鸡
日期:2014-03-21 23:19:50狮子座
日期:2014-08-01 22:11:40酉鸡
日期:2015-01-10 21:31:442015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2014-07-08 12:38 |显示全部楼层
回复 17# asuka2001


谢谢兄弟,可是代码和spec相关我看了啊,你发的就是写存储的方式触发msix。

可是还是不能解答我12楼和15楼的疑问啊。。。

论坛徽章:
0
发表于 2014-07-08 12:39 |显示全部楼层
本帖最后由 xs3c 于 2014-07-08 13:01 编辑

回复 15# chishanmingshen
不确定你到底看这个函数了没native_setup_msi_irqs,这里会给msi分配中断号。对于X86而言,除了保留个legacy device的中断,其他剩余的中断都可以用。
line 3150,就是在分配空闲的irq 给msi用。
  1. int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
  2. -  3138 {
  3. |  3139     unsigned int irq, irq_want;
  4. |  3140     struct msi_desc *msidesc;
  5. |  3141     int node, ret;
  6. |  3142
  7. |  3143     /* Multiple MSI vectors only supported with interrupt remapping */
  8. |  3144     if (type == PCI_CAP_ID_MSI && nvec > 1)
  9. |  3145         return 1;
  10. |  3146
  11. |  3147     node = dev_to_node(&dev->dev);
  12. |  3148    irq_want = nr_irqs_gsi;
  13. |- 3149     list_for_each_entry(msidesc, &dev->msi_list, list) {
  14. || 3150         irq = create_irq_nr(irq_want, node);
  15. || 3151         if (irq == 0)
  16. || 3152             return -ENOSPC;
  17. || 3153
  18. || 3154         irq_want = irq + 1;
  19. || 3155
  20. || 3156         ret = setup_msi_irq(dev, msidesc, irq, 0);
  21. || 3157         if (ret < 0)
  22. || 3158             goto error;
  23. || 3159     }
  24. |  3160     return 0;
  25. |  3161
  26. |  3162 error:
  27. |  3163     destroy_irq(irq);
  28. |  3164     return ret;
  29. |  3165 }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP