PCI構成空間とは、従来のPCI、PCI-X、およびPCI Expressが、バスに挿入されたカードの自動構成を実行するための基本的な仕組みです。
PCIデバイスには、コンフィギュレーション空間と呼ばれる一連のレジスタがあり、PCI Expressではデバイス向けに拡張コンフィギュレーション空間が導入されています。コンフィギュレーション空間レジスタはメモリ位置にマッピングされます。デバイスドライバと診断ソフトウェアはコンフィギュレーション空間にアクセスできる必要があり、オペレーティングシステムは通常、 APIを使用してデバイスコンフィギュレーション空間へのアクセスを許可します。オペレーティングシステムにメモリマップドコンフィギュレーション空間要求用のアクセス方法やAPIが定義されていない場合、ドライバまたは診断ソフトウェアは、オペレーティングシステムの基盤となるアクセスルールと互換性のある方法でコンフィギュレーション空間にアクセスする責任を負います。すべてのシステムにおいて、デバイスドライバはオペレーティングシステムが提供するAPIを使用してデバイスの構成空間にアクセスすることが推奨されます。
PCI ローカルバスが他の I/O アーキテクチャに比べて大きく改善された点の 1 つは、その構成メカニズムです。通常のメモリマップド空間と I/O ポート空間に加えて、バス上の各デバイス機能には、256 バイトの長さの構成空間があり、デバイスの 8 ビットの PCIバス番号、5 ビットのデバイス番号、および 3 ビットの機能番号 (一般的にバス/デバイス/機能の略でBDFまたはB/D/Fと呼ばれます) を知ることでアドレス指定できます。これにより、最大 256 個のバスが使用可能になり、各バスには最大 32 個のデバイスが接続され、各デバイスは 8 つの機能をサポートします。単一の PCI拡張カードはデバイスとして応答でき、少なくとも機能番号 0 を実装する必要があります。構成空間の最初の 64 バイトは標準化されており、残りはベンダー定義の目的で使用できます。一部のハイエンドコンピュータは、複数の PCI ドメイン (または PCI セグメント) をサポートしており、各 PCI セグメントは最大 256 個のバスをサポートします。PCI セグメントは、PCI ルートブリッジと呼ばれることもあります。
既存の用途と競合することなく、構成空間のより多くの部分を標準化できるようにするため、残りの 192 バイトの PCI 構成空間内に機能のリストを定義することができます。各機能には、それがどの機能であるかを記述する 1 バイトと、次の機能を指す 1 バイトがあります。追加バイト数は、機能 ID によって異なります。機能が使用されている場合、Statusレジスタのビットが設定され、標準化レジスタで定義されている機能ポインタレジスタに、機能のリンク リストの最初の項目へのポインタが提供されます。
PCI-X 2.0とPCI Expressでは、最大4096バイトの拡張構成空間が導入されました。拡張構成空間の中で標準化されているのは、アドレス0x100の最初の4バイトのみで、これは拡張機能リストの開始部分です。拡張機能は、通常の機能と非常によく似ていますが、拡張構成空間内の任意のバイトを参照できる点(8ビットではなく12ビットを使用)、4ビットのバージョン番号、および16ビットの機能IDを持つ点が異なります。拡張機能IDは通常の機能IDと重複する部分がありますが、別々のリストに格納されているため、混同することはありません。

