Go to main content
Oracle® Solaris 11.3 デバイスドライバの記述

印刷ビューの終了

更新: 2016 年 11 月
 
 

デバイスメモリー

プログラム式入出力をサポートするデバイスには、デバイスのアドレス指定可能領域にマップされるバスアドレス空間の 1 つ以上の領域が割り当てられます。これらのマッピングは、デバイスに関連付けられた reg プロパティー内の値ペアとして記述されます。各値ペアはバスアドレスの 1 つのセグメントを記述します。

ドライバは、特定のバスアドレスマッピングを特定するために、レジスタ番号または regspec を指定します。この番号は、デバイスの reg プロパティー内でのインデックスです。reg プロパティーは、デバイスの busaddrsize を特定します。ドライバは、ddi_regs_map_setup(9F) などの DDI 関数を呼び出すときに、このレジスタ番号を渡します。ドライバ内で、デバイスに割り当てられたマップ可能領域の個数を判定するには、ddi_dev_nregs(9F) を呼び出します。

デバイスとホストのエンディアンの違いの管理

ホストのデータ形式は、デバイスのデータ形式とは異なるエンディアン特性を備えている可能性があります。そのような場合、ホストとデバイスとの間で転送されるデータをバイトスワップすることで、転送先のデータ形式の要件に合わせる必要があります。ホストと同じエンディアン特性を備えたデバイスでは、データのバイトスワップを行う必要はありません。

ドライバでデバイスのエンディアン特性を指定するには、ddi_regs_map_setup(9F) に渡される ddi_device_acc_attr(9S) 構造体の対応するフラグを設定します。そうした場合、ドライバが ddi_get8(9F) などの ddi_getX ルーチンや ddi_put16(9F) などの ddi_putX ルーチンを呼び出してデバイスメモリーに対する読み書きを行うときに、DDI フレームワークによって必要なバイトスワップがすべて実行されます。

データ順序付け要件の管理

各プラットフォームでは、データのロードや格納の順序を変更することでパフォーマンスを最適化できます。デバイスによっては順序変更が許されない場合もあるため、ドライバでデバイスへのマッピングを設定する際にデバイスの順序付け要件を指定する必要があります。

ddi_device_acc_attr 構造体

この構造体は、デバイスのエンディアン要件とデータ順序要件を記述します。ドライバは、この構造体を初期化し、ddi_regs_map_setup(9F) の引数として渡す必要があります。

typedef struct ddi_device_acc_attr {
    ushort_t    devacc_attr_version;
    uchar_t     devacc_attr_endian_flags;
    uchar_t     devacc_attr_dataorder;
} ddi_device_acc_attr_t;
devacc_attr_version

DDI_DEVICE_ATTR_V0 を指定します。

devacc_attr_endian_flags

デバイスのエンディアン特性を記述します。ビット値として指定され、使用可能な値は次のとおりです。

  • DDI_NEVERSWAP_ACC – データのスワップを一切行わない

  • DDI_STRUCTURE_BE_ACC – デバイスのデータ形式がビッグエンディアンである

  • DDI_STRUCTURE_LE_ACC – デバイスのデータ形式がリトルエンディアンである

devacc_attr_dataorder

CPU がデバイスから要求されたデータを参照する際に従うべき順序を記述します。列挙値として指定されます。ただし、データアクセス制限は、厳格度の高いものから順に並べられます。

  • DDI_STRICTORDER_ACC – ホストは、プログラマによって指定された順番で参照を発行する必要があります。このフラグがデフォルトの動作です。

  • DDI_UNORDERED_OK_ACC – ホストは、デバイスメモリーに対するロードや格納の順序を変更できます。

  • DDI_MERGING_OK_ACC – ホストは、個々の格納をマージして連続する場所にまとめることができます。この設定では暗黙的に順序変更も許可されます。

  • DDI_LOADCACHING_OK_ACC – 格納が発生するまで、ホストはデバイスからデータを読み取ることができます。

  • DDI_STORECACHING_OK_ACC – ホストは、デバイスに書き込むデータをキャッシュに格納しておくことができます。このときホストは、デバイスへのデータ書き込みを、将来必要になるまで遅らせることができます。


注 - システムは、ドライバで devacc_attr_dataorder に指定されているよりも厳格に、データへのアクセスを行うことができます。厳格なデータ順序付けからキャッシュ格納へと移る間、ドライバによるデータアクセスに関してホストの制限が小さくなります。

デバイスメモリーのマッピング

ドライバは通常、attach(9E) の実行中にデバイスのすべての領域をマップします。ドライバ内でデバイスメモリーの 1 つの領域をマップするには、そのマップする領域のレジスタ番号、領域のデバイスアクセス属性、オフセット、およびサイズを指定して ddi_regs_map_setup(9F) を呼び出します。DDI フレームワークは、そのデバイス領域のマッピングを設定し、不透明なハンドルをドライバに返します。このデータアクセスハンドルは、デバイスのその領域からデータを読み取ったりその領域にデータを書き込んだりする際に、ddi_get8(9F) または ddi_put8(9F) ルーチンファミリの引数として渡されます。

ドライバは、デバイスマッピングの形式がドライバで求められる形式と一致しているかどうかを確認するために、デバイスからエクスポートされたマッピングの数をチェックします。ドライバは、ddi_dev_nregs(9F) を呼び出したあと、各マッピングのサイズを確認するために ddi_dev_regsize(9F) を呼び出します。

マッピングの設定例

次に、DDI データアクセスインタフェースの簡単な例を示します。このドライバは、一度に 1 つの文字を受け付け、次の文字の受け付け準備が整ったら割り込みを生成するような、架空のリトルエンディアンデバイスに対するものです。このデバイスには 2 つのレジスタセットが実装されています。1 つは 8 ビット CSR レジスタ、もう 1 つは 8 ビットデータレジスタです。

使用例 15  マッピングの設定
#define CSR_REG 0
#define DATA_REG 1
/*
 * Initialize the device access attributes for the register
 * mapping
 */
dev_acc_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
dev_acc_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
dev_acc_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
/*
 * Map in the csr register (register 0)
 */
if (ddi_regs_map_setup(dip, CSR_REG, (caddr_t *)&(pio_p->csr), 0,
  sizeof (Pio_csr), &dev_acc_attr, &pio_p->csr_handle) != DDI_SUCCESS) {
    mutex_destroy(&pio_p->mutex);
    ddi_soft_state_free(pio_softstate, instance);
    return (DDI_FAILURE);
}
/*
 * Map in the data register (register 1)
 */
if (ddi_regs_map_setup(dip, DATA_REG, (caddr_t *)&(pio_p->data), 0,
  sizeof (uchar_t), &dev_acc_attr, &pio_p->data_handle) \
  != DDI_SUCCESS) {
    mutex_destroy(&pio_p->mutex);
    ddi_regs_map_free(&pio_p->csr_handle);
    ddi_soft_state_free(pio_softstate, instance);
    return (DDI_FAILURE);
}