Oracle® Solaris 11.2 デバイスドライバの記述

印刷ビューの終了

更新: 2014 年 9 月
 
 

ハードウェアの概要

この付録では、Oracle Solaris OS をサポートできるハードウェアに関する一般的な問題について説明します。この説明には、オペレーティングシステムがサポートするプロセッサ、バスアーキテクチャー、およびメモリーモデルが含まれます。デバイスのさまざまな問題と、Oracle プラットフォームで使用される PROM についても説明します。


注 - この付録に記載されている資料は、情報の提供のみを目的としています。この情報は、ドライバのデバッグ時に役立つことがあります。ただし、実装に関するこれらの詳細の多くは、Oracle Solaris DDI/DKI インタフェースによってデバイスドライバから隠されています。

この付録では、次の内容について説明します。

SPARC プロセッサの問題

このセクションでは、データ割り当て、バイト順序、レジスタウィンドウ、浮動小数点命令の可用性など、SPARC プロセッサ固有のいくつかのトピックについて説明します。x86 プロセッサ固有のトピックについては、x86 Processor Issuesを参照してください。


注 - 浮動小数点演算はカーネルでサポートされていないため、ドライバでこの演算を実行しないでください。

SPARC のデータ割り当て

すべての数量は、標準の C データ型を使用して、自然な境界に割り当てる必要があります。

  • short 整数は、16 ビットの境界に割り当てます。

  • int 整数は、32 ビットの境界に割り当てます。

  • long 整数は、SPARC システムでは 64 ビットの境界に割り当てます。データモデルについては、Appendix C, Making a Device Driver 64-Bit Readyを参照してください。

  • long long 整数は、64 ビットの境界に割り当てます。

通常、割り当ての問題はコンパイラで処理されます。ただし、ドライバの作成者は、デバイスへのアクセスに適切なデータ型を使用する必要があるため、割り当てに注意を払う傾向があります。一般にデバイスレジスタにはポインタ参照によってアクセスするため、ドライバはデバイスへのアクセス時にポインタが適正に割り当てるようにする必要があります。

SPARC 構造体のメンバー割り当て

SPARC プロセッサによって生じるデータ割り当ての制限のため、C 構造体にも割り当ての要件があります。構造体の割り当て要件は、もっとも厳密に割り当てられた構造体コンポーネントによって生じます。たとえば、文字だけを含む構造体には割り当ての制限はありませんが、long long メンバーを含む構造体は、このメンバーが 64 ビットの境界で割り当てられることを保証するように構築する必要があります。

SPARC のバイト順序

SPARC プロセッサでは、ビッグエンディアンのバイト順序を使用します。整数の最上位バイト (MSB) は、その整数の一番低いアドレスに格納されます。最下位バイトは、このプロセッサのワードの一番高いアドレスに格納されます。たとえば、バイト 63 は 64 ビットプロセッサの最下位バイトです。

image:図は、ビッグエンディアンアーキテクチャーでのバイトの順序を示しています。バイト 0 が最上位バイトです。

SPARC のレジスタウィンドウ

SPARC プロセッサでは、レジスタウィンドウを使用します。各レジスタウィンドウは、8 個の インレジスタ、8 個の ローカルレジスタ、8 個の アウトレジスタ、および 8 個の グローバルレジスタで構成されています。アウトレジスタは、次のウィンドウのインレジスタになります。レジスタウィンドウの数は、プロセッサの実装によって 2 - 32 の範囲で変わります。

ドライバは通常 C で記述されるため、レジスタウィンドウが使用されていることは、通常、コンパイラによって隠されています。ただし、ドライバをデバッグするときには、レジスタウィンドウを使用する必要が生じる場合があります。

SPARC の乗算命令と除算命令

バージョン 7 の SPARC プロセッサには、乗算命令または除算命令はありません。乗算命令および除算命令は、ソフトウェアでエミュレートされます。ドライバはバージョン 7、バージョン 8、またはバージョン 9 のプロセッサで実行されることがあるため、負荷がかかる整数の乗算や除算は避けてください。代わりに、ビット単位の左シフトや右シフトを使用して、2 のべき乗で乗算や除算を行ってください。

