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 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_IRQ) 16 17 int interrupt_init(void) 18 { 19 return 0; 20 } 21 22 void enable_interrupts(void) 23 { 24 return; 25 } 26 27 int disable_interrupts(void) 28 { 29 return 0; 30 } 31 #endif 32 33 #if (!defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)) 34 #define REG_BITS(val, shift, mask) (((val) >> (shift)) & (mask)) 35 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 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 for (i = 0; i < 29; i += 2) 123 printf("x%-2d: %016lx x%-2d: %016lx\n", 124 i, regs->regs[i], i+1, regs->regs[i+1]); 125 printf("\n"); 126 127 dump_core_stack(regs); 128 } 129 #endif 130 131 /* 132 * do_bad_sync handles the impossible case in the Synchronous Abort vector. 133 */ 134 void do_bad_sync(struct pt_regs *pt_regs, unsigned int esr) 135 { 136 efi_restore_gd(); 137 printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08x\n", esr); 138 show_regs(pt_regs); 139 panic("Resetting CPU ...\n"); 140 } 141 142 /* 143 * do_bad_irq handles the impossible case in the Irq vector. 144 */ 145 void do_bad_irq(struct pt_regs *pt_regs, unsigned int esr) 146 { 147 efi_restore_gd(); 148 printf("Bad mode in \"Irq\" handler, esr 0x%08x\n", esr); 149 show_regs(pt_regs); 150 panic("Resetting CPU ...\n"); 151 } 152 153 /* 154 * do_bad_fiq handles the impossible case in the Fiq vector. 155 */ 156 void do_bad_fiq(struct pt_regs *pt_regs, unsigned int esr) 157 { 158 efi_restore_gd(); 159 printf("Bad mode in \"Fiq\" handler, esr 0x%08x\n", esr); 160 show_regs(pt_regs); 161 panic("Resetting CPU ...\n"); 162 } 163 164 /* 165 * do_bad_error handles the impossible case in the Error vector. 166 */ 167 void do_bad_error(struct pt_regs *pt_regs, unsigned int esr) 168 { 169 efi_restore_gd(); 170 printf("Bad mode in \"Error\" handler, esr 0x%08x\n", esr); 171 show_regs(pt_regs); 172 panic("Resetting CPU ...\n"); 173 } 174 175 /* 176 * do_sync handles the Synchronous Abort exception. 177 */ 178 void do_sync(struct pt_regs *pt_regs, unsigned int esr) 179 { 180 efi_restore_gd(); 181 printf("\"Synchronous Abort\" handler, esr 0x%08x\n", esr); 182 show_regs(pt_regs); 183 panic("Resetting CPU ...\n"); 184 } 185 186 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_IRQ) 187 /* 188 * do_irq handles the Irq exception. 189 */ 190 void do_irq(struct pt_regs *pt_regs, unsigned int esr) 191 { 192 efi_restore_gd(); 193 printf("\"Irq\" handler, esr 0x%08x\n", esr); 194 show_regs(pt_regs); 195 panic("Resetting CPU ...\n"); 196 } 197 #endif 198 199 /* 200 * do_fiq handles the Fiq exception. 201 */ 202 void do_fiq(struct pt_regs *pt_regs, unsigned int esr) 203 { 204 efi_restore_gd(); 205 printf("\"Fiq\" handler, esr 0x%08x\n", esr); 206 show_regs(pt_regs); 207 panic("Resetting CPU ...\n"); 208 } 209 210 /* 211 * do_error handles the Error exception. 212 * Errors are more likely to be processor specific, 213 * it is defined with weak attribute and can be redefined 214 * in processor specific code. 215 */ 216 void __weak do_error(struct pt_regs *pt_regs, unsigned int esr) 217 { 218 efi_restore_gd(); 219 printf("\"Error\" handler, esr 0x%08x\n", esr); 220 show_regs(pt_regs); 221 panic("Resetting CPU ...\n"); 222 } 223