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