RISC-V IOMMUの構成について、概略をざっくり理解するためのメモ。
何回か読もうとして挫折してきたので、もう一度ちゃんと読んでみようと思う。
IOVAを変換するプロセスは、ハードウェアID(device_id
とprocess_id
)を使って、デバイス・コンテキストとプロセス・コンテキストを特定する。Device-contextとProcess-contextは、ページテーブルのルートPPN、 PSCID
、 GSCID
、アドレス変換と保護プロセスに影響する他の制御パラメータを提供する。アドレス変換キャッシュ(???)が実装されている場合、変換プロセスは、GSCID
と PSCID
を使用して、キャッシュされた変換をそのアドレス空間に関連付けることができる。
IOVA を変換するプロセスは以下の通りである:
ddtp.iommu_mode == Off
の場合、停止し、"All inbound transactions disallowed" (cause = 256)と報告する。ddtp.iommu_mode == Bare
で、以下の条件のいずれかが成立する場合、停止し、"Transaction type disallowed" (cause = 260)と報告します。- トランザクションタイプは、Translatedリクエスト(read, write/AMO, read-for-execute)、またはPCIe ATS Translationリクエストである。
capabilities.MSI_FLAT
が0の場合、IOMMUはベースフォーマットのデバイスコンテキストを使用する。DDI[0]
をdevice_id[6:0]
とし、DDI[1]
をdevice_id[15:7]
であり、DDI[2]
はdevice_id[23:16]
である。capabilities.MSI_FLAT
が1の場合、IOMMUは拡張フォーマットデバイスコンテキストを使用する。DDI[0]
をdevice_id[5:0]
とし、DDI[1]
をdevice_id[14:6]
であり、DDI[2]
はdevice_id[23:15]
である。- もし
device_id
が IOMMU モードでサポートされているものより広い場合、以下のチェックによって決定され、停止して "Transaction type disallowed" (cause = 260) を報告する。ddtp.iommu_mode
が2LVL
で、かつDDI[2]
が 0 ではない。ddtp.iommu_mode
is1LVL
and eitherDDI[2]
is not 0 orDDI[1]
is not 0
device_id
を使用して、 ??? で指定されたデバイスコンテキスト(DC
)を見つける。- 以下の条件のいずれかが成立する場合、停止して "Transaction type disallowed"(原因=260)を報告する。
- トランザクションタイプがTranslatedリクエスト(読み取り、書き込み/AMO、実行用読み取り)であるか、PCIe ATS Translationリクエストであり、
DC.tc.EN_ATS
が0である。 - トランザクションは有効な
process_id
を持ち、DC.tc.PDTV
は0です。 - トランザクションは有効な
process_id
を持ち、DC.tc.PDTV
は1であり、process_id
はpdtp.MODE
がサポートするものより広い。 - トランザクションタイプはIOMMUによってサポートされていない。
- トランザクションタイプがTranslatedリクエスト(読み取り、書き込み/AMO、実行用読み取り)であるか、PCIe ATS Translationリクエストであり、
- リクエストが変換済みリクエストであり、
DC.tc.T2GPA
が0の場合、変換処理は完了する。 ステップ20に進む。 - 要求が変換済み要求で、
DC.tc.T2GPA
が1の場合、IOVAはGPAである。 次のページ表情報でステップ17に進みます:- A をIOVA とする(IOVA はGPA)。
iosatp.MODE
をBare
とする。PSCID
の値は、ファーストステージがBare
の場合は使用されない。
iohgatp
をDC.iohgatp
フィールドの値とする。
- もしDC.tc.PDTVが0に設定されているなら、次のページテーブルの情報を使ってステップ17に進む:
iosatp.MODE
をDC.fsc.MODE
フィールドの値とする。iosatp.PPN
をDC.fsc.PPN
フィールドの値とする。PSCID
をDC.ta.PSCID
フィールドの値とする。iohgatp
をDC.iohgatp
フィールドの値とする。
- DPEが1で、トランザクションに関連する
process_id
がない場合、process_id
をデフォルト値の0とする。- もしDPEが0で、トランザクションに関連する
process_id
がなければ、次のページテーブル情報でステップ17に進む: iosatp.MODE
をBare
とする。PSCID
の値は、ファーストステージがBare
の場合は使用されない。
iohgatp
をDC.iohgatp
フィールドの値とする。
- もしDPEが0で、トランザクションに関連する
- もし
DC.fsc.pdtp.MODE = Bare
ならば、次のページテーブル情報でステップ17に進む:iosatp.MODE
をBare
とします。PSCID
の値は、ファーストステージがBare
の場合は使用されない。
iohgatp
をDC.iohgatp
フィールドの値とする。
- ??? で指定されたプロセスコンテキスト(
PC
)を見つける。 - 以下の条件のいずれかが成立する場合、停止して "Transaction type disallowed" (cause = 260) を報告する。
- トランザクションはスーパーバイザ権限を要求しているが、
PC.ta.ENS
が設定されていない。
- トランザクションはスーパーバイザ権限を要求しているが、
- 次のページテーブル情報でステップ17に進みます:
iosatp.MODE
をPC.fsc.MODE
フィールドの値とする。iosatp.PPN
をPC.fsc.PPN
フィールドの値とする。PSCID
をPC.ta.PSCID
フィールドの値とする。iohgatp
をDC.iohgatp
フィールドの値とする。
- トランザクションによってアクセスされる GPA を決定するために、RISC-V Privileged 仕様書 [4] のセクション「2段階アドレス変換」で指定されたプロセスを使用する。第一段階のアドレス変換処理で障害が検出された場合、その障害を停止して報告する。変換処理が正常に完了した場合、A を変換されたGPAとする。
- MSIページテーブルを使用するMSIアドレス変換が有効である場合(すなわち、
DC.msiptp.MODE != Off
)、 ??? で指定されたMSIアドレス変換プロセスが起動される。 もしGPA A が仮想割込みファイルのアドレスであると決定されなければ、プロセスはステップ19で継続する。 もしMSIアドレス変換プロセスによって障害が検出されれば、停止して障害を報告し、そうでなければプロセスはステップ20で継続する。 - トランザクションによってアクセスされるSPAを決定するために、GPAA を変換するために、RISC-V特権仕様[4 のセクション「2段階アドレス変換」で指定された第2段階アドレス変換プロセスを使用する。 アドレス変換プロセスによって障害が検出された場合、その障害を停止して報告する。
- 変換処理完了
セカンドステージのPTEで U
ビットをチェックする場合、トランザクションはスーパーバイザ特権を要求していないものとして扱われる。Zicfiss [5] 拡張で指定されている pte.xwr=010
エンコーディングは、シングル ステージおよび VS ステージ ページテーブルのシャドウ スタック ページ タイプのために、IO トランザクションのために予約されたエンコーディングのままです。
変換プロセスがフォールトを報告し、リクエストが未変換リクエストまたは変換リクエストである場合、IOMMUはIOブリッジにトランザクションを中止するよう要求する。IOブリッジでフォールトトランザクションを処理するためのガイドラインは、??? に記載されている。 フォルトは、??? で指定されたフォルト/イベント報告メカニズムおよびフォルト記録形式を使用して報告される。
フォルトが PCIe ATS Translation Request によって検出された場合、IOMMU はソフトウェアにフォルトを報告したり、アボートを引き起こしたりする代わりに、PCIe プロトコルで定義された応答を提供することができる。 フォールトが発生した PCIe ATS Translation Requests の処理は、 ???に規定されている。