ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
デバイスドライバの記述 Oracle Solaris 11.1 Information Library (日本語) |
パート I Oracle Solaris プラットフォーム用デバイスドライバの設計
2. Oracle Solaris カーネルとデバイスツリー
DMA ソフトウェアコンポーネント: ハンドル、ウィンドウ、cookie
22. ドライバのコンパイル、ロード、パッケージ化、およびテスト
23. デバイスドライバのデバッグ、テスト、およびチューニング
DMA 転送の手順は、どの種類の DMA でも似ています。以降のセクションでは、DMA 転送を実行する方法について説明します。
注 - ファイルシステムから生成されるバッファー用のブロックドライバのメモリー内に DMA オブジェクトをロックしておく必要はありません。メモリー内のデータは、ファイルシステムによってすでにロックされています。
ドライバは、バスマスター DMA に関する次の手順を実行します。
DMA 属性を記述します。この手順により、DMA ルーチンで、デバイスがバッファーにアクセスできることを保証できるようになります。
DMA ハンドルを割り当てます。
DMA オブジェクトがメモリー内でロックされていることを確認します。physio(9F) または ddi_umem_lock(9F) のマニュアルページを参照してください。
DMA 資源をオブジェクトに割り当てます。
デバイス上で DMA エンジンをプログラミングします。
エンジンを起動します。
転送が完了したら、バスマスター操作を続行します。
必要なオブジェクト同期があれば、それを行います。
DMA 資源を解放します。
DMA ハンドルを解放します。
ドライバは、ファーストパーティー DMA に関する次の手順を実行します。
DMA チャネルを割り当てます。
ddi_dmae_1stparty(9F) を使用してチャネルを構成します。
DMA オブジェクトがメモリー内でロックされていることを確認します。physio(9F) または ddi_umem_lock(9F) のマニュアルページを参照してください。
DMA 資源をオブジェクトに割り当てます。
デバイス上で DMA エンジンをプログラミングします。
エンジンを起動します。
転送が完了したら、バスマスター操作を続行します。
必要なオブジェクト同期があれば、それを行います。
DMA 資源を解放します。
DMA チャネルを解放します。
ドライバは、サードパーティー DMA に関する次の手順を実行します。
DMA チャネルを割り当てます。
ddi_dmae_getattr(9F) を使用してシステムの DMA エンジンの属性を取得します。
DMA オブジェクトをメモリー内にロックします。physio(9F) または ddi_umem_lock(9F) のマニュアルページを参照してください。
DMA 資源をオブジェクトに割り当てます。
ddi_dmae_prog(9F) を使用して、転送を行うようにシステムの DMA エンジンをプログラミングします。
必要なオブジェクト同期があれば、それを行います。
ddi_dmae_stop(9F) を使用して DMA エンジンを停止します。
DMA 資源を解放します。
DMA チャネルを解放します。
ハードウェアプラットフォームの中には、バス固有の方法で DMA 機能を制限しているものもあります。ドライバは ddi_slaveonly(9F) を使用して、DMA を使用できるスロット内にデバイスがあるかどうかを確認します。
DMA 属性には、次のような DMA エンジンの属性と制限が記述されています。
デバイスがアクセスできるアドレスの制限
最大転送数
アドレスの配置の制限
デバイスドライバは、ddi_dma_attr(9S) 構造体を通じて DMA エンジンのすべての制限をシステムに通知する必要があります。この処理により、システムが割り当てた DMA 資源にデバイスの DMA エンジンからアクセスできるようになります。システムでは、デバイス属性にさらなる制限を加えることはありますが、ドライバが設定した制限を削除することはありません。
typedef struct ddi_dma_attr { uint_t dma_attr_version; /* version number */ uint64_t dma_attr_addr_lo; /* low DMA address range */ uint64_t dma_attr_addr_hi; /* high DMA address range */ uint64_t dma_attr_count_max; /* DMA counter register */ uint64_t dma_attr_align; /* DMA address alignment */ uint_t dma_attr_burstsizes; /* DMA burstsizes */ uint32_t dma_attr_minxfer; /* min effective DMA size */ uint64_t dma_attr_maxxfer; /* max DMA xfer size */ uint64_t dma_attr_seg; /* segment boundary */ int dma_attr_sgllen; /* s/g length */ uint32_t dma_attr_granular; /* granularity of device */ uint_t dma_attr_flags; /* Bus specific DMA flags */ } ddi_dma_attr_t;
各表記の意味は次のとおりです。
属性構造体のバージョン番号です。dma_attr_version は DMA_ATTR_V0 に設定されます。
DMA エンジンがアクセスできる最下位のバスアドレスです。
DMA エンジンがアクセスできる最上位のバスアドレスです。
DMA エンジンが 1 つの cookie で処理できる最大転送数を指定します。上限は、最大数から 1 を引いた数で表されます。この数はビットマスクとして使用されるため、2 のべき乗よりも小さくする必要もあります。
ddi_dma_mem_alloc(9F) からメモリーを割り当てるときの配置要件を指定します。配置要件の例として、ページ境界での配置があります。dma_attr_align フィールドはメモリーの割り当て時にしか使用されません。バインド操作時には、このフィールドは無視されます。バインド操作では、ドライバはバッファーが適切に配置されるようにする必要があります。
デバイスがサポートするバーストサイズを指定します。バーストサイズとは、デバイスがバスを放棄する前に転送できるデータ量のことです。バーストこのメンバーはバイナリ符号化方式のバーストサイズです。このサイズは、2 のべき乗になるものとみなされます。たとえば、デバイスが 1 バイト、2 バイト、4 バイト、および 16 バイトのバーストを処理できる場合、このフィールドは 0x17 に設定されます。システムでは、このフィールドを使用して配置制限も決めます。
デバイスが実行できる効果的な最低転送サイズです。このサイズは、配置やパディングの制限にも影響を及ぼします。
DMA エンジンが 1 回の入出力コマンドで格納できる最大バイト数を記述します。この制限が意味を持つのは、dma_attr_maxxfer が (dma_attr_count_max + 1) * dma_attr_sgllen よりも小さい場合のみです。
DMA エンジンのアドレスレジスタの上限です。dma_attr_seg は、アドレスレジスタの上位 8 ビットがセグメント番号を含むラッチである場合に頻繁に使用されます。下位 24 ビットはセグメントのアドレス指定に使用されます。この場合、dma_attr_seg は 0xFFFFFF に設定されます。これにより、オブジェクトへの資源の割り当て時にシステムは 24 ビットのセグメント境界を越えることはできません。
scatter/gather リストに含まれる最大エントリ数を指定します。dma_attr_sgllen は、DMA エンジンがデバイスへの 1 回の入出力要求で使用できる cookie の数です。DMA エンジンに scatter/gather リストがない場合、このフィールドは 1 に設定されます。
このフィールドは、デバイスの DMA 転送機能の粒度をバイト単位で指定します。この値の使用方法の例として、外部ストレージデバイスのセクターサイズの指定が挙げられます。バインド操作で部分的なマッピングが必要な場合、このフィールドを使用して、DMA ウィンドウ内の cookie のサイズ合計が粒度の整数倍になるようにします。ただし、デバイスに scatter/gather 機能がない場合は、DDI で粒度を保証することはできません。この場合、 dma_attr_granular フィールドの値は 1 になります。
このフィールドには DDI_DMA_FORCE_PHYSICAL を設定できます。これは、システムが物理入出力アドレスと仮想入出力アドレスの両方をサポートしている場合に、仮想ではなく物理アドレスが返されることを示します。システムが物理 DMA をサポートしていない場合、ddi_dma_alloc_handle(9F) の戻り値は DDI_DMA_BADATTR になります。この場合、ドライバは DDI_DMA_FORCE_PHYSICAL をクリアし、処理を再試行する必要があります。
SPARC マシンの SBus 上の DMA エンジンには、次の属性があります。
0xFF000000 から 0xFFFFFFFF までのアドレスにのみアクセス
32 ビットの DMA カウンタレジスタ
バイト整列された転送を処理できる
1 バイト、2 バイト、および 4 バイトのバーストサイズをサポート
効果的な最低転送サイズが 1 バイト
32 ビットのアドレスレジスタ
scatter/gather リストなし
セクターのみ (ディスクなど) での操作
SPARC マシンの SBus 上の DMA エンジンには、次の属性構造体があります。
static ddi_dma_attr_t attributes = { DMA_ATTR_V0, /* Version number */ 0xFF000000, /* low address */ 0xFFFFFFFF, /* high address */ 0xFFFFFFFF, /* counter register max */ 1, /* byte alignment */ 0x7, /* burst sizes: 0x1 | 0x2 | 0x4 */ 0x1, /* minimum transfer size */ 0xFFFFFFFF, /* max transfer size */ 0xFFFFFFFF, /* address register max */ 1, /* no scatter-gather */ 512, /* device operates on sectors */ 0, /* attr flag: set to 0 */ };
x86 マシンの ISA バス上の DMA エンジンには、次の属性があります。
最初の 16M バイトのメモリーにのみアクセス
1 回の DMA 転送で 1M バイト境界を越えることはできない
16 ビットのカウンタレジスタ
バイト整列された転送を処理できる
1 バイト、2 バイト、および 4 バイトのバーストサイズをサポート
効果的な最低転送サイズが 1 バイト
17 以下の scatter/gather 転送を保持できる
セクターのみ (ディスクなど) での操作
x86 マシンの ISA バス上の DMA エンジンには、次の属性構造体があります。
static ddi_dma_attr_t attributes = { DMA_ATTR_V0, /* Version number */ 0x00000000, /* low address */ 0x00FFFFFF, /* high address */ 0xFFFF, /* counter register max */ 1, /* byte alignment */ 0x7, /* burst sizes */ 0x1, /* minimum transfer size */ 0xFFFFFFFF, /* max transfer size */ 0x000FFFFF, /* address register max */ 17, /* scatter-gather */ 512, /* device operates on sectors */ 0, /* attr flag: set to 0 */ };