5

私は現在、趣味の OS、具体的には ATA ドライバーに取り組んでいます。割り込みを伴う PIO データ入力コマンドで問題が発生しています。READ MULTIPLE コマンドを実行して、ブロックごとに割り込みを発生させながら、ブロックごとにドライブから複数のセクターを読み取ろうとしています。

4 ブロック (ブロックごとに 1 セクター) の読み取りを要求した場合。データ ブロックごとに 1 つずつ、合計 4 つの割り込みが発生すると予想しています。4 番目の割り込みを受信すると、すべてのデータを転送したことを識別し、それに応じてリクエスト構造を更新できます。ただし、VirtualBox では、最後のデータ ブロックが転送された後、さらに別の割り込みを受信したことがわかりました (STATUS = 0x50、READY、OVERLAPPED MODE SERVER REQ)。ステータス レジスタを読み取るだけでクリアできますが、仕様によると 5 番目の割り込みを受信する必要はないと思います。

では、ATA デバイスによって発行された割り込みを確認する適切な方法は何ですか?

この例では、READ MULTIPLE コマンドを発行すると、ISR は次のことを行います。

  1. CPU 割り込みを無効にし、nIEN を設定します
  2. DATA レジスタから 1 つのデータ ブロック (セクタではありません!) を読み取ります。
  3. すべてのデータが読み取られた場合は、STATUS レジスタを読み取って「余分な」割り込みをクリアします。
  4. nIEN をクリアして終了し、マスター PIC とスレーブ PIC の両方に EOI を送信します。

PIO データ入力コマンド プロトコルの ATA 仕様は、ステータス レジスタを読み取る必要があることを示していません。そのことから、割り込みを受け取ったら、プロトコルに従い、EOI を PIC に送信して終了するだけでよいと思いました。nIEN の設定/クリアに関しては、VirtualBox を扱う際に、これを行わないと、最初の割り込みを超えて割り込みを受け取らないことがわかりました。そのため、ISR に入るときに nIEN を設定し、出発する前にクリアします。効果はないと思いますが、その特定のレジスタの読み取り/書き込みに関連している必要があります。

4

1 に答える 1

8

これはいつも私に起こります。私は苦労してきた質問を投稿しましたが、すぐに自分で答えを見つけました.

私が参照してきた ATA-6 仕様には、PIO データ入力セクション (9.5) に次の 1 行があります。

この状態では、ホストはデバイスのステータス レジスタを読み取る必要があります。

ATA では、ステータス レジスタに副作用があります。保留中の割り込みをクリアします。私はこれを知っていましたが、以前はこの部分を正しく読みませんでした。レジスタを読む必要がある理由については言及されておらず、上記とまったく同じように述べられています。

重要な部分は、これが割り込みハンドラでどのように機能するかです。PIO データ入力コマンドを発行した後、INTRQ がアサートされると、ステータス レジスタを 1 回読み取って割り込みをクリアし、割り込みの処理を続行して通常どおりに戻ります (PIC に EOI を送信するだけです)。私が読んだドキュメントのどれも、これが割り込みでどのように機能するかを正確に述べていないということです(INTRQを受け取り、ステータスを読み取り、割り込みを処理します)。ほとんどのオンラインガイドは、ポーリングされたIOのみを扱います。

これは、低レベル プログラミングの難しさの 1 つであり、ISR のステータス レジスタを読み取る必要があるなどの重要な詳細が見過ごされがちです。これは、プロトコルの説明に 1 行として残されていました。うるさいと言いますが、この点をもっと強調することを期待していたでしょう。

于 2011-09-20T17:21:13.227 に答える