2252245_ja-JP

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2252245_ja-JP

2252245_ja-JP

PCIレガシー割込みはPCIeでどのようにエミュレートされ、Linuxカーネルでどのように処理されるのですか?

PCIの世界では、PCIのレガシー割込みは過去のものとなりました。PCI Expressではより効率的なMSI割込みが導入され、様々なアプリケーションで広く利用されています。しかし、これらは主に下位互換性と起動サポートのために依然として使用されています。

レガシー割込み[INTx]はPCIでは物理信号として扱われていましたが、
PCIeデバイスには物理的なINTxピンがありません。そのため、PCIeはこれらのレガシー割込みをサポートするために、それらを論理的にエミュレートします。これは、仮想INTxメカニズムのようなものです。このガイドでは、開発者や愛好家が実践形式で動作を確認できるよう、これらの割込みがPCI Expressでどのように実現されているかを見ていきます。このブログのテーマは以下のとおりです。

     
1. PCIe のレガシー INTx スタイルの割込みについて考慮する必要があるのはなぜですか?

  1. システム概要
  2. INTxレガシー割込みはPCIeでどのように実現されますか?
  3. iMX8MMでのINTxエミュレーションの有効化とテスト


なぜPCIeのレガシーINTxスタイルの割込みにこだわる必要があるのですか?


今現在に至るまで、レガシー INTx割込みを理解することが重要な理由は以下のとおりです。

  1. 多くのオペレーティングシステム、ドライバ、およびアプリケーションは、もともとPCI用に設計されており、INTxスタイルの割込みについては想定済みですが、MSI/MSIXをサポートしていない可能性があります。
  2. PCIeデバイスをレガシーPCIの動作が想定されるシステムで使用しても、INTxエミュレーションにより、デバイスは古い方法で引き続き割込みを通知できます。これにより、MSI/MSI-Xをサポートしていない古いソフトウェアスタックが壊れることがなくなります。

  3. (リソースの制約や構成の問題により)MSI/MSI-Xを割り当てられない場合、フォールバックメカニズムとして、INTXエミュレーションが役立つことが証明されています。

システム概要
 

Figure. 1Figure. 1図1

 

テスト対象のシステムには以下のコンポーネントがあります。


ハードウェア・コンポーネント:

iMX8MM EVKボード -
i.MX 8Mミニ評価キット | NXP Semiconductors
iMX95 19x19 EVK -
i.MX 95アプリケーション・プロセッサ・ファミリ | NXP Semiconductors



ソフトウェア・コンポーネント:

GitHub - nxp-imx/linux-imx: i.MX Linux kernel

iMX95 RC上のLinux BSP - 6.6.3
iMX8MM EP上のLinux BSP - 6.1.55

図1で示されている通り、システムではiMX8MM EVKとiMX95 19x19 EVKがM.2 Key E PCIeブリッジを介して並べて接続されています。

iMX8MM EVKはPCIeエンドポイントとなり、iMX95 EVKはPCIeルートコンプレックスとして機能します。

iMX95<------> iMX8MM
[RC] [EP]

上記の構成でセットアップするには、こちらのブログをご参照ください。

iMX95 torradexボードとiMX8MM EVK上でのPCIeエンドポイント・フレームワークの有効化 - NXPコミュニティ


この後、PCIエンドポイント・テストフレームワークを使用して、iMX8MMとiMX95 EVKの間でPCIeトランザクションをトリガーできるようになります。

このセットアップを使用して、PCIe EP[iMX8MM EVK]がPCIe RC[iMX95 EVK]にレガシーINTx割込みを送信する方法を示します。また、linux-imxソースコード上のLinuxドライバにおけるこれらの割込みの発生源も追跡します。



INTx レガシー割り込みは PCIe でどのように実現されますか


PCI Expressは、PCIローカルバス仕様で定義されているPCI割込みをサポートします。これには、PCIコンフィグレーション・スペースの割込みピン・レジスタと割込みライン・レジスタが含まれます。PCIeデバイスは下位互換性を確保するため、これらのレジスタをサポートします。したがって、実際のシグナル割込みは物理ピンを使用するのではなく、インバンドメッセージを使用します。


