FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-V IOMMU の構成についてマニュアルを読んでまとめる (17. MRIFについて)

前回:msyksphinz.hatenablog.com

github.com

RISC-V IOMMUの構成について、概略をざっくり理解するためのメモ。

IOMMUのMSIアドレス変換について、MRIFを理解する必要が生じてきたのでメモ。


MRIFのフォーマットは以下のようになる。以下のアドレスマップは、512バイトのアドレス境界にアラインされていないといけない。

offset size contents
0x000 8 bytes interrupt-pending bits for (minor) identities 1–63
0x008 8 bytes interrupt-enable bits for identities 1–63
0x010 8 bytes interrupt-pending bits for identities 64–127
0x018 8 bytes interrupt-enable bits for identities 64–127
. . . . . .
0x1F0 8 bytes interrupt-pending bits for identities 1984–2047
0x1F8 8 bytes interrupt-enable bits for identities 1984–2047

要するに、1から2047までの割り込みIDに対して、それぞれ64ビット毎にインタリーブされた形でInterrupt-Pendingビットと、Interrupt-Enableビットが並んでいるようになる。

これに対して具体的にどのように書き込むかというと、IOMMUが特定の割り込みIDのMRIFのInterrupt-Pendingビットを1とする。MRIFの領域に対してアトミックメモリアクセスがサポートされているならば、AMOOR命令を使って設定することができる。 さらに、MRIFに書き込んだだけではなく、その後IOMMUはMRIF用に設定されたMSI通知を送信する。

さらに、IMSICのeideliveryレジスタとeithresholdレジスタを保存する領域をMRIF内に確保しておかなければならないのだが、仮想HARTの割り込みファイルをIMSICからMRIFに移動するためには、以下の手順を実行する必要がある。

  1. MRIFのInterrupt-Pendingビットをすべてゼロにして、IMSICの割り込みファイルのeie配列をMRIFのInterrupt-Enableビットにコピーする。
  2. IMSIC割り込みファイルのレジスタ eideliveryeithreshold をどこかのメモリに保存し、eidelivery = 0に設定する。
  3. IOMMUの関連するすべての変換テーブルを変更する。これは、この仮想割り込みファイルのMSIがMRIFに転送されるようにするための処理である。
  4. AMOOR命令を使って、IMSICの割り込みファイルのeip配列の内容をMRIFのInterrupt-Pendingビットに論理ORする。

ハイパーバイザ・ソフトウェアは、 AMOOR および AMOAND 命令を使用して、MRIF の割り込みペンディング・ビットと割り込みイネーブル・ビットを安全に設定およびクリアすることができる。

これの逆で、割り込みファイルを MRIF から IMSIC に戻すには以下の手順を踏む:

  • 戻す対象となる IMSIC 割り込みファイルで、eidelivery = 0 に設定し、eip 配列をゼロにする。
  • IOMMUの関連するすべての変換テーブルを変更する。この仮想割込みファイルのMSIがIMSIC割込みファイルに送信されるようにするためである。
  • CSRS命令を使用して eip 配列に書き込み、MRIF から IMSIC 割り込みファイルにInterrupt-Pendingビットを論理 OR する。また、Interrupt-EnableビットをMRIFからIMSIC割り込みファイルのeie配列にコピーする。
  • IMSIC 割り込みファイルのレジスタ eithresholdeidelivery に、メモリ上に保存してあった値をロードする。