@@ -32,53 +32,59 @@ extern struct target_ops gdbstub_ops;
3232#include "riscv_private.h"
3333
3434/* 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 */
4442
4543enum {
46- #define _ (type ) GET_EXCEPTION_CODE( type) ,
44+ #define _ (type , code ) rv_exception_code## type = code ,
4745 RV_EXCEPTION_LIST
4846#undef _
4947};
5048
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+ } \
7884 }
7985
8086/* RISC-V exception handlers */
81- #define _ (type ) EXCEPTION_HANDLER_IMPL(type)
87+ #define _ (type , code ) EXCEPTION_HANDLER_IMPL(type, code )
8288RV_EXCEPTION_LIST
8389#undef _
8490
@@ -775,7 +781,7 @@ static inline bool op_system(struct riscv_t *rv, uint32_t insn)
775781 switch (funct12 ) { /* dispatch from imm field */
776782 case 0 : /* ECALL: Environment Call */
777783 rv -> io .on_ecall (rv );
778- break ;
784+ return true ;
779785 case 1 : /* EBREAK: Environment Break */
780786 rv -> io .on_ebreak (rv );
781787 return true;
@@ -2118,6 +2124,7 @@ void rv_reset(struct riscv_t *rv, riscv_word_t pc)
21182124 rv -> X [rv_reg_sp ] = DEFAULT_STACK_ADDR ;
21192125
21202126 /* reset the csrs */
2127+ rv -> csr_mtvec = 0 ;
21212128 rv -> csr_cycle = 0 ;
21222129 rv -> csr_mstatus = 0 ;
21232130
@@ -2141,3 +2148,10 @@ void ebreak_handler(struct riscv_t *rv)
21412148 assert (rv );
21422149 rv_except_breakpoint (rv , rv -> PC );
21432150}
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