• 検索結果がありません。

Kernel PlugIn での割り込み処理

ドキュメント内 WinDriver v11.70 ユーザーズ ガイド (ページ 123-126)

第 9 章 実行に当たっての問題

11.6 Kernel PlugIn の仕組み

11.6.5 Kernel PlugIn での割り込み処理

セクション [11.6.5.2] の説明のとおり、Kernel PlugIn ドライバの使用を有効にした場合、Kernel PlugIn ドライ バで割り込みを処理します。

Kernel PlugIn の割り込みを有効にした場合、WinDriver がハードウェアの割り込みを受信した際には、

Kernel PlugIn ド ラ イ バ の 高 い IRQL ハ ン ド ラ (KP_IntAtIrql() (レ ガ シ ー 割 り 込 み) ま た は

KP_IntAtIrqlMSI() (MSI / MSI-X)) を呼びます。高い IRQL ハンドラが TRUE を返す場合、高い IRQL ハンドラが処理を終え、TRUE を返した後に、Kernel PlugIn の割り込み遅延ハンドラ (KP_IntAtDpc() (レ ガシー割り込み) または KP_IntAtDpcMSI() (MSI / MSI-X)) を呼びます。DPC 関数の戻り値は、ユー ザーモードの割り込み処理ルーチンを実行する回数です。たとえば、KP_PCI のサンプルでは、Kernel

PlugIn で実行中の割り込みハンドラは割り込みを 5 回カウントし、5 回毎にユーザーモードに通知します。

従って、WD_IntWait() は、ユーザーモードでは受け取った割り込みの 5 回に 1 回しか通知しません。高 い IRQL (KP_IntAtIrql() または KP_IntAtIrqlMSI()) は 5 回の割り込み毎に TRUE を返し、

DPC ハンドラ (KP_IntAtDpc() または KP_IntAtDpcMSI()) を有効にし、DPC 関数は高い IRQL ハン

ドラからの実際の DPC 呼び出しの回数を返します。つまりユーザーモードの割り込み処理は 5 回の割り込 み毎に 1 回しか実行されません。

11.6.5.1 ユーザーモードの割り込み処理 (Kernel PlugIn なし)

Kernel PlugIn 割り込み処理が無効の場合、割り込みを受信する度に WD_IntWait() を返し、WinDriver

がカーネルで割り込み処理を終了すると、ユーザーモードの割り込み処理ルーチンを起動します (主に、

WDC_IntEnable() またはより低レベルの InterruptEnable() または WD_IntEnable() への呼 び出しで渡される割り込み転送コマンドの実行) – 図 11.2 を参照。

図 11.2: Kernel PlugIn なしでの割り込みの処理 11.6.5.2 カーネルでの割り込み処理 (Kernel PlugIn あり)

Kernel PlugIn で割り込みを処理するには、ユーザーモード アプリケーションが Kernel PlugIn ドライバへの

ハンドルをオープンし、そして fUseKP パラメータに TRUE を設定して、WDC_IntEnable() を呼びます。

ドライバ コード

WD_IntWait()

WinDriver カーネル

割り込み 信号 ユーザー モード

カーネル モード

WD_IntWait()

ハードウェア

図 11.3: Kernel PlugIn ありでの割り込み処理

WDC_xxx API を 使 用 し な い 場 合 、 ア プ リ ケ ー シ ョ ン は 、Kernel PlugIn ド ラ イ バ へ の ハ ン ド ル を WD_IntEnable() 関数またはラッパー InterruptEnable() 関数へ渡します (WD_IntEnable() と WD_IntWait() を 呼 び ま す)。Kernel PlugIn 割 り 込 み 処 理 を 有 効 に し ま す (関 数 へ 渡 さ れ る WD_INTERRUPT 構造体の hKernelPlugIn フィールド内に Kernel PlugIn ハンドルを渡します)。

WDC_IntEnable() / InterruptEnable() / WD_IntEnable() を呼び出して Kernel PlugIn で割り 込みを有効にする際、Kernel PlugIn の KP_IntEnable() コールバック関数を有効にします。この関数 で、Kernel PlugIn 割り込み処理へ渡される割り込みコンテキストを設定できます。また同様に、ハードウェア で実際に割り込みを有効にするためにデバイスへの書き込みや、デバイスの割り込みを正確に有効にする ために必要なコードを実装できます。

Kernel PlugIn 割り込みハンドラが有効な場合、有効になった割り込みの種類を基に、関連する高い IRQL

ハンドラ (KP_IntAtIrql() (レガシー割り込み) または KP_IntAtIrqlMSI() (MSI / MSI-X)) が割り 込みのたびに呼び出されます。高い IRQL ハンドラのコードを高い割り込みレベルで実行します。このコー ドの実行中はシステムが停止します (そのため、コンテキスト スイッチや、優先度の低い割り込みが処理され ません)。

高い IRQL で実行中のコードは、次の制約があります。

 ページしないメモリに対してのみアクセス可能です。

 次の関数だけを呼び出し可能です (または、これらの関数を呼び出したラッパー関数)。

 WDC_xxx() のアドレスまたは設定空間 read / write 関数

 WDC_MultiTransfer() 、 ま た は 低 レ ベ ル の WD_Transfer() 、 WD_MultiTransfer() または WD_DebugAdd() 関数

ドライバ コード WD_IntEnable()

. .

WinDriver カーネル

KP_IntAtIrql()

{

優先度の 高いコード }

KP_IntAtDpc() {

優先度の 低いコード }

WinDriver Kernel PlugIn

割り込み 信号 ユーザー モード

カーネル モード

ハードウェア

 高い割り込み要求レベルから呼び出される OS 固有のカーネル関数 (WDK 関数など)。(これ らの関数を使用すると、その他の OS とのコード互換性が損なわれる場合があるのでご注意く ださい。)

 malloc()、free() または上記の関数以外の WDC_xxx または WD_xxx API 関数は呼びま せん。

前述の制限のため、高い IRQL ハンドラ (KP_IntAtIrql() または KP_IntAtIrqlMSI()) のコードは できだけ小さくします (レベル センシティブ割り込みの検知 (消去) など)。割り込み処理で実行するその他の コードを DPC 関数 (KP_IntAtDpc() または KP_IntAtDpcMSI()) で実装します。DPC 関数は、遅延 割り込みレベルで実行され、高い IRQL ハンドラと同じような制限はありません。その DPC 関数と一致する 高い IRQL 関数が戻り値を返した後に (TRUE を返した場合)、DPC 関数を呼びます。

ユ ー ザ ー モ ー ド で 割 り 込 み 処 理 を 行 う こ と も で き ま す 。DPC 関 数 (KP_IntAtDpc() ま た は KP_IntAtDpcMSI()) の戻り値が、カーネルモードでの割り込み処理が終了した後に、ユーザーモードの 割り込み処理ルーチンを呼ぶ回数となります。

ドキュメント内 WinDriver v11.70 ユーザーズ ガイド (ページ 123-126)