IEEE1394バス構造のメモ


IEEE1394のアドレシング概説

64bitアドレシング

IEEE1394では合計64bitのアドレスを用いて、ケーブルでつながっているどのデバイスのどのアドレスかが一意に指定できます。そのうち最上位16bit(bit[48:63])は各nodeの所在を指定します。その16bitのうち下位6bit(bit[48:53])がnode IDを示し、上位10bit(bit[54:63])がbus IDを示しますただし、node IDを全bit1にする(003Fh)と同一バス番号内でブロードキャスト扱いとなります。また、bus IDを全bit1にすると(FFC0h)所属バスを指定することになります。残り48bit(bit[0:47])が各デバイスに所属するアドレスになります。ちなみにバス番号はバスブリッヂを通じて決定されるようです(1394-1995.pdf 1.4.3)。Ethernetでルーターで適宜セグメント化するのと同様に、台数制限を行うことで帯域の圧迫を回避できると考えれば良いんですかね。あと、後述するバスリセットの際のツリー構築を、一つノードを追加するたびに16bit分のノード間で行うというのは、ありえない話ですもんね。ともあれ、通常の接続ではバスブリッヂを越えないので、同一バス上で最大63台のデバイスを接続できるということになります。

さて、各デバイスに48Bbit分アドレスがあるわけですが、これはx86マシンのIO空間とメモリ空間を合わせたものと同じように、通常のRAMも見えますし(メモリ空間)、ROMが読み出せたりMemory Mapped IOなアドレスもあります(レジスタ空間)。デバイス内で閉じたアドレスというのもご丁寧にあります(プライベート空間)。

Node ID

種々の要因でバスリセットが起きるそのたびごとに、デバイスは自律的にツリー構造(根つき木)を構築し、前述したnode IDはデバイス間で取り決められます。注記するべき点として、USBと違い1394OHCI準拠ホストコントローラ、つまりPCがぶら下がっているIEEE1394拡張ボードはその際ひとつのnode以上の存在に過ぎず、特別な存在、ルートになるという保証はどこにもありません。また、この過程にはランダムな要素が含まれ、node IDは接続状態が同じでも一意的に確定しないものとなります。これは結構困った話で、HDDの場合、node IDをTarget IDにあててエミュレーションしようとすると、再起動するごと、バスリセットが起きるたびにTarget IDが入れ替わってドライブレターが一定しないということになります。しかもユーザーがSCSIのTarget IDのようにnode IDを強制的に割り振ることはできません。端的に言うと同一デバイスの順序はnode IDの大小に依存できないわけです。まあ、OHCI間をケーブルで繋いでIP over 1394するときとか、OHCIの関与しないデバイス同志だけで繋いだときを考えれば分からないでもないんですが、もうちょっと工夫できなかったんですかね。

ではどのようにして同一デバイスに順序を規定したらよいか?例えばホストアダプタをルートとした根付き木を構築する方法が考えられます。これはIEEE1394がデバイス間で取り決めるルートとは別の、1394OHCI準拠ホストコントローラを中心とした木です。これならユーザーの配線の仕方で一意に確定できます。ではソフトウェア的にどのようにしてそのような木構造を把握するか?バスリセット後には各ノードは自分のnode IDと、そのノードのどのポートが「親に接続」 or 「子に接続」 or 「未接続」 or 「そもそもない」という情報を自分の能力とともにブロードキャストします。これがself-IDパケットになります。これを元にトポロジは把握できます。ただ、この情報は木構造を一意に確定できますが、「私には親が一人と長男と三男がいます。次男は音信不通です」という程度の情報にしか過ぎないわけです。しかも「親と子が二人いるのは知ってるが誰だったかは忘れた」みたいな(^^;。こんな「オレだよ、オレオレ」みたいなメッセージがデバイスの数送られてくるわけで。文句言わずに構築しろよということになるんでしょうが、もうちょっと親切な情報くらい送ってくれてもよいんではないかと。例えば親のnode IDとか、子孫の総数とか。なにはともあれ、そうして構築した木を参照して、1394OHCI準拠ホストコントローラをルートとした木を作ることはできるんではないでしょうか。

configuration ROM

IEEE1394は多種多様なデバイスを接続することを考えて作られています。逆にいうと、接続されているものが何物であるか、どう言うコマンド体系(AV/C,SBP-2,IP over 1394,mLAN... etc)で制御すればよいのか知る必要があるわけです。こう言った情報はConfiguration ROMに記載されており、レジスタ空間のオフセット400h、つまりアドレス[0:47]がFFFF F000 0400hから読み出せるようになっております。具体例はSBP-2仕様書のChanpter7とAnnexDにあって、わかりやすいです。

Bus Resetとnode ID

SCSIの時にはTarget IDをジャンパやディップスイッチなどで確定できたため、Bus Reset後にあて先が変わるというようなことは考えずにすみました。ところが、IEEE1394ではユーザーがHDDならHDDにIDを振る必要がなくなったため、(振りたくても振れなくなったともいう)問題が複雑化します。IEEE1394ではBus Reset後にツリーを1から構築し、node IDをまっさらな状態から振りなおします。node IDの決定過程はランダムな要素にも依存しているため、Bus Reset前のnode IDとBus Reset後のnode IDとは別のものになる可能性があり、しかも確実な予測は一般的には不可能であります。これはSBP-2に限ったことではなく、IEEE1394デバイス一般的な問題です。

ではどのようにしてBus Reset前にnode ID #Xとして把握していたデバイスを見つけるのか?解決手段はConfiguration ROMのBus information blockの中にあります。Chip IDと node_Vendor IDを合わせると64bitの値からなり、同じメーカーの同じ型番のチップであっても、チップ1枚1枚に固有で固定の値を持つようになっています。実用上はシリアルNoとかを充てて区別できるようにするんですかね。この64bit値をEUI-64 (Extended Unique Identifier, 64 bits)またはnode unique IDと呼び、EthernetのMacアドレスのような役割を果たします。余談ですが、1394OHCIコントローラにも当然EUIはあります。それは同じボードで何台もIP over 1394接続してるときのことを考えればわかりますね。それはGUIDとしてOHCIの仕様書では記述されています。

パケット一覧

まず最大の関心事であるデータを転送するということから。シリアルバスでデータは共用ですから、よこせといわないとデータは送ってきてくれません。送りつけるのは一方的に送りつけてもよいのですが、返事くらいもらってもいいもんです。アドレスはRead/Writeどちらとも要求する側が指定します。要求される側は要求してきた側のメモリ構造なんか知ったこっちゃないので、送り先のnode IDだけ指定して応答します。データを含むときでも、アドレスは指定しません。


Valid HTML 4.01 Strict