メッセージ シグナル割り込みの概要

メッセージ シグナル割り込み (MSI) は、行ベースの割り込みの代替として、PCI 2.2 の仕様で導入されました。 専用のピンを使用して割り込みをトリガーする代わりに、MSI を使用するデバイスは、特定のメモリ アドレスに値を書き込むことで割り込みをトリガーします。 PCI 3.0 では、MSI-X と呼ばれる拡張形式の MSI が定義されています。これにより、より優れたプログラマビリティがもたらされます。 Windows Vista 以降のバージョンの Windows では、MSI と MSI-X がサポートされています。 MSI と MSI-X の両方を、単一のデバイスがサポートすることができます。 このようなデバイスの場合、オペレーティング システムは自動的に MSI-X を使用します。

割り込みメッセージは、割り込みをトリガーするためにデバイスが特定のアドレスに書き込む特定の値です。 行ベースの割り込みとは異なり、メッセージ シグナル割り込みにはエッジ セマンティクスがあります。 デバイスはメッセージを送信しますが、割り込みが受信されたことを示すハードウェアの確認を受信しません。

PCI 2.2 の場合、メッセージはアドレスと部分的に不透明な 16 ビット値で構成されます。 各デバイスには 1 つのアドレスが割り当てられます。 複数のメッセージを送信するために、デバイスはメッセージ値の下位 4 ビットを使用してメッセージを区別することができます。 したがって、PCI 2.2 の場合、デバイスは最大 16 個のメッセージをサポートできます。

PCI 3.0 の場合、メッセージはアドレスと不透明な 32 ビット値で構成されます。 異なる各メッセージには、独自の一意のアドレスがあります。 PCI 2.2 とは異なり、デバイスは値を変更しません。 PCI 3.0 の場合、デバイスは最大 2,048 個の異なるメッセージをサポートできます。 PCI 3.0 MSI-X をサポートするデバイスには、デバイス内の各割り込みソースのエントリを格納する、動的にプログラム可能なハードウェア テーブルが備わっています。 このテーブル内の各エントリは、デバイスに割り当てられているメッセージの 1 つを使用してプログラミングでき、個別にマスクすることができます。 ドライバーは、テーブル エントリへの割り込みメッセージのプログラミングと、エントリ がマスクされているかどうかを変更することができます。 詳細については、「MSI-X の動的な構成」を参照してください。

ドライバーは、処理できるすべてのメッセージを処理する単一の InterruptMessageService ルーチン、または各メッセージに対し個別の InterruptService ルーチンを登録することができます。

ドライバーは、デバイスが送信する MSI を次のように処理できます。

  1. ドライバーのインストール中に、レジストリで MSI を有効にします。 レジストリを使用して、デバイスに割り当てるメッセージの数を指定することもできます。 詳細については、「レジストリでのメッセージ シグナル割り込みの有効化」を参照してください。

  2. 必要に応じて、割り込みメッセージの数を増やし、IRP_MN_FILTER_RESOURCE_REQUIREMENTS 要求に応答してメッセージごとの設定を保存します。 詳細については、「割り込みリソース記述子の使用」を参照してください。

  3. IRP_MN_START_DEVICE のドライバーのディスパッチ ルーチンで、IoConnectInterruptEx を呼び出して、デバイスの割り込みを処理する InterruptService ルーチンまたは InterruptMessageService ルーチンを登録します。 CONNECT_FULLY_SPECIFIED バージョンの IoConnectInterruptEx を使用して、特定のメッセージの InterruptService ルーチンを登録するか、CONNECT_MESSAGE_BASED バージョンの IoConnectInterruptEx を使用して、すべてのメッセージに対して 1 つの InterruptMessageService ルーチンを登録します。 詳細については、「IoConnectInterruptEx の CONNECT_MESSAGE_BASED バージョンの使用」および「IoConnectInterruptEx の CONNECT_FULLY_SPECIFIED バージョンの使用」を参照してください。

  4. ドライバーがデバイスからの割り込みを処理する必要がなくなったら、IoDisconnectInterruptEx を (デバイスの割り込みを無効にした後に) 呼び出して、登録されている割り込みサービス ルーチンを削除します。

複数のメッセージを使用するように設計されたドライバーは、想定されている数のメッセージが割り当てられていることをチェックする必要があります。 プラグ アンド プレイ (PnP) マネージャーが要求された数のメッセージを割り当てることができない場合は、代わりにデバイスに 1 つのメッセージを割り当てます。 ドライバーは、次のいずれかの方法で実際に割り当てられているメッセージの数をチェックすることができます。

  • PnP マネージャーで、生のリソース記述子の一覧に割り当てられたメッセージの数を報告します。 詳細については、「割り込みリソース記述子の使用」を参照してください。

  • IoConnectInterruptEx が返されたときに、割り当てられたメッセージの数を Parameters->MessageBased.ConnectContext.InterruptMessageTable->MessageCount に設定します。