[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: new MIPS cache ops and R4000/4400 with L2 cache



Izumi Tsutsui <tsutsui@ceres.dti.ne.jp> writes:
> ・mips3_VCED の前に nop を入れると動く
> ・mips3_VCED の後に nop を入れても動かない
> 
> という結果になりました。
> 
> で、 mips3_VCED の中身を見ると vce_saveat 等の data segment に
> 配置されるべき変数領域が text segment に配置されてるようだった
> ので、添付のパッチのように各変数領域を .data 以降に持っていくと
> 今のところ nop なしでもちゃんと動いているようです。

これは、VCED(Virtual Coherency Exception -- Data)の処理中に再度VCEDが発
生している可能性が高いと思います。

VCEDの処理の先頭でvce_saveatにアクセスした際にさらにVCEDが発生し、ATレジ
スタの内容が破壊されるというのがシナリオです。

ソースコードの意図しているのは、処理中にはAT,k0,k1のみを使用し、破壊され
ては困るATを変数vce_saveatに退避/復帰するというものですが、変数を使用し
ているのでネストすることはできません。(他にもMIPS固有の事情でネストでき
ない理由はありますが。)

nopを入れても.dataに移動しても、いずれもvce_saveatのアドレスが変化するの
で、これによってVCEDの発生条件を満たさなくなると考えるとつじつまが合いま
す。

ところで、以上の仮説が正しいとすると、「アドレスをずらす」というのは本質
的な解決にはなりません。なぜなら、ずらしたアドレスでVCEDが発生しないのは
偶然だからです。正しくは、「絶対にVCEDが発生しない処理方法」にしなければ
なりません。

正しい解決方法を考えてみます。

オーバヘッドは大きくなりますが、カーネルスタックを使って必要なレジスタの
退避/復帰を行なうのも一案です。カーネルスタックはVCEDが発生しないことが
保証されている(保証しなければならない)領域なので、安全に処理できます。

あるいは、一切data cacheをアクセスしないようにして処理する方法を考えると
いう手もあります。つまり、k0,k1のみを使用して、メモリをアクセスしないと
いうことです。(こういう処理が書けるかどうかは作ったことがないのでわかり
ません。私が昔移植したOSではカーネルスタックを使っていました。)

> 同一メモリが I-cache と D-cache との両方に載るとどうなるかとか
> 忘れてしまったんですが、いずれにせよ .text の memory は
> read only でないといけないんですよね?

カーネルのstaticなtextやdataはkseg0に置かれているので、read-onlyにするこ
とはできません。したがって、変数がtext領域に置かれていても(少々気持ちが
悪いですが)特にに動作上の問題は発生しません。(ファイル上のイメージとメモ
リ上のイメージが一致しなくなりますが。)

篠原