Platform Level Interrupt Controllerといい、コア外部から挿入される割り込みを処理するためのモジュールと考えてよい。当初PLICの仕様はRISC-Vの命令仕様と同様のグループで定義されていたが、命令仕様とは関係ないので分離して別ページで管理されている。
もう一つに多様な概念として、CLINT (Core Local Interrupt Controller)というものある。PLICとは異なり、コアのより近い場所で発生する割込みを処理するために使用する。
CLINTはタイマ割り込みとソフトウェア割り込み(コア間割り込みのようなもの)を制御するが、PLICは外部デバイスからの割り込みなど、もう少しシステムよりの割り込み処理を行う。
PLICが定義するレジスタ
PLICは割り込みを処理するための単なる配線群ではない。システムからは複数の割り込みがCPUに対して挿入され、どのような優先度でどの割り込みをどのCPUに挿入するかという制御をPLICによって決定する。
- 複数の割り込みが挿入されたとき
- どのような優先度で処理され
- どのターゲット(CPU)に通知されるのか
ということを、PLICの内部に定義されているレジスタによって制御する。
PLICのレジスタは、制御する種類によってサイズが異なるので注意。つまり
ということを考慮して仕組みを眺める必要がある。
1. 割り込みの優先度
各割り込み要因毎に設定できるレジスタ。それぞれの割り込み要因がどの程度の優先度を持っているのかを指定する。優先度は、値が大きいほど大きくなる。
指定する優先度の数は任意だが、要因毎に設定可能なレジスタのサイズの最大値が32ビットなので、それを超えることはできない。逆に言えば、各要因で4バイトずつレジスタが定義されている。
メモリマップは以下の表のようになっており、割り込み要因のサイズは最大で1023個指定できる。
割り込み要因 | オフセット | サイズ | 説明 |
---|---|---|---|
0 | 0 | 32ビット以下 | |
1 | 4 | 32ビット以下 | |
… | … | ||
1023 | 0xFFC | 32ビット以下 |
2. Pendingビット
複数の割り込みが同時にPLICに挿入された場合、優先度の高いものを一つ選んでターゲットのHARTに通知する。当然この時優先度の低いものは通知することができないので、この割り込みはPending状態となる。
Pending状態である割り込みを保持しておくためのレジスタが定義されている。これは数だけ定義されたレジスタであるが、割り込み要因毎に1ビットあれば十分なので、32ビットのレジスタ1つで32種類のPendingビットが保持されている。
逆に言えば、上記のように最大1024個の割り込み要因が存在する場合、1024/32 = 32個のPendingレジスタが定義される。
割り込み要因 | オフセット | サイズ | 説明 |
---|---|---|---|
31 - 0 | 0x1000 | 32ビット | |
63-32 | 0x1004 | 32ビット | |
… | |||
1023 - 992 | 0x107c | 32ビット |
実装の観点から言うと、1つの要因のみPLICに挿入されたとしても、ターゲットのHARTにより割り込みが取り込まれるまではPendingビットが1に設定されている。「取り込まれる」というのはHARTによってPLICのCLAIMレジスタが読み込まれることを言い、HARTによりPLICで通知された割り込み要因を調査したことによって、Pendingビットが解除されるという仕組みである。
3. 割り込みEnable
割り込みEnableビットは、以下の2つのことを制御する
- どの種類の割込みが
- どのターゲット(HARTS)に対して挿入可能か
この2つを制御するのが割り込みEnableレジスタであり、したがってレジスタは2次元的な配置を取っている。
ターゲット(HART) | 割込み要因 | オフセット | サイズ | 説明 |
---|---|---|---|---|
0 | 31 - 0 | 0x2000 | 32 | 割込み要因31-0がターゲット0に対して挿入可能か |
0 | 63 - 32 | 0x2004 | 32 | 割込み要因63-32がターゲット0に対して挿入可能か |
… | … | |||
0 | 1023 - 992 | 0x207c | 32 | 割込み要因1023 - 992がターゲット0に対して挿入可能か |
1 | 31 - 0 | 0x2080 | 32 | 割込み要因31-0がターゲット1に対して挿入可能か |
1 | 63 - 32 | 0x2084 | 32 | 割込み要因63-32がターゲット1に対して挿入可能か |
… | … | |||
1 | 1023 - 992 | 0x21fc | 32 | 割込み要因1023 - 992がターゲット1に対して挿入可能か |
… | … | |||
15871 | 31 - 0 | 0x1f1f80 | 32 | 割込み要因31-0がターゲット15871に対して挿入可能か |
15871 | 63 - 32 | 0x1f1f84 | 32 | 割込み要因63-32がターゲット15871に対して挿入可能か |
… | … | |||
15871 | 1023 - 992 | 0x1f1ffc | 32 | 割込み要因1023 - 992がターゲット15871に対して挿入可能か |
4. 優先度のスレッショルド
これはターゲット(HART)毎に定義されたレジスタで、割り込み要因のスレッショルドを指定する。つまり、ターゲット向けに通知される割り込みの優先度が、スレッショルドの値よりも小さい場合は通知されない。
ターゲット(HART) | オフセット | サイズ | 説明 |
---|---|---|---|
0 | 0x200000 | 32 | HART0向けの優先度スレッショルド値 |
1 | 0x201000 | 32 | HART1向けの優先度スレッショルド値 |
2 | 0x202000 | 32 | HART2向けの優先度スレッショルド値 |
… | … | … | |
15871 | 0x3fff000 | 32 | HART15871向けの優先度スレッショルド値 |
もう一つ、重要なレジスタとしてclaim/completeレジスタというものがある。これは、HARTが割込み要因をチェックする際に参照するレジスタで、HART毎にどの割り込み要因が入っているのかというのを示している。
さらに、このレジスタには副次的な作用がある。
このレジスタをReadすることによって上記のPendingレジスタが解放され、さらに別の割込み要因が挿入できるようになる。
さらに、このレジスタをWriteすることによって当該割込み要因がCompleteする。Completeすることによって、同じ割込み要因からさらに新しい割り込みが挿入することができるようになる。
ターゲット(HART) | オフセット | サイズ | 説明 |
---|---|---|---|
0 | 0x200004 | 32 | HART0向けのclaim/completeレジスタ |
1 | 0x201004 | 32 | HART1向けのclaim/completeレジスタ |
2 | 0x202004 | 32 | HART2向けのclaim/completeレジスタ |
… | … | … | |
15871 | 0x3fff004 | 32 | HART15871向けのclaim/completeレジスタ |