1. HOME
  2. FAQ
  3. CPU-50 割り込みハンドリングについて

FAQ

CPU-50 割り込みハンドリングについて

  • 概要

CPU-50ではRORAにて割り込み開放するには、オールベクター割り込みを
使用する必要があります。
これは、VMEDriverユーザーズ・マニュアルにも記載されている事項でもあり、
Universeを搭載したCPU-50にてRORAの割り込み開放機能をするには
割り込みハンドリングルーチン等を変更する必要があります。

  • 解説

Universeの仕様により割り込みハンドリング桙ノIACKサイクルが終了すると
内部の割り込みステータスレジスタの内容がクリアされます。
このとき、Universeは内部の割り込みステータスレジスタのビットがクリアされていて、
VMEbus上でまだ、IRQxラインがアサートされていると、次の割り込みが入ったと判断してしまいます。
このため、Universeの割り込みステータスレジスタのビットがクリアされる前に、
割り込みサービスルーチンにてRORAで割り込み開放が出来ないと
次のIACKサイクルが開始されてしまい、ベクター無しの割り込みが起きてしまいます。

  • 対策

RORAにて割り込み開放する際には、ベクター無し割り込みを使用する必要があります。

  • VMEでベクター割り込みを使用するときは
割り込みハンドリングルーチン起動 (VMEドライバ)

                 ↓

割り込みベクタの取得 (VMEドライバ)

                 ↓

ベクターに対応した割り込みサービスルーチン起動 (VMEドライバ)

                 ↓

割り込みサービスルーチン実行 (Leafドライバ)

の順番で実行されます。

  • VMEでベクター無しの割り込みを使用するときには
割り込みハンドリングルーチン起動 (VMEドライバ)

                 ↓

割り込みサービスルーチン起動 (VMEドライバ)

                 ↓

割り込みベクターの取得 (Leafドライバでdi_intr_acknowledge()を呼び出す)

                 ↓

ベクターに対応した割り込みサービスルーチンを起動 (Leafドライバ)

                 ↓

割り込みサービスルーチン実行 (Leafドライバ)

の順番で実行されます。

[ドライバ設定ファイルの変更]

ベクター無しの割り込みを使用する際には、xxx.confファイルの
”interrupts"プロパティのベクターに"-1"を指定します。
また、ベクター定義用に"vector"プロパティを用意します。

※ドライバ内にddi_getlong_prop()を使用してプロパティを取得する必要があります。
 

コンフィギュレーションファイルの例

name="pvme332" class="vme"
reg=0x2d,0x6000,24
interrupts=1,-1
vector=0xc0,0xc1;

[ドライバ変更について]

vdi_intr_acknowledge()を呼び出すには、VMEドライバの機能をインクルードする必要があります。

ソースコードの最初の方に追加します。



#include <sys/ddi.h>
#include <sys/sunddi.h> #include <sys/vdi.h>  <- VMEドライバのインクルードファイル


/* Support Force VMEDriver function */ char _depends_on[]="drv/VME";

    

割り込みサービスルーチン等の変更について

attachルーチンにて



ddi_add_intr(dip,0,&pvme332->iblock_cookie1,
&pvme332->idevice_cookie1,pvme332_intr,(caddr_t)0) <- 引数6には、割り込みプロパティ番号を代入します。 …

ddi_getlongprop(DDI_DEV_T_NONE,dip,0,"vector",
(caddr_t)&pvme332->vector,&len)  <- コンフィグレーションファイル中の”vector”より読み込みます。

…    

intrルーチンにて


static u_int pvme332_intr(int arg)
{
    register pvme332device *pvme332;
    register int vec;     pvme332 = ddi_get_soft_state(pvme332_state,unit);     mutex_enter(&pvme332->mutex);     if(pvme332->pvme332reg->intstat != INT_STS_ASRT){  <- 割り込みをクリアする。
      return (DDI_INTR_UNCLAIMED);
    }     vec = vdi_intr_acknowledge(pvme332->pvme332dip,arg);  <- 割り込みベクタを得る。
    if(vec != VDI_SUCCESS){
      if(vec == VDI_FAILURE)
        cmn_err(CE_WARN,"pvme332_intr() IACK cycle BusErr or Timeout");
    }     pvme332->pv_busy &= ~PVME332_INTR_BUSY;     pvme332->pvme332reg->intcntrl = INTR_DIS;     if(vec == pvme332->vector->vect1){  <- 各ベクターに対応した割り込みサービスルーチンを実行する。
       pvme332intr1();
    } else
      if(vec == pvme332->vector->vect2){
        pvme332intr2();
      } else
      if(vec == pvme332->vector->vect3){
        pvme332intr3();
    }     cv_broadcast(&pvme332->pv_cv);
    mutex_exit(&pvme332->mutex);     return (DDI_INTR_CLAIMED);
}