SH4A続き。
マイOSに戻ってOCBI命令ついてじっくり調べてみた。その結果、OCBI命令は
TLBの保護がリードオンリーの時は必ずTLB保護例外を出すことがわかった。そ
してOCBP,OCBWB命令はリードオンリーでも例外を出さない。
...これ、反対の挙動では?OCBIはキャッシュの無効化だけだから(メモリアクセ スがない) TLBの保護に関わらず成功し、OCBP,OCBWBは書き戻しがあるからTLB の保護を見るべきでしょう。
ということで、アドレス変換を有効にしたらOCBI命令は使えないことがわかっ た。メモリ割り付けのキャッシュからの操作だと、もしUビットが立っていたら (Dirty) V(有効)ビットを落としたところで自動的に書き戻しが発生するので、 無効化だけはできない。
一応その動作も確かめてみることにした。これは連想ビット(A)を立てて操作。
アドレス変換を有効にしたら、キャッシュの無効化だけというのは無用なTLB例 外が起きてしまうためできない。メモリ割りつけのキャッシュからは無効化だ けはできない。ということで、 sh4a_dcache_inv_rangeではOCBIではなくOCBPにするしかないかな...。
そして連想ビットの動作がおかしいのは本当か?なにか勘違いしてるかも。そも そもメモリ割りつけのキャッシュの連想はTLBミスしたらなにもしないという仕 様なので、使いどころがよくわからない。
...これ、反対の挙動では?OCBIはキャッシュの無効化だけだから(メモリアクセ スがない) TLBの保護に関わらず成功し、OCBP,OCBWBは書き戻しがあるからTLB の保護を見るべきでしょう。
ということで、アドレス変換を有効にしたらOCBI命令は使えないことがわかっ た。メモリ割り付けのキャッシュからの操作だと、もしUビットが立っていたら (Dirty) V(有効)ビットを落としたところで自動的に書き戻しが発生するので、 無効化だけはできない。
一応その動作も確かめてみることにした。これは連想ビット(A)を立てて操作。
void
sh4a_dcache_wbinv_range_associate (vaddr_t va, vsize_t sz)
{
vsize_t eva = ROUND_CACHELINE_32 (va + sz);
va = TRUNC_CACHELINE_32 (va);
_cpu_run_P2();
while (va < eva)
{
uint32_t addr = SH4A_CCDA |
(va & (CCDA_ENTRY_MASK << CCDA_ENTRY_SHIFT)) | CCDA_A;
*(volatile uint32_t *)addr &= ~(CCDA_U | CCDA_V);
va += SH4A_CACHE_LINESZ;
}
CPU_SYNC_RESOURCE ();
_cpu_run_P1();
}
しかしだ。
wbinv_associate test buffer P1=890099e0 pattern=c0 [Entry cf](19e0)---------------------------------------------- way 0 tag=900b800 (D|V) a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 way 1 tag=9009800 (-|-) dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd way 2 tag=9009800 (-|-) cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc way 3 tag=900b800 (-|-) a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 [Entry cf](19e0)---------------------------------------------- way 0 tag=900b800 (D|V) a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 way 1 tag=9009800 (D|V) c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 way 2 tag=9009800 (-|-) cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc way 3 tag=900b800 (-|-) a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 Dump from P2 dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd Dump from P2 dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd [Entry cf](19e0)---------------------------------------------- way 0 tag=900b800 (-|-)本来はこのウェイがDirty|Validで残るはずなのに a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 way 1 tag=9009800 (D|V)ここがDirty|Validで残ってしまっている。 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 way 2 tag=9009800 (-|-) cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc way 3 tag=900b800 (-|-) a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 test4>いろいろテストをしてみると、
wbinv_associate test buffer P1=890099e0 pattern=c0 [Entry cf](19e0)---------------------------------------------- way 0 tag=9009800 (-|-) c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 way 1 tag=9009800 (-|-) aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa way 2 tag=9009800 (-|-) c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 way 3 tag=900b800 (D|V) a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 [Entry cf](19e0)---------------------------------------------- way 0 tag=9009800 (-|-) c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 way 1 tag=9009800 (D|V) c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 way 2 tag=9009800 (-|-) c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 way 3 tag=900b800 (D|V) a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 Dump from P2 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 Dump from P2 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 [Entry cf](19e0)---------------------------------------------- way 0 tag=9009800 (-|-) c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 way 1 tag=9009800 (-|-) c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 way 2 tag=9009800 (-|-) c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0 way 3 tag=900b800 (D|V) ウェイの最後のがDirty|Validなら無事。 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 a5a5a5a5 test4>なんか、どうも連想じゃなく、ウェイで一番最初に見つかったのだけ操作して いるような...。メモリ割り付けの連想ビット(今迄使ってなかった)も、動作が おかしい。
アドレス変換を有効にしたら、キャッシュの無効化だけというのは無用なTLB例 外が起きてしまうためできない。メモリ割りつけのキャッシュからは無効化だ けはできない。ということで、 sh4a_dcache_inv_rangeではOCBIではなくOCBPにするしかないかな...。
そして連想ビットの動作がおかしいのは本当か?なにか勘違いしてるかも。そも そもメモリ割りつけのキャッシュの連想はTLBミスしたらなにもしないという仕 様なので、使いどころがよくわからない。
