PCI Expressバスアナライザ
開発中の特電PCI ExpressのIPコアですが、マザーボードを新しくしたら動かなくなってしまいました。
Intelのマザーボードなのですが、正体不明のMessageパケットをとてもいっぱい吐き出してきます。CPUもチップセットもIntelです。いろんなアプリを立ち上げるとメッセージパケットの数が増えますので、きっとIntelのチップ同士で会話しているのでしょう。
このマザーボードもBIOSの立ち上がりで、PCIのコンフィグレジスタを設定してくるのですが、WindowsXPが起動したときにはBAR0に設定されたアドレスが消えてしまっています。これが原因のようです。
どういう経緯でそうなったのか、ロジアナの波形とにらめっこしながらK27.7・・とか読んでいても埒があかないので、PCI Expressバスアナライザを作ることにしました。
PCI Expressの生の信号のうち、TLPだけをFPGA内に作りこんだFIFOに貯め、それをRS232Cで吐き出すようにしてみました。FIFOに入れるときには、取得した時刻の情報を付与しておきます。こうすることで解析の役に立つからです。
RS232CとPCI Expressの信号の速度の差は約2万倍あるのですが、FIFOのおかげで、パソコン起動時のパケットはなんとか損失せずに読むことができました。パソコン起動時のTLPの密度は平均すると0.005%程度ということでしょう。
非常にシンプルなツールで、バグも多いのですが、ロジアナの波形で見るよりもずっと楽になりました。
なんだかnullified TLPというパケットをみつけました。上手く起動しないのは、これをちゃんと取り扱っていないからかもしれません。
追記
どうやら、リカバリーステートというものが原因でした。
JTAGロジックアナライザ(バウンダリスキャン版)で調べてみたら、すぐにわかりました。
このパソコンでは、リセットがかかってから8秒くらいの間はちゃんとリンクがアップして、なにやらデータをやりとりしているのですが、突然リンクが切られてしまうようなのです。
上の図で、中央の暗い部分が、リンク確立している時間です。
で、なぜリンクが切られてしまうかというと、JTAGロジックアナライザ(BLOGANA版)で調べてみたら、すぐにわかりました。
PCI Expressはリンクが確立すると、L0ステートというステート(通常の通信が行えるモード)に移行します。
バスのリンクアップが終わり、L0ステートに移行し、PCIコンフィグレジスタとかいろいろ読み書きしたところで、このパソコンはいきなりTS1パケットを送ってきているのです。TS1パケットというのは、PCI Expressのリンクが確立する前にお互いの情報を交換するためのパケットなのですが、通信中に再確認のような意味でTS1を送ってくることがあるようなのです。
本来ならば、TS1を受け取ったらL0ステートを離れ、リカバリーステートに移行しなければなりません。
パソコン側は、ターゲットボードから返信のTS2が送られてくることを期待しています。
リカバリーステートで正しくお互いの情報をやりとりすれば再びL0に戻れるのですが、ここで失敗すると最初のDetectステートに戻らなければなりません。(ゴール直前でふりだしに戻る感じ)
本来ならリカバリーステートをちゃんとつくるべきなのですが、いきなりDetectステートに戻すようにしてみたところ、見事にうまくいきました。つまり、何らかのエラーが起きたら、バスの状態をリセットして最初からリンクアップしなおすようにしたわけです。
こうしたら、このパソコンでもPCI Expressはリンクアップし、Windowsが起動するとPnPで認識され、問題なく通信できることが確認できました。
バスアナライザなんて作らなくてもよかったかも。いやいや、きっとこれから役に立つときがくるはず。
| 固定リンク
コメント