使い方

概要説明
ダウンロード
使い方
関数一覧
もっと知りたい

DLLの中には以下の関数が含まれています。とにかく使用してみたいという方はこの説明と関数一覧を見て使用してみてください。Win32アプリから使用できます。

DLLの状態判定

PCIバス情報取得関数

PCIデバイス検索関数

コンフィグレーションレジスタアクセス関数

メモリーアクセス関数

IOアクセス関数

割り込み

NT特有の事情

Visual C++からの利用方法

95/98のリソースの割り当て

関数一覧

 

DLLの状態判定

アプリケーションが開始し、DLLが読み込まれた時にデバイスドライバーの組みなど初期化動作をします。プログラムの初めにgetdllstatus()を呼び出してこの処理が正常に終了しDLLが動作できる常態かどうか確認します。

DLLSTATUS_NOERROR(値0)以外を返した場合は正常に動作してないことを表します。

デバイスドライバーのファイルが無い場合やNTadministratorまたはその権限を持っているユーザーでない場合ドライバーの組み込みができないためDLLSTATUS_DRIVERNOTLOADEDを返します。

PCIバス情報取得関数

PCI BIOSにはバスの情報を取得する関数がいろいろ用意されていますがこのDLLでは、PCIバスの数を調べる関数だけ実装しています。

PCIデバイス検索関数

ベンダーID,デバイスIDや、クラスコードが一致するデバイスを検索し、PCIデバイスアドレスを求める為に使用します。同じカードが複数有る場合は引数のIndex値を変えて呼び出せば2枚目以降のカードを探すことができます。

コンフィグレーションレジスタアクセス関数

PCIデバイスのコンフィグレーション空間の値を読み書きします。

PCIデバイスは、バス番号、スロット番号、ファンクション番号を16ビットにまとめたPCIアドレスを使います。

32bit, 16bit, 8bit単位で読み書きのバリエーションがあり6個の関数が用意されています。

メモリーアクセス関数

指定した物理アドレスのメモリーを読み書きします。

アクセスの単位(32bit, 16bit, 8bit)連続又は1ワード、読み書きのバリエーションがあり12個の関数が用意されています。

PCIデバイスのメモリー空間にアクセスする場合は、そのデバイスのベースアドレスレジスターの値から物理アドレス先頭アドレスを調べて使用します。

PCIバスにはバースト転送のモードがありますが、連続アクセスが必ずしもバースト転送になるわけではありません。また1ワードアクセスが必ずシングル転送になるわけでもありません。

多くのCPU-PCIブリッジでは連続したアドレスに書き込みを行うとバースト転送するように実装されています。リードの場合にバースト転送にCPU−PCIブリッジは無い様です。

 

IOアクセス関数

任意のI/O空間の値を読み書きします。

X86アーキテクチャーではPCIバスのI/O空間もISAバスも同じ空間になるのでISAデバイスにもアクセスできます。アクセス単位(32bit, 16bit, 8bit)と読み書きの組み合わせて6個の関数があります

PCIデバイスのI/O空間にアクセスする場合は、そのデバイスのベースアドレスレジスターの値を調べそれをオフセット値として使用します。

 

割り込み

PCIデバイスからの割り込みを受け取るために3つの関数を提供します。DOS用ライブラリと同じ用に使える_hookIRQ() ,_freeIRQ()とOSがNTの場合は、引数を拡張した _hookIRQ_NT()が使用できます。

基本的には、割り込みハンドラー関数を作成してその関数へのポインターと割り込みの番号を渡します。

割り込みハンドラー関数は

void WINAPI isr(void);

の型とします。他の言語からも利用可能なように呼び出し規約を_stdcall(WINAPI)型にしています。

割り込みの番号はコンフィグレーションレジスタの0x3Cの値を読み出して調べます。

使用し終わったときには_freeIRQ()又は、割り込みハンドラー関数をNULLとして_hookIRQ()や_hookIRQ_NT()を呼び出します。

複数回_hookIRQ()を呼び出すと最後に呼び出した_hookIRQが有効で、その前の_hookIRQ呼び出しで登録した割り込みは取り消されます。

割り込みに関しては一つ制限事項があります。PCIの仕様では割り込みの共有ができるのですが、_hookIRQ()でハンドルする割り込みは共有することができません。詳しくは後のNT用ドライバーの説明を参照してください。

