Share via


バス相対アドレスの仮想アドレスへのマッピング

プロセッサによっては、メモリ アドレス空間と I/O アドレス空間を別々に実装していることがあります。 ハードウェア プラットフォームのこのような違いにより、I/O 常駐デバイス リソースやメモリ常駐デバイス リソースへのアクセスでドライバーが使用するメカニズムはプラットフォームによって異なります。

PnP マネージャーの IRP_MN_QUERY_RESOURCE_REQUIREMENTS IRP への応答で、ドライバーはデバイス I/O リソースとメモリ リソースを要求します。 HAL は、ハードウェア アーキテクチャに応じて、I/O 空間またはメモリ空間に I/O リソースを割り当てることができ、I/O 空間またはメモリ空間にメモリ リソースを割り当てることができます。

HAL がバス相対メモリ領域を使用してデバイス リソース (デバイス レジスタなど) にアクセスする場合、ドライバーでは、これらのリソースにアクセスできるように I/O 空間を仮想メモリにマッピングする必要があります。 ドライバーは、デバイスの起動時に PnP マネージャーからドライバーに渡された変換済みリソースを調べることによって、リソースが I/O 常駐であるかメモリ常駐であるかを判断できます。 HAL が I/O 空間を使用する場合、マッピングは不要です。

具体的には、IRP_MN_START_DEVICE 要求を受け取ったドライバーは、IrpSp->Parameters.StartDevice.AllocatedResourcesIrpSp->Parameters.StartDevice.AllocatedResourcesTranslated の構造を調べる必要があります。これらのパラメーターは、それぞれ PnP マネージャーがデバイスに割り当てた生 (バス相対) リソースと変換済みリソースを記述しています。 ドライバーは、デバッグの補助としてデバイス拡張機能の各リソース一覧のコピーを保存する必要があります。

このリソース一覧は、CM_RESOURCE_LIST 構造体のペアです。この構造では、生リソース一覧の各要素が、変換済みリソース一覧にある同じ要素に対応しています。 たとえば、AllocatedResources.List[0] が生リソースの I/O ポート範囲を記述している場合、AllocatedResourcesTranslated.List[0] は変換済みリソースの同じ範囲を記述しています。 変換済みの各リソースには、そのリソースの物理アドレスと種類が記述されています。

変換済みメモリ リソース (CmResourceTypeMemory) が割り当てられたドライバーは、MmMapIoSpace を呼び出して、デバイス レジスタへのアクセスで指定できる仮想アドレスに物理アドレスをマッピングする必要があります。 ドライバーがプラットフォームに依存せずに動作するには、返された変換済みリソースをすべて確認し、必要に応じてマッピングする必要があります。

カーネル モード ドライバーは、IRP_MN_START_DEVICE 要求を受けて以下の手順を実行し、すべてのデバイス リソースにアクセスできるようにする必要があります。

  1. IrpSp->Parameters.StartDevice.AllocatedResources をデバイス拡張機能にコピーします。

  2. IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated をデバイス拡張機能にコピーします。

  3. AllocatedResourcesTranslated の各記述子要素をループ処理で調べます。 記述子リソースの種類が CmResourceTypeMemory である場合は MmMapIoSpace を呼び出し、変換済みリソースの物理アドレスと長さを渡します。

PnP マネージャーから IRP_MN_STOP_DEVICE 要求または IRP_MN_REMOVE_DEVICE 要求を受け取ったドライバーは、上記と同様のループで MmUnmapIoSpace を呼び出してマッピングを解除する必要があります。 IRP_MN_START_DEVICE 要求を失敗にする必要がある場合、ドライバーでは MmUnmapIoSpace も呼び出す必要があります。

ドライバーが呼び出す必要がある HAL アクセス ルーチンは生リソースの種類で示されます (READ_REGISTER_XXXWRITE_REGISTER_XXXREAD_PORT_XXXWRITE_PORT_XXX)。 ほとんどのドライバーでは、生リソース一覧を確認してこれらのルーチンのどれを使用するかを判断する必要はありません。ドライバー自体がリソースを要求しているか、デバイス ハードウェアの性質から必要とするリソースの種類をドライバーの作成者が知っているからです。

I/O 空間のリソース (CmResourceTypePortCmResourceTypeInterruptCmResourceTypeDma) の場合、ドライバーでは、返された物理アドレスの下位 32 ビットを使用してデバイス リソースにアクセスする必要があります。たとえば、HAL の読み込みルーチンと書き込みルーチンである READ_REGISTER_XXXWRITE_REGISTER_XXXREAD_PORT_XXXWRITE_PORT_XXX を使用します。