Skip to content

Commit

Permalink
Add supervisor memory fence instruction SFENCE.VMA (sysprog21#458)
Browse files Browse the repository at this point in the history
The supervisor memory-management fence instruction SFENCE.VMA is used
to synchronize updates to in-memory memory-management data structures
with current execution. Linux kernel leverage this instruction for
synchronization, support emulating this instruction is needed to boot
Linux kernel. Since we have only one hart and we have not yet support
cache (TLB) at present, the implementation of this instruction is
straight forward and it could be further improved in the future.

Related: sysprog21#310, sysprog21#438
  • Loading branch information
ChinYikMing authored Jun 16, 2024
1 parent 30ae2a0 commit 1e769a5
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -810,12 +810,22 @@ static inline bool op_system(rv_insn_t *ir, const uint32_t insn)
* MRET 001100000010 00000 000 00000 1110011
*/

/* inst funct7 rs2 rs1 funct3 rd opcode
* -----------+-------+---+---+------+------+-------
* SFENCE.VMA 0001001 rs2 rs1 000 00000 1110011
*/

/* decode I-type */
decode_itype(ir, insn);

/* dispatch from funct3 field */
switch (decode_funct3(insn)) {
case 0:
if ((insn >> 25) == 0b0001001) { /* SFENCE.VMA */
ir->opcode = rv_insn_sfencevma;
break;
}

/* dispatch from imm field */
switch (ir->imm) {
case 0: /* ECALL: Environment Call */
Expand Down
1 change: 1 addition & 0 deletions src/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ enum op_field {
_(sret, 1, 4, 0, ENC(rs1, rd)) \
_(hret, 0, 4, 0, ENC(rs1, rd)) \
_(mret, 1, 4, 0, ENC(rs1, rd)) \
_(sfencevma, 1, 4, 0, ENC(rs1, rs2, rd)) \
/* RV32 Zifencei Standard Extension */ \
IIF(RV32_HAS(Zifencei))( \
_(fencei, 1, 4, 0, ENC(rs1, rd)) \
Expand Down
7 changes: 6 additions & 1 deletion src/rv32_constopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,14 @@ CONSTOPT(sret, {})
/* HRET: return from traps in H-mode */
CONSTOPT(hret, {})

/* MRET: return from traps in U-mode */
/* MRET: return from traps in M-mode */
CONSTOPT(mret, {})

/* SFENCE.VMA: synchronize updates to in-memory memory-management data
* structures with current execution
*/
CONSTOPT(sfencevma, {})

#if RV32_HAS(Zifencei) /* RV32 Zifencei Standard Extension */
CONSTOPT(fencei, {})
#endif
Expand Down
14 changes: 14 additions & 0 deletions src/rv32_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,20 @@ RVOP(
assert; /* FIXME: Implement */
}))

/* SFENCE.VMA: synchronize updates to in-memory memory-management data
* structures with current execution
*/
RVOP(
sfencevma,
{
PC += 4;
/* FIXME: fill real implementations */
goto end_op;
},
GEN({
assert; /* FIXME: Implement */
}))

#if RV32_HAS(Zifencei) /* RV32 Zifencei Standard Extension */
RVOP(
fencei,
Expand Down
2 changes: 2 additions & 0 deletions src/t2c_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ T2C_OP(hret, { __UNREACHABLE; })

T2C_OP(mret, { __UNREACHABLE; })

T2C_OP(sfencevma, { __UNREACHABLE; })

#if RV32_HAS(Zifencei)
T2C_OP(fencei, { __UNREACHABLE; })
#endif
Expand Down

0 comments on commit 1e769a5

Please sign in to comment.