// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2016-17 Microsemi Corporation. * Padmarao Begari, Microsemi Corporation * * Copyright (C) 2017 Andes Technology Corporation * Rick Chen, Andes Technology Corporation */ #include #include #include #include #include #include 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 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", }; 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 exception code: %ld , epc %lx , ra %lx\n", code, epc, regs->ra); } hang(); } int interrupt_init(void) { return 0; } /* * enable interrupts */ void enable_interrupts(void) { } /* * disable interrupts */ int disable_interrupts(void) { return 0; } ulong handle_trap(ulong cause, ulong epc, struct pt_regs *regs) { ulong is_irq, irq; 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; } /* *Entry Point for PLIC Interrupt Handler */ __attribute__((weak)) void external_interrupt(struct pt_regs *regs) { } __attribute__((weak)) void timer_interrupt(struct pt_regs *regs) { }