PCI 構成空間のベース アドレス レジスタ (BAR) が PCI アドレスの開始位置を定義することは知っていますが、この領域のサイズはどのように確立されるのでしょうか?
アドレス空間のどこまで処理できるかはハードウェアだけが知っているので、これは確かにハードウェアの特性です。ただし、PCI 構成構造に BAR サイズ フィールドが表示されないようです。
まず、BAR サイズは 2 のべき乗 (1 KiB、2 MiB など) である必要がlog2(size)
あり、ベースアドレスの下位ビットが常にゼロになるように、各領域がメモリ内で整列されている必要があります。たとえば、エンドポイントに 4 KiB のメモリ領域があり、アドレス範囲が0-0xfff
. ホストは、この領域の開始を fx0x1000
または0xabcd000
BAR レジスタに書き込むことによって再マップできますが、0x1080
またはには再マップできません0xabcd100
。
BAR レジスタが書き込まれると、エンドポイントは LSB を無視し、読み取り時に常にゼロを返します。したがって、レジスタに書き込み0xffffffff
、次に値を読み戻すと、領域のサイズが示されます。4 KiB の例では、これが返されます0xfffff00X
(下位 4 ビットは予約されています。仕様を参照してください)。サイズを決定するには:
0xfffff000
)0xfff
)0x1000 = 4096 bytes
)これは 64 ビット領域でも機能します。次のベース アドレス レジスタの値は、ベース アドレスの MSB を形成します。これは、PCI 3.0 仕様のセクション 6.2.5.1 で説明されています。
OSDev Wikiで答えを見つけました:
「PCI デバイスが必要とするアドレス空間の量を決定するには、BAR の元の値を保存し、レジスタにすべて 1 の値を書き込んでから、それを読み戻す必要があります。」
PCIe デバイスは、タイプ 0 (エンドポイント) またはタイプ 1 (RC またはスイッチまたはブリッジ) 構成スペースのいずれかを持つことができます。
-- Type-0 デバイスは合計 6 つの BAR を持つことができますが、Type-1 は 2 つの BAR しか持つことができません。
--BAR は、デバイスが必要とするアドレス空間に関する情報を提供します。
-- 各 BAR は 32 ビットで、最初の 4 ビット 3:0 は常に読み取り専用です。
-- 2^(最下位ビットからの最後の R/W ビットの位置) = 特定の BAR に必要なアドレス ウィンドウ。
任意の BAR によって表される領域のアドレス ウィンドウまたはサイズを知る方法:
1) 最初に任意の BAR を読み取ります (この場合は BAR0 とします)。値は 32'h0000_000F です。(覚えておいてください: 最後の 4 ビットは読み取り専用です!!)。
2) BAR0 にすべて 1 を書き込みます。
3) BAR0 を再度読み取り、値 32'hFFFF_000F を取得したとします。したがって、ビット位置 16 が最下位 R/W ビットです。したがって、BAR0 が必要とするアドレス空間は 2^16 になります。