もう一つ大きな違いは、Doorbell Arrayの存在だ。これはxHCIで初めて搭載されたもので、文字通り「呼び鈴」である。Doorbell Arrayは256個のDoorbell Registerの集合であり、各々のRegisterが256個のUBS DeviceなりHub(Specificationの中の表現に従えば、各Device Slot)にそのまま対応している(0番のRegisterはxHCIのHost Controllerを指しており、これはCommand Ringの管理に利用される)。Host上のSoftware、要するにBase Driverということになるが、これがxHCIに対して何らかのActionを要求する場合に、このDoorbell Tegisterは例えばあるDeviceが追加された場合、そのDeviceのSetupに必要なデータ構造をキューに入れたあとで、当該のDoorbell Registerに値を書きこむ(つまりDoorbellを押す)と、xHCIがこれをトリガーに必要な処理を行うことになっている。なのでHostからDoorbell RegisterはWrite only Registerとして見えることになる。

ここで出てきたDevice Slotなる用語は、各々のUSBデバイスにそれぞれ割り当てられるデータ構造全体を指すものである。Device Slotに含まれるものにはこのDevice Registerの他、前回のPhoto02にも出てくるDevice Context"もある。こちらが具体的な各Deviceを管理するデータであり、このデータ構造の格納場所を管理するのがDevice Context Base Address Arrayである。そして全てのDevice Contextは、Transfer Ringと呼ばれるデータ転送キューで管理されるが、このTransfer Ringは一つのEndpointもしくはStreamあたり一つづつ作成されるので、全体としてのTransfer Ringの数は膨大になる。これ以外にも、xHCIの制御を行うためのCommand Ring(これはxHCI全体で一つ)と、xHCIからSoftware(つまりBase Driverやその上位)に完了通知や非同期イベントを通知するためのEvent Ring(これはInterruptあたり一つ)が設けられる。

こうしてみると、かなりデータ構造が複雑になっていることが判る。更に共有メモリ上には、実際に転送を行う際に利用される最大64KBのデータバッファが、これまた当然複数も受けられることになる。更に言えば、ここまではあくまでxHCIで規定された、(Write可能かどうかはともかく)Softwareからアクセス可能なメモリ領域であるが、これとは別にxHCI Controllerが内部的に使う領域が必要である。例えばxHCI Controllerは当然複数のTransfer Ringに登録された転送要求(これをTransfer Descriptorと呼ぶ)を管理しながら順に転送をかけ、終わったものを必要に応じてTransfer Ringから外したり、あるいは順序を入れ替えたりするわけだが、こうした作業を行うための管理領域をxHCI Controller内部で確保するのは非常に難しいから、やっぱり共有メモリ領域を使わざるを得ない。必然的に、xHCIが利用するメモリ量は大幅に増えることになる。

具体的にちょっと見てみた。Photo01はICH10のEHCI Controllerのプロパティを見たものだが、マッピングしているメモリの範囲はF7FFD000~F7FFD3FFで、僅か1KBしかないことが判る。対するxHCIは? というと、FBEFE000~FBEFFFFFで、8KBに増えている。ちなみにこれはどこの範囲かといえば、前回のPhoto02で言うところの"MMIO Space(Memory-Mapped I/O Soace)"にあたり、共有メモリ領域はここにはMapされない(「共有」されているわけだから、Deviceで占有されている訳ではないので、入らない)。

Photo01: EHCIの場合、IRQは一つだけ。

Photo02: xHCIでは、IRQも-3~-10の8つを利用する。まぁこのあたりは実装にも関係するのだろうけど。

これ以外のものとしては、xHCIとしてではなく、PCI Express DeviceとしてAllocateする分がある。Photo03がUSB 3.0カード未装着、Photo04がUSB 3.0カードを装着の場合のメモリの状況である。Photo04の方には、xHCIの占有分とは別に、PCI Express DeviceとしてFBE00000~FBEFFFFFの範囲の1MB分のメモリを占有しているのがわかるはずだ。これはPCI Expressデバイスを装着した場合、自動的にPCI Express側が割り当ててDeviceが利用できる領域である。通常この仕組みは、拡張ボード側が持つメモリ領域をHostから利用できるようにする(例えばビデオカードの上のメモリをCPU側からアクセスできるようにする部分がこれにあたる。勿論最近の1GBとか2GBとかいう巨大なフレームバッファを全部アクセスできるわけではなく、VGAとかXGAなどが定義するフレームバッファ領域を、互換性を保つためにアクセスできるようにするものである)ためのものであるが、逆にメインメモリをデバイス側で利用できるようにするためにも利用できる。ちなみにEHCIが利用するメモリ領域は、「マザーボードリソース」表記になっているため、この画面からは「どれ」と特定することが出来ないので、直接サイズの比較が出来ないのはちょっと残念である。

Photo03: IntelのP55マザーにGeForce 8800 GTを装着という構図。この企画用にインストールした機材のビデオだけを入れ替えたもの。

Photo04: 真ん中よりやや下あたり、"Renesas Electronics USB 3.0 Host Controller"の一つ上である。

(続く)