Skip to content

Commit

Permalink
lib: sbi_illegal_insn: Add emulation for fence.tso
Browse files Browse the repository at this point in the history
While OpenC906 appears to properly decode `fence.tso` as a fence
instruction[1], the version of the C906 taped out in the Allwinner D1
does not, and raises illegal instruction.

Handle this errata by emulating `fence.tso` as `fence rw, rw`.

[1]: https://github.com/T-head-Semi/openc906/blob/30827e7f/C906_RTL_FACTORY/gen_rtl/idu/rtl/aq_idu_id_decd.v#L2097

Signed-off-by: Samuel Holland <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
  • Loading branch information
smaeul authored and Fishwaldo committed Apr 9, 2024
1 parent 1bd2e81 commit d009644
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
3 changes: 3 additions & 0 deletions opensbi/include/sbi/riscv_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,9 @@
#define INSN_MASK_WFI 0xffffff00
#define INSN_MATCH_WFI 0x10500000

#define INSN_MASK_FENCE_TSO 0xffffffff
#define INSN_MATCH_FENCE_TSO 0x8330000f

#define INSN_16BIT_MASK 0x3
#define INSN_32BIT_MASK 0x1c

Expand Down
14 changes: 13 additions & 1 deletion opensbi/lib/sbi/sbi_illegal_insn.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

#include <sbi/riscv_asm.h>
#include <sbi/riscv_barrier.h>
#include <sbi/riscv_encoding.h>
#include <sbi/sbi_bitops.h>
#include <sbi/sbi_emulate_csr.h>
Expand All @@ -31,6 +32,17 @@ static int truly_illegal_insn(ulong insn, struct sbi_trap_regs *regs)
return sbi_trap_redirect(regs, &trap);
}

static int misc_mem_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
{
/* Errata workaround: emulate `fence.tso` as `fence rw, rw`. */
if ((insn & INSN_MASK_FENCE_TSO) == INSN_MATCH_FENCE_TSO) {
smp_mb();
return 0;
}

return truly_illegal_insn(insn, regs);
}

static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
{
int do_write, rs1_num = (insn >> 15) & 0x1f;
Expand Down Expand Up @@ -83,7 +95,7 @@ static illegal_insn_func illegal_insn_table[32] = {
truly_illegal_insn, /* 0 */
truly_illegal_insn, /* 1 */
truly_illegal_insn, /* 2 */
truly_illegal_insn, /* 3 */
misc_mem_opcode_insn, /* 3 */
truly_illegal_insn, /* 4 */
truly_illegal_insn, /* 5 */
truly_illegal_insn, /* 6 */
Expand Down

0 comments on commit d009644

Please sign in to comment.