SPARC Architecture Manual, Version 9』には、SPARC CPU の詳細が記載されています。『SPARC Compliance Definition, Version 2.4』には、SPARC V9 のアプリケーションバイナリインタフェース (ABI) の詳細が記載されています。このマニュアルでは、32 ビット SPARC V8 ABI と 64 ビット SPARC V9 ABI. について説明しています。このドキュメントは SPARC International (http://www.sparc.com) から取得できます。

x86 プロセッサの問題

データ型に割り当ての制限はありません。ただし、割り当てが正しくないデータ転送を x86 プロセッサで適正に処理するには、追加のメモリーサイクルが必要になることがあります。


注 - カーネルでは浮動小数点演算はサポートされていないため、ドライバでこの演算を実行しないでください。

x86 のバイト順序

x86 プロセッサでは、リトルエンディアンのバイト順序を使用します。整数の最下位バイト (LSB) は、その整数の一番低いアドレスに格納されます。最上位バイトは、このプロセッサのデータ項目の一番高いアドレスに格納されます。たとえば、バイト 7 は 64 ビットプロセッサの最上位バイトです。

image:図は、リトルエンディアンアーキテクチャーでのバイトの順序を示しています。バイト 0 が最下位バイトです。

x86 アーキテクチャーのマニュアル

Intel Corporation も AMD も、x86 ファミリのプロセッサに関する書籍を多数出版しています。http://www.intel.com および http://www.amd.com/ を参照してください。

エンディアン

マルチプラットフォーム、複数命令セットアーキテクチャーの互換性の目標を達成するために、ホストバス依存性がドライバから削除されました。依存性に関して最初に取り組むべき問題は、プロセッサのエンディアン、つまりバイト順序でした。たとえば、x86 プロセッサファミリはリトルエンディアンですが、SPARC アーキテクチャーはビッグエンディアンです。

バスアーキテクチャーにも、プロセッサと同じエンディアンのタイプがあります。たとえば、PCI ローカルバスはリトルエンディアン、SBus はビッグエンディアン、ISA バスはリトルエンディアン、などです。

プロセッサとバスの間の互換性を維持するために、DDI 準拠のドライバはエンディアンに関して中立である必要があります。ドライバは、実行時検査や、ソースコードの #ifdef _LITTLE_ENDIAN などのプリプロセッサ指令によって、エンディアンを管理できますが、長期的な保守がわずらわしくなる可能性があります。場合によっては、DDI フレームワークでソフトウェアを利用してバイトスワッピングを実行します。また、メモリー管理ユニット (MMU) の場合のようにハードウェアのページレベルスワッピングによって、または特別なマシン命令によって、バイトスワッピングを実行することもできます。DDI フレームワークでは、ハードウェアの機能を活用してパフォーマンスを向上させることができます。

図 A-1  ホストバス依存性に必要なバイト順序

image:図は、エンディアンを反転するバイトスワッピングを示しています。

互換性のあるドライバは、エンディアンに関して中立であるとともに、プロセッサのデータ順序から独立している必要もあります。ほとんどの環境では、ドライバが命令する順序でデータを転送する必要があります。ただし、次の図に示すように、データをマージしたり、バッチ処理したり、順序を変更したりして、データ転送を合理化できることもあります。たとえば、データマージを適用して、フレームバッファーでグラフィックス表示を高速化できます。ドライバは、転送時にほかの最適なデータ転送メカニズムを使用するように DDI フレームワークに指示することもできます。

図 A-2  データ順序のホストバス依存性

image:図は、CPU によるバイトの順序変更を示しています。

ストアバッファー

パフォーマンスを向上させるため、CPU は内部ストアバッファーを使用して一時的にデータを格納します。内部バッファーを使用すると、デバイスの入出力処理の同期に影響が及ぶことがあります。したがって、ドライバは、明示的な手順を実行して、レジスタへの書き込みが適切なときに完了するようにする必要があります。

たとえば、レジスタやフレームバッファーなどのデバイス空間へのアクセスがロックによって同期される場合を考えてみます。ドライバは、デバイス空間への格納がロックの解放前に実際に完了したことを確認する必要があります。ロックの解放は、I/O バッファーのフラッシュを保証するものではありません。

別の例として、ドライバは通常、割り込みに対して確認応答するときに、デバイス制御レジスタのビットを設定またはクリアします。ドライバは、制御レジスタへの書き込みが割り込みハンドラの復帰前にデバイスに到達するよう保証する必要があります。同様に、デバイスに遅延が必要になることがあります。つまり、制御レジスタにコマンドを書き込んだあと、ドライバはビジー状態で待機します。そのような場合、ドライバは、遅延の前に書き込みがデバイスに到達するよう保証する必要があります。

好ましくない結果がなく、デバイスレジスタを読み取ることができる場合、書き込みの検証は、単純に書き込み直後のレジスタの読み取りで構成できます。好ましくない結果がなく、その特定のレジスタを読み取ることができない場合は、同じレジスタセット内の別のデバイスレジスタを使用できます。

システムのメモリーモデル

システムのメモリーモデルは、ロードストアなどのメモリー処理のセマンティクスを定義し、それらの処理をプロセッサが実行する順序を、それらの処理がメモリーに到達する順序に関連付ける方法を指定します。メモリーモデルは、単一プロセッサとメモリー共有型マルチプロセッサの両方に適用されます。トータルストアオーダリング (TSO) とパーシャルストアオーダリング (PSO) の 2 つのメモリーモデルがサポートされています。

トータルストアオーダリング (TSO)

TSO では、ストア、フラッシュ、および原子的ロード/ストアの各命令が指定されたプロセッサのメモリーに出現する順序が、それらの命令をプロセッサが実行する順序と同じであることが保証されます。

x86 プロセッサと SPARC プロセッサの両方が TSO をサポートしています。

パーシャルストアオーダリング (PSO)

PSO では、ストア、フラッシュ、および原子的ロード/ストアの各命令が指定されたプロセッサのメモリーに出現する順序が、それらの命令をプロセッサが実行する順序と同じであることが保証されません。プロセッサはストアの順序を変更することができ、その場合、メモリーのストアの順序は CPU が実行するストアの順序と同じでなくなります。

SPARC プロセッサは PSO をサポートしていますが、x86 プロセッサはサポートしていません。

SPARC プロセッサでは、実行順序とメモリー順序の合致は、STBAR 命令を使用するシステムフレームワークによって可能になります。上の命令のうち 2 つがプロセッサの実行順序内で STBAR 命令によって分離される場合、または命令が同じ位置を参照する場合、その 2 つの命令のメモリー順序は実行順序と同じになります。DDI 準拠のドライバでの強いデータ順序の実施は、ddi_regs_map_setup(9F) インタフェースによって可能になります。準拠ドライバは、STBAR 命令を直接使用することはできません。

SPARC のメモリーモデルの詳細については、『SPARC Architecture Manual, Version 9』を参照してください。

バスアーキテクチャー

このセクションでは、デバイスの識別、デバイスのアドレス指定、および割り込みについて説明します。

デバイスの識別

デバイスの識別とは、システムに存在しているデバイスを判定するプロセスのことです。一部のデバイスは、自己識別を行います。つまり、デバイス自体がシステムに情報を提供して、使用する必要のあるデバイスドライバをシステムが識別できるようにします。SBus と PCI ローカルバスのデバイスは、自己識別を行うデバイスの例です。SBus では、情報は通常、デバイスの FCode PROM に格納されている小さい Forth プログラムから派生します。ほとんどの PCI デバイスには、デバイスの構成情報を含む構成スペースが用意されています。詳細は、sbus(4)およびpci(4)のマニュアルページを参照してください。

新しいバスアーキテクチャーではすべて、デバイスは自己識別を行う必要があります。

サポートされている割り込みタイプ

Oracle Solaris プラットフォームは、ポーリング方式とベクター方式の両方の割り込みをサポートしています。Oracle Solaris DDI/DKI 割り込みモデルは、両方のタイプの割り込みで同じです。割り込み処理の詳細については、Chapter 8, Interrupt Handlersを参照してください。

バスの仕様

このセクションでは、Oracle Solaris プラットフォームがサポートしているバスに固有の、アドレス指定とデバイス構成の問題について説明します。

PCI ローカルバス

PCI ローカルバスは、高速なデータ転送のために設計された高性能なバスです。PCI バスは、システムボード上にあります。このバスは通常、高度に統合された周辺コンポーネント、周辺アドオンボード、およびホストプロセッサまたはメモリーシステムの間の相互接続メカニズムとして使用されます。ホストプロセッサ、メインメモリー、および PCI バス自体は、Figure A–3 に示すように、PCI ホストブリッジを介して接続されます。

相互に接続された I/O バスのツリー構造は、一連の PCI バスブリッジを介してサポートされます。下位の PCI バスブリッジを PCI ホストブリッジの下で拡張し、単一のバスシステムを拡張して、複数のセカンダリバスを持つ複雑なシステムにできます。PCI デバイスは、これらの 1 つ以上のセカンダリバスに接続できます。また、SCSI や USB などのほかのバスブリッジも接続できます。

すべての PCI デバイスには、一意なベンダー ID とデバイス ID があります。同じ種類の複数のデバイスは、デバイスが存在するバスの一意のデバイス番号によってさらに識別されます。

図 A-3  マシンのブロック図

image:図は、PCI ホストブリッジによって CPU とメインメモリーを PCI バスに接続する方法を示しています。

PCI ホストブリッジによって、プロセッサと周辺コンポーネントが相互に接続されます。プロセッサは、PCI ホストブリッジを介して、ほかの PCI バスマスターから独立して直接メインメモリーにアクセスできます。たとえば、CPU がホストブリッジのキャッシュコントローラからデータを取得している間に、ほかの PCI デバイスもホストブリッジを介してシステムメモリーにアクセスできます。このアーキテクチャーの利点は、このアーキテクチャーによって I/O バスとプロセッサのホストバスが分離されることです。

PCI ホストブリッジによって、CPU と周辺入出力デバイスの間のデータアクセスマッピングも提供されます。ブリッジは、すべての周辺デバイスをホストアドレスドメインにマッピングして、プロセッサがプログラム式入出力経由でデバイスにアクセスできるようにします。ローカルバス側では、PCI ホストブリッジはシステムメモリーを PCI アドレスドメインにマッピングして、PCI デバイスがバスマスターとしてホストメモリーにアクセスできるようにします。Figure A–3 は、2 つのアドレスドメインを示しています。

PCI アドレスドメイン

PCI アドレスドメインは、構成、メモリー、および I/O 空間という 3 つの個別のアドレス空間で構成されています。

PCI 構成アドレス空間

構成空間は地理的に定義されます。周辺デバイスの位置は、PCI バスブリッジの相互に接続されたツリー内のその物理的な位置によって決定されます。デバイスは、そのバス番号デバイス (スロット) 番号によって検出されます。各周辺デバイスには、その PCI 構成空間に一連の十分に定義された構成レジスタが含まれています。レジスタは、デバイスを識別するためだけでなく、構成フレームワークにデバイス構成情報を提供するためにも使用されます。たとえば、デバイスがデータアクセスに応答するためには、デバイス構成空間の基底アドレスレジスタをマッピングする必要があります。

構成サイクルを生成するための方法はホストに依存しています。x86 マシンでは、特殊な I/O ポートが使用されます。ほかのプラットフォームでは、ホストアドレスドメイン内の PCI ホストブリッジに応じて、PCI 構成空間を特定のアドレス位置にメモリーマッピングできます。デバイス構成レジスタにプロセッサがアクセスすると、要求が PCI ホストブリッジにルーティングされます。次に、ブリッジは、そのアクセスをバスの適切な構成サイクルに変換します。

PCI 構成基底アドレスレジスタ

PCI 構成空間は、デバイスごとに最大 6 つの 32 ビット基底アドレスレジスタで構成されています。これらのレジスタは、サイズとデータ型の両方の情報を提供します。システムファームウェアは、PCI アドレスドメインの基底アドレスをこれらのレジスタに割り当てます。

各アドレス指定可能領域には、メモリーまたは I/O 空間を使用できます。基底アドレスレジスタのビット 0 に含まれる値によってタイプが識別されます。ビット 0 にある 0 の値はメモリー空間を示し、1 の値は I/O 空間を示します。次の図は、2 つの基底アドレスレジスタを示しています。1 つはメモリータイプ用で、もう 1 つは入出力タイプ用です。

図 A-4  メモリーおよび入出力の基底アドレスレジスタ

image:図は、基底アドレスのビット 0 がメモリーまたは I/O 空間を示す方法を示しています。

PCI メモリーアドレス空間

PCI は、メモリー空間について 32 ビットと 64 ビットの両方のアドレスをサポートしています。システムファームウェアは、PCI アドレスドメインのメモリー空間の領域を PCI 周辺デバイスに割り当てます。領域の基底アドレスは、デバイスの PCI 構成空間の基底アドレスレジスタに格納されます。各領域のサイズは 2 のべき乗にする必要があり、割り当てられる基底アドレスは領域のサイズと等しい境界で割り当てる必要があります。メモリー空間のデバイスアドレスはホストアドレスドメインにメモリーマッピングされるため、デバイスへのデータアクセスはプロセッサのネイティブのロード命令またはストア命令によって実行できます。

PCI I/O アドレス空間

PCI は、32 ビット I/O 空間をサポートしています。I/O 空間にアクセスする方法はプラットフォームによって異なります。Intel プロセッサファミリなどの特殊な入出力命令を持つプロセッサは、in および out 命令を使って I/O 空間にアクセスします。特殊な入出力命令を持たないマシンは、ホストアドレスドメインの PCI ホストブリッジに応じてアドレス位置にマッピングします。プロセッサがメモリーマッピングされたアドレスにアクセスすると、入出力要求が PCI ホストブリッジに送られ、次にアドレスが入出力サイクルに変換されて PCI バスに配置されます。メモリーマッピングされた入出力は、プロセッサのネイティブのロード/ストア命令によって実行されます。

PCI ハードウェア構成ファイル

ハードウェア構成ファイルは、PCI ローカルバスデバイスには必要ないはずです。ただし、場合によっては、PCI デバイスのドライバはハードウェア構成ファイルを使用してドライバの固有情報を増やす必要があります。詳細は、driver.conf(4)およびpci(4)のマニュアルページを参照してください。

PCI Express

標準の PCI バスは、PCI Express に発展しています。PCI Express は、デスクトップ、モバイル、ワークステーション、サーバー、埋め込み型コンピューティング/通信プラットフォームなどのアプリケーションで周辺デバイスを接続するための、次世代の高性能 I/O バスです。

PCI Express ではバスパフォーマンスが向上し、全体的なシステムコストが減少し、コンピュータ設計の新しい発展を活用しています。PCI Express では、2 つのデバイス間の通信にシリアルのポイントツーポイント型相互接続を使用します。スイッチの使用により、ユーザーはシステム内の多数のデバイスを一緒に接続できます。シリアルの相互接続では、デバイスパッケージあたりのピンが少なくなるので、コストが減少し、パフォーマンスが高度にスケーラブルになります。

PCI Express バスには、次の技術に対応する機能が組み込まれています。

  • QoS (Quality of Service)

  • ホットプラグによる取り付けとホットスワップ

  • 詳細な電源管理

  • RAS (信頼性、可用性、保守性)

  • 向上したエラー処理

  • MSI 割り込み

2 つのデバイスを一緒に接続する PCI Express の相互接続は、リンクと呼ばれます。リンクでは、x1、x2、x4、x8、x12、x16、または x32 の双方向のシグナルペアを使用できます。これらのシグナルは、レーンと呼ばれます。各レーンの帯域幅 (x1) は、全二重モードで 500M バイト/秒です。PCI-X と PCI Express のハードウェア接続は異なりますが、2 つのバスはドライバの作成者の観点からは同じです。PCI-X は共有バスです。たとえば、バス上のすべてのデバイスが 1 つのセットのデータラインとシグナルラインを共有します。PCI-Express はスイッチバスであり、デバイスとシステムバスの間で帯域幅を使用するときの効率を向上させることができます。

PCI Express の詳細については、Web サイト http://www.pcisig.com/home を参照してください。

SBus

通常の SBus システムは、マザーボード (CPU と SBus インタフェースロジックを含む)、マザーボード自体にあるいくつかの SBus デバイス、およびいくつかの SBus 拡張スロットで構成されています。SBus は、適切なバスブリッジを介して、ほかのタイプのバスに接続することもできます。

SBus は地理的にアドレス指定されます。各 SBus スロットは、システム内の固定した物理アドレスに存在します。SBus カードは、差し込むスロットによってアドレスが異なります。SBus デバイスを新しいスロットに移動すると、システムはこのデバイスを新しいデバイスと見なします。

SBus では、ポーリング方式の割り込みを使用します。SBus デバイスが割り込みを行っても、システムは、いくつかあるデバイスのどれかが割り込みを実行した可能性があることしか認識できません。システムの割り込みハンドラは、各デバイスのドライバに、そのデバイスが割り込みを行ったかどうか問い合わせる必要があります。

SBus の物理アドレス空間

次の表は、Sun UltraSPARC 2 コンピュータの物理アドレス空間のレイアウトを示しています。UltraSPARC 2 モデルの物理アドレスは、41 ビットで構成されています。41 ビットの物理アドレス空間はさらに、PA(40:33) によって識別される複数の 33 ビットアドレス空間に細分化されます。

表 A-1  Ultra 2 のデバイス物理空間
PA(40:33)
33 ビット空間
用途
0x0
0x000000000 - 0x07FFFFFFF
2G バイトのメインメモリー
0x80 – 0xDF
Reserved on Ultra 2
Ultra 2 で予約済み
0xE0
Processor 0
プロセッサ 0
0xE1
Processor 1
プロセッサ 1
0xE2 – 0xFD
Reserved on Ultra 2
Ultra 2 で予約済み
0xFE
0x000000000 - 0x1FFFFFFFF
UPA スレーブ (FFB)
0xFF
0x000000000 - 0x0FFFFFFFF
システム I/O 空間
0x100000000 - 0x10FFFFFFF
SBus スロット 0
0x110000000 - 0x11FFFFFFF
SBus スロット 1
0x120000000 - 0x12FFFFFFF
SBus スロット 2
0x130000000 - 0x13FFFFFFF
SBus スロット 3
0x1D0000000 - 0x1DFFFFFFF
SBus スロット D
0x1E0000000 - 0x1EFFFFFFF
SBus スロット E
0x1F0000000 - 0x1FFFFFFFF
SBus スロット F

物理 SBus アドレス

SBus には、『SBus Specification』で説明されているように、32 のアドレスビットがあります。次の表で、Ultra 2 でアドレスビットを使用する方法について説明します。

表 A-2  Ultra 2 の SBus のアドレスビット
ビット
説明
0 - 27
これらのビットは、SBus カードがその内容をアドレス指定するために使用する SBus アドレスラインです。
28 - 31
SBus スロットの 1 つを選択するために CPU で使用します。これらのビットは、SlaveSelect ラインを生成します。

このアドレス指定方式により、Table A–1 に示す Ultra 2 アドレスが生成されます。ほかの実装では、異なる数のアドレスビットを使用することがあります。

Ultra 2 には 7 つの SBus スロットがあり、そのうちの 4 つは物理的です。スロット 0 - 3 は、SBus カードで使用できます。スロット 4 - 12 は、予約されています。これらのスロットは、次のように使用します。

  • スロット 0 - 3 は、DMA マスター機能のある物理スロットです。

  • スロット D、E、および F は、実際の物理スロットではありませんが、オンボードのダイレクトメモリーアクセス (DMA)、SCSI、Ethernet、およびオーディオコントローラを参照します。便宜上、これらのクラスのデバイスは、スロット D、E、および F に差し込まれているものと見なされます。


    注 - 一部の SBus スロットは、スレーブのみのスロットです。DMA 機能が必要なドライバでは、ddi_slaveonly(9F) を使用して、ドライバのデバイスが DMA 対応のスロットに入っているかどうかを判定するべきです。この関数の例については、attach() Entry Pointを参照してください。

SBus のハードウェア構成ファイル

ハードウェア構成ファイルは通常、SBus デバイスには必要ありません。ただし、場合によっては、SBus デバイスのドライバは、ハードウェア構成ファイルを使用して、SBus カードが提供する情報を増やす必要があります。詳細は、driver.conf(4)およびsbus(4)のマニュアルページを参照してください。

デバイスの問題

このセクションでは、特殊なデバイスの問題について説明します。

タイミングクリティカルセクション

ほとんどのドライバの処理は、ロックプリミティブによって提供されるものを超える同期や保護のメカニズムなしで実行できますが、一部のデバイスでは一連のイベントが割り込みなしで順番に発生する必要があります。ロックプリミティブに関連して、関数 ddi_enter_critical(9F) は、現在のスレッドが横取りされたり割り込まれたりしないことを最大限に保証するようにシステムに求めます。この保証は、閉じるための呼び出しを ddi_exit_critical(9F) に対して行うまで有効です。詳細は、ddi_enter_critical(9F)のマニュアルページを参照してください。

遅延

多くのチップは、それらのチップが指定された間隔でのみアクセスできるように指定します。たとえば、Zilog Z8530 SCC には、1.6 マイクロ秒の「書き込み回復時間」があります。この仕様は、8530 で文字を書き込むときに drv_usecwait(9F) で遅延を実施する必要があることを意味します。場合によっては、この仕様では必要な遅延が明示されないため、経験に基づいて遅延を判定する必要があります。

たとえば、幾千もの SCSI ディスクドライブなど、数多く存在することがあるデバイスのパーツの遅延を大きくしないように注意してください。

内部順序付けロジック

内部順序付けロジックのあるデバイスは、複数の内部レジスタを同じ外部アドレスにマッピングします。さまざまな種類の内部順序付けロジックには、次のタイプが含まれています。

  • Intel 8251A と Signetics 2651 は、2 つの内部モードレジスタの間で同じ外部レジスタを交互に使用します。最初の内部レジスタへの書き込みは、外部レジスタへの書き込みによって完成します。ただし、この書き込みには、チップの順序付けロジックが設定され、次の読み取り/書き込み処理で 2 番目の内部レジスタを参照するという想定外の結果が伴います。

  • NEC PD7201 PCC には、複数の内部データレジスタがあります。特定のレジスタにバイトを書き込むには、2 つの手順を実行する必要があります。最初の手順は、後続のデータバイトが入るレジスタの番号をレジスタ 0 に書き込むことです。次に、データは、指定されたデータレジスタに書き込まれます。順序付けロジックによって、次に送信されるバイトがデータレジスタ 0 に入るようにチップが自動的に設定されます。

  • AMD 9513 タイマーには、データバイトが入るデータレジスタをポイントするデータポインタレジスタがあります。データレジスタにバイトを送信すると、ポインタは増分されます。ポインタレジスタの現在の値を読み取ることはできません

割り込みの問題

割り込みに関係した次の一般的な問題に注意してください。

  • コントローラによる割り込みは、必ずしもコントローラそのスレーブデバイスの 1 つの両方の準備ができたことを示すものではありません。一部のコントローラでは、割り込みは、両方の準備ができたことではなく、コントローラの準備ができたか、またはそのデバイスの 1 つの準備ができたかのいずれかを示すことがあります。

  • 割り込みを無効にしてもすべてのデバイスのパフォーマンスが向上するわけではありません。また、すべてのデバイスが任意の時点で割り込みを開始できるわけでもありません。

  • 一部のデバイスでは、ボードが割り込みを生成したことを判定する方法が用意されていません。

  • 割り込みを停止するように指示されたときに、またはバスがリセットされたあとで、すべての割り込みボードが割り込みを停止するわけではありません。

SPARC マシンの PROM

一部のプラットフォームには、オペレーティングシステムなしでデバイスのデバッグを行うためのサポートを提供する PROM モニターがあります。このセクションでは、SPARC マシンで PROM を使用してデバイスレジスタをマッピングし、それらのデバイスレジスタにアクセスできるようにする方法について説明します。通常、デバイスは、PROM コマンドを使って十分に動作テストを実行し、正しく動作するかどうかを判定できます。

x86 のブートサブシステムについては、boot(1M)のマニュアルページを参照してください。

PROM には、次のようないくつかの目的があります。

  • 電源を入れてから、またはハードリセットの PROM reset コマンドからマシンを起動する

  • メモリー、デバイスレジスタ、およびメモリーマッピングを調べたり設定したりする対話型のツールを提供する

  • Oracle Solaris システムのブート。

    単にコンピュータを拡張し、その PROM を使用してデバイスレジスタを調べようとしても、失敗することがあります。デバイスが正しく取り付けられていても、マッピングは Oracle Solaris OS 固有のものであり、Oracle Solaris カーネルがブートされるまではアクティブになりません。拡張時に、PROM は、キーボードなどの基本的なシステムデバイスだけをマッピングします。

  • sync コマンドを使用して、システムクラッシュダンプを実行する

Open Boot PROM 3

Open Boot PROM の完全なドキュメントについては、『Open Boot PROM Toolkit User's Guide』およびmonitor(1M)のマニュアルページを参照してください。このセクションの例では、Sun4U アーキテクチャーを参照しています。ほかのアーキテクチャーでは、アクションの実行に別のコマンドが必要になることがあります。


注 - Open Boot PROM は現在、SBus または UPA/PCI を搭載した Sun マシンで使用されています。Open Boot PROM では、「ok」プロンプトを使用します。古いマシンでは、「n」を入力して「ok」プロンプトを表示する必要が生じる場合があります。

PROM がセキュリティー保護モード (security-mode パラメータがなしに設定されていない) になっている場合、PROM パスワードを要求されることがあります (security-password パラメータで設定)。

printenv コマンドは、すべてのパラメータとその値を表示します。

ヘルプは、help コマンドで利用できます。

EMACS スタイルのコマンド行履歴を利用できます。履歴リストをたどるときは、Control + N (次) および Control + P (前) を使用します。

Forth コマンド

Open Boot PROM では、Forth というプログラミング言語を使用します。Forth は、スタックベースの言語です。引数は、正しいコマンドを実行する前にスタック (ワードと呼ばれる) にプッシュする必要があります。結果はスタックに残ります。

数値をスタックに配置するには、その値を入力します。

ok 57
ok 68

上の 2 つの値をスタックに追加するには、+ 演算子を使用します。

ok +

結果はスタックに残ります。スタックは .s ワードで表示されます。

ok .s
bf

デフォルトの基数は 16 進数です。hexdecimal の各ワードを使用すると、基数を切り替えることができます。

ok decimal
ok .s
191

詳細は、Forth のユーザーガイドを参照してください。

PROM デバイスツリーの調査

コマンド pwdcd、および ls は、PROM デバイスツリーを調べてデバイスに到達します。pwd が機能する前にツリー内の位置を確立するには、cd コマンドを使用する必要があります。次の例は、SBus で cgsix フレームバッファーを使用する Ultra 1 ワークステーションのものです。

ok cd /

ツリー内の現在のノードに接続されているデバイスを表示するには、ls を使用します。

ok ls
f006a064 SUNW,UltraSPARC@0,0
f00598b0 sbus@1f,0
f00592dc counter-timer@1f,3c00
f004eec8 virtual-memory
f004e8e8 memory@0,0
f002ca28 aliases
f002c9b8 options
f002c880 openprom
f002c814 chosen
f002c7a4 packages

完全なノード名を使用できます。

ok cd sbus@1f,0
ok ls
f006a4e4 cgsix@2,0
f0068194 SUNW,bpp@e,c800000
f0065370 ledma@e,8400010
f006120c espdma@e,8400000
f005a448 SUNW,pll@f,1304000
f005a394 sc@f,1300000
f005a24c zs@f,1000000
f005a174 zs@f,1100000
f005a0c0 eeprom@f,1200000
f0059f8c SUNW,fdtwo@f,1400000
f0059ec4 flashprom@f,0
f0059e34 auxio@f,1900000
f0059d28 SUNW,CS4231@d,c000000

前の例で完全なノード名を使用する代わりに、省略名を使用することもできます。省略したコマンド行エントリは、次の例のようになります。

ok cd sbus

この名前は、実際には device@slot,offset (SBus デバイスの場合) です。cgsix デバイスはスロット 2 にあり、オフセット 0 から始まります。SBus デバイスがこのツリーに表示される場合、そのデバイスは PROM に認識されています。

.properties コマンドは、デバイスの PROM プロパティーを表示します。これらのプロパティーを調べることで、デバイスがエクスポートするプロパティーを判定できます。この情報は、あとでドライバが正しいハードウェアプロパティーを検索していることを確認するときに役立ちます。これらのプロパティーは、ddi_getprop(9F) で取得できるプロパティーと同じです。

ok cd cgsix
ok .properties
character-set            ISO8859-1
intr                     00000005 00000000
interrupts               00000005
reg                      00000002 00000000 01000000
dblbuf                   00 00 00 00
vmsize                   00 00 00 01
...

reg プロパティーは、次のフィールドを含むレジスタ記述構造体の配列を定義します。

uint_t        bustype;       /* cookie for related bus type*/
uint_t        addr;          /* address of reg relative to bus */
uint_t        size;          /* size of this register set */

cgsix の例の場合、アドレスは 0 です。

デバイスのマッピング

デバイスは、テストするメモリーにマッピングする必要があります。次に、PROM を使用して、データ転送コマンドを使用し、バイト、ワード、およびロングワードを転送することで、デバイスの適切な動作を確認できます。PROM から限定的にでもデバイスを操作できる場合は、ドライバもデバイスを操作できるはずです。

初期テスト用にデバイスを設定するには、次の手順を実行します。

  1. デバイスが存在する SBus スロット番号を判定します。

    この例では、cgsix デバイスはスロット 2 にあります。

  2. デバイスが使用する物理アドレス空間内のオフセットを判定します。

    使用されるオフセットは、デバイスに固有です。cgsix の例では、ビデオメモリーは 0x800000 のオフセットから始まっています。

  3. Sbus デバイスを選択するには、select-dev ワードを使用し、デバイスを内部にマッピングするには、map-in ワードを使用します。

    select-dev ワードは、デバイスパスの文字列をその引数と見なします。map-in ワードは、オフセットスロット番号、およびサイズを、マッピングする引数と見なします。オフセットと同様、バイト転送のサイズはデバイスに固有です。cgsix の例では、サイズは 0x100000 バイトに設定されています。

    次のコード例では、Sbus のパスが select-dev ワードの引数として表示されており、フレームバッファーのオフセット、スロット番号、およびサイズの値が map-in ワードの引数として表示されています。select-dev 引数内の開始引用符と / の間の空白に注意してください。使用する仮想アドレスは、スタックの上位に残っています。スタックは .s ワードを使って表示されます。スタックには、constant 処理で名前を割り当てることができます。

    ok " sbus@1f,0" select-dev
    ok 800000 2 100000 map-in
    ok .s
    ffe98000
    ok constant fb

読み取りと書き込み

PROM には、8 ビット、16 ビット、および 32 ビットのさまざまな処理が用意されています。一般に、c (文字) 接頭辞は 8 ビット (1 バイト) の処理、w (ワード) 接頭辞は 16 ビット (2 バイト) の処理、L (ロングワード) 接頭辞は 32 ビット (4 バイト) の処理を示します。

接頭辞 ! は、書き込み処理を示します。書き込み処理では、スタックの最初の 2 つの項目を使用します。最初の項目はアドレスで、2 番目の項目は値です。

ok 55 ffe98000 c!

接頭辞 @ は、読み取り処理を示します。読み取り処理では、スタックのアドレスを使用します。

ok ffe98000 c@
ok .s
55

接頭辞 ? は、スタックに影響を与えないように値を表示するときに使用します。

ok ffe98000 c?
55

デバイスにクエリーしようとするときは注意してください。マッピングが正しく設定されていない場合は、読み取りまたは書き込みを行おうとすると、エラーが発生することがあります。このようなケースを扱うときは、特殊なワードを指定します。たとえば、cprobewprobe、および lprobe は、指定されたアドレスから読み取りますが、その場所から応答がない場合はゼロを返し、応答がある場合はゼロ以外を返します。

ok fffa4000 c@
Data Access Error

ok fffa4000 cprobe
ok .s0

ok ffe98000 cprobe
ok .s
0 ffffffffffffffff

メモリーの領域は、dump ワードで表示できます。このワードではアドレス長さを使用し、メモリー領域の内容をバイト単位で表示します。

次の例では、fill ワードを使用してビデオメモリーをパターンで埋めます。fill では、アドレス、埋めるバイト数、および使用するバイトを使います。ワードおよびロングワードの場合は、wfill および Lfill を使用します。次の fill の例では、cgsix によって、渡されたバイトに基づいて単純なパターンが表示されます。

ok " /sbus" select-dev
ok 800000 2 100000 map-in
ok constant fb
ok fb 10000 ff fill
ok fb 20000 0 fill
ok fb 18000 55 fill
ok fb 15000 3 fill
ok fb 10000 5 fillok fb 5000 f9 fill