CPU は、少なくともソフトウェアの意味では、割り込みをポーリングしません。ソフトウェアに関しては、割り込みは非同期イベントです。
何が起こるかというと、CPU 内のハードウェアが割り込み要求 (割り込みラインの電気的入力) を認識し、それに応答して、割り込みに応答するイベントの通常の実行を脇に置きます。最近のほとんどの CPU では、次に何が起こるかは CPU のタイプに固有のハードウェア ハンドシェイクによって決定されますが、ほとんどの CPU は割り込みデバイスから何らかの種類の番号を受け取ります。その数は、CPU の設計に応じて、8 ビットまたは 32 などになります。次に、CPU はこの割り込み番号を使用して割り込みベクトル テーブルにインデックスを付け、割り込みサービス ルーチンの実行を開始するアドレスを見つけます。そのアドレスが決定されると (そして現在の実行コンテキストが安全にスタックに保存されると)、CPU は ISR の実行を開始します。
2 つのデバイスが割り込み要求ラインを共有している場合、そのハンドシェーク プロセス中に異なる割り込み番号を返すことで、異なる ISR を実行させることができます。利用可能なベクトル数が十分にある場合、各割り込みデバイスは独自の割り込みベクトルを使用できます。
ただし、共有された ISR が、特定の割り込みの考えられるすべてのソースに戻り、ステータス レジスタをチェックして、どのデバイスがサービスを要求したかを確認できるほど賢い場合は、2 つのデバイスで割り込み要求ラインと割り込みベクトルを共有することもできます。
もう少し詳しく
CPU、割り込みコントローラ、および割り込みデバイスで構成されるシステムがあるとします。昔は、これらは別々の物理デバイスでしたが、現在では 3 つすべてが同じチップに存在することさえありますが、すべての信号はセラミック ケース内に残っています。うまく機能する例として、PCI バス上のデバイスに接続された統合割り込みコントローラーを備えた powerPC (PPC) CPU を使用します。
デバイスが何らかのデータを送信しているシリアル ポートであるとしましょう。典型的なシリアル ポート ドライバーは、大量のデータをデバイスの FIFO にロードし、デバイスが処理を行っている間、CPU は通常の作業を行うことができます。通常、これらのデバイスは、送信するデータが不足しているときに割り込み要求を生成するように構成できます。これにより、デバイス ドライバーが戻ってきて、より多くのデータをデバイスに送り込むことができます。
デバイスのハードウェア ロジックは、PCI バス割り込みの確認応答を予期します。この時点で、いくつかのことが発生する可能性があります。一部のデバイスは「自動ベクトル化」を使用します。つまり、割り込みコントローラーに依存して、正しいサービス ルーチンが選択されるようにします。他のデバイスには、デバイス ドライバーが事前にプログラムするレジスタがあり、デバイスが割り込み確認応答に応答してデータ バスに配置する割り込みベクトルを含み、割り込みコントローラーがピックアップします。
PCI バスには割り込み要求ラインが 4 つしかないため、シリアル デバイスはそのうちの 1 つをアサートする必要があります。(現時点ではどちらでもかまいません。通常はスロットに依存します。) 次は割り込みコントローラ (PIC/APIC など) で、設定されたマスク ビットに基づいて割り込みを確認するかどうかを決定します。独自のレジスタ。割り込みを確認すると仮定すると、(データ バス ラインを介して) 割り込みデバイスからベクトルを取得するか、そのようにプログラムされている場合は、APIC 自体のデバイス ドライバーによって提供される「既定の」値を使用することができます。これまでのところ、CPU はこれらすべての進行状況を幸いなことに認識していませんでしたが、それが変わろうとしています。
ここで、割り込みコントローラーが CPU コアの注意を引きます。CPU には、PIC からの要求を単に無視する原因となる独自の割り込みマスク ビットがあります。CPU が割り込みを受ける準備ができていると仮定すると、実際のアクションを開始するときが来ました。通常、現在の命令は ISR を開始する前にリタイアする必要があるため、パイプライン化されたプロセッサではこれは少し複雑ですが、命令ストリームのある時点で、プロセッサ コンテキストがスタックとハードウェアに保存されると言えば十分です。 -決定された ISR が引き継ぎます。
一部の CPU コアには複数のリクエスト ラインがあり、CPU 命令ポインターをいくつかの最上位ハンドラーの 1 つにジャンプさせるハードウェア ロジックを介して、実行する ISR を絞り込むプロセスを開始できます。古い 68K も、おそらく他の人もそうしていたでしょう。powerPC (そして x86 だと思います) には、単一の割り込み要求入力があります。x86 自体は PIC のように動作し、外部 PIC からベクトルを取得できますが、powerPC は固定アドレス 0x00000500 にジャンプするだけです。
PPC では、0x0500 のコードは、重大な意思決定コードを実行するのに十分なスペースがあるメモリ内のどこかにおそらくすぐに飛び出しますが、それは依然として割り込みサービス ルーチンです。そのルーチンは、最初に PIC に移動してベクトルを取得し、PIC に CPU コアへの割り込み要求のアサートを停止するように要求します。ベクターが判明すると、最上位の ISR は、そのベクターを使用していることがわかっているすべてのデバイスにサービスを提供する、より具体的なハンドラーにケースアウトできます。次に、ベクター固有のハンドラーは、そのベクターに割り当てられたデバイスのリストをたどり、それらのデバイスの割り込みステータス ビットをチェックして、サービスが必要なデバイスを確認します。
仮想シリアル ポートのようなデバイスがサービスを必要としていることが判明すると、そのデバイスの ISR は適切なアクションを実行します。たとえば、次の FIFO のデータをオペレーティング システム バッファからポートの送信 FIFO にロードします。一部のデバイスは、アクセスに応じて割り込み要求を自動的にドロップします。たとえば、送信 FIFO にバイトを書き込むと、シリアル ポート デバイスが要求ラインをディアサートする場合があります。他のデバイスでは、要求をドロップするために、トグル、セット、クリア、What-have-you を行う特別な制御レジスタ ビットが必要になります。無数の異なる I/O デバイスがあり、それらの中で同じ方法を実行するものはないように見えるため、一般化するのは困難ですが、通常はその方法です。
さて、言うべきことは他にもあります。割り込みの優先度についてはどうでしょうか。マルチコア プロセッサで何が起こるか? ネストされた割り込みコントローラはどうですか? しかし、サーバー上で十分なスペースを消費しました。これが役立つことを願っています。