MIPS 4Kには6本の割り込みがあり、最後の1本はタイマーに予約されています。
PICを使う場合は残りの5本のどれかにつなぎます。Atherosの古いSOCでは以下のようになっています。
割り込みの確認にはタイマーを使うのが一番確実です。
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の割り込みの事は以前調べていました。
