[ TOP | Recently ]

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 はスパるsplhigh()でシリアルをpollingしてるので
割り込みは入らないか。
ふむ。

ためしに 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