xref: /rk3399_rockchip-uboot/arch/arm/lib/interrupts_64.c (revision 01b8c4d110abb0dcbe36dc5b6b10d93b2b8e2667)
1 /*
2  * (C) Copyright 2013
3  * David Feng <fenghua@phytium.com.cn>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <linux/compiler.h>
10 #include <efi_loader.h>
11 #include <iomem.h>
12 #include <stacktrace.h>
13 
14 DECLARE_GLOBAL_DATA_PTR;
15 
16 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_IRQ)
17 
18 int interrupt_init(void)
19 {
20 	return 0;
21 }
22 
23 void enable_interrupts(void)
24 {
25 	return;
26 }
27 
28 int disable_interrupts(void)
29 {
30 	return 0;
31 }
32 #endif
33 
34 #define REG_BITS(val, shift, mask)	(((val) >> (shift)) & (mask))
35 
36 #if (!defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD))
37 void show_regs(struct pt_regs *regs)
38 {
39 	int el = current_el();
40 	int i;
41 
42 	const char *esr_bits_ec[] = {
43 		[0]  = "an unknown reason",
44 		[1]  = "a WFI or WFE instruction",
45 		[3]  = "an MCR or MRC access",
46 		[4]  = "an MCRR or MRRC access",
47 		[5]  = "an MCR or MRC access",
48 		[6]  = "an LDC or STC access to CP14",
49 		[7]  = "an access to an Advanced SIMD or floating-point register, resulting from CPACR_EL1.FPEN or CPTR_ELx.TFP",
50 		[8]  = "an MCR or MRC access",
51 		[12] = "an MCRR or MRRC access",
52 		[14] = "an Illegal execution state, or a PC or SP alignment fault",
53 		[10] = "HVC or SVC instruction execution",
54 		[18] = "HVC or SVC instruction execution",
55 		[19] = "SMC instruction execution in AArch32 state",
56 		[21] = "HVC or SVC instruction execution",
57 		[22] = "HVC or SVC instruction execution",
58 		[23] = "SMC instruction execution in AArch64 state",
59 		[24] = "MSR, MRS, or System instruction execution in AArch64 state",
60 		[31] = "IMPLEMENTATION DEFINED exception to EL3",
61 		[32] = "an Instruction abort",
62 		[33] = "an Instruction abort",
63 		[34] = "an Illegal execution state, or a PC or SP alignment fault",
64 		[36] = "a Data abort, from lower exception level",
65 		[37] = "a Data abort, from current exception level",
66 		[38] = "an Illegal execution state, or a PC or SP alignment fault",
67 		[40] = "a trapped Floating-point exception",
68 		[44] = "a trapped Floating-point exception",
69 		[47] = "SError interrupt",
70 		[48] = "a Breakpoint or Vector Catch debug event",
71 		[49] = "a Breakpoint or Vector Catch debug event",
72 		[50] = "a Software Step debug event",
73 		[51] = "a Software Step debug event",
74 		[52] = "a Watchpoint debug event",
75 		[53] = "a Watchpoint debug event",
76 		[56] = "execution of a Software Breakpoint instructio",
77 	};
78 
79 	printf("\n");
80 
81 	/* PC/LR/SP ... */
82 	printf("* Reason:        Exception from %s\n", esr_bits_ec[REG_BITS(regs->esr, 26, 0x3f)]);
83 	if (gd->flags & GD_FLG_RELOC) {
84 		printf("* PC         =   %016lx\n", regs->elr - gd->reloc_off);
85 		printf("* LR         =   %016lx\n", regs->regs[30] - gd->reloc_off);
86 	} else {
87 		printf("* ELR(PC)    =   %016lx\n", regs->elr);
88 		printf("* LR         =   %016lx\n", regs->regs[30]);
89 	}
90 	printf("* SP         =   %016lx\n", regs->sp);
91 	printf("* ESR_EL%d    =   %016lx\n", el, regs->esr);
92 	printf("* Reloc Off  =   %016lx\n\n", gd->reloc_off);
93 
94 	/* CPU */
95 	for (i = 0; i < 29; i += 2)
96 		printf("x%-2d: %016lx x%-2d: %016lx\n",
97 		       i, regs->regs[i], i+1, regs->regs[i+1]);
98 	printf("\n");
99 
100 	/* SoC */
101 #ifdef CONFIG_ROCKCHIP_CRASH_DUMP
102 	iomem_show_by_compatible("-cru", 0, 0x400);
103 	iomem_show_by_compatible("-pmucru", 0, 0x400);
104 	iomem_show_by_compatible("-grf", 0, 0x400);
105 	iomem_show_by_compatible("-pmugrf", 0, 0x400);
106 #endif
107 	/* Call trace */
108 	dump_core_stack(regs);
109 }
110 
111 #else
112 void show_regs(struct pt_regs *regs)
113 {
114 	int i;
115 
116 	if (gd->flags & GD_FLG_RELOC) {
117 		printf("ELR:     %lx\n", regs->elr - gd->reloc_off);
118 		printf("LR:      %lx\n", regs->regs[30] - gd->reloc_off);
119 	} else {
120 		printf("ELR:     %lx\n", regs->elr);
121 		printf("LR:      %lx\n", regs->regs[30]);
122 	}
123 
124 	printf("ESR:     %lx (ec=%ld)\n", regs->esr, REG_BITS(regs->esr, 26, 0x3f));
125 
126 	for (i = 0; i < 29; i += 2)
127 		printf("x%-2d: %016lx x%-2d: %016lx\n",
128 		       i, regs->regs[i], i+1, regs->regs[i+1]);
129 	printf("\n");
130 
131 	dump_core_stack(regs);
132 }
133 #endif
134 
135 /*
136  * do_bad_sync handles the impossible case in the Synchronous Abort vector.
137  */
138 void do_bad_sync(struct pt_regs *pt_regs, unsigned int esr)
139 {
140 	efi_restore_gd();
141 	printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08x\n", esr);
142 	show_regs(pt_regs);
143 	panic("Resetting CPU ...\n");
144 }
145 
146 /*
147  * do_bad_irq handles the impossible case in the Irq vector.
148  */
149 void do_bad_irq(struct pt_regs *pt_regs, unsigned int esr)
150 {
151 	efi_restore_gd();
152 	printf("Bad mode in \"Irq\" handler, esr 0x%08x\n", esr);
153 	show_regs(pt_regs);
154 	panic("Resetting CPU ...\n");
155 }
156 
157 /*
158  * do_bad_fiq handles the impossible case in the Fiq vector.
159  */
160 void do_bad_fiq(struct pt_regs *pt_regs, unsigned int esr)
161 {
162 	efi_restore_gd();
163 	printf("Bad mode in \"Fiq\" handler, esr 0x%08x\n", esr);
164 	show_regs(pt_regs);
165 	panic("Resetting CPU ...\n");
166 }
167 
168 /*
169  * do_bad_error handles the impossible case in the Error vector.
170  */
171 void do_bad_error(struct pt_regs *pt_regs, unsigned int esr)
172 {
173 	efi_restore_gd();
174 	printf("Bad mode in \"Error\" handler, esr 0x%08x\n", esr);
175 	show_regs(pt_regs);
176 	panic("Resetting CPU ...\n");
177 }
178 
179 /*
180  * do_sync handles the Synchronous Abort exception.
181  */
182 void do_sync(struct pt_regs *pt_regs, unsigned int esr)
183 {
184 	efi_restore_gd();
185 	printf("\"Synchronous Abort\" handler, esr 0x%08x\n", esr);
186 	show_regs(pt_regs);
187 	panic("Resetting CPU ...\n");
188 }
189 
190 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_IRQ)
191 /*
192  * do_irq handles the Irq exception.
193  */
194 void do_irq(struct pt_regs *pt_regs, unsigned int esr)
195 {
196 	efi_restore_gd();
197 	printf("\"Irq\" handler, esr 0x%08x\n", esr);
198 	show_regs(pt_regs);
199 	panic("Resetting CPU ...\n");
200 }
201 #endif
202 
203 /*
204  * do_fiq handles the Fiq exception.
205  */
206 void do_fiq(struct pt_regs *pt_regs, unsigned int esr)
207 {
208 	efi_restore_gd();
209 	printf("\"Fiq\" handler, esr 0x%08x\n", esr);
210 	show_regs(pt_regs);
211 	panic("Resetting CPU ...\n");
212 }
213 
214 /*
215  * do_error handles the Error exception.
216  * Errors are more likely to be processor specific,
217  * it is defined with weak attribute and can be redefined
218  * in processor specific code.
219  */
220 void __weak do_error(struct pt_regs *pt_regs, unsigned int esr)
221 {
222 	efi_restore_gd();
223 	printf("\"Error\" handler, esr 0x%08x\n", esr);
224 	show_regs(pt_regs);
225 	panic("Resetting CPU ...\n");
226 }
227