audio

trunkにある audio 試してみました。割り込みが来てないとのことでしたがキタキタ!

カーネルに割り込みが来ているか?を調べる方法

kernel/ihandlers.cppで

// こいつをコメントアウト
//IRQHANDLERSlave(9)

// こいつを追加
void irqHandler_9()
{
    g_console->printf("interrupt 9!");
    outp8(0xA0, 0x20);
    outp8(0x20, 0x20);
    if (g_irqInfo[9].maskInterrupt) outp8(0xa1, inp8(0xa1) | (1 << (9 - 8)));
    SendInterrupt(9);
}

来ていました!。

割り込みを有効にするには

いろいろなレイヤで割り込みがマスクされたりするので注意。

  • カードの設定で割り込みを許可する
    • void ES1370Driver::enableInterrupt(Channel ch)に相当
  • 割り込みコントローラで割り込みを許可する
    • irq=9 を有効にする monapi_set_irq(this->pciinfo.IrqLine, MONAPI_TRUE, MONAPI_TRUE);に相当。
      • カスケードも有効にすること
  • 割り込みメッセージをうけとることを宣言する
    • syscall_set_irq_receiver(this->pciinfo.IrqLine, SYS_MASK_INTERRUPT);
    • 第2引数に注意。詳細は後述


上記を全部クリアすれば、割り込みは来ます。
ただし Yumeさんが書いているように、一見すると固まって割り込みが来てないように見えます。

monapi_set_irqで第二、第三引数をMONAPI_TRUEにすると固まる。割り込みが全く来ない…

これは、割り込み頻度が多すぎて

  • 割り込みが来る → メッセージ で通知

のサイクルでほぼ CPU を使いきってしまうからです。


これを防ぐために
syscall_set_irq_receiverの第二引数に SYS_MASK_INTERRUPT を設定しています。


これをやるとカーネル

  • 割り込みが来る
  • カーネル割り込み
    • そのIRQの割り込みをマスクする(次の割り込みは無視する)設定をする
    • 割り込みをレシーバにメッセージで通知する
    • 割り込みハンドラから抜ける
  • 他のプロセスへ


というフローになります。


割り込みメッセージを受け取る方は

case MSG_INTERRUPTED:
    // なんらかの割り込み処理
    syscall_print("MSG_INTERRUPTED\n");

    // 次の割り込みを有効に
    monapi_set_irq(this->pciinfo.IrqLine, MONAPI_TRUE, MONAPI_TRUE);
    break;

という風にやってやると、次の割り込みも来ます。→id:shotaro_tsuji

一応割り込みが来るコードを
ここに置いておきました。

本筋とは関係ない部分

  • -lPci => -lpciに変更
  • MONADIR=$(PWD)/../../mona => export MONADIR=$(shell cd $(PWD)/../../../mona; pwd)
  • trunk/contrib/のどこかにいれませんか?