第 3 章 インタフェースモジュール制御 9
3.5 割り込み設定・制御
3.5.4 割り込み処理関数使用例
28 if (!r) {
29 port = bar[0] & 0xfffc;
30 printf("BAR0 = %04XH ¥n", port);
31 printf("IRQ = %d ¥n", irq);
32 /* 割り込み処理の登録 */
33 handle = PciSetInterrupt(irq, user_func, port, 0L);
34 if (handle != 0xffff) {
35 outp(port + 0x04, 0x00); /* インターバルタイマの設定 */
36 outp(port + 0x05, 0x00);
37 outp(port + 0x06, 0x01);
38 outp(port + 0x03, 0x10); /* 割り込みマスクのオープン */
39 outp(port + 0x07, 0x02); /* インターバルタイマの開始 */
40 while (1) {
41 printf("TIMER = %04XH¥n", timer);
42 if (kbhit()) { 43 getch();
44 printf("¥n");
45 break;
46 } 47 }
48 outp(port + 0x07, 0x00); /* インターバルタイマの停止*/
49 outp(port + 0x03, 0x00); /* 割り込みマスクのクローズ*/
50 PciKillInterrupt(handle); /* 割り込み処理の削除 */
51 } 52 } 53 }
割り込み処理の登録の例
最初にリソース取得用のPciGetConfigReg関数を使用し、ハードウェアリソース情報(I/Oポートアド レスと割り込み番号)を取得します。
次に割り込み処理の登録を行います。パラメータには、取得した割り込み番号, 割り込み処理への ポインタ, I/Oポートアドレスを指定しています。
最後の2つのパラメータは、デジタルの引数で、割り込み処理に渡したい値を書きます。この例で は、I/Oポートアドレスを引き渡しています。
次の処理ではインタフェースモジュールの割り込みマスクをオープンしています。
インタフェースモジュールには、いくつかの割り込み要因があり、どの要因を有効にするかを設定 するマスクレジスタがあります。この操作はインタフェースモジュールによって違いますので、I/O 公開資料でご確認ください。
ここまでの処理で割り込みの設定は完了です。割り込みが発生すれば、指定した割り込み処理が実 行されます。
プログラムの最後で行う割り込み解除の処理です。インタフェースモジュールの割り込みマスクを クローズして、割り込み処理の解除をします。
割り込み発生時の処理の例
user_funcという関数名は、割り込み処理登録関数(PciSetInterrupt関数)で指定した名前です。
第1パラメータは、ユーザ割り込み処理関数を一意に識別するハンドルです。PciSetInterrupt関数に て返されるハンドルと同一値です。このハンドルの値をチェックすることにより、1つのユーザ割 り込み処理関数を複数のIRQにて共有する時に、どのIRQから発生した割り込みであるかを判定する ことができます。
第2パラメータは、I/Oポートアドレスが引き渡されてきます。
stat = inp(adr + 0x02)という処理で、インタフェースモジュールに対し割り込みが発生しているか確 認をしています。この操作はインタフェースモジュールによって違いますので、I/O公開資料でご確 認ください。
この処理は、割り込みが共有されている場合、他のデバイスからの割り込みである可能性があるた め、自インタフェースモジュールからの割り込みを判断するために行います。インタフェースモジ ュールには、割り込みを発生したかどうかを示すステータスがあります。このステータスを必ず確 認してください。
自インタフェースモジュールへの割り込みであれば、割り込み発生時の処理を行い、最後に
“return 1”で処理を終わります。
こうすることで、総合ライブラリは、割り込み処理が完了したことを認識し、EOIを発行します。
自インタフェースモジュールへの割り込みでなかった場合は、“return 0”で処理を終わります。
この場合、総合ライブラリは、割り込みが完了していないことを認識し、別のデバイスの割り込み 処理にチェインします。