私は現在、趣味の OS、具体的には ATA ドライバーに取り組んでいます。割り込みを伴う PIO データ入力コマンドで問題が発生しています。READ MULTIPLE コマンドを実行して、ブロックごとに割り込みを発生させながら、ブロックごとにドライブから複数のセクターを読み取ろうとしています。
4 ブロック (ブロックごとに 1 セクター) の読み取りを要求した場合。データ ブロックごとに 1 つずつ、合計 4 つの割り込みが発生すると予想しています。4 番目の割り込みを受信すると、すべてのデータを転送したことを識別し、それに応じてリクエスト構造を更新できます。ただし、VirtualBox では、最後のデータ ブロックが転送された後、さらに別の割り込みを受信したことがわかりました (STATUS = 0x50、READY、OVERLAPPED MODE SERVER REQ)。ステータス レジスタを読み取るだけでクリアできますが、仕様によると 5 番目の割り込みを受信する必要はないと思います。
では、ATA デバイスによって発行された割り込みを確認する適切な方法は何ですか?
この例では、READ MULTIPLE コマンドを発行すると、ISR は次のことを行います。
- CPU 割り込みを無効にし、nIEN を設定します
- DATA レジスタから 1 つのデータ ブロック (セクタではありません!) を読み取ります。
- すべてのデータが読み取られた場合は、STATUS レジスタを読み取って「余分な」割り込みをクリアします。
- nIEN をクリアして終了し、マスター PIC とスレーブ PIC の両方に EOI を送信します。
PIO データ入力コマンド プロトコルの ATA 仕様は、ステータス レジスタを読み取る必要があることを示していません。そのことから、割り込みを受け取ったら、プロトコルに従い、EOI を PIC に送信して終了するだけでよいと思いました。nIEN の設定/クリアに関しては、VirtualBox を扱う際に、これを行わないと、最初の割り込みを超えて割り込みを受け取らないことがわかりました。そのため、ISR に入るときに nIEN を設定し、出発する前にクリアします。効果はないと思いますが、その特定のレジスタの読み取り/書き込みに関連している必要があります。