@@ -49,7 +49,7 @@ void neorv32_rte_setup(void) {
49
49
__neorv32_rte_vector_lut [1 ][index ] = (uint32_t )(& neorv32_rte_debug_handler );
50
50
}
51
51
}
52
- asm volatile ("fence" ); // flush handler table to main memory
52
+ asm volatile ("fence" ); // flush vector table to main memory
53
53
}
54
54
55
55
@@ -60,8 +60,8 @@ void neorv32_rte_setup(void) {
60
60
* @note Trap handler installation applies to both cores. Hence, both
61
61
* cores will execute the same handler for the same trap.
62
62
*
63
- * @param[in] code Identifier (type ) of the targeted trap
64
- * See #NEORV32_RTE_TRAP_enum .
63
+ * @param[in] code Trap code (MCAUSE CSR value ) of the targeted trap.
64
+ * See #NEORV32_EXCEPTION_CODES_enum .
65
65
*
66
66
* @param[in] handler The actual handler function for the specified trap
67
67
* (function must be of type "void function(void);").
@@ -97,7 +97,7 @@ void __attribute__((__naked__,aligned(4))) neorv32_rte_core(void) {
97
97
"addi sp, sp, -16*4 \n"
98
98
#endif
99
99
100
- "sw x0, 0*4(sp) \n" // is always zero, but backup to have a " complete" register frame
100
+ // "sw x0, 0*4(sp) \n" // x0 is hardwired to zero; but add a blank slot here to have a complete stack frame
101
101
"sw x1, 1*4(sp) \n"
102
102
103
103
"csrrw x1, mscratch, sp \n" // mscratch = base address of original context
@@ -136,40 +136,28 @@ void __attribute__((__naked__,aligned(4))) neorv32_rte_core(void) {
136
136
#endif
137
137
);
138
138
139
- // flush context (stack frame) to main memory
140
- // reload trap table from main memory
141
- asm volatile ("fence" );
142
-
143
- // get trap handler base address
139
+ // get trap cause
144
140
uint32_t mcause = neorv32_cpu_csr_read (CSR_MCAUSE );
145
- uint32_t handler_base = 0 ;
146
- handler_base = __neorv32_rte_vector_lut [mcause >> 31 ][mcause & 31 ];
147
-
148
- // call handler
149
- if (handler_base != 0 ) {
150
- typedef void handler_t ();
151
- handler_t * handler = (handler_t * )handler_base ;
152
- handler ();
153
- }
154
-
155
- // compute return address (for exceptions only)
156
- // do not alter return address if instruction access exception (fatal?)
157
- if (((mcause >> 31 ) == 0 ) && (mcause != TRAP_CODE_I_ACCESS )) {
158
-
159
- uint32_t mepc = neorv32_cpu_csr_read (CSR_MEPC );
160
- mepc += 4 ; // default: faulting instruction is uncompressed
161
141
142
+ // compute return address (for synchronous exceptions only)
143
+ if ((mcause >> 31 ) == 0 ) {
144
+ uint32_t mepc = neorv32_cpu_csr_read (CSR_MEPC ) + 4 ; // default: faulting instruction is uncompressed
162
145
#ifdef __riscv_c
163
- // adjust return address if compressed instruction
164
- if ((neorv32_cpu_csr_read (CSR_MTINST ) & 3 ) != 3 ) { // faulting instruction is compressed instruction
165
- mepc -= 2 ;
146
+ if ((neorv32_cpu_csr_read (CSR_MTINST ) & 3 ) != 3 ) {
147
+ mepc -= 2 ; // faulting instruction is compressed 16-bit instruction
166
148
}
167
149
#endif
168
-
169
- // update return address
170
150
neorv32_cpu_csr_write (CSR_MEPC , mepc );
171
151
}
172
152
153
+ // flush context (stack frame) to main memory and reload trap vector table from main memory
154
+ asm volatile ("fence" );
155
+
156
+ // call handler
157
+ typedef void handler_t ();
158
+ handler_t * handler = (handler_t * )__neorv32_rte_vector_lut [mcause >> 31 ][mcause & 31 ];
159
+ handler ();
160
+
173
161
// restore context
174
162
asm volatile (
175
163
// "lw x0, 0*4(sp) \n" // hardwired to zero
@@ -232,7 +220,12 @@ uint32_t neorv32_rte_context_get(int x) {
232
220
#else
233
221
tmp += (x & 31 ) << 2 ;
234
222
#endif
235
- return neorv32_cpu_load_unsigned_word (tmp );
223
+ if (x ) {
224
+ return neorv32_cpu_load_unsigned_word (tmp );
225
+ }
226
+ else { // return zero if x = x0 (hardwired to zero)
227
+ return 0 ;
228
+ }
236
229
}
237
230
238
231
@@ -256,7 +249,9 @@ void neorv32_rte_context_put(int x, uint32_t data) {
256
249
#else
257
250
tmp += (x & 31 ) << 2 ;
258
251
#endif
259
- neorv32_cpu_store_unsigned_word (tmp , data );
252
+ if (x ) { // no store if x = x0 (hardwired to zero)
253
+ neorv32_cpu_store_unsigned_word (tmp , data );
254
+ }
260
255
}
261
256
262
257
@@ -386,4 +381,3 @@ static void __neorv32_rte_print_hex(uint32_t num, int digits) {
386
381
}
387
382
}
388
383
}
389
-
0 commit comments