PIC 8259Aのページ

  • PICは「Programmable Interrupt Controller」の略
  • つまり割り込みコントローラ。IRQ周りの大事なところ。
  • AT互換機、TOWNS、PC-9801とも、2個ずつ入っている(98には一部例外があったかもしれない)。
  • たいていこれらの機種にはIRQ0~IRQ15の16種(厳密には15種)の割り込みがあると思いますが、CPUはこれらの割り込み信号を直接には管理していません。CPUにはIRQ関係の信号線は1つしかなく、それが15もあるように見えるのは、このPICのおかげなのです。
  • 基本的にPICは、8つの割り込み信号を監視して1つの信号線にまとめる能力があります。しかし、これだとIRQ0-7までしか使えないことになって割り込み不足になるので、もう一つ子供のPICを用意して、その割り込み通知ピンを親のIRQピンにつないでいます。こういう接続の仕方をカスケード接続といいます。この方法をもっと押し進めれば最大で64個のIRQをサポートできますが(スレーブ8個)、そんなマシンは無いようです。また8259Aは3段重ねはサポートしていないようです。
    CPU ---1本--- PIC(マスタ:IRQ0-7)
                   +------ IRQ
                   +------ IRQ
                   +------ IRQ
                   +------------ PIC(スレーブ:IRQ8-15)
                                  +------ IRQ
                                  +------ IRQ
                                  +------ IRQ
                                  +------ IRQ
       (註)図の簡略化のため、PICからは4本のIRQ線しか書いていませんが、本当は8本です。
  • このような仕組みのため、マスタに直接つながっている割り込みと、スレーブにつながっている割り込みとでは、いろいろ扱いが変わります。マスタにつながっているやつのほうが簡単です(マスタだけいじればいいので)。

関係するI/Oポートなど

AT互換機

アドレス(hex)wideR/Wデバイス説明備考
0020byteRPIC-0IRR/ISR
0020byteWPIC-0OCW2/OCW3/ICW1
0021byteRPIC-0IMR
0021byteWPIC-0OCW1/ICW2/ICW3/ICW4
00A0byteRPIC-1IRR/ISR
00A0byteWPIC-1OCW2/OCW3/ICW1
00A1byteRPIC-1IMR
00A1byteWPIC-1OCW1/ICW2/ICW3/ICW4
  • PIC-0がマスタ(IRQ0-7)、PIC-1がスレーブ(IRQ8-15)
  • 基本的にエッジトリガモードで使用するように設計されている(PCIサポート以降では、チップセットで部分的にレベルトリガにもできるが、とにかくPICに対してはエッジトリガで設定する):ICW1参照
  • 割り込み番号表
    IRQ0タイマ
    IRQ1キーボード
    IRQ2スレーブとのカスケード接続に使用
    IRQ3シリアルポート(COM2)
    IRQ4シリアルポート(COM1)
    IRQ5主にISA/PCI拡張デバイス用
    IRQ6FDC
    IRQ7パラレルポート
    IRQ8RTC
    IRQ9主にISA/PCI拡張デバイス用
    IRQ10主にISA/PCI拡張デバイス用
    IRQ12マウス
    IRQ13FPU(?)
    IRQ14ATA-0
    IRQ15ATA-1
    • DOS/BIOSでは、IRQ0~7は INT 0x08~0x0f に割り当て。
    • DOS/BIOSでは、IRQ8~15は INT 0x70~0x77 に割り当て。
    • (まだ未完成)

TOWNS

