Skip to content

Commit

Permalink
Handle csr mstatus and misa correctly
Browse files Browse the repository at this point in the history
In the privileged arch-test, we need to set the extensions we used in
the Machine ISA Register and set the Machine Status Register to
privileged mode when we invoke the exception handler
  • Loading branch information
qwe661234 committed Oct 7, 2023
1 parent b23d10a commit c8d4acb
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 30 deletions.
61 changes: 32 additions & 29 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,35 +58,38 @@ static void rv_exception_default_handler(riscv_t *rv)
rv->PC = rv->csr_mepc; /* mret */
}

#define EXCEPTION_HANDLER_IMPL(type, code) \
static void rv_except_##type(riscv_t *rv, uint32_t mtval) \
{ \
/* mtvec (Machine Trap-Vector Base Address Register) \
* mtvec[MXLEN-1:2]: vector base address \
* mtvec[1:0] : vector mode \
*/ \
const uint32_t base = rv->csr_mtvec & ~0x3; \
const uint32_t mode = rv->csr_mtvec & 0x3; \
/* mepc (Machine Exception Program Counter) \
* mtval (Machine Trap Value Register) \
* mcause (Machine Cause Register): store exception code \
*/ \
rv->csr_mepc = rv->PC; \
rv->csr_mtval = mtval; \
rv->csr_mcause = code; \
if (!rv->csr_mtvec) { /* in case CSR is not configured */ \
rv_exception_default_handler(rv); \
return; \
} \
switch (mode) { \
case 0: /* DIRECT: All exceptions set PC to base */ \
rv->PC = base; \
break; \
/* VECTORED: Asynchronous interrupts set PC to base + 4 * code */ \
case 1: \
rv->PC = base + 4 * code; \
break; \
} \
#define EXCEPTION_HANDLER_IMPL(type, code) \
static void rv_except_##type(riscv_t *rv, uint32_t mtval) \
{ \
/* mtvec (Machine Trap-Vector Base Address Register) \
* mtvec[MXLEN-1:2]: vector base address \
* mtvec[1:0] : vector mode \
*/ \
const uint32_t base = rv->csr_mtvec & ~0x3; \
const uint32_t mode = rv->csr_mtvec & 0x3; \
/* mepc (Machine Exception Program Counter) \
* mtval (Machine Trap Value Register) \
* mcause (Machine Cause Register): store exception code \
* mstatus (Machine Status Register): keep track of and controls the \
* hart’s current operating state \
*/ \
rv->csr_mepc = rv->PC; \
rv->csr_mtval = mtval; \
rv->csr_mcause = code; \
rv->csr_mstatus = MSTATUS_MPP; /* set privilege mode */ \
if (!rv->csr_mtvec) { /* in case CSR is not configured */ \
rv_exception_default_handler(rv); \
return; \
} \
switch (mode) { \
case 0: /* DIRECT: All exceptions set PC to base */ \
rv->PC = base; \
break; \
/* VECTORED: Asynchronous interrupts set PC to base + 4 * code */ \
case 1: \
rv->PC = base + 4 * code; \
break; \
} \
}

/* RISC-V exception handlers */
Expand Down
12 changes: 11 additions & 1 deletion src/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,18 @@ void rv_reset(riscv_t *rv, riscv_word_t pc, int argc, char **args)
rv->csr_mtvec = 0;
rv->csr_cycle = 0;
rv->csr_mstatus = 0;

rv->csr_misa |= MISA_SUPER | MISA_USER | MISA_I;
#if RV32_HAS(EXT_A)
rv->csr_misa |= MISA_A;
#endif
#if RV32_HAS(EXT_C)
rv->csr_misa |= MISA_C;
#endif
#if RV32_HAS(EXT_M)
rv->csr_misa |= MISA_M;
#endif
#if RV32_HAS(EXT_F)
rv->csr_misa |= MISA_F;
/* reset float registers */
memset(rv->F, 0, sizeof(float) * N_RV_REGS);
rv->csr_fcsr = 0;
Expand Down
12 changes: 12 additions & 0 deletions src/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ enum {
};
/* clang-format on */

#define MISA_SUPER (1 << ('S' - 'A'))
#define MISA_USER (1 << ('U' - 'A'))
#define MISA_I (1 << ('I' - 'A'))
#define MISA_M (1 << ('M' - 'A'))
#define MISA_A (1 << ('A' - 'A'))
#define MISA_F (1 << ('F' - 'A'))
#define MISA_C (1 << ('C' - 'A'))
#define MSTATUS_MPIE_SHIFT 7
#define MSTATUS_MPP_SHIFT 11
#define MSTATUS_MPIE (1 << MSTATUS_MPIE_SHIFT)
#define MSTATUS_MPP (3 << MSTATUS_MPP_SHIFT)

/* forward declaration for internal structure */
typedef struct riscv_internal riscv_t;
typedef void *riscv_user_t;
Expand Down
1 change: 1 addition & 0 deletions src/rv32_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ RVOP(hret, {

/* MRET: return from traps in U-mode */
RVOP(mret, {
rv->csr_mstatus = MSTATUS_MPIE;
rv->PC = rv->csr_mepc;
return true;
})
Expand Down

1 comment on commit c8d4acb

@jserv
Copy link
Contributor

@jserv jserv commented on c8d4acb Oct 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarks

Benchmark suite Current: c8d4acb Previous: b23d10a Ratio
Dhrystone 1325.5 Average DMIPS over 10 runs 1332.33 Average DMIPS over 10 runs 1.01
Coremark 1024.756 Average iterations/sec over 10 runs 1024.827 Average iterations/sec over 10 runs 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.