PCI構成スペースのベースアドレスレジスタ(BAR)がPCIアドレスの開始位置を定義することは知っていますが、この領域のサイズはどのように確立されますか?
確かに、これはハードウェアの特性です。アドレス空間のどこまで処理できるかを知っているのはハードウェアだけだからです。ただし、PCI構成構造にBARサイズフィールドが表示されないようです。
まず、BARサイズは2の累乗(たとえば、1 KiB、2 MiB)である必要があり、ベースアドレスの下位log2(size)
ビットが常にゼロになるように各領域をメモリ内で整列させる必要があります。 。たとえば、エンドポイントに4 KiBのメモリ領域があり、アドレス範囲が0-0xfff
であるとします。ホストは、この領域の開始をf.xに再マップできます。 0x1000
または0xabcd000
は、BARレジスタに書き込みますが、0x1080
または0xabcd100
には書き込みません。
BARレジスタが書き込まれると、エンドポイントはLSBを無視し、読み取り時に常にゼロを返します。したがって、レジスタに0xffffffff
を書き込んでから値を読み戻すと、領域のサイズが示されます。 4 KiBの例では、これは0xfffff00X
を返します(下位4ビットは予約されています。仕様を参照してください)。サイズを決定するには:
0xfffff000
)0xfff
)0x1000 = 4096 bytes
)これは64ビット領域でも機能します。次のベースアドレスレジスタの値は、ベースアドレスのMSBを形成します。これは、PCI3.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)すべての1をBAR0に書き込みます。
3)BAR0を再度読み取り、値32'hFFFF_000Fを取得したとします。したがって、ビット位置16は最下位のR/Wビットです。したがって、BAR0に必要なアドレス空間は2 ^ 16になります。