PCIeでは、仕様に従って2種類のメッセージが定義されています。

PCI INTxシグナルのエミュレーションのためのAssert_INTxDeassert_INTx
x -> A/B/C/D

これらのメッセージはリンク間でのシグナル割込みの「仮想ワイヤー」として機能します。これら「仮想ワイヤー」の形式のメッセージは「ルート・コンプレックス」に到達し、その後システム割込みコントローラにマッピングされます。つまり、RCはこれらインバンドの「仮想ワイヤー」メッセージを受信すると、それを適切なハードウェア割込みに変換してCPUに送ります。

注:PCI Express IntXエミュレーションのシステム割込みへのマッピングは、実装によって異なります。物理的なシグナル割込みと同様に、INTxエミュレーション・メカニズムは疑似割込みを引き起こす可能性があります。これはシステム・ソフトウェアによって処理する必要があります。


iMX8MMでのINTxエミュレーションの有効化とテスト


公式のLinuxファクトリーカーネルでは、レガシー割込みはまだサポートされていません。このブログには、PCIeのレガシー割込みを有効にするためのパッチを含むZIPファイルが添付されています。以下の3つのファイルがあります。

      1.legacy_intx_tested_imx8mm_patch_1

  1. legacy_intx_tested_imx8mm_patch_2
  2. README


パッチの適用方法は、READMEファイルに記載されています。何か問題がありましたら、お気軽にDMを送信してください。

LinuxでPCIe INTxエミュレーションを有効にする手順を簡潔にまとめると、以下の通りです。

1. ボード上でデフォルトのiMX8MM 6.1.55 wicイメージをフラッシュし、Linuxで起動することを確認します。

2. linux-imxリポジトリを取得[ブランチlf-6.1.yをチェックアウト]します。

3. Linuxのソースコードにパッチを適用します。

4.カーネルとscp「arch/arm64/boot/Image」をボードにビルドします。この「Image」と「imx8mm-evk-pcie-ep.dtb」でボードを起動します。

問題が発生した場合は、次のブログを参考にしてください:iMX95 torradexボードとiMX8MM EVK上でのPCIeエンドポイント・フレームワークの有効化


この時点で、PCIe EP iMX8MM上で動作するカーネルは、PCIe RC [iMX95]にINTx割込みを送信できます。テスト方法は以下のとおりです。

1. iMX95 RCがM.2経由でiMX8MM EPに接続されていることを確認します。どちらも起動しており、iMX8MMはiMX95のPCIeエンドポイントとして表示されます。iMX95で「lspci」を実行すると、「割り当てられていないクラス」というエントリが表示されます。

2. iMX95EVK RC上で、以下の2つのコマンドを実行して、INTxエミュレーションをテストします。

a. pcitest -i 0

b.pcitest -l


コンソール出力:-

root@imx95evk:~# pcitest -i 0

IRQタイプをレガシーに設定:OK


root@imx95evk:~# pcitest -l

レガシーIRQ:OK


「pcitest・i 0」は、レガシーINTx割込みを処理するようにRCを設定します。この結果、ioctlコールは「PCITEST_SET_IRQTYPE」となります。

drivers/misc/pci_endpoint_test.cでは以下のように処理されます。
 

 

Figure. 2Figure. 2図2



IRQ_TYPE_LEGACYのargは0です。


以下のスニペットでは、すべてがどこから始まるのかを示しています。

 

Figure. 3Figure. 3図3



pci_endpoint_test_release_irqの内部


 Figure. 4Figure. 4図4

 

test->num_irqs=16の場合、エンドポイントでは以下のようになります。

echo 16 > functions/pci_epf_test/func1/msi_interrupts

pci_irq_vectorは、MSI割込み0から16に対応するLinux IRQ番号を返します。

その後、devm_free_irqを使ってこれらのirqを解放し、再び割り当てられるようにします。

free_irqはこの関数内で使用され、割込みハンドラを削除します。

そして、割り込みラインがどのドライバによっても使用されていない場合、それは無効化されます。

共有IRQでは、呼び出し元はこの関数を呼び出す前に、駆動するカード上で割込みが無効になっていることを確認する必要があります。


 

