2 Commits

Author SHA1 Message Date
thead_admin
d5d8cd2e5c lib/sbi/illegal_insn.c: add emulation for fence.tso 2023-07-30 04:24:52 +08:00
Han Gao
69a3baddbe Linux_SDK_V1.2.0 2023-07-30 04:24:38 +08:00
4 changed files with 27 additions and 1 deletions

View File

@@ -713,6 +713,7 @@ fw_platform_init:
.globl _trap_handler
.globl _trap_exit
_trap_handler:
sfence.vma zero, t0
TRAP_SAVE_AND_SETUP_SP_T0
TRAP_SAVE_MEPC_MSTATUS 0

View File

@@ -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

View File

@@ -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>
@@ -31,6 +32,18 @@ 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();
regs->mepc += 4;
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;
@@ -83,7 +96,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 */

View File

@@ -225,6 +225,15 @@ struct sbi_trap_regs *sbi_trap_handler(struct sbi_trap_regs *regs)
if (mcause & (1UL << (__riscv_xlen - 1))) {
mcause &= ~(1UL << (__riscv_xlen - 1));
/*
* DCACHE.CALL:
* | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
* 0000000 00001 00000 000 00000 0001011
*/
if ((regs->mepc & 0x7f) == 4)
asm volatile(".long 0x0010000b\n");
switch (mcause) {
case IRQ_M_TIMER:
sbi_timer_process();