[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: malloc & phys address



筒井です。

<20010119.182003.125129490.hamajima@nagoya.ydc.co.jp>の記事において
hamajima@nagoya.ydc.co.jpさんは書きました。

> 濱嶋です。

> 作っているのはAIUです。年末くらいからamigaのauccを参考にちょこちょこと作っ
> ていましたが、auccがbus_dmaを使っていないのとNetBSDのドライバを書くのは
> はじめなので、DMAまわりでつまずいています。

> DCUの仕様からDMA bufferは最大2k(alignmentも2k)なので大丈夫そうですね。
> 何かbus_dmaの参考になりそうなソースを探して、もう少し頑張ってみます。

audio の DMA はいじったことないんですが、
/sys/dev/pci/eap.c あたりが参考になるんじゃないでしょうか。

bus_dma(9) になんとなく書いてありますが、おおざっぱに書くと、

1) bus_dmamem_alloc() で(DMA 可能なアドレスの)物理メモリ確保
2) bus_dmamem_map() で 上記物理メモリをkernel 変数に map
3) bus_dmamap_creat() で DMA 転送用 tag を用意
4) bus_dmamap_load() で S/G および VA → PA 変換
5) bus_dmamap_sync() で bounce buffer 転送および cache flush
6) 以上まで用意して DMA 転送開始
7) 転送が終わったら再度 bus_dmamap_sync()

てな感じです。audio だと 2) のところで bus_dmamem_mmap() を
使った方がいいのかもしれません。

mips だと 5) と 7) での cache flush はまじめにやらないといけませんが、
i386 だと不要なのでまじめにやってないドライバが多いのが実情です。
ただ 2) で map の際に BUS_DMA_COHERENT を指定していると mips では
最初から KSEG1 のアドレスが返るのであまり問題になりませんけど。

SCSI のドライバのデータ転送とかだと 4) の bus_dmamap_load()
で dm_segs[].ds_addr とかに S/G された PA が返りますが、
bus_dmamem_alloc() して確保したメモリならば最初から連続だし
dm_segs[0].ds_addr もいつも同じ値になるかと思います。
SCSI や Network ドライバだとパラメータ受渡し用のメモリを
bus_dmamem_alloc() で確保することが多いです。
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp