koma
2016年9月26日 21時30分
komaです。
EXT空間(cs5)にデュアルポートメモリを使用しています。
この際にキャッシュにヒットするみたいで、
eva(r-mobile-a1)を外部cpu(5aa5を書き込む)より先に立ち上げるとwhile文が終了しません。
eva(r-mobile-a1)を外部cpu(5aa5を書き込む)より後に立ち上げるとwhile文が終了します。
アドレスは target1 = 0x14100000;//cs5です。 ためしに0xb410,0000にしたのですが、
目的の空間にアクセスしないみたいです。
キャッシュにヒットさせないで、外部空間(1410,0000)をアクセスさせるための記述
教えて頂きたいのですが。
以下 テストプログラム
target1 = 0x14100000;//cs5
if((fd1 = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
map_base1 = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd1, target1 & ~MAP_MASK);
if(map_base1 == (void *) -1) FATAL;
virt_addr1 = map_base1 + target1;
dpCAT_w=(unsigned short *) virt_addr1;
while(dpCAT_w[0] ==0x5aa5){
}
コメント
izawa
毎度お世話様、伊澤@ITTOです。
必要な回答はat_yashiさんが概ね書いていますが、一つだけ注意を。
at_yashiさんは
*(volatile unsigned int *)(addr)
と書かれていますが、元のコードを見る限り4バイトアクセスは拙いのでは?
元のコードではdpCAT_wでアクセスしていますのでこれの型がはっきりしません。
# ソースを引用するならその辺りも含めていただいた方が話が手っ取り早いのですが……
恐らくunsigned shortのポインタだと思われますのでこれの宣言を
volatile unsigned short * dpCAT_w;
などとして、代入を
dpCAT_w = (volatile unsigned short *) virt_addr1;
とでもすれば宜しいかと。
それはそれとして、while文の条件と現象が噛み合っていない気がします。
デュアルポートメモリの振る舞いが分からないので単なる推測ですが、
・外部を後に立ち上げると、該当メモリが不定値なのでwhileループをスルーする。
・外部を先に立ち上げると、該当メモリが0x5aa5なのでwhileループを脱出できない。
となるような気がします。
whileの条件が逆だと仮定すると、
・外部を後に立ち上げると、該当メモリが不定値なのでwhileループに突入し、(メモリを再参照しないために)ループを脱出できない。
・外部を先に立ち上げると、該当メモリが0x5aa5なのでwhileループをスルーする。
となって、辻褄は合いそうです。
更に蛇足ですがvolatileの言語仕様的には、
・外部を後に立ち上げると、該当メモリが不定値なのでwhileループに突入し、外部から0x5aa5に書き換えられたときにループを脱出する。
と言う振る舞いになろうかと。
koma
at_yashi
2016年9月27日 11時15分
> EXT空間(cs5)にデュアルポートメモリを使用しています。
> この際にキャッシュにヒットするみたいで、
キャッシュというより、register ですかね?
mmap() するときは、nocache の ioremap() が動くはず(たぶん)
while(dpCAT_w[0] == 0x5aa5){} → write 5aa5 → 終らない
write 5aa5 → while(dpCAT_w[0] == 0x5aa5){} → 終る
disassemble してみると分ると思いますが while(...); の dpCAT_w[0] は
register を確認しているだけだと思います。 volatile address の read に
置き換えたらどうでしょう?
上手くいけば良いですが、register や cache を考慮するなら、アプリではな
くデバイスドライバーを書いた方が良いと思います。