@@ -24,160 +24,56 @@ extern struct target_ops gdbstub_ops;
24
24
#include "riscv.h"
25
25
#include "riscv_private.h"
26
26
27
- static void rv_except_insn_misaligned (struct riscv_t * rv , uint32_t old_pc )
28
- {
29
- /* mtvec (Machine Trap-Vector Base Address Register)
30
- * mtvec[MXLEN-1:2]: vector base address
31
- * mtvec[1:0] : vector mode
32
- */
33
- const uint32_t base = rv -> csr_mtvec & ~0x3 ;
34
- const uint32_t mode = rv -> csr_mtvec & 0x3 ;
35
-
36
- /* Exception Code: Instruction Address Misaligned */
37
- const uint32_t code = 0 ;
38
-
39
- /* mepc (Machine Exception Program Counter)
40
- * mtval (Machine Trap Value Register) : Misaligned Instruction
41
- */
42
- rv -> csr_mepc = old_pc ;
43
- rv -> csr_mtval = rv -> PC ;
44
-
45
- switch (mode ) {
46
- case 0 : /* DIRECT: All exceptions set PC to base */
47
- rv -> PC = base ;
48
- break ;
49
- case 1 : /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
50
- rv -> PC = base + 4 * code ;
51
- break ;
27
+ /* RISC-V exception code list */
28
+ #define GET_EXCEPTION_CODE (type ) rv_exception_code_##type
29
+ #define RV_EXCEPTION_LIST \
30
+ _(insn_misaligned) /* Instruction address misaligned */ \
31
+ _ (insn_fault ) /* Instruction access fault */ \
32
+ _ (illegal_insn ) /* Illegal instruction */ \
33
+ _ (breakpoint ) /* Breakpoint */ \
34
+ _ (load_misaligned ) /* Load address misaligned */ \
35
+ _ (load_fault ) /* Load access fault */ \
36
+ _ (store_misaligned ) /* Store/AMO address misaligned */
37
+
38
+ enum {
39
+ #define _ (type ) GET_EXCEPTION_CODE(type),
40
+ RV_EXCEPTION_LIST
41
+ #undef _
42
+ };
43
+
44
+ #define EXCEPTION_HANDLER_IMPL (type ) \
45
+ UNUSED static void rv_except_##type(struct riscv_t *rv, uint32_t mtval) \
46
+ { \
47
+ /* mtvec (Machine Trap-Vector Base Address Register) \
48
+ * mtvec[MXLEN-1:2]: vector base address \
49
+ * mtvec[1:0] : vector mode \
50
+ */ \
51
+ const uint32_t base = rv -> csr_mtvec & ~0x3 ; \
52
+ const uint32_t mode = rv -> csr_mtvec & 0x3 ; \
53
+ /* Exception Code */ \
54
+ const uint32_t code = GET_EXCEPTION_CODE (type ); \
55
+ /* mepc (Machine Exception Program Counter) \
56
+ * mtval (Machine Trap Value Register) \
57
+ */ \
58
+ rv -> csr_mepc = rv -> PC ; \
59
+ rv -> csr_mtval = mtval ; \
60
+ switch (mode ) { \
61
+ case 0 : /* DIRECT: All exceptions set PC to base */ \
62
+ rv -> PC = base ; \
63
+ break ; \
64
+ /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */ \
65
+ case 1 : \
66
+ rv -> PC = base + 4 * code ; \
67
+ break ; \
68
+ } \
69
+ /* mcause (Machine Cause Register): store exception code */ \
70
+ rv -> csr_mcause = code ; \
52
71
}
53
72
54
- /* mcause (Machine Cause Register): store exception code */
55
- rv -> csr_mcause = code ;
56
- }
57
-
58
- static void rv_except_load_misaligned (struct riscv_t * rv , uint32_t addr )
59
- {
60
- /* mtvec (Machine Trap-Vector Base Address Register)
61
- * mtvec[MXLEN-1:2]: vector base address
62
- * mtvec[1:0] : vector mode
63
- */
64
- const uint32_t base = rv -> csr_mtvec & ~0x3 ;
65
- const uint32_t mode = rv -> csr_mtvec & 0x3 ;
66
-
67
- /* Exception Code: Load Address Misaligned */
68
- const uint32_t code = 4 ;
69
-
70
- /* mepc (Machine Exception Program Counter)
71
- * mtval(Machine Trap Value Register) : Misaligned Load Address
72
- */
73
- rv -> csr_mepc = rv -> PC ;
74
- rv -> csr_mtval = addr ;
75
-
76
- switch (mode ) {
77
- case 0 : /* DIRECT: All exceptions set PC to base */
78
- rv -> PC = base ;
79
- break ;
80
- case 1 : /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
81
- rv -> PC = base + 4 * code ;
82
- break ;
83
- }
84
-
85
- /* mcause (Machine Cause Register): store exception code */
86
- rv -> csr_mcause = code ;
87
- }
88
-
89
- static void rv_except_store_misaligned (struct riscv_t * rv , uint32_t addr )
90
- {
91
- /* mtvec (Machine Trap-Vector Base Address Register)
92
- * mtvec[MXLEN-1:2]: vector base address
93
- * mtvec[1:0] : vector mode
94
- */
95
- const uint32_t base = rv -> csr_mtvec & ~0x3 ;
96
- const uint32_t mode = rv -> csr_mtvec & 0x3 ;
97
-
98
- /* Exception Code: Store Address Misaligned */
99
- const uint32_t code = 6 ;
100
-
101
- /* mepc (Machine Exception Program Counter)
102
- * mtval(Machine Trap Value Register) : Misaligned Store Address
103
- */
104
- rv -> csr_mepc = rv -> PC ;
105
- rv -> csr_mtval = addr ;
106
-
107
- switch (mode ) {
108
- case 0 : /* DIRECT: All exceptions set PC to base */
109
- rv -> PC = base ;
110
- break ;
111
- case 1 : /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
112
- rv -> PC = base + 4 * code ;
113
- break ;
114
- }
115
-
116
- /* mcause (Machine Cause Register): store exception code */
117
- rv -> csr_mcause = code ;
118
- }
119
-
120
- static void rv_except_illegal_insn (struct riscv_t * rv , uint32_t insn )
121
- {
122
- /* mtvec (Machine Trap-Vector Base Address Register)
123
- * mtvec[MXLEN-1:2]: vector base address
124
- * mtvec[1:0] : vector mode
125
- */
126
- const uint32_t base = rv -> csr_mtvec & ~0x3 ;
127
- const uint32_t mode = rv -> csr_mtvec & 0x3 ;
128
-
129
- /* Exception Code: Illegal Instruction */
130
- const uint32_t code = 2 ;
131
-
132
- /* mepc (Machine Exception Program Counter)
133
- * mtval(Machine Trap Value Register) : Illegal Instruction
134
- */
135
- rv -> csr_mepc = rv -> PC ;
136
- rv -> csr_mtval = insn ;
137
-
138
- switch (mode ) {
139
- case 0 : /* DIRECT: All exceptions set PC to base */
140
- rv -> PC = base ;
141
- break ;
142
- case 1 : /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
143
- rv -> PC = base + 4 * code ;
144
- break ;
145
- }
146
-
147
- /* mcause (Machine Cause Register): store exception code */
148
- rv -> csr_mcause = code ;
149
- }
150
-
151
- static void rv_except_breakpoint (struct riscv_t * rv , uint32_t old_pc )
152
- {
153
- /* mtvec (Machine Trap-Vector Base Address Register)
154
- * mtvec[MXLEN-1:2]: vector base address
155
- * mtvec[1:0] : vector mode
156
- */
157
- const uint32_t base = rv -> csr_mtvec & ~0x3 ;
158
- const uint32_t mode = rv -> csr_mtvec & 0x3 ;
159
-
160
- /* Exception Code: Breakpoint */
161
- const uint32_t code = 3 ;
162
-
163
- /* mepc (Machine Exception Program Counter)
164
- * mtval(Machine Trap Value Register) : Breakpoint
165
- */
166
- rv -> csr_mepc = old_pc ;
167
- rv -> csr_mtval = old_pc ;
168
-
169
- switch (mode ) {
170
- case 0 : /* DIRECT: All exceptions set PC to base */
171
- rv -> PC = base ;
172
- break ;
173
- case 1 : /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
174
- rv -> PC = base + 4 * code ;
175
- break ;
176
- }
177
-
178
- /* mcause (Machine Cause Register): store exception code */
179
- rv -> csr_mcause = code ;
180
- }
73
+ /* RISC-V exception handlers */
74
+ #define _ (type ) EXCEPTION_HANDLER_IMPL(type)
75
+ RV_EXCEPTION_LIST
76
+ #undef _
181
77
182
78
/* RV32I Base Instruction Set
183
79
*
0 commit comments