Jun 21, 2000 onl50t: Solaris 2.6 cc ドライバのデバッグ. cc ドライバのデバッグ#03(その1) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (http://www-online.kek.jp/~inoue/CAMAC/ onl50t-sol2.6/Desktop/debug-step06.txt) 高エネルギー加速器研究機構 素粒子原子核研究所 物理、オンライングループ 井上 栄二 (1). 現状確認 (A). 株式会社ロジックハウスの白田様より SPARC CPU-50T を借用した。 (B). FORCE,CPU-50(UltraSPARC-IIi 300MHz)、に Solaris2.6 のシステムを インストールした。 (C). /etc の下の各設定、および /export/home の作成をやった。 (D). "Solaris2.6 Hardware: 5/98 SMCC Desktop 日本語版 SPARC版"では ディスクレス・クライアントを設定することはできないことを確認した。 (E). CPU-50T に Solaris2.6用の VMEドライバ、FRCvme-2.3.1 をインストール した。 (F). onl50t に ccドライバをインストールした。 (G). サンプル・プログラムを実行した。 (1). cam1、シングル・アクション 24ビット camac read/write の実行 NG. システムはパニックを起こしてリブートしてしまう。 (2). cam3、camac LAM割り込み処理の実行 NG. システムはパニックを起こしてリブートしてしまう。 (3). cam2、ブロック転送 16ビット read/write の実行 ok. 正常に実行できた。 (4). cam2、ブロック転送 24ビット read/write の実行 ok. 正常に実行できた。 (H). クラッシュ時の savecoreファイルを入手してデバッグを始めた。 (I). cam1プログラムのデバッグ、icc_ioctlルーチンを修正した。 ok. cam1プログラムは正常に実行できた。 (J). cam3プログラムのデバッグを始めた。 camac_s()ルーチンの中で "cc->k->dhr = *dat;" を実行したところでエラーになっている。 message構造体をcc_device構造体の中に入れてみたが改善されない。 (K). cam3プログラムは正常に動作できるようになった。 (L). cam3プログラムのデバッグ時に付加したゴミをはずして最終的な動作確認 をやった。 ok. (M). onl50t 上でデバッグしたcamacドライバをfrc7v-cl2 上で動作確認した。 ok. (N). onl50t 上でデバッグしたcamacドライバを onl7v2、スタンドアロン Solaris2.6 上で動作確認した。 ok. (O). onl50t 上でデバッグしたcamacドライバを frc8vt、ディスクレス・サーバ Solaris2.6 上で動作確認した。 ok. (P). onl50t 上でデバッグしたcamacドライバを onl8v1、スタンドアロン Solaris2.6 上で動作確認した。 ok. (Q). onl50t 上でデバッグしたcamacドライバを onl5v4、スタンドアロン Solaris2.6 上で動作確認した。 ok. (R). スタンドアロン Solaris2.6、onl50t 上で、シングルアクションの実行 速度を測定時に、camac_s()コールを連続実行すると不正割り込みが かかってしまった。 (S). camac_s()コールを連続実行しても不正割り込みはかからないように なった。 ok. (2). ここでやるべきこと ブロック転送read を実行した時、指定したワード数のデータが アプリケーションに届いていない件について調べる。 (3). 症状確認 症状を確認するために camac例題プログラム、cam2.f から修正したテスト用の プログラムを使って症状を再現してみる。 (3-1). cam2.f から変更してテスト用のプログラムを用意する onl50t[41]% pwd /export/home/onl50t/inoue/CAMAC/Driver/Kit-test/DMA onl50t[42]% ls Makefile cam3.c cc.c-maclo_hi-chk forlib.o README camlib.c cc.c-tmp fort.5 cam1* camlib.h cc.conf fort.6 cam1.c camlib.o cc.h k2917.h cam2* cc cc.h-org k2917.h-org cam2.f cc.c cc_common.h libcamac.a cam2.f-bak cc.c-bak cc_config.h script/ cam2.f-org cc.c-bak1 core cam3* cc.c-bak2 forlib.c onl50t[43]% vi cam2.f ******************************************************************** * cam2.f 8-OCT-1991 Y.Takeuchi * * * * Modified: * * 22-May-1997 E.Inoue set up of data * * * * CAMAC block action continuous test program * * SPARC SFVME-100 K2917 K3922 * ******************************************************************** integer i, j, loop, nword integer naf, nnaf, nn, na, nf integer mode, len, lenr, nerr, ndat(1000000) integer*2 ndats(1000000) CCC integer*2 ndats(60000) integer dat integer chk_f print 70 read(*, *) nword print 40 read(*, *) loop print 50 read(*, *) mode print 60 read(*, *) len call CAMOPN() call CGENZ() call CGENC() call CREMI() do 100 i = 1, loop dat = 0 do 600 j = 1, 66000 CCC if (nword .eq. 1) then ndats(j) = dat else ndat(j) = dat endif 600 continue print 10 read(*, *) nn, na, nf if (nf .ge. 16 .and. nf .lt. 24) then CCCC CCCC set up of 16bits data or 24 bits data. CCCC print 20 read(*, *) dat do 200 j = 1, len if (nword .eq. 1) then ndats(j) = dat else ndat(j) = dat endif 200 continue endif CCCCC nnaf = NAF(nn, na, nf) if (nword .eq. 1) then call CDMAW(mode, nnaf, ndats, len, lenr, nerr) else call CDMAL(mode, nnaf, ndat, len, lenr, nerr) endif print 30, mode, nn, na, nf, len, lenr, nerr print * do 300 j = 1, 10 CCC do 300 j = 1, len+3 if (nword .eq. 1) then print 35, j, ndats(j), ndats(j) else print 35, j, ndat(j), ndat(j) endif 300 continue do 500 j = lenr-3, lenr+3 if (nword .eq. 1) then print 80, j, ndats(j), ndats(j) else print 80, j, ndat(j), ndat(j) endif 500 continue chk_f = 0 do 400 j = 1, 66000 CCC do 400 j = 1, 60000 if (chk_f .ne. 1) then if (nword .eq. 1) then if (ndats(j) .eq. 0) then print 80, j-3, ndats(j-3), ndats(j-3) print 80, j-2, ndats(j-2), ndats(j-2) print 80, j-1, ndats(j-1), ndats(j-1) print 80, j, ndats(j), ndats(j) print 80, j+1, ndats(j+1), ndats(j+1) print 80, j+2, ndats(j+2), ndats(j+2) chk_f = 1 endif else if (ndats(j) .eq. 0) then print 80, j-3, ndats(j-3), ndats(j-3) print 80, j-2, ndats(j-2), ndats(j-2) print 80, j-1, ndats(j-1), ndats(j-1) print 80, j, ndats(j), ndats(j) print 80, j+1, ndats(j+1), ndats(j+1) print 80, j+2, ndats(j+2), ndats(j+2) chk_f = 1 endif endif endif 400 continue print * 100 continue call CAMCLS() stop 10 format('Input n a f >', $) 20 format('Input data >', $) 30 format(' MODE=', i1, ' N=', i2, ' A=', i2, ' F=', i2, $ ' len=', i5, ' lenr=', i5, ' error=', z2, '(Hex)') CCC 35 format('Data(',i2,')=', i, ' 0x', z, '(Hex)') 35 format('Data(',i6,')=', i, ' 0x', z, '(Hex)') 80 format('Data(',i6,')=', i, ' 0x', z, '(Hex)') 40 format('Input loop >', $) 50 format('Input mode (0:QSTOP 1:QIGNORE 2:QREPEAT 3:QSCAN) >', $) 60 format('Input data counts >', $) 70 format('Input transfer mode (1:word 2:long word) >', $) end onl50t[44]% onl50t[45]% make f77 -fast -O3 -u cam2.f -o cam2 -I. -L. -lcamac cam2.f: MAIN: onl50t[46]% (3-2). cam2 プログラム(修正版)を実行する onl50t[58]% cam2 Input transfer mode (1:word 2:long word) >1 Input loop >1 Input mode (0:QSTOP 1:QIGNORE 2:QREPEAT 3:QSCAN) >1 Input data counts >20 Input n a f >3 1 0 MODE=1 N= 3 A= 1 F= 0 len= 20 lenr= 20 error= 0(Hex) Data( 1)= 5 0x 5(Hex) Data( 2)= 5 0x 5(Hex) Data( 3)= 5 0x 5(Hex) Data( 4)= 5 0x 5(Hex) Data( 5)= 5 0x 5(Hex) Data( 6)= 5 0x 5(Hex) Data( 7)= 5 0x 5(Hex) Data( 8)= 5 0x 5(Hex) Data( 9)= 5 0x 5(Hex) Data( 10)= 5 0x 5(Hex) Data( 17)= 0 0x 0(Hex) Data( 18)= 0 0x 0(Hex) Data( 19)= 0 0x 0(Hex) Data( 20)= 0 0x 0(Hex) Data( 21)= 0 0x 0(Hex) Data( 22)= 0 0x 0(Hex) Data( 23)= 0 0x 0(Hex) Data( 8)= 5 0x 5(Hex) Data( 9)= 5 0x 5(Hex) Data( 10)= 5 0x 5(Hex) Data( 11)= 0 0x 0(Hex) Data( 12)= 0 0x 0(Hex) Data( 13)= 0 0x 0(Hex) Note: Nonstandard floating-point mode enabled See the Numerical Computation Guide, ieee_sun(3M) onl50t[59]% 転送ワード数を 20 と指定したのに、アプリケーションプログラムには 10 しか 届いていない。 (4). DMA 転送完了の Done割り込みがかかった時の状況を調べる (4-1). Done割り込みがかかった時の K2917 のレジスタの値を調べる : static u_int cc_intr(int unit) { /* register struct cc_device *cc = &ccdevice[0]; */ register struct cc_device *cc; /* register struct K_REG *k = cc->k; */ cc = ddi_get_soft_state(cc_state,unit); camac_b(int unit, u_short mode, u_short naf, int len, int *retlen) { register struct cc_device *cc; register dev_t dev; /* register struct K_REG *k = cc->k; */ /* register struct uio *uio = cc->uio; */ register struct uio *uio; cc = ddi_get_soft_state(cc_state,unit); dev = cc->dev; uio = cc->uio; cc->klist = CC_KLIST_NO; cc->mode = mode; cc->naf = naf; cc->len = len; /* set uio for DMA */ mutex_enter(&cc->mutex); /* start MUTEX */ /* check K2917 register */ if ((cc->k->csr & CC_LAM) != 0) cc->interrupt |= CC_INT_LAM; if ((cc->k->csr & CC_DONE) != 0) cc->interrupt |= CC_INT_DONE; if ((cc->k->empc & CC_INT_ENABLE) == 0) cc->interrupt |= CC_INT_EMPTY; if ((cc->k->aboc & CC_INT_ENABLE) == 0) cc->interrupt |= CC_INT_ABORT; cmn_err(CE_NOTE," cc_intr: 0x%x", cc->interrupt); /* free DMA resources */ if (cc->executing_dma_flag != 0) { : onl50t[93]% cam2 Input transfer mode (1:word 2:long word) >1 Input loop >1 Input mode (0:QSTOP 1:QIGNORE 2:QREPEAT 3:QSCAN) >1 Input data counts >20 Input n a f >3 1 0 MODE=1 N= 3 A= 1 F= 0 len= 20 lenr= 20 error= 0(Hex) Data( 1)= 5 0x 5(Hex) Data( 2)= 5 0x 5(Hex) Data( 3)= 5 0x 5(Hex) Data( 4)= 5 0x 5(Hex) Data( 5)= 5 0x 5(Hex) Data( 6)= 5 0x 5(Hex) Data( 7)= 5 0x 5(Hex) Data( 8)= 5 0x 5(Hex) Data( 9)= 5 0x 5(Hex) Data( 10)= 5 0x 5(Hex) Data( 17)= 5 0x 5(Hex) Data( 18)= 5 0x 5(Hex) Data( 19)= 5 0x 5(Hex) Data( 20)= 5 0x 5(Hex) Data( 21)= 0 0x 0(Hex) Data( 22)= 0 0x 0(Hex) Data( 23)= 0 0x 0(Hex) Data( 18)= 5 0x 5(Hex) Data( 19)= 5 0x 5(Hex) Data( 20)= 5 0x 5(Hex) Data( 21)= 0 0x 0(Hex) Data( 22)= 0 0x 0(Hex) Data( 23)= 0 0x 0(Hex) Note: Nonstandard floating-point mode enabled See the Numerical Computation Guide, ieee_sun(3M) onl50t[94]% NOTICE: cc_intr: 0xc cc.cファイルの cc_intr() に cmn_err()ルーチンを1行入れたら、読み出した データは指定した 20ワード全てがアプリケーションプログラムに届いた。 この時、cc->interrupt変数には "0xc" の値がセットされた。 onl50t[56]% grep CC_INT_LAM *.h cc.h:#define CC_INT_LAM 1 onl50t[57]% grep CC_INT_DONE *.h cc.h:#define CC_INT_DONE 2 onl50t[58]% grep CC_INT_EMPTY *.h cc.h:#define CC_INT_EMPTY 4 onl50t[59]% grep CC_INT_ABORT *.h cc.h:#define CC_INT_ABORT 8 onl50t[60]% "0xc" の値は、CC_INT_EMPTY で CC_INT_ABORT により割り込みがかかった ことを意味している。 (4-2). cc->k->csr の Doneビットが立つまで待つように変更してみる DMAを実行する場合にだけcc->k->csr の Doneビットが立つまで待つように変更 してみる。 : if ((cc->k->aboc & CC_INT_ENABLE) == 0) cc->interrupt |= CC_INT_ABORT; cmn_err(CE_NOTE," cc_intr: 0x%x", cc->interrupt); /* free DMA resources */ if (cc->executing_dma_flag != 0) { chk_done = 0xffffffff; while (chk_done-- > 0){ if ((cc->k->csr & CC_DONE) != 0) cc->interrupt |= CC_INT_DONE; break; } /* change logichouse */ /* ddi_dma_free(cc->handle); : onl50t[108]% cam2 Input transfer mode (1:word 2:long word) >1 Input loop >1 Input mode (0:QSTOP 1:QIGNORE 2:QREPEAT 3:QSCAN) >1 Input data counts >20 Input n a f >3 1 0 MODE=1 N= 3 A= 1 F= 0 len= 20 lenr= 20 error= 0(Hex) Data( 1)= 5 0x 5(Hex) Data( 2)= 5 0x 5(Hex) Data( 3)= 5 0x 5(Hex) Data( 4)= 5 0x 5(Hex) Data( 5)= 5 0x 5(Hex) Data( 6)= 5 0x 5(Hex) Data( 7)= 5 0x 5(Hex) Data( 8)= 5 0x 5(Hex) Data( 9)= 5 0x 5(Hex) Data( 10)= 5 0x 5(Hex) Data( 17)= 5 0x 5(Hex) Data( 18)= 5 0x 5(Hex) Data( 19)= 5 0x 5(Hex) Data( 20)= 5 0x 5(Hex) Data( 21)= 0 0x 0(Hex) Data( 22)= 0 0x 0(Hex) Data( 23)= 0 0x 0(Hex) Data( 18)= 5 0x 5(Hex) Data( 19)= 5 0x 5(Hex) Data( 20)= 5 0x 5(Hex) Data( 21)= 0 0x 0(Hex) Data( 22)= 0 0x 0(Hex) Data( 23)= 0 0x 0(Hex) Note: Nonstandard floating-point mode enabled See the Numerical Computation Guide, ieee_sun(3M) onl50t[109]% cam2 Input transfer mode (1:word 2:long word) >1 Input loop >1 Input mode (0:QSTOP 1:QIGNORE 2:QREPEAT 3:QSCAN) >1 Input data counts >32000 Input n a f >3 1 0 MODE=1 N= 3 A= 1 F= 0 len=32000 lenr=32000 error= 0(Hex) Data( 1)= 5 0x 5(Hex) Data( 2)= 5 0x 5(Hex) Data( 3)= 5 0x 5(Hex) Data( 4)= 5 0x 5(Hex) Data( 5)= 5 0x 5(Hex) Data( 6)= 5 0x 5(Hex) Data( 7)= 5 0x 5(Hex) Data( 8)= 5 0x 5(Hex) Data( 9)= 5 0x 5(Hex) Data( 10)= 5 0x 5(Hex) Data( 31997)= 5 0x 5(Hex) Data( 31998)= 5 0x 5(Hex) Data( 31999)= 5 0x 5(Hex) Data( 32000)= 5 0x 5(Hex) Data( 32001)= 0 0x 0(Hex) Data( 32002)= 0 0x 0(Hex) Data( 32003)= 0 0x 0(Hex) Data( 31998)= 5 0x 5(Hex) Data( 31999)= 5 0x 5(Hex) Data( 32000)= 5 0x 5(Hex) Data( 32001)= 0 0x 0(Hex) Data( 32002)= 0 0x 0(Hex) Data( 32003)= 0 0x 0(Hex) Note: Nonstandard floating-point mode enabled See the Numerical Computation Guide, ieee_sun(3M) onl50t[110]% cam2 Input transfer mode (1:word 2:long word) >1 Input loop >1 Input mode (0:QSTOP 1:QIGNORE 2:QREPEAT 3:QSCAN) >1 Input data counts >32800 Input n a f >3 1 0 MODE=1 N= 3 A= 1 F= 0 len=32800 lenr=32800 error= 0(Hex) Data( 1)= 5 0x 5(Hex) Data( 2)= 5 0x 5(Hex) Data( 3)= 5 0x 5(Hex) Data( 4)= 5 0x 5(Hex) Data( 5)= 5 0x 5(Hex) Data( 6)= 5 0x 5(Hex) Data( 7)= 5 0x 5(Hex) Data( 8)= 5 0x 5(Hex) Data( 9)= 5 0x 5(Hex) Data( 10)= 5 0x 5(Hex) Data( 32797)= 5 0x 5(Hex) Data( 32798)= 5 0x 5(Hex) Data( 32799)= 5 0x 5(Hex) Data( 32800)= 5 0x 5(Hex) Data( 32801)= 5 0x 5(Hex) Data( 32802)= 5 0x 5(Hex) Data( 32803)= 5 0x 5(Hex) Data( 33002)= 5 0x 5(Hex) Data( 33003)= 5 0x 5(Hex) Data( 33004)= 5 0x 5(Hex) Data( 33005)= 0 0x 0(Hex) Data( 33006)= 0 0x 0(Hex) Data( 33007)= 0 0x 0(Hex) Note: Nonstandard floating-point mode enabled See the Numerical Computation Guide, ieee_sun(3M) onl50t[111]% NOTICE: cc_intr: 0xe NOTICE: cc_intr: 0xe NOTICE: cc_intr: 0xe NOTICE: cc_intr: 0xe 転送ワード数が 32000 くらいまでは指定したワード数だけ正しく読み出せて いる。 しかし、それ以上のワード数を読み出そうとすると、指定したワード数 よりも多くの数のデータがアプリケーションに届いている。 (4-3). DMA に関係する情報をチェック : if((ddi_dma_buf_bind_handle(cc->handle, bp , flags | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, (caddr_t)0, &cc->dma_cookie, &cc->ccount) != DDI_DMA_MAPPED)){ cmn_err(CE_WARN,"cc_strategy: ddi_dma_buf_bind_handle failed"); bp->b_flags |= B_ERROR; bp->b_error = EIO; return bp->b_flags; } cmn_err(CE_NOTE," cc_strategy: cc->ccount = 0x%x, %d", cc->ccount, cc->ccoun t); cmn_err(CE_NOTE," cc_strategy: cc->dma_cookie.dmac_address = 0x%x", cc->dma_ cookie.dmac_address); cmn_err(CE_NOTE," cc_strategy: cc->dma_cookie.dmac_size = 0x%x, %d", cc->dma _cookie.dmac_size, cc->dma_cookie.dmac_size); : onl50t[50]% cam2 Input transfer mode (1:word 2:long word) >1 Input loop >1 Input mode (0:QSTOP 1:QIGNORE 2:QREPEAT 3:QSCAN) >1 Input data counts >32000 Input n a f >3 1 0 MODE=1 N= 3 A= 1 F= 0 len=32000 lenr=32000 error= 0(Hex) Data( 1)= 5 0x 5(Hex) Data( 2)= 5 0x 5(Hex) Data( 3)= 5 0x 5(Hex) Data( 4)= 5 0x 5(Hex) Data( 5)= 5 0x 5(Hex) Data( 6)= 5 0x 5(Hex) Data( 7)= 5 0x 5(Hex) Data( 8)= 5 0x 5(Hex) Data( 9)= 5 0x 5(Hex) Data( 10)= 5 0x 5(Hex) Data( 31997)= 5 0x 5(Hex) Data( 31998)= 5 0x 5(Hex) Data( 31999)= 5 0x 5(Hex) Data( 32000)= 5 0x 5(Hex) Data( 32001)= 0 0x 0(Hex) Data( 32002)= 0 0x 0(Hex) Data( 32003)= 0 0x 0(Hex) Data( 31998)= 5 0x 5(Hex) Data( 31999)= 5 0x 5(Hex) Data( 32000)= 5 0x 5(Hex) Data( 32001)= 0 0x 0(Hex) Data( 32002)= 0 0x 0(Hex) Data( 32003)= 0 0x 0(Hex) Note: Nonstandard floating-point mode enabled See the Numerical Computation Guide, ieee_sun(3M) onl50t[51]% cam2 Input transfer mode (1:word 2:long word) >1 Input loop >1 Input mode (0:QSTOP 1:QIGNORE 2:QREPEAT 3:QSCAN) >1 Input data counts >33000 Input n a f >3 1 0 MODE=1 N= 3 A= 1 F= 0 len=33000 lenr=33000 error= 0(Hex) Data( 1)= 5 0x 5(Hex) Data( 2)= 5 0x 5(Hex) Data( 3)= 5 0x 5(Hex) Data( 4)= 5 0x 5(Hex) Data( 5)= 5 0x 5(Hex) Data( 6)= 5 0x 5(Hex) Data( 7)= 5 0x 5(Hex) Data( 8)= 5 0x 5(Hex) Data( 9)= 5 0x 5(Hex) Data( 10)= 5 0x 5(Hex) Data( 32997)= 5 0x 5(Hex) Data( 32998)= 5 0x 5(Hex) Data( 32999)= 5 0x 5(Hex) Data( 33000)= 5 0x 5(Hex) Data( 33001)= 5 0x 5(Hex) Data( 33002)= 5 0x 5(Hex) Data( 33003)= 5 0x 5(Hex) Data( 37058)= 5 0x 5(Hex) Data( 37059)= 5 0x 5(Hex) Data( 37060)= 5 0x 5(Hex) Data( 37061)= 0 0x 0(Hex) Data( 37062)= 0 0x 0(Hex) Data( 37063)= 0 0x 0(Hex) Note: Nonstandard floating-point mode enabled See the Numerical Computation Guide, ieee_sun(3M) onl50t[52]% <<< データ数 32000 を読み出した時のコンソール上のメッセージ >>> onl50t console login: onl50t console login: NOTICE: cc_strategy: cc->ccount = 0x1, 1 NOTICE: cc_strategy: cc->dma_cookie.dmac_address = 0x1e78 NOTICE: cc_strategy: cc->dma_cookie.dmac_size = 0xfa00, 64000 NOTICE: cc_intr: 0xe onl50t console login: <<< データ数 33000 を読み出した時のコンソール上のメッセージ >>> onl50t console login: onl50t console login: NOTICE: cc_strategy: cc->ccount = 0x1, 1 NOTICE: cc_strategy: cc->dma_cookie.dmac_address = 0x1e78 NOTICE: cc_strategy: cc->dma_cookie.dmac_size = 0x10000, 65536 NOTICE: cc_intr: 0xe NOTICE: cc_strategy: cc->ccount = 0x1, 1 NOTICE: cc_strategy: cc->dma_cookie.dmac_address = 0x1e78 NOTICE: cc_strategy: cc->dma_cookie.dmac_size = 0x1d0, 464 NOTICE: cc_intr: 0xe onl50t console login: データ数 32000 を読み出した時は、cc_strategyルーチンは一度しか実行 されていない。 この場合は、指定したデータ数 32000ワード分が正しく 読み出されている。 データ数 33000 を読み出した時は、cc_strategyルーチンが二度実行されて いる。 この場合は、一度目は 65536バイト用の資源が用意され、その後で 二度目の cc_strategyルーチンのコールで 464バイト用の資源が用意されて いる。合わせて 66000バイト分の資源が用意されている。 しかし、 アプリケーションには指定したデータ数よりも多い、37060ワードが届いて いる。 (4-4). DMA attributes をチェック ---xxxx ここまでやった(継続中) --- (6). 項目タイトル (6-1). サブ項目タイトル (6-1-1). サブサブ項目タイトル