APC8750にNetBSD/evbarmを移植するための記録 9/17
2014/01/13(月) 25:49 NetBSD はてブ情報 はてブに登録 はてブ数

もしかしたら、UARTの初期化が足らないのかもしれない。

U-bootでシリアル付近をダンプ
WMT # md.l d8200000 64
d8200000: 0000003a 0000000d 00010007 00000007    :...............
d8200010: 00000000 00000000 00000081 00000003    ................
d8200020: 00000000 00000000 000001d8 0000000a    ................
bus spaceで読んでみる。
0000: 0000000d
0004: 0000000d
0008: 00010007
000c: 00000007
0010: 00000000
0014: 00000000
0018: 00000041
001c: 00000003
0020: 00000000
0024: 00000000
0028: 000001d8
わかりやすく並べる。
d8200000: 0000003a 0000000d 00010007 00000007    :...............
d8200000: 0000000d 0000000d 00010007 00000007

d8200010: 00000000 00000000 00000081 00000003    ................
d8200010: 00000000 00000000 00000041 00000003

d8200020: 00000000 00000000 000001d8 0000000a    ................
d8200020: 00000000 00000000 000001d8
ほとんど変わらない。00000081と00000041ぐらいか。無理やり上書きしてもダメであった。

ひとまず、IC Highest-priority Status registerのやつ、本当かどうか試してみる。

任意のIRQをON/OFFできる配列を作り、attachで書き込み、自在に割り込みをコントロールしようとしたのだが、うまくいかない。

気づいたのだが、割り込みは、ビット的に右から割り振られるようだ。
つまり、IRQ0からIRQ3を32bitで表現すると0x[IRQ3][IRQ2][IRQ1][IRQ0]という並び順になるようだ。どうりでOn/Offがうまくいかないわけだ。左からだとてっきり思っていた。ということで、このルールにしたがうと、ちゃんと割り込みを制御できることがわかった。

ついでに気づいたのだが、IC Interrupt Status registerをみてみると、当該IRQ番目のビットに1が立っている。
たとえば、IRQ22であれば左から0から始めて22番目にビットが立った0x00400000になっている。

調子に乗って、eth0のIRQ10も同時に発生させると、22番目と10番目の両方にビットが立った0x00400400が得られるようだ。
同時に複数の割り込みが入った時には、ここを見ればよいことがわかった。で、複数入ったうちの優先度の高いものが、その名のとおりIC Highest-priority Status registerに数字として格納されるということのようだ。

さて、ここまできたが、一向にUARTの割り込みが入らない。

良く考えてみたら、u-bootは割り込みで動いていないのではないか?
そういえば、割り込みの64個あるディスクリプタは全部ゼロだったではないか。割り込みが上がるはずはない。しかしながら、入力はできている。もしかして、ポーリングモードなのかもしれない。

そういえば、wmt_uart.hにはFIFO full/emptyだのregister full/emptyだのとあった。そもそも16550AはFIFOを持っていて割り込みで動くとWikipediaにも書いてあって、割り込みじゃなきゃいけないと思い込んでいたのか?だんだん混乱してきたぞ。

UART register fifoでググると素晴らしいページが見つかった。

beagleboard を触ろう - 割り込み [組み込みソフト]

ここにかいてあるところによると、割り込みモードというのがあるらしい。
IER Interrupt Enable RegisterとFCR FIFO Control Registerやらに設定を行えば、割り込みが入ると書いてある。割り込みがアサートされる、というのが言い回しのようで勉強になる。

とりあえず、いっぱいビットを立てて動かしてみたれ、IERとFCRの両方に大量にビットを立ててみた。

なんと、割り込みが入った。ちゃんとInterrput status registerの32番目に1が立っているし、IC Highest-priority Status registerにも0x20が表示されている。よしよし。やっぱりUARTの初期化が足らなかったのだな。

とにかく、いっぱいビットを立てすぎてしまったので、割り込みが入りまくって、当初の狙いであるシリアル入力の割り込みだけを捕捉したい。

おそらく、IERとFCRのビットをそれぞれうまくセットすればよいのだろう。

ということで、TXっぽいビットをかたっぱしから落としたが、こんどはシリアル出力ができなくなった。
そもそもIERのまえにFCRを設定しなければ、意味がないのでは、などと順番を入れ替えたり、あれこれ試したが、どうにも入力だけに反応するような状態にはならない。

場当たり的な試行錯誤で頑張るのはやめて、すこしほかの実装を見るほうが今は近道かな。

とりえず、UARTからの割り込みの上げ方は(制御はできないけれども)わかったのでよしとしよう。

動作確認するために無理やりコードをいじっていて、収拾がつかなくなっていたりするし、unblock・blockのルーチンも間違ったままなので、すこし割り込みコントローラ周りを本来の動作にしてあげなければならないと思う。

irq_handlerが本来何をすべきなのか、そこから呼ばれるルーチンからcomドライバの割り込み処理まで繋いでであげないといけないし。複数の同時割込みも、レジスタを見たらわかる、ということが判明したし。

そういえば、UARTの表示が遅くて手を入れた件は、もしかしたらレジスタはポーリングモードだがcomドライバは割り込み前提で作られていたりするからタイムアウトに時間がかかっているのかもしれないな。ということは、手を入れたところをもどして、割り込みのOn/Offで挙動が変わるか調べてみればよいかもしれない。いらないかと思っていたTXの割り込みも実際には必要なのかも?

今日はここまでにしよう。

名前:  非公開コメント   

  • TB-URL  http://www.tokuda.net/diary/adiary.cgi/0833/tb/