FPGA開発日記

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

RISC-Vの特権レジスタ群の割り当てまとめ

訳あってRISC-Vの特権レジスタ群の仕様を読み込んでいるのだが、Privilege Instructionの仕様書をしっかり読むとなかなか面白い。 Chapter-2のControl and Status Registers(CSR)ではCSRレジスタ群についてまずは簡単に分類がされているのだが、いろんなことを考慮した構成になっているのでまとめてみようと思う。

CSRレジスタ群のアドレスマップ

そもそもCSRレジスタ群は12ビットのアドレスマップから構成されており、最大で4096個のCSRレジスタを格納することができる。この12ビットのアドレスは上位から分類がなされており、まとめると大体以下のようになる。

11:10 9:8 7:6 5:0
Read-Write Accesibilty Lowest Privilege Standard/Non-standard Others
00 Read & Write User Standard
01 Read & Write Supervisor Standard
10 Read & Write Hypervisor Standard
11 Read Only Machine Non-standard

つまり、上位の11-10ビットは読み書きの特性を表し、9-8ビットはアクセス可能な特権モード、7-6ビットは特殊なモードかどうかを指定するレジスタとなる。このように分類することで、ハードウェアが特権アクセス違反などを簡単に検出することができるようになる。

Shadow Registersについて

RISC-VのCSRを読み解いていると、CSRレジスタマップ上にShadow-Registersという空間が定義されているのがわかる。 Shadow-Registerについて簡単にまとめると

  • より低い特権モードではRead-Onlyレジスタであるが、高い特権モードになるとRead-Write可能なレジスタ

ということになる。このような空間を用意した理由として、たとえばユーザモードではRead-Onlyだが、マシンモードではRead-Write可能なCSRが存在しているとすると、そのレジスタをShadow-Registerに配置しておく。 すると、通常はユーザモードでアクセスすると特権例外でReadすら出来ないのだが、Shadow-Registerに配置しておくとWriteは出来ないがReadは可能になる。 これにより仮想マシンなどユーザモード中で動作するプログラムが特権モードを取得するために例外に飛ぶ機会を減らすことが出来る(という理解で良いのだろうか?)。

たとえば、マシンモードのShadow-Registerには以下のレジスタ群が割り当てられていた。

f:id:msyksphinz:20170103012607p:plain

f:id:msyksphinz:20170103012638p:plain

これはパフォーマンスカウンタは、読み取り専用なのでユーザモードから読めても良い、ということなのだろうか。まあ、書き込みさえ出来なければ、ユーザモードから直接このような性能調査系のシステムレジスタは読めても良い気がする。

StandardレジスタとNon-standardレジスタ群について

StandardレジスタとNon-standardレジスタ群の違いについては、

  • Standard : この仕様以降で再定義されることがある
  • Non-standard : この仕様以降で再定義されることはない

というものらしい。イメージでは逆のような気がするのだけれども?

とりあえず、現状Non-standardに割り当てられているCSRレジスタ群は存在していないようだ。