xref: /openbmc/u-boot/arch/riscv/lib/interrupts.c (revision e7ab6dfc)
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 <asm/ptrace.h>
12 #include <asm/system.h>
13 #include <asm/encoding.h>
14 
15 static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs)
16 {
17 	static const char * const exception_code[] = {
18 		"Instruction address misaligned",
19 		"Instruction access fault",
20 		"Illegal instruction",
21 		"Breakpoint",
22 		"Load address misaligned",
23 		"Load access fault",
24 		"Store/AMO address misaligned",
25 		"Store/AMO access fault",
26 		"Environment call from U-mode",
27 		"Environment call from S-mode",
28 		"Reserved",
29 		"Environment call from M-mode",
30 		"Instruction page fault",
31 		"Load page fault",
32 		"Reserved",
33 		"Store/AMO page fault",
34 	};
35 
36 	if (code < ARRAY_SIZE(exception_code)) {
37 		printf("exception code: %ld , %s , epc %lx , ra %lx\n",
38 		       code, exception_code[code], epc, regs->ra);
39 	} else {
40 		printf("Reserved\n");
41 	}
42 
43 	hang();
44 }
45 
46 int interrupt_init(void)
47 {
48 	return 0;
49 }
50 
51 /*
52  * enable interrupts
53  */
54 void enable_interrupts(void)
55 {
56 }
57 
58 /*
59  * disable interrupts
60  */
61 int disable_interrupts(void)
62 {
63 	return 0;
64 }
65 
66 ulong handle_trap(ulong cause, ulong epc, struct pt_regs *regs)
67 {
68 	ulong is_irq, irq;
69 
70 	is_irq = (cause & MCAUSE_INT);
71 	irq = (cause & ~MCAUSE_INT);
72 
73 	if (is_irq) {
74 		switch (irq) {
75 		case IRQ_M_EXT:
76 		case IRQ_S_EXT:
77 			external_interrupt(0);	/* handle external interrupt */
78 			break;
79 		case IRQ_M_TIMER:
80 		case IRQ_S_TIMER:
81 			timer_interrupt(0);	/* handle timer interrupt */
82 			break;
83 		default:
84 			_exit_trap(cause, epc, regs);
85 			break;
86 		};
87 	} else {
88 		_exit_trap(cause, epc, regs);
89 	}
90 
91 	return epc;
92 }
93 
94 /*
95  *Entry Point for PLIC Interrupt Handler
96  */
97 __attribute__((weak)) void external_interrupt(struct pt_regs *regs)
98 {
99 }
100 
101 __attribute__((weak)) void timer_interrupt(struct pt_regs *regs)
102 {
103 }
104