FPGA開発日記

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

RISC-Vの例外処理の機構

RISC-Vの権限階層は4階層構造を取っている。強い方から順に、

  • Machine Mode
  • Hypervisor Mode
  • Supervisor Mode
  • User mode

ちなみに、Hypervisorモードはまだちゃんとした規定が無い。命令については、Under constructionという感じだ。とりあえずパタンとしては、User→Supervisor→Machineモードと遷移していっても問題無い気がする。 もちろん、上位の階層のシステムレジスタに書き込むことはできない。例外処理などのために、RISC-Vのシステムレジスタは各階層別にシステムレジスタを保持している。

  • mstatus, mepc, mcause, etc... ; マシンレベルでのCPUの状態を示す
  • hstatus, hepc, hcause, etc... ; ハイパーバイザレベルでのCPUの状態を示す
  • sstatus, sepc, scause, etc... ; スーパバイザレベルでのCPUの状態を示す

などが存在する。

ひとまず、あるCPUの実行モード中に例外が発生(ミスアラインアクセスなど)すると、Trapベクタに従って例外に飛ぶ。このとき、権限が一つ上げられる。

f:id:msyksphinz:20150602022527j:plain

例外ベクタ中で要因(xstatusレジスタに格納される)を解析し、要因ごとに処理を実施するのだと思う。 また、権限を一つ上げたり、元に戻ったりするためには、以下の命令が用意されている。

  • ECALL; 一つ上の権限に上がる。Trapを発生し、必要な情報をシステムレジスタに記録して、権限を上げる。
  • EBREAK; ブレークポイント例外を発生させる。
  • ERET; 前の権限に戻る。必要な情報をシステムレジスタから書き戻す。

f:id:msyksphinz:20150602022831j:plain

これらの基本的な権限と、例外処理系の機構が備わっていれば、とりあえずテストパタンを複雑なやつも、通るようになると思う。

滅茶苦茶な実装だが、とりあえず自作シミュレータにトラップ系の機構と階層機構を定義して実行してみた(まだ権限毎のライトプロテクトとか全然である)。

[M]         99 : [000002f0] 02049063 : bne        r09,r00,0x01         r09=>00000000 r00=>00000000
[M]        100 : [000002f4] 00400313 : addi       r06,r00,0x004        r00=>00000000 r06<=00000004
[M]        101 : [000002f8] 342022f3 : csrrs      r05,0x342,r00        r00=>00000000 mcause=>00000004 r05<=00000004
[M]        102 : [000002fc] fc6298e3 : bne        r05,r06,0x7e         r05=>00000004 r06=>00000004
[M]        103 : [00000300] 341022f3 : csrrs      r05,0x341,r00        r00=>00000000 mepc=>00000280 r05<=00000280
[M]        104 : [00000304] 00828293 : addi       r05,r05,0x008        r05=>00000280 r05<=00000288
[M]        105 : [00000308] 34129073 : csrrw      r00,0x341,r05        mepc=>00000280 r05=>00000288 mepc<=00000288 r00<=00000280
[S]        106 : [0000030c] 10000073 : eret                            mepc=>00000288 pc<=00000288
[S]        107 : [00000288] 00600e13 : addi       r28,r00,0x006        r00=>00000000 r28<=00000006
<Error: Address Misalign: Byte Addr = 000002f3>
[M]        108 : [0000028c] 00342003 : lw         r00,r08,0x003        r08=>000002f0 mepc<=0000028c mcause<=00000004 stvec=>00000140 pc<=00000140 (000002f3)=>ffffffff r00<=ffffffff
[M]        109 : [00000140] 34202f73 : csrrs      r30,0x342,r00        r00=>00000000 mcause=>00000004 r30<=00000004
[M]        110 : [00000144] fa0f5ee3 : bge        r30,r00,0x7d         r30=>00000004 r00=>00000000 pc<=00000100
[M]        111 : [00000100] 00000f17 : auipc      r30,0x00000          r30<=00000100
[M]        112 : [00000104] 22cf0f13 : addi       r30,r30,0x22c        r30=>00000100 r30<=0000032c
[M]        113 : [00000108] 34102ff3 : csrrs      r31,0x341,r00        r00=>00000000 mepc=>0000028c r31<=0000028c
[M]        114 : [0000010c] 07ff0c63 : beq        r30,r31,0x03         r30=>0000032c r31=>0000028c
[M]        115 : [00000110] 00000f17 : auipc      r30,0x00000          r30<=00000110
[M]        116 : [00000114] ef0f0f13 : addi       r30,r30,0xef0        r30=>00000110 r30<=00000000
[M]        117 : [00000118] 020f1863 : bne        r30,r00,0x01         r30=>00000000 r00=>00000000
[M]        118 : [0000011c] 00000f17 : auipc      r30,0x00000          r30<=0000011c
[M]        119 : [00000120] 1d4f0f13 : addi       r30,r30,0x1d4        r30=>0000011c r30<=000002f0
[M]        120 : [00000124] 1c0f1663 : bne        r30,r00,0x0e         r30=>000002f0 r00=>00000000 pc<=000002f0
[M]        121 : [000002f0] 02049063 : bne        r09,r00,0x01         r09=>00000000 r00=>00000000
[M]        122 : [000002f4] 00400313 : addi       r06,r00,0x004        r00=>00000000 r06<=00000004
[M]        123 : [000002f8] 342022f3 : csrrs      r05,0x342,r00        r00=>00000000 mcause=>00000004 r05<=00000004
[M]        124 : [000002fc] fc6298e3 : bne        r05,r06,0x7e         r05=>00000004 r06=>00000004
[M]        125 : [00000300] 341022f3 : csrrs      r05,0x341,r00        r00=>00000000 mepc=>0000028c r05<=0000028c
[M]        126 : [00000304] 00828293 : addi       r05,r05,0x008        r05=>0000028c r05<=00000294
[M]        127 : [00000308] 34129073 : csrrw      r00,0x341,r05        mepc=>0000028c r05=>00000294 mepc<=00000294 r00<=0000028c

かろうじてミスアラインのテストパタンは通るようになったかなー。上記のログを見ると、Supervisorのモードでミスアライン例外が発生して、マシンモードに遷移している。 このとき、スーパバイザからの遷移は、Trapベクタによって0x140に飛ぶと規定されているので、そのようになっている。 xcauseレジスタに格納されている(この場合はmcause)のは、例外の要因だ。

f:id:msyksphinz:20150602023157j:plain

この規定によると、ミスアラインアクセスの場合はException Codeとして4を挿入することになっているので、mcauseに4を入れたという訳だ。ここらへんの機構としては、一応理解はしたつもりだけど、まだ通らないパタンがあるなー。