[arch][riscv] simplify the exception decoding logic
Use the sign bit on the cause register to separate interrupts from
exceptions.
@@ -38,29 +38,32 @@ struct riscv_short_iframe {
extern enum handler_return riscv_platform_irq(void);
extern enum handler_return riscv_software_exception(void);
-void riscv_exception_handler(ulong cause, ulong epc, struct riscv_short_iframe *frame) {
+void riscv_exception_handler(long cause, ulong epc, struct riscv_short_iframe *frame) {
LTRACEF("hart %u cause %#lx epc %#lx status %#lx\n",
riscv_current_hart(), cause, epc, frame->status);
- // top bit of the cause register determines if it's an interrupt or not
- const ulong int_bit = (__riscv_xlen == 32) ? (1ul<<31) : (1ul<<63);
-
enum handler_return ret = INT_NO_RESCHEDULE;
- switch (cause) {
+
+ // top bit of the cause register determines if it's an interrupt or not
+ if (cause < 0) {
+ switch (cause & LONG_MAX) {
#if WITH_SMP
- case int_bit | RISCV_EXCEPTION_XSWI: // machine software interrupt
+ case RISCV_EXCEPTION_XSWI: // machine software interrupt
ret = riscv_software_exception();
break;
#endif
- case int_bit | RISCV_EXCEPTION_XTIM: // machine timer interrupt
+ case RISCV_EXCEPTION_XTIM: // machine timer interrupt
ret = riscv_timer_exception();
break;
- case int_bit | RISCV_EXCEPTION_XEXT: // machine external interrupt
+ case RISCV_EXCEPTION_XEXT: // machine external interrupt
ret = riscv_platform_irq();
break;
default:
- TRACEF("unhandled cause %#lx, epc %#lx, tval %#lx\n", cause, epc, riscv_csr_read(RISCV_CSR_XTVAL));
- panic("stopping");
+ panic("unhandled exception cause %#lx, epc %#lx, tval %#lx\n", cause, epc, riscv_csr_read(RISCV_CSR_XTVAL));
+ }
+ } else {
+ // all synchronous traps go here
+ panic("unhandled exception cause %#lx, epc %#lx, tval %#lx\n", cause, epc, riscv_csr_read(RISCV_CSR_XTVAL));
}
if (ret == INT_RESCHEDULE) {