デバイスID(DID)レジスタとベンダーID(VID)レジスタは、デバイス(ICなど)を識別するためのもので、一般的にPCI IDと呼ばれています。16ビットのベンダーIDはPCI-SIGによって割り当てられ、16ビットのデバイスIDはベンダーによって割り当てられます。既知のベンダーIDとデバイスIDをすべて収集するプロジェクトが現在進行中ですが、現在は活動していません。(下記の外部リンクを参照してください。)
ステータスレジスタは、サポートされている機能と、特定の種類のエラーが発生したかどうかを報告するために使用されます。コマンドレジスタには、個別に有効/無効にできる機能のビット マスクが含まれています。ヘッダー タイプ レジスタの値は、デバイスの機能に応じて、ヘッダーの残りの 48 バイト (64 - 16)のさまざまなレイアウトを決定します 。つまり、ルート コンプレックス、スイッチ、ブリッジの場合はタイプ 1 ヘッダー、エンドポイントの場合はタイプ 0 ヘッダーです。キャッシュ ライン サイズレジスタは、デバイスがメモリ書き込みおよび無効化トランザクションを使用できると通知される前にプログラムする必要があります。これは通常、CPU のキャッシュライン サイズと一致する必要がありますが、正しい設定はシステムに依存します。このレジスタは PCI Express には適用されません。
サブシステム ID (SSID)とサブシステム ベンダー ID (SVID)は、特定のモデル (アドイン カードなど) を区別します。ベンダー ID はチップセットメーカーの ID ですが、サブシステム ベンダー ID はカードメーカーの ID です。サブシステム ID はサブシステム ベンダーによって割り当てられ、デバイス ID はチップセットメーカーによって割り当てられます。たとえば、無線ネットワーク カードの場合、チップメーカーはIntel、Broadcom 、またはAtherosであり、カードメーカーはNetgearまたはHewlett-Packardである可能性があります。一般的に、ベンダー IDとデバイス ID の組み合わせは、ホストがデバイスを処理するためにロードすべきドライバを指定します。同じ VID:DID の組み合わせを持つすべてのカードは、同じドライバで処理できます。サブシステム ベンダー IDとサブシステム ID の組み合わせはカードを識別します。これは、ドライバが動作にカード固有の小さな変更を適用するために使用する情報です。
PCI デバイスにアクセスするには、システムの I/O ポート アドレス空間またはメモリ マップド アドレス空間にマッピングして有効にする必要があります。システムのファームウェア( BIOSなど) またはオペレーティングシステムは、ベース アドレス レジスタ(一般に BAR と呼ばれる) をプログラムして、構成コマンドを PCI コントローラに書き込むことにより、デバイスにリソース構成を通知します。システム リセット時にすべての PCI デバイスは非アクティブ状態になるため、オペレーティングシステムやデバイス ドライバが通信できるアドレスは割り当てられません。BIOS またはオペレーティングシステムは、スロットごとまたはデバイスごとの IDSEL (Initialization Device Select) 信号を使用して、PCI コントローラを介して PCI デバイス (たとえば、マザーボード上の最初の PCI スロット、2 番目の PCI スロット、3 番目の PCI スロット、または統合 PCI デバイスなど) を地理的にアドレス指定します。
コンピュータの電源投入時、BIOSまたはオペレーティングシステムはPCIバスとデバイスを列挙する必要があります。バスの列挙は、各バス、デバイス、および機能に対応するPCI構成空間レジスタへのアクセスを試みることで実行されます。デバイス番号は、VIDやDIDとは異なり、単にそのバス上のデバイスの連番であることに注意してください。さらに、新しいブリッジが検出されると、新しいバス番号が定義され、デバイス番号0からデバイスの列挙が再開されます。
デバイスの機能番号0から応答がない場合、バスマスターはアボートを実行し、すべてのビットがオンの値(16進数でFFFFFFFF)を返します。これは無効なVID/DID値であるため、BIOSまたはオペレーティングシステムは、指定されたバス/デバイス番号/機能(B/D/F)の組み合わせが存在しないことを認識できます。したがって、特定のバス/デバイスの機能IDがゼロである読み取りによってマスター(イニシエータ)がアボートした場合、そのバス上には動作するデバイスが存在しないと想定する必要があります。なぜなら、デバイスは機能番号0を実装する必要があるからです。この場合、残りの機能番号(1 ~ 7)への読み取りは不要です。それらも存在しないためです。
ベンダーIDレジスタの指定されたB/D/Fの組み合わせへの読み出しが成功すると、システムファームウェアまたはオペレーティングシステムはそれが存在することを認識し、BARにすべて1を書き込み、デバイスが要求したメモリサイズをエンコードされた形式で読み戻します。この設計は、すべてのアドレス空間サイズが2のべき乗であり、自然に整列されていることを意味します。[ 1 ]
この時点で、BIOSまたはオペレーティングシステムは、メモリマップドアドレスとI/OポートアドレスをデバイスのBAR構成レジスタにプログラムします。これらのアドレスは、システムがオンになっている限り有効です。電源を切ると、これらの設定は失われ、システムが次にオンになったときにこの手順が繰り返されます。BIOSまたはオペレーティングシステムは、各PCIデバイスに対して、割り込み要求などのPCI構成空間の他のレジスタもプログラムします。このプロセス全体が完全に自動化されているため、ユーザーはカード自体のDIPスイッチを変更して、新しく追加されたハードウェアを手動で構成する作業を省くことができます。この自動的なデバイス検出とアドレス空間の割り当てにより、プラグアンドプレイが実現されます。
PCI-to-PCIブリッジが検出された場合、システムはブリッジの先のセカンダリPCIバスにゼロ以外のバス番号を割り当て、そのセカンダリバス上のデバイスを列挙する必要があります。さらにPCIブリッジが検出された場合は、考えられるすべてのドメイン/バス/デバイスの組み合わせがスキャンされるまで、検出処理が再帰的に継続されます。
各非ブリッジPCIデバイス機能は最大6つのBARを実装でき、それぞれがI/Oポートとメモリマップドアドレス空間内の異なるアドレスに応答できます。各BARは、4ギガバイトのアドレス空間制限より下に位置する、16バイトから2ギガバイトのサイズの領域[ 2 ] [ 1 ]を記述します。プラットフォームがシステムファームウェアで「4G以上」オプションをサポートしている場合、64ビットBARを使用できます。
PCIデバイスにはオプションROMが搭載されている場合もある。
リサイズ可能な BAR ( Re-Size BAR、AMD Smart Access Memory (SAM)、ASRock Clever Access Memory (CAM) [ 3 ]とも呼ばれる) は、PCIe デバイスがより大きな BAR サイズをネゴシエートするために使用できる機能です。[ 4 ]従来、BAR のサイズは 256MB に制限されていましたが、最新のグラフィックス カードはそれよりもはるかに大きなフレーム バッファを備えています。この不一致により、CPU がフレーム バッファにアクセスする際に非効率が生じていました。リサイズ可能な BAR を使用すると、CPU はフレーム バッファ全体に一度にアクセスできるため、パフォーマンスが向上します。[ 5 ]
コンフィギュレーション空間アクセスを実行する際、PCI デバイスはアドレスをデコードして応答すべきかどうかを判断するのではなく、初期化デバイス選択信号 (IDSEL) を参照します。各 IDSEL 信号には、システム全体で一意のアクティベーション方法があります。PCI デバイスは、アドレス空間 (AD[10] ~ AD[0]) のアドレス/データ信号の下位 11 ビットのみをデコードすればよく、上位 21 ビットの A/D 信号 (AD[31] ~ AD[11]) のデコードは無視できます。これは、コンフィギュレーション空間アクセスの実装では、各スロットの IDSEL ピンが、異なる上位アドレス/データライン AD[11] ~ AD[31] に接続されているためです。IDSEL 信号は、PCI デバイス/アダプタ/スロットごとに異なるピンです。
スロットnのカードを構成するために、PCI バス ブリッジは、構成空間アクセス サイクルを実行します。このサイクルでは、アドレス指定する PCI デバイスのレジスタがライン AD[7:2] (レジスタはダブル ワード (32 ビット) であるため、AD[1:0] は常にゼロです) に、指定された PCI 機能番号がビット AD[10:8] に示され、AD[ n + 11] を除くすべての上位ビットがゼロで、特定のスロット/デバイス上の IDSEL 信号として使用されます。
タイミングが重要で(したがって電気的負荷に敏感な)AD[]バスへの電気的負荷を軽減するため、PCIスロットコネクタのIDSEL信号は通常、抵抗を介して割り当てられたAD[ n +11]ピンに接続されます。これにより、PCIのIDSEL信号は、他のPCIバス信号よりもアクティブ状態に達するのが遅くなります(抵抗とIDSELピンの入力容量の両方のRC時定数による)。そのため、IDSEL信号が有効なレベルに達するまでの時間を確保するために、コンフィギュレーション空間へのアクセスはよりゆっくりと実行されます。
Intelプラットフォームでは、バスのスキャンは、定義された2つの標準ポートにアクセスすることによって実行されます。これらのポートは、コンフィギュレーション空間アドレス(0xCF8)I/Oポートとコンフィギュレーション空間データ(0xCFC )I/Oポートです。コンフィギュレーション空間アドレスI/Oポートに書き込まれる値は、B/D/F値とレジスタアドレス値を組み合わせて32ビットワードを作成することによって生成されます。
CPU から構成の読み書きを開始するには 2 つの方法があります。 1 つは I/O アドレス0xCF8と0xCFCを介した従来の方法、もう 1 つはメモリ マップ構成と呼ばれる方法です。[ 6 ]
従来の方法は、オリジナルの PCI に存在し、構成アクセス機構 (CAM) と呼ばれています。これは、PCI CONFIG_ADDRESS および PCI CONFIG_DATA と呼ばれる 2 つの 32 ビット レジスタを介して、デバイスのアドレス空間の 256 バイトに間接的にアクセスすることを可能にします。これらのレジスタは、x86 I/O アドレス空間のアドレス0xCF8および0xCFCにあります。 [ 7 ]例えば、ソフトウェア ドライバ (ファームウェア、OS カーネル、またはカーネル ドライバ) は、これらのレジスタを使用して、デバイスのレジスタのアドレスを CONFIG_ADDRESS に書き込み、デバイスに書き込むべきデータを CONFIG_DATA に格納することにより、PCI デバイスを構成できます。このプロセスでは、デバイスのレジスタに書き込むためにレジスタへの書き込みが必要となるため、「間接」と呼ばれます。
CONFIG_ADDRESSのフォーマットは以下のとおりです。
0x80000000 |バス<< 16 |デバイス<< 11 |関数<< 8 |オフセット前述のとおり、バス、デバイス、および機能 (BDF) を介してデバイスにアドレス指定することは、「デバイスを地理的にアドレス指定する」とも呼ばれます。地理的アドレス指定を使用するコードの例については、Linux カーネルのコードをarch/x86/pci/early.c参照してください。 [ 8 ]
一部の AMD CPU で拡張構成空間が使用される場合、オフセットの追加ビット 11:8 が CONFIG_ADDRESS レジスタのビット 27:24 に書き込まれます。[ 9 ] [ 10 ]
0x80000000 | (オフセット& 0xf00 ) << 16 |バス<< 16 |デバイス<< 11 |関数<< 8 | (オフセット& 0xff )2つ目の方法はPCI Express向けに開発されたもので、拡張構成アクセス機構(ECAM)と呼ばれています。これは各機能の構成空間を4 KiBに拡張し、下位256バイトがPCIの元の(従来の)構成空間と重複するようにします。アドレス指定可能な空間の一部が「奪われる」ことで、CPUからのアクセスはメモリではなく、PCI Expressファブリック内の特定のデバイスに届きます。システム初期化時に、BIOSはこの「奪われた」アドレス領域のベースアドレスを決定し、それをルートコンプレックスとオペレーティングシステムに伝達します。
各関数はそれぞれ 4 KiB の領域を持ち、各関数の情報は単純な配列を介してアクセスできるdev[bus][device][function]ため、 この用途のために 256 MiB の連続した物理領域が「奪われる」(256 バス × 32 デバイス × 8 関数 × 4 KiB = 256 MiB)。この配列のベース物理アドレスは指定されていない。例えば、最新の x86 システムでは、ACPIテーブルに必要な情報が含まれている。[ 11 ]