chakokuのブログ(rev4)

テック・コミック・DTM・・・ごくまれにチャリ

俺OS;SH2A GCCによる実装課題;割り込みでアドレス例外

まだ十分理解できていないけど、SH2A(Interfaceの付録基板;SH2A;7260)で俺OSの開発に向けて割り込みプログラミングをしていて、CPUアドレス例外が発生する。よくよく原因を調べると、割り込み処理の退避で、


FF0B FMOV.S FR0,@-R15

のコードがあるのだが、このコードはFPSCRのSZフラグの値によって


FF0B FMOV.D DR0,@-R15

にも解釈される。(SZ:0の時はFMOV.Sで、SZ:1の時はFMOV.Dと解釈される)実行時のFPSCR内のフラグによって機械語の解釈が異なる。

で、、gccが生成した時はFMOV.S(SZ:0)を想定して機械語、FF0Bを吐くのだが、別のルーチンでFPSCRのSZフラグを1にセットする実装があり、その状態で割り込みが発生すると、gccが当初期待したFMOV.Sとして動作せず、FMOV.Dとして動作する。この結果、サイズがおかしくなって?*1違反例外が発生するようだ。(自分の理解の範囲)

このフラグはFPU用のレジスタであり、割り込み処理とFPU呼び出しを正しく使うにはもう少し関数の属性等を設定する必要があると思われる。

多分、、割り込みシーケンスの先頭で、FF0Bを実行する前にまずFPSCRのSZフラグを1から0に戻すステップが必要なんだろうけど、どういう属性やオプションを指定したらそういうコードを吐いてくれるのか分からない*2。逃げの方法として、当分FPU使わないのでコンパイルオプションで下記の指定でFPU関連のコードを吐かない様にした。


-m2a-nofpu

この結果、退避レジスタからもFPU用のレジスタはすべて対象外になったが違反例外は発生しなくなった。この状態ではFPUは使えないので、今後FPUを使う場合に対策が必要。。多分、かなり昔から既知の注意点と思われるけど、、回避方法をご存知の方がおられたらお教えください。。(m(..)m)

というわけで、、タスク管理機能の最低仕様は実装できたので、これを使ってアプリを試作して実用に耐えるか検証。。とりあえず、光デジタル入出力を使って録音や再生をやってみたい。。今の俺OSで気になる点は、ハードウエア割り込み処理で直接タスクを起動してる点。起動queueにリクエストを入れるようにして、割り込みからは早々に抜けるべきとは思いますが。。そうでないと割り込み禁止時間が長くなりすぎる。。

■参考URL

GCCのドキュメント類
http://gcc.gnu.org/onlinedocs/gcc/index.html
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
http://gcc.gnu.org/onlinedocs/gcc/SH-Options.html#SH-Options

阿部 昌裕様の資料;linux-sh kernelの起動シーケンス解説
http://www.aandd.co.jp/dvhome/linuxsh/doc/linux-sh-kernel-bootup_J.txt
SH用KernelディスパッチでFPSCRのSZフラグを設定されている

■関連記事

茶国::シビレタ本;「組み込みOS自作入門」
http://d.hatena.ne.jp/chakoku/20101027

*1:どう動作が異なるのか未調査

*2:割り込みハンドラをasm文で手書きすればいいと思うけど面倒なのだ