« WindowsのDMAとMapRegister | トップページ | PCI Express 64bitでのDMA »

2017.08.10

PCI ExpressのDMA転送を改善する

前回の記事ではWindowsが用意するしくみでは、1MBや2MBといったサイズでDMAが制限されていることを書きました。

具体的には、ドライバのコードで以下のようなものを書きます。

DEVICE_DESCRIPTION DeviceDescription;
RtlZeroMemory(&DeviceDescription,sizeof(DeviceDescription));
DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
DeviceDescription.Master = TRUE;
DeviceDescription.ScatterGather = TRUE;
DeviceDescription.Dma32BitAddresses = TRUE;
DeviceDescription.Dma64BitAddresses = FALSE;
DeviceDescription.InterfaceType = PCIBus;
DeviceDescription.MaximumLength = 0x10000000; // 256MByte
// DMAアダプタを作成
dx->dmaAdapter = IoGetDmaAdapter(dx->pdo, &DeviceDescription, &dx->NumOfMappedRegister);
KdPrint(("DmaAdapter: Num of Mapped registers =%d \n",dx->NumOfMappedRegister));

このコードは、DMAアダプタというものを獲得するコードなのですが、32bitのPCIバスを使って最大256MByteのDMA転送をするようなDMAアダプタを作ってくれ、と要求するものです。

ポイントは上の赤い字で記した、Dma64BitAddress=FALSEというところにあります。

64bitAddressesがFALSEだと、マップレジスタが256個しかとられません。

64bitAddressesをTRUEにしてみると、あら不思議、マップレジスタが65537個取れました。

Combuf_office_64

さくっと256MByte用のマップレジスタが取れたのでしょうか?

いや、PCI Expressも64bitでCPUも64bitなので、おそらくマップレジスタを使わずにDMA転送を行えるようになったのでしょう。

64bit版PCI Expressデバイスのすごいところはマップレジスタを使わないだけではなく、コモンバッファも巨大なサイズが取れるということです。

メインメモリ16GB積んだPCで、0xffffffffバイトのCommonBufferを要求したら、物理アドレス0x00000003-00000000から連続した4GBの長さのバッファが取れました。

Combuf_office_64_4gb

32bit版のPCIeとドライバでは4MBや8MBが限度だったので、4GBのバッファというのはすごいことです。

64bit版ドライバと64bit版デバイスはすごいですね。

sun

本当にPCI Expressを64bitにするには、64bit BARを有効にしなければなりません。XILINXのXDMAコアでは、以下のオプションを設定します。

Xdma_64bit

これで64bit版のBARが有効になります。

そして論理合成してBitファイルを書き込んだら、一度再起動します。32bitBARから64bitBARに切り替えるには、デバイスマネージャからの無効→有効するだけではうまくいかないようです。

|

« WindowsのDMAとMapRegister | トップページ | PCI Express 64bitでのDMA »

コメント

コメントを書く



(ウェブ上には掲載しません)




« WindowsのDMAとMapRegister | トップページ | PCI Express 64bitでのDMA »