[arch][riscv] simplify the exception decoding logic

Use the sign bit on the cause register to separate interrupts from
exceptions.
This commit is contained in:
Travis Geiselbrecht
2020-05-15 18:44:51 -07:00
parent a5e6261e48
commit 3e66ea6361

View File

@@ -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
ret = riscv_software_exception();
break;
case RISCV_EXCEPTION_XSWI: // machine software interrupt
ret = riscv_software_exception();
break;
#endif
case int_bit | RISCV_EXCEPTION_XTIM: // machine timer interrupt
ret = riscv_timer_exception();
break;
case int_bit | 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");
case RISCV_EXCEPTION_XTIM: // machine timer interrupt
ret = riscv_timer_exception();
break;
case RISCV_EXCEPTION_XEXT: // machine external interrupt
ret = riscv_platform_irq();
break;
default:
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) {