« 割り込みを確実に受け取るために | トップページ | DMAと他人の割り込みとの共存 »

2010.03.09

DMAに失敗する

開発中のPCI ExpressのDMA機能で、検証用のマシンを変えてみたら、かなりの頻度でデータのエラーが起きました。

データを128バイト単位でFPGA→PCのメインメモリに送っているのですが、DMAで転送されてきたデータを見ると、128バイト単位で転送されてきたデータが、途中から00になっていることが稀に起こります。
Dma_failed

もし、伝送線路上で電気的なエラーが起きていたり、パケットの組み立てやプロトコル上の誤りがあると、パケットごと無効になるので、こうはならないはず。

だとすると、キャッシュの問題か、それともFPGAが間違ったデータを送ってきているのか。

最初に疑ったのは、キャッシュを制御する関数。
KeFlushIoBuffersという関数は、どうやら、wdm.hの中で
#define KeFlushIoBuffers(Mdl, ReadOperation, DmaOperation)
と無効化されているので、これではなさそう。

うーん。悩ましい。

#追記
原因がわかってきました。

問題の起こるPCでは、割り込み番号が、グラフィックカードの間で共有されています。
Int_shared

そのため、グラフィックカードで割り込みが発生した場合も、当ドライバのISRが呼び出されます。そして、当ドライバのISRでは、デバイスのBAR0に配置した割り込みコントロール、ステータスレジスタを読みにいきます。これがDMA中に行なわれると、アクセスがぶつかって、以後送信するデータが化けてしまうようです。
Dma_bug

つまり、このIPコアは、今はDMA中はデバイスのステータスレジスタを読めないけど、割り込みを共有する他のデバイスが割り込みをかけたときにはDMA中でもデバイスのステータスレジスタを読まなければなりません。

自分のデバイスがDMAを完了したことは、割り込みによって通知するしかないので、さあ、どうしましょう、ということになります。メモリ空間読み出しリクエストが来たら、いったんDMAを中断して、そちらを優先するしかなさそうです。

|

« 割り込みを確実に受け取るために | トップページ | DMAと他人の割り込みとの共存 »

コメント

コメントを書く



(ウェブ上には掲載しません)




« 割り込みを確実に受け取るために | トップページ | DMAと他人の割り込みとの共存 »