那天和一個朋友討論了一下MSI/MSIX方面的問題,下面是對討論內容的整理:
1.MSI-X Table和PBA結構太大,MSIX Capability又只能放到配置空間64-255這個地區,所以只能把Table和PBA放到裝置記憶體空間了。MSIX Capability存著BAR的編號和位移量來從配置空間索引Table和PBA。
2.
MSI capability裡“訊息地址”欄位在PCI規範裡沒有格式定義,這是因為PCI規範需要支援多種平台。在x86上和在SPARC上,訊息地址的定義是不同的。
3. x86上MSI”訊息地址“(64或32位)在Intel 系統編程卷裡定義,
Solaris是用本地APIC的基地址0xfee00000按位或8位目標處理器ID再或1位RH(取值0),或1位DM(取值0),得到的地址就是裝置發中斷用的記憶體位址。
4. x86上MSI“訊息資料”(16位)的定義比較簡單, Solaris使用邊緣觸發方式,投遞模式是固定,最後低8位是中斷向量地址。 關於“訊息地址”和“訊息資料”,Solaris請參考apic_pci_msi_enable_vector。
5. 需要注意的是,MSI“訊息資料"的低3位是要根據MSI控制寄存器的Multiple Message Enable位來由裝置動態修改的,所以一個”訊息資料“寄存器可以被最多32個向量共用。
6. MSI capability裡支援最多32個向量,但由於這32個向量共用一個“訊息地址”。而在x86上,這個"訊息地址"用來決定發送到哪一個CPU的本地APIC,所以32個向量只能綁定在同一個CPU了。
7. MSIX capability指向了Table和PBA表在哪一個BAR對應的記憶體空間裡。Table裡包含了“訊息地址”和”訊息資料“, x86下格式和MSI的完全一樣。PBA指示了是否有待處理的中斷訊息。
8.
一
個裝置理論上最多分配32個MSI中斷, 向量數大於1時,需要分配連續相鄰的向量,這是MSI
capability裡”訊息資料“和”Multiple Message
Enable“的定義決定的。Solaris可參考apic_alloc_msi_vectors的實現。
9.
一個裝置理論上最多可以分配2K個MSIX中斷, 而且每個中斷向量可以是不連續的, 因為Table的大小是11位二進位表示的, 其中每個表項都有獨立的”訊息地址“和“訊息資料”。Solaris可參考apic_alloc_msix_vectors。
10. 因為每個向量對應獨立的“訊息地址”和“訊息資料”, MSIX可以讓一個裝置多至2K個中斷獨立的綁定在不同的CPU上,CPU足夠多的時候它們互相不影響,所以Intel的SRIOV 1/10G卡的VF都只支援MSIX而不是MSI。