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