今回はCellで最も重要であるともいえるDMA転送について
SPEが参照できるのは自身のLSのみであり
メインメモリは参照できない。
DMA転送によってメインメモリからデータを転送する。
DMA転送命令は
spu_mfcdma64(32)
mfc_get
mfc_put
などがある。
まぁどれがいいのかってのは分からないけど、
動作自体は同じなので問題ない。
今回はspu_mfcdma64について
この関数はこんな感じになっています。
void spu_mfcdma64(volatile void *ls_addr,
unsigned int ea_h,
unsigned int ea_l,
unsigned int dma_size,
unsigned int tag_id,
unsigned int cmd);
ls_addrはLSのアドレス
es_hとes_lはメインメモリ側のアドレスで
es_hはそのアドレスの上位32bit
es_lは下位32bitとなる。
mfc_ea2h()マクロとmfc_ea2l()ってのが用意されているから
64bitで渡されたアドレス(addrとすると)
mfc_ea2h(addr)マクロとmfc_ea2l(addr)とすると
自動的に上位bitと下位bitに分けてくれる。
dma_sizeはDMA転送サイズを指定する。
DMA転送のサイズは
1,2,4,8,16byteまたは16byteの倍数で最大16kBとなっています。
tag_idはDMA転送のタグをしています。
転送するにあたって問題はないけど、同期をとるときに使用します。
cmdはDMA転送の種類を指定します。
細かいのはよく分からないので
(SPEから見て)送信の場合は32
受信の場合は64を入力します。
一応、MFC_GET_CMDやMFC_PUT_CMDでも送信受信の指定ができます。
同期を取るために
spu_writech
spu_mfcstat
ってマクロと関数が定義されています。
spu_writech(imm, 1 ra);
spu_mfcstat(unsigned int type)
immはMFCに渡すチャネル番号を指定。
MFC_WrTagMaskと書けば問題ない。(数値だと多分22かな?)
raはタグの指定
DMA転送時に指定したタグを、1bit左にシフトした値がタグマスクになります。
typeはDMA転送の終了時にタグが更新されたかを確認します。
MFC_TAG_UPDATE_ALLと書けばいい。
これは上でセットした、タグマスクの完了を待つという意味。
(数値で入力する場合、多分0,1,2のどれを入力したかで動作が変化すると思われる。
0なら無条件、1ならどれか一つでも完了していれば、2なら全部が終了したら・・・
今回の場合は2かな)
詳細については
フィックスターズのサイトをご覧ください。
自分で定義したものなら、ともかくAPIとして定義されてるのは調べるのが面倒です。
そのためC言語と違ってマクロや関数とかを使わないので、
アセンブラのほうがシンプルです。
次はアセンブリでのDMA転送について説明したいと思います。
PR