Skip to content

Commit fdc08b5

Browse files
committed
[rte] minor rte core optimizations and cleanups
1 parent e77d5e9 commit fdc08b5

File tree

1 file changed

+27
-33
lines changed

1 file changed

+27
-33
lines changed

sw/lib/source/neorv32_rte.c

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ void neorv32_rte_setup(void) {
4949
__neorv32_rte_vector_lut[1][index] = (uint32_t)(&neorv32_rte_debug_handler);
5050
}
5151
}
52-
asm volatile ("fence"); // flush handler table to main memory
52+
asm volatile ("fence"); // flush vector table to main memory
5353
}
5454

5555

@@ -60,8 +60,8 @@ void neorv32_rte_setup(void) {
6060
* @note Trap handler installation applies to both cores. Hence, both
6161
* cores will execute the same handler for the same trap.
6262
*
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.
6565
*
6666
* @param[in] handler The actual handler function for the specified trap
6767
* (function must be of type "void function(void);").
@@ -97,7 +97,7 @@ void __attribute__((__naked__,aligned(4))) neorv32_rte_core(void) {
9797
"addi sp, sp, -16*4 \n"
9898
#endif
9999

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
101101
"sw x1, 1*4(sp) \n"
102102

103103
"csrrw x1, mscratch, sp \n" // mscratch = base address of original context
@@ -136,40 +136,28 @@ void __attribute__((__naked__,aligned(4))) neorv32_rte_core(void) {
136136
#endif
137137
);
138138

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
144140
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
161141

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
162145
#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
166148
}
167149
#endif
168-
169-
// update return address
170150
neorv32_cpu_csr_write(CSR_MEPC, mepc);
171151
}
172152

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+
173161
// restore context
174162
asm volatile (
175163
// "lw x0, 0*4(sp) \n" // hardwired to zero
@@ -232,7 +220,12 @@ uint32_t neorv32_rte_context_get(int x) {
232220
#else
233221
tmp += (x & 31) << 2;
234222
#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+
}
236229
}
237230

238231

@@ -256,7 +249,9 @@ void neorv32_rte_context_put(int x, uint32_t data) {
256249
#else
257250
tmp += (x & 31) << 2;
258251
#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+
}
260255
}
261256

262257

@@ -386,4 +381,3 @@ static void __neorv32_rte_print_hex(uint32_t num, int digits) {
386381
}
387382
}
388383
}
389-

0 commit comments

Comments
 (0)