pci中断号分配_0019 MSI/MSI-X中断

MSI全称Message Signaled Interrupt。

当设备向一个特殊地址写入时,会向CPU产生一个中断,即也MSI中断。

与传统引脚中断相比,MSI/MSI-X有三个方面的优势。

基于引脚的PCI中断经常在几个设备间共享,内核必须调用与该中断相关的每一个中断处理函数,降低了效率。MSI不是共享的,所以不存在这个问题。

当设备向内存写入数据,然后发起引脚中断时,有可能在CPU收到中断时,数据还未到达内存(在PCI-PCI桥后的设备更有可能如此)。为了保证数据已达 内存,中断处理程序必须轮询产生该中断的设备的一个寄存器,PCI事务保序规则会确保所有数据到达内存后,寄存器才会返回值。

使用MSI时,产生中断的写不能越过数据写,因而避免了这个问题。当中断产生时,驱动可以确信所有数据已经到达内存。

787cf6ff21500ba52e32b17b3ed13879.png

bdd61ecb2145e28c01092110898c3409.png

MSI在PCI Capability ID=05,有4种类型,如上面图所示。

MSI主要是Message Address,跟Message Data,PCI设备把Message Data写入Message Address这个地址,CPU就会发生中断。

static void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg)
{
    msg->address_hi = MSI_ADDR_BASE_HI;

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

    msg->address_lo =
        MSI_ADDR_BASE_LO |
        MSI_ADDR_DEST_MODE_PHYSICAL|
        MSI_ADDR_REDIRECTION_CPU |
        MSI_ADDR_DEST_ID(cfg->dest_apicid);

   msg->data =
       MSI_DATA_TRIGGER_EDGE |
       MSI_DATA_LEVEL_ASSERT |
       MSI_DATA_DELIVERY_FIXED |
       MSI_DATA_VECTOR(cfg->vector);
}
void msi_compose_msg(uint vector,uint destid, struct msi_msg *msg)
{
    struct irq_cfg cfg={.vector = vector,.dest_apicid = destid};
    __irq_msi_compose_msg(&cfg,msg);
}

msi_compose_msg这个函数生成msi消息,即64位地址跟32位data。地址空间在0xfee00000起始的1M内存。每个cpu有不同的地址。

data里面最总要的一个就是中断向量,告诉设备产生几号中断(vector)

bool msi_write_entry(pci_device_t pci, int entry_id, msi_msg *msg)
{
    if (!pci_is_msi(pci)) {
       
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值