-
Notifications
You must be signed in to change notification settings - Fork 5
PCI Memo
PCI および PCIe についてのメモ書き
2016/05/02 by uchan
PCI / PCIe は拡張カードを挿すだけでなく、オンボード NIC や SATA ディスクもつながる、重要なバス。 PCI デバイスは統一的な手法で識別できるので、PCI バスを一度扱えるようになると世界が広がる。
最終的に SATA ディスクを制御することを目標に、しかし知的好奇心が満たされるよう、最短経路よりは少し豊富な情報を提供する。 PCI ホストブリッジについて、PCI デバイスの列挙方法、PCI-PCI ブリッジの仕組み、PCI コンフィグレーションレジスタ、BAR とメモリマップといった話題を扱う。
本来 PCI バスはコンピュータ自体のアーキテクチャには依存しないが、ここでは PC/AT 互換機を前提として記述する。
PCI バスの信号タイミングなどの電気的特性の話は扱わない。
PCI ホストブリッジは CPU 側のバスと PCI バスを仲介する部品。
PCI デバイスは、制御のためのレジスタを I/O 空間やメモリ空間にマップして使う。したがって、メモリアドレス空間の中の特定のアドレス範囲を PCI バスへ転送するために、PCI ホストブリッジにはアドレス範囲を設定できる必要がある。さもないと、CPU がメインメモリを読み書きしようとしてホストブリッジが反応してしまい、大変なことになる。
Intel のチップセット(Mobile Intel GS45 Express →データシート)のホストブリッジでは TOLUD レジスタがその機能を提供する。大雑把に区分すると 0 から TOLUD が DRAM、TOLUD から 4GB が PCI や APIC などのメモリマップトレジスタとなっている。TOLUD は起動時に初期化プログラム(BIOS)が適切な値を設定することになっている(すなわち、BIOS はメモリの大きさを計測し、被らない位置に TOLUD を設定する)。
Intel のチップセット仕様書に記載がある(Mobile Intel GS45 Express →データシート)。PC/AT 互換機はすべて同じはず。
I/O 空間にある DWORD 幅のレジスタ CONFIG_ADDRESS (0CF8h), CONFIG_DATA (0CFCh) を用いてコンフィグレーションレジスタを読み書きする。CONFIG_ADDRESS にアクセスしたいバス番号、デバイス番号、ファンクション番号、レジスタアドレスを書き込むと CONFIG_DATA がそのレジスタを読み書きする窓になる仕組み。
CONFIG_ADDRES
DROWD 幅でのみ読み書き可能。
ビット | アクセス | 初期値 | 意味 |
---|---|---|---|
31 | R/W | 0 | Configuration Enable ビット。1 を書き込むと PCI コンフィグレーション空間へのアクセスが有効になる。 |
30:24 | RO | 0 | 予約 |
23:16 | R/W | 0 | バス番号 |
15:11 | R/W | 0 | デバイス番号 |
10:8 | R/W | 0 | ファンクション番号 |
7:2 | R/W | 0 | レジスタアドレス |
1:0 | RO | 0 | 予約 |
1:0 が 0 固定であることからも分かる通り、コンフィグレーションレジスタへのアクセスは DROWD 境界でのみ可能。
CONFIG_DATA
こちらは特に DROWD 幅のアクセスでなくても良い。CONFIG_ADDRESS[31] が 1 のとき、CONFIG_ADDRESS で指定された PCI デバイスのコンフィグレーションレジスタの内容を CONFIG_DATA レジスタを経由して読み書きできる。