1999-07-05 interrupt
mips/trap.c と、newsmips/newsmips_intr.c と、R4400 の pdf を読む。
MIPS の割り込みは、割り込んだ際に、CPU の CAUSE register
に割り込み原因が入っている。
TLB miss とか illegal instruction とかの CPU 的な割り込みは、
arch/mips/mips/ の下でうまくやってくれてるので(私は)考えなくてよい。
hardware 割り込みがかかった時のみ、arch/mips 以下のルーチン群が、
mips_hardware_intr に登録してあるハンドラを呼んでくれる。
ここに machine dependent な関数を登録する。
引数として cause register などなどが渡される。
hardware 割り込みがかかった際は、
CAUSE register の IM0〜IM7 のどれかが立っている。
これが上の bit から順に、level5 interrupt、level4 interrupt、ときて、
level0 interrupt、software1 interrupt、software0 interrupt となる。
つまり、いわゆる vector 割り込みじゃなくて、レベル割り込み。
デバイスはとうぜんこれらのレベルの数以上あるので、
いくつかのデバイスは同じレベルの割り込みを共有することになる、と。
...ということは、割り込みハンドラだけではどのデバイスの割り込みかわからないので、
どのデバイスの割り込みかを知るためには、
どっかの(CPU ではなく NEWS5000 の hardware が用意してくれている)
status port を見る必要がある。
ということをふまえつつ、いろいろ調べる。
NEWS5000 は
level0 APBUS level1 APBUS level2 TIMER level4 SB,MB,FB,AB level5 SB,MB,AB
となっている。
デバイス毎の割り込み status は、
0xBFA00020 から level0、level1、level2、... と並んでる。
割り込み level と、この status を見れば、どのデバイスの割り込みかが
特定できる、と。
* * *
忘れないうちにまとめよう。
例えば APBUS 上のデバイス (etherとしよう) から割り込みがかかる場合。
最初に MIPS 的に割り込みがかかり、arch/mips/ がうまいこと処理してくれて、
結果、hardware 割り込みなので、(*mips_hardware_intr)() が呼ばれて、
最終的に news5000_intr() が呼ばれる。
news5000_intr() で、cause register を見て、割り込み level を調べる。
(この場合 APbus 上の ether だから level0 とする)
cause Register を見ると level0 なので、apbus 上のどれかのデバイスである。
よって次はどのデバイスかを特定するために、
0xBFA00020 の interrupt status を見る。
bit がそれぞれの device に対応しているので、
立っている bit があればそのデバイスの割り込みである。
で、内蔵 ether の場合だと、0xBFA00020 の bit1 が立つことになっているので、
ここで ether driver の interrupt handler を呼ぶ、と。
...でいいのか?
* * *
こんなかんじで、とりあえず timer 割り込みを書いてみたが、
...確認できない。
割り込みルーチン内で LED をつけるようにすると、確かに点灯。
少くとも一回は呼ばれている様子。
が、つばいさんがやっていた(跡が newsmips_trap.c に残ってるけど)ように、
割り込み回数を count して LED を blink させると、ぜんぜん動かん。
いっそのこと...と思って serial に printf すると...
ぐぁ。
字をまき散らして死んだ :P
むーーーーーー。
* * *
落ち付いて考えよう。
ap0 at mainbus0 mkclock0 at ap0 slot0 addr bf881fe0
TIMERの初期化はここでやっている。
で、timer 割り込みルーチン内で LED を付けると付く。
その後
boot device: <unknown> root device: _
となる。timer 割り込み内で count up して LED を blink させるようにしてるのに、
来ない。
そうだよな。あたりまえか。
root device: _
の時は、CPU は
割り込みは入らないか。
ふむ。
ためしに serial の polling んところで splhigh をとっぱらってみると...。
> bo -a APbus Primary Boot Program APbus Full Boot Program (0x83e00000-0x83e153df) : scsi()/netbsd text_start=0x80001000, data_start=0x800914d0, entry=0x80001000 .text: address=0x80001000-0x800914cf, size=591056 .rodata: address=0x800914d0-0x8009c3bf, size=44784 .reginfo: address=0x8009c3c0-0x8009c3d7, size=24 .data: address=0x8009d3e0-0x800a23df, size=20480 .sdata: address=0x800a23e0-0x800a241f, size=64 .sbss: address=0x800a2420-0x800a241f, size=0 .bss: address=0x800a2420-0x800bc08f, size=105584 .mdebug: address=0x800bc084-0x80102e83, size=290304 Copyright (c) 1996, 1997, 1998, 1999 The NetBSD Foundation, Inc. All rights reserved. Copyright (c) 1982, 1986, 1989, 1991, 1993 The Regents of the University of California. All rights reserved. NetBSD 1.4 (MISAKI) #215: Mon Jul 5 04:35:23 JST 1999 ryo@moveq:/src/news5000/sys/arch/newsmips/compile/MISAKI real mem = 66060288 avail mem = 56889344 using 1612 buffers containing 6602752 bytes of memory SONY NET WORK STATION, Model NWS-5000, Machine ID #14894 mainbus0 (root) cpu0 at mainbus0 cpu0: MIPS R4400 CPU Rev. 6.0 with MIPS R4010 FPC Rev. 0.0 cpu0: L1 cache: 16kb/32b Instruction, 16kb/16b Data, direct mapped cpu0: L2 cache: 1024kb/64b mixed, no snooping ap0 at mainbus0 mkclock0 at ap0 slot0 addr bf881fe0 boot device: <unknown> root device:
の polling キー入力待ちの状態で、LED が点滅。
点灯じゃなくて点滅だ。
間違いないって。
なんだ、動いてるやん。だまされ。悩んで損した。
EOF