アドレス(hex)wideR/Wデバイス説明備考
0000byteRPIC-0IRR/ISR
0000byteWPIC-0OCW2/OCW3/ICW1
0002byteRPIC-0IMR
0002byteWPIC-0OCW1/ICW2/ICW3/ICW4
0010byteRPIC-1IRR/ISR
0010byteWPIC-1OCW2/OCW3/ICW1
0012byteRPIC-1IMR
0012byteWPIC-1OCW1/ICW2/ICW3/ICW4
  • PIC-0がマスタ(IRQ0-7)、PIC-1がスレーブ(IRQ8-15)
  • 基本的にレベルトリガモードで使用するように設計されている:ICW1参照
  • 割り込み番号表
    IRQ0タイマ
    IRQ1キーボード
    IRQ2RS-232C
    IRQ3拡張RS-232C
    IRQ4拡張ボード用
    IRQ5拡張ボード用
    IRQ6FDC
    IRQ7スレーブとのカスケード接続に使用
    IRQ8SCSI
    IRQ9内蔵CD-ROMドライブコントローラ
    IRQ10拡張ボード用
    IRQ11VSYNC
    IRQ12プリンタ
    IRQ13FM音源&PCM音源(註:レベルトリガなので割り込みが共存できる)
    IRQ14拡張ボード用
    IRQ15リザーブ

概要

  • IRR:インタラプトリクエストレジスタ
    • IRQピンの状態を表す。ポートを読んだときに、IRRになるかISRになるかは、OCW3で選択する。
    • 1になっているビットは、現在要求が来ている(もしくは処理中の)割り込み。
  • ISR:インサービスレジスタ
    • 現在処理中の割り込みがどれであるかを示す。ポートを読んだときに、IRRになるかISRになるかは、OCW3で選択する。
    • 1になっているビットは、現在処理中の割り込み。処理中というのは、CPUに対してINT命令を発行したが、EOI(割り込み終了命令)を受け取ってはいない割り込み。
  • IMR:インタラプトマスクレジスタ
    • これが1になっている割り込みは、IRRが1になっていても、反応しない。
      • スペシャルマスクモード(OCW3参照)になっているときは、IMRの設定はIRRに対するマスクにはならない。つまり割り込みをマスクできない。
  • OCW1:動作コマンドワード1
    • 書き込んだ8ビットがそのままIMRに転送される。
  • OCW2:動作コマンドワード2
    • 主に、割り込み処理終了をPICに伝える。これをしないと次の割り込みは受けられないので注意(CPUに対してIRETしてもPICにはそんなこと分からない!)。
      • たぶんアセンブラ初心者は、なんて不便な仕様なんだ、CPUがIRET命令の実行をPICに伝えてくれて良さそうなものなのに、と思うでしょう。しかし実は割り込み処理以外でもIRETを使うことは(たまに)ありますし、割り込み処理が終わってもIRET以外の方法で処理する場合もあるのです。また、後述のように(必要なら)割り込み処理中にさらに別の割り込みを受けたりもでき、そうするとどのIRETがどの割り込みの終了を意味するのかわからないということもあります(CPUはもともとIRQ割り込みは一個しか考えていなくて、それをPICで増やしているに過ぎないということを忘れずに)。だから、この仕様でいいのです。
      • 割り込み終了をPICに送るのが面倒だという人は自動EOIモードというのをICW4で設定しておくこともできますが、スレーブには使えない方法ですし、ICW4を使うということはPICを全面的に再設定しなければいけないということなので、あまりおすすめしません(自動EOIモードについてはICW4参照)。割り込み処理を終わる前に同じIRQの割り込みを受け付けてしまうことも当然ありえて、それに対する配慮も必要です。その観点からも自動EOIは一長一短です。
    • bit0-2:(終了させたい)割り込み番号
    • bit3-4:常に00:むしろここが00だからOCW2であるとPICは判断している(参考:OCW3/ICW1)。
    • bit5-7:コマンド
      • 000:自動EOIモードにおいて、割り込み優先順位の回転モードをオフ。このコマンドでは、bit0-2の割り込み番号は無視される。
      • 001:通常モードにおいて、現在処理中の最優先度の割り込みを終了させる(ISRをみてPICは判断する)。このコマンドでは、bit0-2の割り込み番号は無視される。もし割り込み優先順位の回転モードがオンになっていれば、これをオフにする。
      • 010:何もしない
      • 011:通常モードにおいて、指定された割り込みを終了させる。このコマンドでは、bit0-2の割り込み番号を参照する。もし割り込み優先順位の回転モードがオンになっていれば、これをオフにする。
      • 100:自動EOIモードにおいて、割り込み優先順位の回転モードをオン。このコマンドでは、bit0-2の割り込み番号は無視される。
      • 101:通常モードにおいて、現在処理中の最優先度の割り込みを終了させる(ISRをみてPICは判断する)。このコマンドでは、bit0-2の割り込み番号は無視される。もし割り込み優先順位の回転モードがオフになっていれば、これをオンにする。
      • 110:もし割り込み優先順位の回転モードがオフになっていれば、これをオンにして、指定された割り込みが最優先になるように設定する(もしかしたらもっとも優先度が低くなるんだったかもしれない)。このコマンドは、通常モードでも自動EOIモードでも使う。
      • 111:通常モードにおいて、指定された割り込みを終了させる。このコマンドでは、bit0-2の割り込み番号を参照する。もし割り込み優先順位の回転モードがオフになっていれば、これをオンにする。
    • 割り込みの優先順位について
      • 2つの割り込みが同時に来たとき(これはありえないと思うかもしれないが、CLI→STIしたときなどは、容易に起こり得る)、もしくは1つの割り込み処理中にもう一つの割り込みが来た場合など、PICはどうしたらいいのかを優先順位という考え方で解決している。
      • 優先順位には、どの割り込みがどの割り込みに対して優先するのかということが固定的に決まっている非回転モードと、割り込みを受け付けるたびに割り込み優先順位が回転していく回転モードがある。
      • 非回転モードの場合、割り込み番号が小さいほど優先順位は高い。つまりIRQ0がもっとも優先度の高い割り込みになる。たいていの機種ではIRQ0にタイマーがあり、IRQ1にキーボードがある。これにより、時刻を正確に管理できる(優先度が一番高いので割り込みをうけやすい)とか、異常事態でもキーボードからの指令を優先できるようになっている。この思想を生かすなら、たとえ割り込みルーチンであっても長い期間CLIしないようにして(つまり長くなるようならSTIして)、タイマやキーからのIRQをまめに拾えばいいだろ う。
      • 一方、もし高優先度の割り込みが集中してしまうと、順位の低い割り込みは全く受け付けてもらえないことになり、これは困る場合があるかもしれない。それを解決するのが回転モードである。回転モードでは、たとえばIRQ1を受け付けたら、優先順位が23456701に変更され、もしIRQ2以降からの割り込み要求があれば、それを優先してくれるのである。同様にIRQ4を受け付けたら56701234になる。こうして、どのIRQもほぼ平等になる。
    • 割り込み終了を受け付けると、対応する割り込みのISRとIRRがクリアされる。
      • 割り込み終了コマンドでISRがクリアされるのは間違いないが、IRRがクリアされるタイミングには自信がない。もしかしたら、割り込みを受け付けてISRをセットするのと同時にIRRをクリアしていたかもしれない。これは現在確認中。
  • OCW3:動作コマンドワード2
    • その他の簡単な設定を行う。
    • bit0-1:IRR/ISR読み出しポートの設定
      • 00:設定は変更しない
      • 01:設定は変更しない
      • 10:IRRに設定
      • 11:ISRに設定
    • bit2:PICの動作モード(0:通常、1:ポールコマンドモード)
      • ポールコマンドモードとは、PICがINT命令を一切発行しないモードで、つまり割り込みは起きない。CPUは常にCLI状態にある必要があり、PICをこまめにリードしてIRQ応対をする。使い方の詳細はよく分からないが、こんなモードを使う人はまずいないと思うので、詳細を調べる予定はない。
    • bit3-4:常に01:むしろここが01だからOCW3であるとPICは判断している(参考:OCW2/ICW1)。
    • bit5-6:スペシャルマスクモードに関する設定
      • 00:設定は変更しない
      • 01:設定は変更しない
      • 10:通常モード(IMRはIRRに対するマスクとして働く)
      • 11:スペシャルマスクモード(IMRはISRに対するマスクとして働く)
      • スペシャルマスクモードになっているときは、IMRの設定はIRRに対するマスクにはならない。つまり割り込みをマスクできない。
      • スペシャルマスクモードでは、IMRは割り込み優先順位解決の際のISRへのマスクとして働く。すなわち、IMRでマスクされた割り込みの処理中であっても、より下位の割り込みを妨げることはない。
      • おそらく、スペシャルマスクモードでIMRを0xffにすると、自動EOIモードとよく似たことになる。
    • bit7:常に0。
  • ICW1:初期化コマンドワード1
    • PICを初期化して、設定をやり直す。このコマンドを発行するときには、マザーボード上でPICがどのように接続されているかの知識が必要になるので、よく理解してから使うこと(間違えると誤動作ばかりではなく、故障の原因になりうる)。
    • このコマンドを書いた時点で、IRRとISRはゼロクリアされ、フリーネステッドモードになり、IRR/ISRの選択はIRRになる。
    • (まだ書いてない)
  • ICW2:初期化コマンドワード2
    • (まだ書いてない)
  • ICW3:初期化コマンドワード3
    • (まだ書いてない)
  • ICW4:初期化コマンドワード4
    • (まだ書いてない)