pci_endpoint_test_free_irq_vectorsの内部


pci_free_irq_vectors[driver/pci/msi/api.c]を呼び出し、以下を行います。

pci_alloc_irq_vectors_affinity()またはpci_alloc_irq_vectors()によって以前に行われた割込みベクタの割り当てとデバイスMSI/MSI-Xのイネーブルメントを元に戻します。


注:PCIエンドポイント・テストドライバでは、IRQベクタを割り当て、レガシーINTx割込みを要求する前に、既に割り当てられたMSI割込みを解放し、それに関連付けられたベクタを解放する必要があります。その過程で、MSI割込みは無効化されます。これはPCIeの仕様上、MSIとINTxが互いに排他的であるためです。MSIとINTxの両方を有効にするとどうなるかテストしてみると面白いでしょう。テストの結果何が起こったかをコメント欄から教えてください。


 

pci_endpoint_test_alloc_irq_vectorsの内部

Figure. 5Figure. 5図5

 

pci_alloc_irq_vectorsは、従来のintx割込みに割込みベクタを割り当てます。これにより、内部深くに、CPUコア0のCPUアフィニティ・マスクが作成され、pci_intxが呼び出され、PCIe構成スペースの読み取りと書き込みによってレガシー割込みが有効になります。

Figure. 6Figure. 6図6

 

pci_endpoint_test_request_irqの内部

Figure. 7Figure. 7図7

 

pci_irq_vectorは、
devm_request_irq -> devm_request_threaded_irq
に渡されるLinux IRQ番号を割り当てます。
Linuxカーネルのdevm_request_irq
はデバイス管理型リソース割り当てAPIの一部です。このAPIの主な役割は、IRQリソースのライフサイクルを自動的に管理することで、デバイス・ドライバの割り込みリクエスト処理を簡素化することです。また、IRQ番号の割込みハンドラを登録し、IRQリソースをデバイスのライフサイクルに結びつけます。デバイスが切り離されるか、ドライバがアンロードされると、カーネルは自動的にIRQを開放します。

IRQF_SHAREDフラグを持つハンドラ「pci_endpoint_test_irqhandler」が渡されます。このハンドラはINTx割込みを着信したときに呼び出されます。
IRQF_SHARED -- 割込み回線を複数のデバイスと共有できます。


注:Linux IRQサブシステムについてはこのブログの範囲外です。カーネルAPIの一部に戸惑っても、今後のブログで取り上げる予定ですのでご安心ください。


ここまでで、PCIeでINTxを有効にすると裏で何が起こるかが少しわかったと思います。


「pcitest -l」がトリガーするIRQテストでは、
すべてがうまくいった場合「OKAY」を、そうでない場合は「NOT OKAY」を返します。

上記のテストを実行すると、PCIe RCはpcie link上のiMX8MM EPにコマンド「COMMAND_RAISE_LEGACY_IRQ」を送信します。このコマンドをハンドラ「pci_epf_test_cmd_handler」の一部として受け取ったEPは「pci_epf_test_raise_irq」を呼び出します。

 Figure. 8Figure. 8図8

 

Figure. 9Figure. 9図9



pci_epc_raise_irqは、
最終的にパッチの__dw_pcie_ep_raise_intx_irqを呼び出します。


Figure. 10Figure. 10図10



これはPCI_CODE_ASSERT_INTAメッセージを送信し、その後遅延を挟んでからPCI_CODE_DEASSERT_INTAを送信します。これらのメッセージはどちらもPCI_MSG_ROUTING_LOCALというルーティングタイプで、同じデバイス内の特定の機能またはスイッチにルーティングされることを意味します。メモリトランザクションがターゲットアドレスを必要とするのとは異なり、INTxメッセージには宛先アドレスがありません。
簡単に言うと、「これを私のローカルルートコンプレックスにルーティングしてください」ということです。

 

Figure. 11Figure. 11図11


その後、ルート・コンプレックスiMX95に到達し、そこから、共有ペリフェラル優先割込みを使用して、割込みコントローラ[GICv3]に到達します。GICは、割込みを処理するよう、CPUコアのいずれかに通知します。ここでは、アフィニティをCPU 0に設定しているため、CPU 0がこれを処理します。最後に、RCのエンドポイント・テストフレームワークでpci_endpoint_test_irqhandlerが呼び出されます。


