@@ -40,14 +40,25 @@ extern struct target_ops gdbstub_ops;
40
40
_ (breakpoint ) /* Breakpoint */ \
41
41
_ (load_misaligned ) /* Load address misaligned */ \
42
42
_ (load_fault ) /* Load access fault */ \
43
- _ (store_misaligned ) /* Store/AMO address misaligned */
43
+ _ (store_misaligned ) /* Store/AMO address misaligned */ \
44
+ _ (store_fault ) /* Store/AMO access fault */ \
45
+ _ (ecall_U ) /* Environment call from U-mode */ \
46
+ _ (ecall_S ) /* Environment call from S-mode */ \
47
+ _ (reserved ) /* Reserved */ \
48
+ _ (ecall_M ) /* Environment call from M-mode */
44
49
45
50
enum {
46
51
#define _ (type ) GET_EXCEPTION_CODE(type),
47
52
RV_EXCEPTION_LIST
48
53
#undef _
49
54
};
50
55
56
+ static void rv_exception_default_handler (struct riscv_t * rv )
57
+ {
58
+ rv -> csr_mepc += rv -> insn_len ;
59
+ rv -> PC = rv -> csr_mepc ; /* mret */
60
+ }
61
+
51
62
#define EXCEPTION_HANDLER_IMPL (type ) \
52
63
UNUSED static void rv_except_##type(struct riscv_t *rv, uint32_t mtval) \
53
64
{ \
@@ -61,9 +72,15 @@ enum {
61
72
const uint32_t code = GET_EXCEPTION_CODE (type ); \
62
73
/* mepc (Machine Exception Program Counter) \
63
74
* mtval (Machine Trap Value Register) \
75
+ * mcause (Machine Cause Register): store exception code \
64
76
*/ \
65
77
rv -> csr_mepc = rv -> PC ; \
66
78
rv -> csr_mtval = mtval ; \
79
+ rv -> csr_mcause = code ; \
80
+ if (!rv -> csr_mtvec ) { /* elf doesn't implement csr instruction */ \
81
+ rv_exception_default_handler (rv ); \
82
+ return ; \
83
+ } \
67
84
switch (mode ) { \
68
85
case 0 : /* DIRECT: All exceptions set PC to base */ \
69
86
rv -> PC = base ; \
73
90
rv -> PC = base + 4 * code ; \
74
91
break ; \
75
92
} \
76
- /* mcause (Machine Cause Register): store exception code */ \
77
- rv -> csr_mcause = code ; \
78
93
}
79
94
80
95
/* RISC-V exception handlers */
@@ -775,7 +790,7 @@ static inline bool op_system(struct riscv_t *rv, uint32_t insn)
775
790
switch (funct12 ) { /* dispatch from imm field */
776
791
case 0 : /* ECALL: Environment Call */
777
792
rv -> io .on_ecall (rv );
778
- break ;
793
+ return true ;
779
794
case 1 : /* EBREAK: Environment Break */
780
795
rv -> io .on_ebreak (rv );
781
796
return true;
@@ -2118,6 +2133,7 @@ void rv_reset(struct riscv_t *rv, riscv_word_t pc)
2118
2133
rv -> X [rv_reg_sp ] = DEFAULT_STACK_ADDR ;
2119
2134
2120
2135
/* reset the csrs */
2136
+ rv -> csr_mtvec = 0 ;
2121
2137
rv -> csr_cycle = 0 ;
2122
2138
rv -> csr_mstatus = 0 ;
2123
2139
@@ -2141,3 +2157,10 @@ void ebreak_handler(struct riscv_t *rv)
2141
2157
assert (rv );
2142
2158
rv_except_breakpoint (rv , rv -> PC );
2143
2159
}
2160
+
2161
+ void ecall_handler (struct riscv_t * rv )
2162
+ {
2163
+ assert (rv );
2164
+ rv_except_ecall_M (rv , 0 );
2165
+ syscall_handler (rv );
2166
+ }
0 commit comments