ものぐさなあなたのために

  • 毎度の、超簡潔な説明です。要するに、どうすればいいのよ、ということで。例によってAT互換機限定。
  • とにかく割り込み処理が終わったとPICに通知したい。
    • IRQ0-7の場合:
      AL = 割り込み番号 + 0x60; OUT(0x20, AL);
    • IRQ8-15の場合:
      AL = (割り込み番号 - 8) + 0x60; OUT(0xa0, AL); AL = 0x62; OUT(0x20, AL);
      • ただしこの方法を使う場合、IRQ8-15の割り込み処理中に他の割り込みを受け付けないこと。
      • 他の割り込みを受け付けているかもしれないときにも対応したいなら、OUT(0xa0, AL);のあとでスレーブのISRをチェックして、これが0x00のときに限って、AL = 0x62; OUT(0x20, AL); するように細工する。

こめんと欄

  • PICはなんとかつかえそうなのですが、APICの使い方が謎・・ -- 名無しさん 2004-10-15 (金) 21:30:32
  • それは僕もまだわかりませんねえ。それはAPICを活用しているOS(もしくは活用予定のOS)をOS-Wikiに誘致しないと・・・。 -- K 2004-10-16 (土) 02:10:30
  • IRQ0をポート0x60に設定し、キーボード割り込みを0x61で受け付けています。一応キーは取得できるのですが、何故か2回連続でキーの割り込みハンドラーがコールされます。行き詰まり、このページに行き着いたのですが、もし原因がおわかりでしたら、ご教授ください。 -- OS勉強中 2005-11-12 (土) 22:27:21
  • OS勉強中さんへ。このサイト内の(AT)keyboardに書いてありましたが、 makeとbreakが原因なのだと思います。 -- 名無しさん 2005-11-20 (日) 13:44:39
  • <br> -- 名無しさん 2005-12-22 (木) 17:01:54
  • キーボード割り込みでは、mov al,0x61;out 0x20,alだけでなくキーボードからデータを受け取らないとキーボードが割り込み信号を出さない?。だからmov al,0x61でキーボードバッファからデータを取り出すことも必要。 -- take 2009-09-12 (土) 09:51:37
  • キーボードバッファからデータを取り出すのはin al,0x60でした。 -- take 2009-09-12 (土) 09:53:20
  • キーコードを受け取らないうちに入力がきても、割り込みは起きません。感覚的には既に読み取り待機中のキーコードさえ忙しくて受け取れていないのに、更に割り込みがきてもCPUが困るだろうと配慮している、なんてふうに思うといいかもしれません。 -- K 2009-09-12 (土) 23:30:16
  • ICW1が実行したら絶対に ICW2 -> ICW3 -> ICW4 っと実行しないといけません。 追記. インテルの場合は8259割り込みコントローラとやらを初期化してからじゃないとICW1をいけないのかな? -- 名無しさん 2021-10-27 (水) 18:36:57

コメントお名前NameLink

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2021-10-27 (水) 18:36:57 (904d)