[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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user