Solaris1.x CPU-3CE/5CE/5TEからCPU-8VT(FGA-5000)への移行について
Solaris1.x CPU-3CE/5CE/5TEからCPU-8VT(FGA-5000)への移行について
・概要
CPU-3CE/5CE/5TEはS4-VMEインターフェースを搭載しており、CPU-8VT(CPU-5V/5VT/7Vを含む)などのFGA-5000を搭載したCPUボードへ移行するには変更が必要です。
以下の機能を使用する場合は、変更が必要になります。
1.FGA-5000のDMA転送機能を使用する
2.デバイスドライバを作成してDVMA又はIOPB(スレーブボードからのDMA転送)を使用する
3.デバイスドライバを作成して2つの異なるVME空間を使用する(例えば A24,A16を同時に使うとき)
4.ユーザプログラムにてマスターウィンドウを切り替えて使用している
1. FGA-5000のDMA転送機能を使用する
CPU-3CE/5CE/5TE S4-VME搭載ボードではDMA転送の機能が無かった為、大容量のデータを転送を行う際にも、プログラム転送を使用していました。
大容量のデータを転送するときは、DMA転送を使用することをお勧めします。
移行するには今までプログラム転送を使用していた個所をDMA転送用へ置き換える等の必要があります。
以下に、変更点について示します。
a. 今まで read,writeシステムコールにてプログラム転送していた場合
DMA転送を行うときも、read,writeシステムコールを使用しますのでこの部分の変更はありません。
但し、プログラム転送のときに使用していたデバイスディスクリプタをDMA転送用に変更する必要と、DMA転送をする際の初期設定(DMAバッファの割り当て等)が合わせて必要になります。
b. 今まで mmapシステムコールを使用してポインタアクセスを使用していた場合
DMA転送を行うには、read,writeシステムコールを使用しますので置き換える必要があります。
今まで、ポインタアクセスを使用していた個所をread,writeシステムコールへ置き換え、
mmapシステムコールのときに使用していたデバイスディスクリプタをDMA転送用に変更する必要があります。
また、DMA転送をする際の初期設定(DMAバッファの割り当て等)が合わせて必要になります。
[DMA転送ルーチンの例]
/* ヘッダファイルのインクルード */
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sbusdev/vme.h>
main()
{
/* ioctl 構造体を定義 */
struct vme_ioctl_map vmeioctl;
/* 各変数の定義 */
int fd,len;
off_t addr;
caddr_t vaddr;
/* DMAデバイスのope? */
if((fd=open("/dev/vmedma32d32",O_RDWR))==-1){
perror("open");
return;
}
/* 転送アドレスを指定 VME A32D32 0x800000 */
addr = 0x800000;
/* 転送サイズを指定 1Mbytes */
len = 0x100000;
/* ioctlの引数にDMAバッファのサイズを代入 */
vmeioctl.data_size = len;
/* ioctlを実行しDMAバッファを割り当て */
if((ioctl(fd,VME_MAP_DMA,&vmeioctl))==-1){
perror("ioctl");
return;
}
/* DMA転送したデータを参照する為、DMAバッファのアドレスをマッピングします */
vaddr = mmap(0,vmeioctl.data_size,(PROT_READ | PROT_WRITE), MAP_SHARED,
fd, (off_t) (vme_ioctl_map.virt_addr));
if(vaddr == (caddr_t)-1){
perror("mmap");
}
/* lseekを使用して転送アドレスの 0x800000へ移動 */
lseek(fd,addr,SEEK_SET);
/* readシステムコールを使用してVMEアドレスよりDMA転送でデータ読み込みます2番目の引数 vmeioctl.virt_addrはioctlタ行桙ノ代入された仮想アドレスです*/
if(read(fd,vmeioctl.virt_addr,len)!=len){
perror("read");
return;
}
/* ioctlを実行しDMAバッファを解放します */
if((ioctl(fd,VME_UNMAP_DMA,&vmeioctl))==-1){
perror("ioctl");
return;
}
/* DMAバッファのマッピングを解放します */
munmap(vaddr,vmeioctl.data_size);
/* DMAデバイスをcloseします */
close(fd);
}
2.デバイスドライバを作成してDVMA又はIOPB(スレーブボードからのDMA転送)を使用する場合
CPU-3CE/5CE/5TEで従来g用していたドライバーでDVMAを使用する場合には、OPENBOOT上の環境変数の設定を変更する必要があります。
この設定をする事で、DVMAでのIOPB領域,DVMA領域の使用ができる様になります。
また、デバイスドライバの一部に修正が必要になります。
a. OPENBOOT上で設定する環境変数について
環境変数名
設定内容
vme-a24-slave-ena?
true
vme-a24-slave-addr
0
vme-a24-slave-size
1048576
設定手順
以下を入力します。
ok setenv vme-a24-slave-ena? true
ok setenv vme-a24-slave-addr 0
ok setenv vme-a24-slave-size 1048576
ok reset
b. デバイスドライバの変更内容について
VMEドライバでは、mbsetup,mbrelseルーチンにてユーザバッファのマップイン、マップアウトが行われないため手動にて行う必要があります。
タ際には、DVMAの設定を行う strategy,intrルーチン内に変更を加える必要があります。
以下に変更内容について示します。
strategyルーチン
strategy(bp)
{
…
…
bp_mapin(bp); /* ユーザバッファのマップイン */
xxx->bp = bp;
xxx->mbinfo = mbsetup(md->md_hd,bp,0); /* DVMAバッファのセットアップ */
…
…
}
intrルーチン
intr()
{
…
…
iodone(xxx->bp); /* バッファの転送終了 */
bp_mapout(bp); /* ユーザバッファのマップアウト */
mbrelse(md->md_hd,&xxx->mbinfo); /* DVMAバッファの解放 */
…
…
}
3. デバイスドライバを作成して2つの異なるVME空間を使用する(例えば A24,A16を同時に使うとき)
VMEbus上の2つのアクセス空間(例えばA32とA16の両方)をマッピングしたい場合には、GENERICファイル中の”flags”にアドレスを指定してドライバーからこのアドレスを取り込み、attachルーチンにて手動でマッピングをします。
CPU-8VT(CPU-5V/5VT/7Vを含む)では、マッピングする際にFGA-5000への設定が必要になります。
この設定については専用ルーチンが用意されていますので従来のattachルーチンに多少の変更をするだけで動作する様になります。
以下に、従来のルーチンと追加後のルーチンの例を示します。
従来のルーチン
xxattach(md)
struct mb_device *md;
{
register long mapindex;
register unsigned long pageval,off;
register caddr_t vaddr;
off = md->md_flags & PAGEOFFSET;
mapindex = rmalloc(kernelmap,(long)btoc(sizeof(xx_reg)));
vaddr = (caddr_t)((int)kmxtob(mapindex));
pageval = PGT_VME_D16 | btop(VME16_BASE);
segkmem_mapin(&kseg,(addr_t)vaddr,(u_int)(ptob(btoc(sizeof(xx_reg)))),
PROT_READ | PROT_WRITE,(u_int)pageval,0);
xx_addr = (caddr_t)vaddr + off;
}
変更後のルーチン
xxattach(md)
struct mb_device *md;
{
register long mapindex;
register unsigned long pageval,off;
register caddr_t vaddr;
off = md->md_flags & PAGEOFFSET;
mapindex = rmalloc(kernelmap,(long)btoc(sizeof(xx_reg)));
vaddr = (caddr_t)((int)kmxtob(mapindex));
pageval = vme_masterwin_setup(VME_BT_D16 | VME_BT_A16 | VME_BT_STD,
md->md_flags & PAGEMASK,sizeof(xx_reg));
segkmem_mapin(&kseg,(addr_t)vaddr,(u_int)(ptob(sizeof(xx_reg)))),
PROT_READ | PROT_WRITE,(u_int)pageval,0);
xx_addr = (caddr_t)vaddr + off;
}
変更後のルーチンの中にvme_masterwin_setupルーチンがあります。
このルーチンは、CPU-8VT(CPU-5V/5VT/7Vを含む)専用ルーチンであり、FGA-5000に必要な設定をするルーチンです。
上記の例では、A16:D16のマッピングをしていますが1番目の引数の内容を変えることで
その他のアドレス空間でのアクセスに可能となります。
以下にここで選択可能な内容について示します。
データ転送サイズ
VME_BT_D64 /* 64bit データ転送用 */
VME_BT_D32 /* 32bit 〃 */
VME_BT_D16 /* 16bit 〃 */
VME_BT_D8 /* 8bit 〃 */
アドレス空間
VME_BT_A64 /* 64bit アドレスw定 */
VME_BT_A32 /* 32bit 〃 */
VME_BT_A24 /* 24bit 〃 */
VME_BT_A16 /* 16bit 〃 */
アクセスモード
VME_BT_SSBLT /* Sbusスレーブ MBLT */
VME_BT_MBLT /* MBLT(VME64)*/
VME_BT_BLT /* BLT(ブロック転送)*/
VME_BT_STD /* 標準(VME32)*/
その他
VME_BT_WP /* 書き込み時のライトポストを有効にするモード */
4. ユーザプログラムにてマスターウィンドウを切り替えて使用している
CPU-3CE/5CE/5TEでは、256MBの境界を越えて使用する場合や、A32とA16,A24を切り替えて使用する場合にはユーザプログラム上でマスターウィンドウ(A32MAPREGの設定)を切り替えて使用する必要がありました。
CPU-8VT(CPU-5V/5VT/7Vを含む)のVMEドライバではユーザプログラムより切り替える必要は無くなりました。
これは、VMEインターフェースがS4-VMEからFGA-5000へ変更されマスターウィンドウが複数設定可能になったからです。
また、マスターウィンドウの設定はVMEドライバが行いますのでユーザプログラムからは、デバイスディスクリプタをopenして使用するだけになります。