BCM3383のタイマーと割り込み

MIPS 4Kには6本の割り込みがあり、最後の1本はタイマーに予約されています。

PICを使う場合は残りの5本のどれかにつなぎます。Atherosの古いSOCでは以下のようになっています。

![mips_intr.png](https://qiita-image-store.s3.amazonaws.com/0/104066/8d13c340-a89e-69c4-6ceb-b32cc706c867.png)

割り込みの確認にはタイマーを使うのが一番確実です。

BCM3383にはMIPS 4Kのタイマー以外に3本のタイマーがあり、PICに割り込みが上げられます。

```
        #define INTC_BASE   0xb4e00000   // interrupts controller registers
        #define TIMR_BASE   0xb4e000c0   // timer registers
 ```

TIMR_BASEを設定すると、割り込みが上がります。Eが抜けてますね。

3本のタイマーの割り込みは1本なので複数動かす場合はタイマーのレジスタを見て処理する事になります。

なかなかうまくいかなかったので、このアドレスをダンプするコードを入れました。

```
00000000 33830032 960d6c83 fffff8ff ffffffff 
00000010 00000000 00000000 00000000 00000000 
00000020 00000000 00000000 00000000 00000000 
00000030 00000000 00002000 00000000 00002000 
00000040 00000000 00002000 00000001 00002000 
00000050 00000000 00000000 00000000 00000000 
00000060 00000000 18840000 00000000 00000fc0 
00000070 00000000 00000000 00000000 00000000 
00000080 00000000 00000000 00000000 ffffffff 
00000090 ffffffff 00000000 00000000 00000000 
000000a0 00000000 00000000 00000000 00000000 
000000b0 00000000 00000000 00000000 ffffffff 
000000c0 00000100 80ffffff 00000000 00000000 
000000d0 002f6646 00000000 00000000 00000000 
000000e0 00000000 02ffffff 00000000 00000000 
000000f0 00000000 1fc0000d 00000000 00000000 
```

 割り込みは4つあります。

 ```
  IntControlPeriphIrqMask             PeriphIrqmask0;          
  IntControlPeriphIrqStatus           PeriphIrqstatus0;        
  IntControlPeriphIrqMask             PeriphIrqmask1;          
  IntControlPeriphIrqStatus           PeriphIrqstatus1;        
  IntControlPeriphIrqMask             PeriphIrqmask2;          
  IntControlPeriphIrqStatus           PeriphIrqstatus2;        
  IntControlPeriphIrqMask             PeriphIrqmask3;          
  IntControlPeriphIrqStatus           PeriphIrqstatus3;    
```

それぞれ32ビットで128個になりますが、同じもののようで実質32個です。おそらくマルチコアの処理を分けるためにあるのだと思いますが、コアは2つしかありません。4コア(thread)の製品もあるようなので、それに合わせたのかもしれません。

よくある話なのですが、ここのmaskは1をセットするとマスクされて無効になるのではなくて、有効になります。Enableの方が正しいです。

起動したコアには0-3のどれかで実際の割り込みが上がるのですが、試行錯誤したら3でした。

Linuxのコードを眺めていたら、チップのレビジョンによって違うみたいなコードがありました。

5本のどれに入っているかは0からこつこつ試して、2に入っていました。

PICのコードはatheros/ar531xで作ったINTRNG対応のpicコード(apb.c)をベースにしました。

MIPS 4Kの6本の次にPICの割り込みとして6から始める事があるのですが、Linuxのコードで最初にソフトウエア割り込みの2本をつけて8始まりのコードもありました。

FreeBSD/mipsは4Kのタイマーで動くので、このタイマーのコードは使いません。

mipsの場合bootverboseが1だと下記のログが出たところで割り込みが有効になります。

```
Device configuration finished.
```

FDTになる前はhintのatで指定されているバスのPICに割り込みは登録されていました。MIPSの場合は4Kの割り込みはnexusでobioなどの独自のPICはそれに登録されます。

INTRNGはこの仕様を残して、FDT対応とPICの共通化を行ったのですが、わかりにくいKPIになっています。うーむ。

結局FDTじゃないとINTRNGは正しく動作しないようだったので、古い処理に戻しました。4Kの割り込みとPICの割り込みが同じテープルで管理されて、正常に動作しませんでした。hintでINTRNGな実装はおそらく無いと思います。

実際に割り込みで処理するのはuartがあります。uartは割り込みが設定されていて、起動後に割り込みが有効になったあとは、受信割り込みと、FIFO空の割り込みで処理を行います。正しく割り込みが処理できないとloginプロンプトが出ません。割り込みが設定されていないとポーリングで割り込み処理ルーチンを呼び出して、処理します。

```
# vmstat -i
interrupt                          total       rate
int2 obio0                            90          3
int5 clock0                         4984        152
obio intr2: uart0                     90          3
Total                               5164        158
```

4kの割り込みの事は以前調べていました。

https://qiita.com/yamori813/items/a22382806c2ed32a0af3