512dce061967ce33d4ef4ca53dbb68d084298400
[oweals/u-boot.git] / arch / riscv / lib / interrupts.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2016-17 Microsemi Corporation.
4  * Padmarao Begari, Microsemi Corporation <padmarao.begari@microsemi.com>
5  *
6  * Copyright (C) 2017 Andes Technology Corporation
7  * Rick Chen, Andes Technology Corporation <rick@andestech.com>
8  */
9
10 #include <common.h>
11 #include <hang.h>
12 #include <irq_func.h>
13 #include <asm/ptrace.h>
14 #include <asm/system.h>
15 #include <asm/encoding.h>
16
17 static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs)
18 {
19         static const char * const exception_code[] = {
20                 "Instruction address misaligned",
21                 "Instruction access fault",
22                 "Illegal instruction",
23                 "Breakpoint",
24                 "Load address misaligned",
25                 "Load access fault",
26                 "Store/AMO address misaligned",
27                 "Store/AMO access fault",
28                 "Environment call from U-mode",
29                 "Environment call from S-mode",
30                 "Reserved",
31                 "Environment call from M-mode",
32                 "Instruction page fault",
33                 "Load page fault",
34                 "Reserved",
35                 "Store/AMO page fault",
36         };
37
38         if (code < ARRAY_SIZE(exception_code)) {
39                 printf("exception code: %ld , %s , epc %lx , ra %lx\n",
40                        code, exception_code[code], epc, regs->ra);
41         } else {
42                 printf("reserved exception code: %ld , epc %lx , ra %lx\n",
43                        code, epc, regs->ra);
44         }
45
46         hang();
47 }
48
49 int interrupt_init(void)
50 {
51         return 0;
52 }
53
54 /*
55  * enable interrupts
56  */
57 void enable_interrupts(void)
58 {
59 }
60
61 /*
62  * disable interrupts
63  */
64 int disable_interrupts(void)
65 {
66         return 0;
67 }
68
69 ulong handle_trap(ulong cause, ulong epc, struct pt_regs *regs)
70 {
71         ulong is_irq, irq;
72
73         is_irq = (cause & MCAUSE_INT);
74         irq = (cause & ~MCAUSE_INT);
75
76         if (is_irq) {
77                 switch (irq) {
78                 case IRQ_M_EXT:
79                 case IRQ_S_EXT:
80                         external_interrupt(0);  /* handle external interrupt */
81                         break;
82                 case IRQ_M_TIMER:
83                 case IRQ_S_TIMER:
84                         timer_interrupt(0);     /* handle timer interrupt */
85                         break;
86                 default:
87                         _exit_trap(cause, epc, regs);
88                         break;
89                 };
90         } else {
91                 _exit_trap(cause, epc, regs);
92         }
93
94         return epc;
95 }
96
97 /*
98  *Entry Point for PLIC Interrupt Handler
99  */
100 __attribute__((weak)) void external_interrupt(struct pt_regs *regs)
101 {
102 }
103
104 __attribute__((weak)) void timer_interrupt(struct pt_regs *regs)
105 {
106 }