NT特有の事情

割り込みハンドラーの登録に_hookIRQ_NT()が用意されています。NTの割り込み処理部分は、割り込みを区別するのに、割り込み番号の他にバスの種類、バス番号を使用できるようになっています。例えば割り込みの指定にIRQの5を指定するだけでなく、PCIバス2のIRQ5のような指定をするわけです。こうすることで、PCIバス1のIRQ5を区別することができます。

ほとんどのPC/AT互換機のWindows NTではIRQ0〜15の番号のみで区別している様子です。

しかし、機種によっては、割り込みの番号だけでなくバスの種類やバス番号を区別する場合があります。筆者の確認したAPICに対応した機種ではバスの種類を区別していました。

_hookIRQは_hookIRQ_NT(PCIBus, 0, 0, LevelSensitive, NULL)と同じ働きをします。バスの種類や、バス番号を変えたい場合は_hookIRQ_NTを使用します。

98/95でこの関数を使用しても_hookIRQと動作はかわりません。

Visual C++からの利用方法

pcidebug.dllWin32アプリケーションから呼び出して使用します。通常のDLLと使い方は同じです。関数のプロトタイプの含まれているpcifunc.hをインクルードし、pcidebug.libをリンクするように指定します。

出来あがったアプリケーションと同じディレクトリにpcidebug.dllpcidebug.sys, pcidbg95.vxdをコピーして実行する。

95/98のリソースの割り当て

PC/ATでは電源投入時にBIOSが起動しPCIデバイスのコンフィグレーションを行います。この段階でデバイスが要求したメモリー、I/O、割り込みなどが割り当てられます。BIOSによっては起動時にこの割り当て状況が表示されるので確認できるでしょう。

この設定が基本的にはOSに引き継がれるのですが、OSR2以降のWindows95Windows98では、デバイスドライバーを組み込んでいないデバイスにはリソースの割り当てを取り消してしまうようです。この状態ではデバイスは動作しません。

動作させるには2つの方法があります。一つは、コンフィグレーション空間を書きかえる方法です。後で紹介するPCIWATCHを使用すればコンフィグレーションレジスターを書きかえる事ができます。システムの未使用のメモリー空間、I/O空間、割り込みをあらかじめ調べておきその値をベースアドレスレジスタに設定します。その後、デバイス制御レジスターのメモリー空間、I/O空間イネーブルのビットをそれぞれ1にします。これでアクセスが可能になります。

もう一つは、INFファイルを用意してシステムにデバイスを認識させる方法です。INFファイルはデバイスドライバーをインストールするために使用しますが、デバイスドライバーをコピーする動作以外にもシステムにデバイスの存在を認識させる働きもあります。ファイルをコピーや、レジストリー修正の項目がなくデバイスを認識させるだけの働きを持つINFファイルを作成ます。INFファイルはDDKに含まれるINFEDIT.EXEを使用すると簡単に作成できますが簡単なテキストファイルなのでテキストエディターでリスト2を修正して作成する事もできるでしょう。

[Version]
Signature=$CHICAGO$
Class=PCITEST
Provider=%String0%

[ClassInstall]

[DestinationDirs]

[Manufacturer]
%String1%=SECTION_0

[SECTION_0]
%String2%=NO_DRV,PCI\VEN_4949&DEV_7777

[NO_DRV]

[ControlFlags]

[Strings]
String0="xxxsoft"
String1="xxxsoft"
String2="pcitestbord"

注)VEN_の後の4桁の文字は、PCIデバイスのベンダーIDに、DEV_の後の文字はデバイスIDを記入する。

リスト2 PCIデバイス認識用INFファイル

PCIデバイスを取り付けでWindows98を起動すると、ドライバーのインストールが開始されます。リスト2を元に作成したINFファイルの場所を指定してインストールを進めると、デバイスが認識されデバイスマネージャー表示されます

この状態ではデバイスにリソースが割り当てられ、デバイスを使用することができます。

一度ドライバーをインストールした後は、デバイスを抜き差しすると自動的にデバイスが認識されます。このときINFファイルはwindows\inf\otherフォルダーにあるコピーが使われ最初の様にINFファイルの場所を問い合わせてはきません。初めの状態に戻したい場合は、windows\inf\otherにあるコピーを消去します。これでドライバーインストール前の状態に戻ります。