Merge git://git.denx.de/u-boot-imx
[oweals/u-boot.git] / arch / arc / lib / interrupts.c
1 /*
2  * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <asm/arcregs.h>
9 #include <asm/ptrace.h>
10
11 /* Bit values in STATUS32 */
12 #define E1_MASK         (1 << 1)        /* Level 1 interrupts enable */
13 #define E2_MASK         (1 << 2)        /* Level 2 interrupts enable */
14
15 int interrupt_init(void)
16 {
17         return 0;
18 }
19
20 /*
21  * returns true if interrupts had been enabled before we disabled them
22  */
23 int disable_interrupts(void)
24 {
25         int status = read_aux_reg(ARC_AUX_STATUS32);
26         int state = (status & (E1_MASK | E2_MASK)) ? 1 : 0;
27
28         status &= ~(E1_MASK | E2_MASK);
29         /* STATUS32 register is updated indirectly with "FLAG" instruction */
30         __asm__("flag %0" : : "r" (status));
31         return state;
32 }
33
34 void enable_interrupts(void)
35 {
36         unsigned int status = read_aux_reg(ARC_AUX_STATUS32);
37
38         status |= E1_MASK | E2_MASK;
39         /* STATUS32 register is updated indirectly with "FLAG" instruction */
40         __asm__("flag %0" : : "r" (status));
41 }
42
43 static void print_reg_file(long *reg_rev, int start_num)
44 {
45         unsigned int i;
46
47         /* Print 3 registers per line */
48         for (i = start_num; i < start_num + 25; i++) {
49                 printf("r%02u: 0x%08lx\t", i, (unsigned long)*reg_rev);
50                 if (((i + 1) % 3) == 0)
51                         printf("\n");
52
53                 /* Because pt_regs has registers reversed */
54                 reg_rev--;
55         }
56
57         /* Add new-line if none was inserted in the end of loop above */
58         if (((i + 1) % 3) != 0)
59                 printf("\n");
60 }
61
62 void show_regs(struct pt_regs *regs)
63 {
64         printf("ECR:\t0x%08lx\n", regs->ecr);
65         printf("RET:\t0x%08lx\nBLINK:\t0x%08lx\nSTAT32:\t0x%08lx\n",
66                regs->ret, regs->blink, regs->status32);
67         printf("GP: 0x%08lx\t r25: 0x%08lx\t\n", regs->r26, regs->r25);
68         printf("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", regs->bta,
69                regs->sp, regs->fp);
70         printf("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", regs->lp_start,
71                regs->lp_end, regs->lp_count);
72
73         print_reg_file(&(regs->r0), 0);
74 }
75
76 void bad_mode(struct pt_regs *regs)
77 {
78         if (regs)
79                 show_regs(regs);
80
81         panic("Resetting CPU ...\n");
82 }
83
84 void do_memory_error(unsigned long address, struct pt_regs *regs)
85 {
86         printf("Memory error exception @ 0x%lx\n", address);
87         bad_mode(regs);
88 }
89
90 void do_instruction_error(unsigned long address, struct pt_regs *regs)
91 {
92         printf("Instruction error exception @ 0x%lx\n", address);
93         bad_mode(regs);
94 }
95
96 void do_machine_check_fault(unsigned long address, struct pt_regs *regs)
97 {
98         printf("Machine check exception @ 0x%lx\n", address);
99         bad_mode(regs);
100 }
101
102 void do_interrupt_handler(void)
103 {
104         printf("Interrupt fired\n");
105         bad_mode(0);
106 }
107
108 void do_itlb_miss(struct pt_regs *regs)
109 {
110         printf("I TLB miss exception\n");
111         bad_mode(regs);
112 }
113
114 void do_dtlb_miss(struct pt_regs *regs)
115 {
116         printf("D TLB miss exception\n");
117         bad_mode(regs);
118 }
119
120 void do_tlb_prot_violation(unsigned long address, struct pt_regs *regs)
121 {
122         printf("TLB protection violation or misaligned access @ 0x%lx\n",
123                address);
124         bad_mode(regs);
125 }
126
127 void do_privilege_violation(struct pt_regs *regs)
128 {
129         printf("Privilege violation exception\n");
130         bad_mode(regs);
131 }
132
133 void do_trap(struct pt_regs *regs)
134 {
135         printf("Trap exception\n");
136         bad_mode(regs);
137 }
138
139 void do_extension(struct pt_regs *regs)
140 {
141         printf("Extension instruction exception\n");
142         bad_mode(regs);
143 }
144
145 #ifdef CONFIG_ISA_ARCV2
146 void do_swi(struct pt_regs *regs)
147 {
148         printf("Software Interrupt exception\n");
149         bad_mode(regs);
150 }
151
152 void do_divzero(unsigned long address, struct pt_regs *regs)
153 {
154         printf("Division by zero exception @ 0x%lx\n", address);
155         bad_mode(regs);
156 }
157
158 void do_dcerror(struct pt_regs *regs)
159 {
160         printf("Data cache consistency error exception\n");
161         bad_mode(regs);
162 }
163
164 void do_maligned(unsigned long address, struct pt_regs *regs)
165 {
166         printf("Misaligned data access exception @ 0x%lx\n", address);
167         bad_mode(regs);
168 }
169 #endif