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