Zynq割り込み仕様調査と考察

#目的
Web上にある割り込みに関する説明は概要レベルのものが多いが、
そこから一歩踏み込んで、Zynqを題材にしてARM GIC仕様書を読みながら学習していったときのまとめ

#参考
[ARM GIC(General Interrupt Controller)仕様書の勉強](https://qiita.com/azuki_bar/items/ef1bbb9f51b4b613a052)  
Zynqテクニカルリファレンスマニュアル

#仕様書からのまとめ、考察
##FPGAからの割り込みをR5#0で受ける想定の動き
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/7cb776c6-3bfb-f689-604c-ca0d3015184e.png)

同一割り込みIDで複数の要因で割り込みが入るときはedge-triggeredだと本質的にソフト側で割り込みを取り逃す可能性があると思った。
・割り込みが入ってCPUでAckする→Activeに遷移
・割り込みハンドラで処理する→Active状態のまま
・ここで、他の要因で同一IDに割り込み（※１）がはいる→Activeのまま。GICの仕様書上はActive and Pendingには遷移しない
・割り込み処理が終了してInactiveに遷移
この場合、※１は取り逃すのでは？？

##割り込みを取り逃すパターン（考察中）
発生元から確認

- HW
    - enableにできていない
    - HWからassertされていない
- GIC
    - 設定
        - enableにしていない
    - Distributor
        - Pendingされている割り込みのなかで十分な優先度を持っていない
        - Pendig状態でない
            - 確認方法：3.2.1の`Finding the active or pending state of an interrupt`参照。レジスタ値でactive or pending or active and pending状態を確認することができる
- SW
    - マルチプロセッサの場合、他のプロセッサに拾われてしまった
    - 割り込みとして認識できなかった
        - assertを取り逃した
            - level-sensitive
                - 不適切なタイミングでSWからdeassertした
            - edge-sensitive
                - 前のセクション参照

#Zynq仕様書の日本語訳
***日本語バージョンは大分端折られているので英語版を呼んだ方が良い***
##参考
テクニカルリファレンスマニュアル Ch.13 Interruptから
##概要
ZynqではGICとして
&emsp;RPUはPL390 GICv1 architecture specification
&emsp;APUはGIC-400 GICv2 architecture specification
を使う。
※<font color="Red">***この記事ではRPU側の PL390 GICv1 architecture specification を扱います。***</font>

|RPU, APUのGICで共通の特徴|RPU GICの特徴|APU GICの特徴|
|:--|:--|:--|
|・マルチプロセッサに対応<br>・アービトレーション（調停）が可能<br>・SGI(Software Generated Interrput) : ソフトからも割り込みを生成できる（Zynq内のCPUから他のCPUに対して）<br>・PLからPrivate Periferal Interrput IRQ, FIQがくる<br>・SPI(Shared Periferal Interrupt) : システム割り込みを管理する|・GICv1モデル<br>・セキュリティ拡張|・GICv2モデル<br>・セキュリティ拡張<br>・割り込み仮想化<br>・割り込みグループ　Group０:IRQ or IFQ, Group１:IRQ, 統一した優先度, group0の割り込みに対する選択式レジスタロックダウン？<br>・CPU privateレジスタをAXIアクセス制約させる|

##システム割り込み
Zynqで発生する割り込み。Proxyの方は置いておいて（PMU向けらしい）IRQの番号が表から確認できる。UARTやPLからの番号を抜粋。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/fe355551-471e-cdce-6634-d28c9b3c2eeb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/9a48c952-78bc-87d2-c4f8-7612dccdd7a8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/53bf2dc1-e805-db01-f35f-057f50a207dd.png)
3. <font color="Red">***GICの4clockが最小の検出できるパルス幅となる。通常100MHzなので、40nsとなる。これより短くても検出できるかもしれないが保証はされていない。***</font>

##RPU GICの割り込みシステムアーキテクチャ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/091cd61a-9183-6784-0ddb-9f49cb056411.png)

###Software Generated Interrputs
CPUは自分自身ともう一方のCPUに対してSGIを使って割り込みを入れることができる。
SGIは16個あり、番号をPL380.enable_sgi_control(ICDSGIR)レジスタにターゲットCPUを指定して書き込むことで、生成できる。
control_n_int_ack_n(ICCIAR)を読むか、enable_sqi_pending(ICDICPR)レジスタに対応するビットを書き込むことでクリアできる
### Shared Periferal Interrupts
１つ以上のCPU or PLにルーティングできる割り込みが約160存在する。割り込みコントローラはCPUへの割り込みの受付と優先度の管理を行う
### SPIのSensitivity
<font color="Red">***SPIは複数のCPUに割り込みを入れることができるが、ハンドルできるのは１つである。***</font>１つの割り込みが両方のCPUをターゲットにしていても、ただ１つのCPUがactive interrupt IDをリードできる。もう一方は、疑似(spurious) ID 1023 or 1022割り込みを受け取るか、次のpending割り込みを待つ（タイミング依存）

PLからの割り込み(IRQ 121 - 128, 136 - 143)を除いて、割り込みのsensitivityはソースによって固定され変更はできない。GICはこれに合わせる必要があるが、BootROMからレジスタはさわれないので、SDK device driverがsensitivityを満たすようにプログラムしなければならない。

立ち上がりエッジ(rising edge) sensitivityでは、GICが取り込めるパルス幅を作る必要がある。通常少なくとも 2つのCPU_2x3x期間となる。

### 割り込み優先度
<font color="Red">***SGI, SPI割り込みはユニークなIDが割り当てられる。GICは調停するためにIDを使う。割り込みdistributorは保留されている割り込みのリストを持ち、それから最大の優先度の割り込みをCPUに発行する。同じ割り込み優先度の場合は、低いIDが優先される***</font>

優先度のロジックは、各CPUへの最も高い割り込みを同時に選択することを可能にするため、物理的に多重化している。distributorは割り込み、プロセッサ、Activeインフォメーションのリストを持っており、CPUへの割り込みを発生させるトリガの責務を負っている

SGI, PPI distributorのレジスタは各CPUへの分割コピーを提供するためにバンクになっている。コントローラは複数のCPU向けの割り込みが、1つのCPUだけがhandleできることを保証している。

distributorは最も優先度の高いpendingされている割り込みをCPUに送る。CPUがacknowlegeを返すことで、割り込みを終えることができる

##APU GIC Interrput Controller
略
##IPI(inter-processor interrupt) Interrupts Message Buffers
### Interrupt Architecture
書いてあることまとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540259/e068ba84-fc7e-94b3-e2e7-90fa0dd7638f.png)


##その他
### 割り込み入れ子（nest）することはあるか？
https://www.xilinx.com/support/answers/54128.html
デフォルトではしていないようだ。
R5では `xscugic.h` に↓のコメントがあるのでサポートしていないようだ
>Nested Interrupts Processing</b>
Nested interrupts are not supported by this driver.