@@ -32,53 +32,59 @@ extern struct target_ops gdbstub_ops;
32
32
#include "riscv_private.h"
33
33
34
34
/* RISC-V exception code list */
35
- #define GET_EXCEPTION_CODE (type ) rv_exception_code_##type
36
- #define RV_EXCEPTION_LIST \
37
- _(insn_misaligned) /* Instruction address misaligned */ \
38
- _ (insn_fault ) /* Instruction access fault */ \
39
- _ (illegal_insn ) /* Illegal instruction */ \
40
- _ (breakpoint ) /* Breakpoint */ \
41
- _ (load_misaligned ) /* Load address misaligned */ \
42
- _ (load_fault ) /* Load access fault */ \
43
- _ (store_misaligned ) /* Store/AMO address misaligned */
35
+ #define RV_EXCEPTION_LIST \
36
+ _(insn_misaligned, 0) /* Instruction address misaligned */ \
37
+ _ (illegal_insn , 2 ) /* Illegal instruction */ \
38
+ _ (breakpoint , 3 ) /* Breakpoint */ \
39
+ _ (load_misaligned , 4 ) /* Load address misaligned */ \
40
+ _ (store_misaligned , 6 ) /* Store/AMO address misaligned */ \
41
+ _ (ecall_M , 11 ) /* Environment call from M-mode */
44
42
45
43
enum {
46
- #define _ (type ) GET_EXCEPTION_CODE( type) ,
44
+ #define _ (type , code ) rv_exception_code## type = code ,
47
45
RV_EXCEPTION_LIST
48
46
#undef _
49
47
};
50
48
51
- #define EXCEPTION_HANDLER_IMPL (type ) \
52
- UNUSED static void rv_except_##type(struct riscv_t *rv, uint32_t mtval) \
53
- { \
54
- /* mtvec (Machine Trap-Vector Base Address Register) \
55
- * mtvec[MXLEN-1:2]: vector base address \
56
- * mtvec[1:0] : vector mode \
57
- */ \
58
- const uint32_t base = rv -> csr_mtvec & ~0x3 ; \
59
- const uint32_t mode = rv -> csr_mtvec & 0x3 ; \
60
- /* Exception Code */ \
61
- const uint32_t code = GET_EXCEPTION_CODE (type ); \
62
- /* mepc (Machine Exception Program Counter) \
63
- * mtval (Machine Trap Value Register) \
64
- */ \
65
- rv -> csr_mepc = rv -> PC ; \
66
- rv -> csr_mtval = mtval ; \
67
- switch (mode ) { \
68
- case 0 : /* DIRECT: All exceptions set PC to base */ \
69
- rv -> PC = base ; \
70
- break ; \
71
- /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */ \
72
- case 1 : \
73
- rv -> PC = base + 4 * code ; \
74
- break ; \
75
- } \
76
- /* mcause (Machine Cause Register): store exception code */ \
77
- rv -> csr_mcause = code ; \
49
+ static void rv_exception_default_handler (struct riscv_t * rv )
50
+ {
51
+ rv -> csr_mepc += rv -> insn_len ;
52
+ rv -> PC = rv -> csr_mepc ; /* mret */
53
+ }
54
+
55
+ #define EXCEPTION_HANDLER_IMPL (type , code ) \
56
+ static void rv_except_##type(struct riscv_t *rv, uint32_t mtval) \
57
+ { \
58
+ /* mtvec (Machine Trap-Vector Base Address Register) \
59
+ * mtvec[MXLEN-1:2]: vector base address \
60
+ * mtvec[1:0] : vector mode \
61
+ */ \
62
+ const uint32_t base = rv -> csr_mtvec & ~0x3 ; \
63
+ const uint32_t mode = rv -> csr_mtvec & 0x3 ; \
64
+ /* mepc (Machine Exception Program Counter) \
65
+ * mtval (Machine Trap Value Register) \
66
+ * mcause (Machine Cause Register): store exception code \
67
+ */ \
68
+ rv -> csr_mepc = rv -> PC ; \
69
+ rv -> csr_mtval = mtval ; \
70
+ rv -> csr_mcause = code ; \
71
+ if (!rv -> csr_mtvec ) { /* in case CSR is not configured */ \
72
+ rv_exception_default_handler (rv ); \
73
+ return ; \
74
+ } \
75
+ switch (mode ) { \
76
+ case 0 : /* DIRECT: All exceptions set PC to base */ \
77
+ rv -> PC = base ; \
78
+ break ; \
79
+ /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */ \
80
+ case 1 : \
81
+ rv -> PC = base + 4 * code ; \
82
+ break ; \
83
+ } \
78
84
}
79
85
80
86
/* RISC-V exception handlers */
81
- #define _ (type ) EXCEPTION_HANDLER_IMPL(type)
87
+ #define _ (type , code ) EXCEPTION_HANDLER_IMPL(type, code )
82
88
RV_EXCEPTION_LIST
83
89
#undef _
84
90
@@ -775,7 +781,7 @@ static inline bool op_system(struct riscv_t *rv, uint32_t insn)
775
781
switch (funct12 ) { /* dispatch from imm field */
776
782
case 0 : /* ECALL: Environment Call */
777
783
rv -> io .on_ecall (rv );
778
- break ;
784
+ return true ;
779
785
case 1 : /* EBREAK: Environment Break */
780
786
rv -> io .on_ebreak (rv );
781
787
return true;
@@ -2118,6 +2124,7 @@ void rv_reset(struct riscv_t *rv, riscv_word_t pc)
2118
2124
rv -> X [rv_reg_sp ] = DEFAULT_STACK_ADDR ;
2119
2125
2120
2126
/* reset the csrs */
2127
+ rv -> csr_mtvec = 0 ;
2121
2128
rv -> csr_cycle = 0 ;
2122
2129
rv -> csr_mstatus = 0 ;
2123
2130
@@ -2141,3 +2148,10 @@ void ebreak_handler(struct riscv_t *rv)
2141
2148
assert (rv );
2142
2149
rv_except_breakpoint (rv , rv -> PC );
2143
2150
}
2151
+
2152
+ void ecall_handler (struct riscv_t * rv )
2153
+ {
2154
+ assert (rv );
2155
+ rv_except_ecall_M (rv , 0 );
2156
+ syscall_handler (rv );
2157
+ }
0 commit comments