diff options
Diffstat (limited to 'arch/riscv/lib/interrupts.c')
-rw-r--r-- | arch/riscv/lib/interrupts.c | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c index 0a0995a7af9..3aff0069773 100644 --- a/arch/riscv/lib/interrupts.c +++ b/arch/riscv/lib/interrupts.c @@ -12,7 +12,7 @@ #include <asm/system.h> #include <asm/encoding.h> -static void _exit_trap(int code, uint epc, struct pt_regs *regs); +static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs); int interrupt_init(void) { @@ -34,17 +34,30 @@ int disable_interrupts(void) return 0; } -uint handle_trap(uint mcause, uint epc, struct pt_regs *regs) +ulong handle_trap(ulong cause, ulong epc, struct pt_regs *regs) { - uint is_int; + ulong is_irq, irq; - is_int = (mcause & MCAUSE_INT); - if ((is_int) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) - external_interrupt(0); /* handle_m_ext_interrupt */ - else if ((is_int) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)) - timer_interrupt(0); /* handle_m_timer_interrupt */ - else - _exit_trap(mcause, epc, regs); + is_irq = (cause & MCAUSE_INT); + irq = (cause & ~MCAUSE_INT); + + if (is_irq) { + switch (irq) { + case IRQ_M_EXT: + case IRQ_S_EXT: + external_interrupt(0); /* handle external interrupt */ + break; + case IRQ_M_TIMER: + case IRQ_S_TIMER: + timer_interrupt(0); /* handle timer interrupt */ + break; + default: + _exit_trap(cause, epc, regs); + break; + }; + } else { + _exit_trap(cause, epc, regs); + } return epc; } @@ -60,16 +73,33 @@ __attribute__((weak)) void timer_interrupt(struct pt_regs *regs) { } -static void _exit_trap(int code, uint epc, struct pt_regs *regs) +static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs) { static const char * const exception_code[] = { "Instruction address misaligned", "Instruction access fault", "Illegal instruction", "Breakpoint", - "Load address misaligned" + "Load address misaligned", + "Load access fault", + "Store/AMO address misaligned", + "Store/AMO access fault", + "Environment call from U-mode", + "Environment call from S-mode", + "Reserved", + "Environment call from M-mode", + "Instruction page fault", + "Load page fault", + "Reserved", + "Store/AMO page fault", }; - printf("exception code: %d , %s , epc %08x , ra %08lx\n", - code, exception_code[code], epc, regs->ra); + if (code < ARRAY_SIZE(exception_code)) { + printf("exception code: %ld , %s , epc %lx , ra %lx\n", + code, exception_code[code], epc, regs->ra); + } else { + printf("Reserved\n"); + } + + hang(); } |