Figure. 12Figure. 12図12



割込みがGICに到達した後のシーケンスは以下のとおりです。
 
Figure. 13Figure. 13図13

 


JTAGをiMX95EVKボードに接続すると、LinuxでレガシーINTx IRQが処理される際に呼び出しを追跡できます。

 Figure. 14Figure. 14図14


imx95上のGICにルーティングされた割込みは、「pcitest -l」を使用してレガシー割込みテストをトリガーするたびに、
「cat /proc/interrupts」

を実行することで確認できます。

INTAの場合、「cat /proc/interrupts」の出力に次のように表示されます。

Figure. 15Figure. 15図15

 


[割込みを処理した]CPU0に表示されている数字の「3」は、レガシー割込みテストをトリガーするたびに増加することがわかります。これは、CPUコアのIRQ番号に対していくつの割込みが生成されたかを示します。

レベル:割込みタイプ
「224」は割込み要求番号です。


//INTA、INTB、INTC、INTDのテスト

単一機能デバイスでサポート可能なINTx割込みの数は1つのみです[PCIeの場合はエミュレートされます]


INTB、INTC、またはINTDを使用するには


  1. drivers/pci/controller/dwc/pcie-designware-ep.c内部

     Figure. 16Figure. 16図16
 

__dw_pcie_ep_raise_intx_irq関数の第3引数


0 = INTA
1 = INTB
2 = INTC

3 = INTD


上記のマッピングに従って変更します。



  1. drivers/pci/endpoint/functions/pci-epf-test.c内部

     Figure. 17Figure. 17図17
 

test_headerinterrupt_pinメンバを変更できます。


PCI_INTERRUPT_INTA = INTA
PCI_INTERRUPT_INTB = INTB
PCI_INTERRUPT_INTC = INTC

PCI_INTERRUPT_INTD = INTD



-- INTAの割込みのモニタリング

Figure. 18Figure. 18図18


-- INTBの割込みのモニタリング

Figure. 19Figure. 19図19

 


-- INTCの割込みのモニタリング

Figure. 20Figure. 20図。20


 

-- INTDの割込みのモニタリング

Figure. 21Figure. 21図21


上記のスニペットから、コア0のみがIntX IRQを処理していることがわかったはずです。これは、CPUアフィニティ・マスクが「1」に設定されることで、CPUコアが「0」になるためです。

kernel/irq/affinity.cの内部


 Figure. 22Figure. 22図22


レガシー割込みのiRQマスクは「1」に設定されているため、コアは「0」になります。


このブログはここで終了です。細かいところまで詳述したため、かなり長くなりました。情報の多さに圧倒されそうでも大丈夫。PCIEとIRQ Linuxサブシステムでの作業を始めれば、次第に理解できるでしょう。この件についてご質問があればお知らせください。DMでもメールでもお気軽にどうぞ。また次回お会いしましょう。


 

PCIの世界では、PCIのレガシー割り込みは過去のものとなりました。PCI Expressではより効率的なMSI割り込みが導入され、様々なアプリケーションで広く利用されています。しかし、これらは主に下位互換性と起動サポートのために依然として使用されています。

レガシー割り込み[INTx]はPCIでは物理信号として扱われていましたが、
PCIeデバイスには物理的なINTxピンがありません。そのため、PCIeはこれらのレガシー割り込みをサポートするために、それらを論理的にエミュレートします。これは、仮想INTxメカニズムのようなものです。このガイドでは、開発者や愛好家が実践形式で動作を確認できるよう、これらの割り込みがPCI Expressでどのように実現されているかを見ていきます。このブログのテーマは以下のとおりです。

1. PCIe のレガシー INTx スタイルの割り込みについて考慮する必要があるのはなぜですか?

2. システム概要

3. PCIeでINTxレガシー割り込みはどのように実現されるのか?

4. iMX8MMでのINTxエミュレーションの有効化とテスト

IMX95EVK
Tags (1)
No ratings
Version history
Last update:
‎12-02-2025 12:40 AM
Updated by: