10ae76531SDavid Feng /* 20ae76531SDavid Feng * (C) Copyright 2013 30ae76531SDavid Feng * David Feng <fenghua@phytium.com.cn> 40ae76531SDavid Feng * 50ae76531SDavid Feng * SPDX-License-Identifier: GPL-2.0+ 60ae76531SDavid Feng */ 70ae76531SDavid Feng 80ae76531SDavid Feng #include <common.h> 90ae76531SDavid Feng #include <linux/compiler.h> 1064982915SAlexander Graf #include <efi_loader.h> 1158d85a14SJoseph Chen #include <iomem.h> 12d554a7b2SJoseph Chen #include <stacktrace.h> 130ae76531SDavid Feng 145e076729SPeng Fan DECLARE_GLOBAL_DATA_PTR; 15f4fc5f8dSKever Yang #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_IRQ) 165e076729SPeng Fan 170ae76531SDavid Feng int interrupt_init(void) 180ae76531SDavid Feng { 190ae76531SDavid Feng return 0; 200ae76531SDavid Feng } 210ae76531SDavid Feng 220ae76531SDavid Feng void enable_interrupts(void) 230ae76531SDavid Feng { 240ae76531SDavid Feng return; 250ae76531SDavid Feng } 260ae76531SDavid Feng 270ae76531SDavid Feng int disable_interrupts(void) 280ae76531SDavid Feng { 290ae76531SDavid Feng return 0; 300ae76531SDavid Feng } 31fa40f8a0SJoseph Chen #endif 320ae76531SDavid Feng 33faa7eb0fSJoseph Chen #if (!defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)) 34faa7eb0fSJoseph Chen #define REG_BITS(val, shift, mask) (((val) >> (shift)) & (mask)) 35faa7eb0fSJoseph Chen 36faa7eb0fSJoseph Chen void show_regs(struct pt_regs *regs) 37faa7eb0fSJoseph Chen { 38faa7eb0fSJoseph Chen int el = current_el(); 39*74ab8aa2SJoseph Chen int i; 40*74ab8aa2SJoseph Chen 41faa7eb0fSJoseph Chen const char *esr_bits_ec[] = { 42*74ab8aa2SJoseph Chen [0] = "an unknown reason", 43*74ab8aa2SJoseph Chen [1] = "a WFI or WFE instruction", 44*74ab8aa2SJoseph Chen [3] = "an MCR or MRC access", 45*74ab8aa2SJoseph Chen [4] = "an MCRR or MRRC access", 46*74ab8aa2SJoseph Chen [5] = "an MCR or MRC access", 47*74ab8aa2SJoseph Chen [6] = "an LDC or STC access to CP14", 48*74ab8aa2SJoseph Chen [7] = "an access to an Advanced SIMD or floating-point register, resulting from CPACR_EL1.FPEN or CPTR_ELx.TFP", 49*74ab8aa2SJoseph Chen [8] = "an MCR or MRC access", 50*74ab8aa2SJoseph Chen [12] = "an MCRR or MRRC access", 51*74ab8aa2SJoseph Chen [14] = "an Illegal execution state, or a PC or SP alignment fault", 52*74ab8aa2SJoseph Chen [10] = "HVC or SVC instruction execution", 53*74ab8aa2SJoseph Chen [18] = "HVC or SVC instruction execution", 54*74ab8aa2SJoseph Chen [19] = "SMC instruction execution in AArch32 state", 55*74ab8aa2SJoseph Chen [21] = "HVC or SVC instruction execution", 56*74ab8aa2SJoseph Chen [22] = "HVC or SVC instruction execution", 57*74ab8aa2SJoseph Chen [23] = "SMC instruction execution in AArch64 state", 58*74ab8aa2SJoseph Chen [24] = "MSR, MRS, or System instruction execution in AArch64 state", 59*74ab8aa2SJoseph Chen [31] = "IMPLEMENTATION DEFINED exception to EL3", 60*74ab8aa2SJoseph Chen [32] = "an Instruction abort", 61*74ab8aa2SJoseph Chen [33] = "an Instruction abort", 62*74ab8aa2SJoseph Chen [34] = "an Illegal execution state, or a PC or SP alignment fault", 63*74ab8aa2SJoseph Chen [36] = "a Data abort, from lower exception level", 64*74ab8aa2SJoseph Chen [37] = "a Data abort, from current exception level", 65*74ab8aa2SJoseph Chen [38] = "an Illegal execution state, or a PC or SP alignment fault", 66*74ab8aa2SJoseph Chen [40] = "a trapped Floating-point exception", 67*74ab8aa2SJoseph Chen [44] = "a trapped Floating-point exception", 68*74ab8aa2SJoseph Chen [47] = "SError interrupt", 69*74ab8aa2SJoseph Chen [48] = "a Breakpoint or Vector Catch debug event", 70*74ab8aa2SJoseph Chen [49] = "a Breakpoint or Vector Catch debug event", 71*74ab8aa2SJoseph Chen [50] = "a Software Step debug event", 72*74ab8aa2SJoseph Chen [51] = "a Software Step debug event", 73*74ab8aa2SJoseph Chen [52] = "a Watchpoint debug event", 74*74ab8aa2SJoseph Chen [53] = "a Watchpoint debug event", 75*74ab8aa2SJoseph Chen [56] = "execution of a Software Breakpoint instructio", 76faa7eb0fSJoseph Chen }; 77faa7eb0fSJoseph Chen 78*74ab8aa2SJoseph Chen printf("\n"); 79faa7eb0fSJoseph Chen 80*74ab8aa2SJoseph Chen /* PC/LR/SP ... */ 81*74ab8aa2SJoseph Chen printf("* Reason: Exception from %s\n", esr_bits_ec[REG_BITS(regs->esr, 26, 0x3f)]); 82faa7eb0fSJoseph Chen if (gd->flags & GD_FLG_RELOC) { 83*74ab8aa2SJoseph Chen printf("* PC = %016lx\n", regs->elr - gd->reloc_off); 84faa7eb0fSJoseph Chen printf("* LR = %016lx\n", regs->regs[30] - gd->reloc_off); 85faa7eb0fSJoseph Chen } else { 86faa7eb0fSJoseph Chen printf("* ELR(PC) = %016lx\n", regs->elr); 87faa7eb0fSJoseph Chen printf("* LR = %016lx\n", regs->regs[30]); 88faa7eb0fSJoseph Chen } 89faa7eb0fSJoseph Chen printf("* SP = %016lx\n", regs->sp); 90faa7eb0fSJoseph Chen printf("* ESR_EL%d = %016lx\n", el, regs->esr); 91*74ab8aa2SJoseph Chen printf("* Reloc Off = %016lx\n\n", gd->reloc_off); 92faa7eb0fSJoseph Chen 93*74ab8aa2SJoseph Chen /* CPU */ 94faa7eb0fSJoseph Chen for (i = 0; i < 29; i += 2) 95faa7eb0fSJoseph Chen printf("x%-2d: %016lx x%-2d: %016lx\n", 96faa7eb0fSJoseph Chen i, regs->regs[i], i+1, regs->regs[i+1]); 97faa7eb0fSJoseph Chen printf("\n"); 9824cd8f36SJoseph Chen 99*74ab8aa2SJoseph Chen /* SoC */ 10024cd8f36SJoseph Chen #ifdef CONFIG_ROCKCHIP_CRASH_DUMP 10124cd8f36SJoseph Chen iomem_show_by_compatible("-cru", 0, 0x400); 10224cd8f36SJoseph Chen iomem_show_by_compatible("-pmucru", 0, 0x400); 10324cd8f36SJoseph Chen iomem_show_by_compatible("-grf", 0, 0x400); 10424cd8f36SJoseph Chen iomem_show_by_compatible("-pmugrf", 0, 0x400); 10524cd8f36SJoseph Chen #endif 106*74ab8aa2SJoseph Chen /* Call trace */ 107d554a7b2SJoseph Chen dump_core_stack(regs); 108faa7eb0fSJoseph Chen } 109faa7eb0fSJoseph Chen 110faa7eb0fSJoseph Chen #else 1110ae76531SDavid Feng void show_regs(struct pt_regs *regs) 1120ae76531SDavid Feng { 1130ae76531SDavid Feng int i; 1140ae76531SDavid Feng 1155e076729SPeng Fan if (gd->flags & GD_FLG_RELOC) { 1165e076729SPeng Fan printf("ELR: %lx\n", regs->elr - gd->reloc_off); 1175e076729SPeng Fan printf("LR: %lx\n", regs->regs[30] - gd->reloc_off); 1185e076729SPeng Fan } else { 1190ae76531SDavid Feng printf("ELR: %lx\n", regs->elr); 1200ae76531SDavid Feng printf("LR: %lx\n", regs->regs[30]); 1215e076729SPeng Fan } 1220ae76531SDavid Feng for (i = 0; i < 29; i += 2) 1230ae76531SDavid Feng printf("x%-2d: %016lx x%-2d: %016lx\n", 1240ae76531SDavid Feng i, regs->regs[i], i+1, regs->regs[i+1]); 1250ae76531SDavid Feng printf("\n"); 126d554a7b2SJoseph Chen 127d554a7b2SJoseph Chen dump_core_stack(regs); 1280ae76531SDavid Feng } 129faa7eb0fSJoseph Chen #endif 1300ae76531SDavid Feng 1310ae76531SDavid Feng /* 1320ae76531SDavid Feng * do_bad_sync handles the impossible case in the Synchronous Abort vector. 1330ae76531SDavid Feng */ 1340ae76531SDavid Feng void do_bad_sync(struct pt_regs *pt_regs, unsigned int esr) 1350ae76531SDavid Feng { 13664982915SAlexander Graf efi_restore_gd(); 1370ae76531SDavid Feng printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08x\n", esr); 1380ae76531SDavid Feng show_regs(pt_regs); 1390ae76531SDavid Feng panic("Resetting CPU ...\n"); 1400ae76531SDavid Feng } 1410ae76531SDavid Feng 1420ae76531SDavid Feng /* 1430ae76531SDavid Feng * do_bad_irq handles the impossible case in the Irq vector. 1440ae76531SDavid Feng */ 1450ae76531SDavid Feng void do_bad_irq(struct pt_regs *pt_regs, unsigned int esr) 1460ae76531SDavid Feng { 14764982915SAlexander Graf efi_restore_gd(); 1480ae76531SDavid Feng printf("Bad mode in \"Irq\" handler, esr 0x%08x\n", esr); 1490ae76531SDavid Feng show_regs(pt_regs); 1500ae76531SDavid Feng panic("Resetting CPU ...\n"); 1510ae76531SDavid Feng } 1520ae76531SDavid Feng 1530ae76531SDavid Feng /* 1540ae76531SDavid Feng * do_bad_fiq handles the impossible case in the Fiq vector. 1550ae76531SDavid Feng */ 1560ae76531SDavid Feng void do_bad_fiq(struct pt_regs *pt_regs, unsigned int esr) 1570ae76531SDavid Feng { 15864982915SAlexander Graf efi_restore_gd(); 1590ae76531SDavid Feng printf("Bad mode in \"Fiq\" handler, esr 0x%08x\n", esr); 1600ae76531SDavid Feng show_regs(pt_regs); 1610ae76531SDavid Feng panic("Resetting CPU ...\n"); 1620ae76531SDavid Feng } 1630ae76531SDavid Feng 1640ae76531SDavid Feng /* 1650ae76531SDavid Feng * do_bad_error handles the impossible case in the Error vector. 1660ae76531SDavid Feng */ 1670ae76531SDavid Feng void do_bad_error(struct pt_regs *pt_regs, unsigned int esr) 1680ae76531SDavid Feng { 16964982915SAlexander Graf efi_restore_gd(); 1700ae76531SDavid Feng printf("Bad mode in \"Error\" handler, esr 0x%08x\n", esr); 1710ae76531SDavid Feng show_regs(pt_regs); 1720ae76531SDavid Feng panic("Resetting CPU ...\n"); 1730ae76531SDavid Feng } 1740ae76531SDavid Feng 1750ae76531SDavid Feng /* 1760ae76531SDavid Feng * do_sync handles the Synchronous Abort exception. 1770ae76531SDavid Feng */ 1780ae76531SDavid Feng void do_sync(struct pt_regs *pt_regs, unsigned int esr) 1790ae76531SDavid Feng { 18064982915SAlexander Graf efi_restore_gd(); 1810ae76531SDavid Feng printf("\"Synchronous Abort\" handler, esr 0x%08x\n", esr); 1820ae76531SDavid Feng show_regs(pt_regs); 1830ae76531SDavid Feng panic("Resetting CPU ...\n"); 1840ae76531SDavid Feng } 1850ae76531SDavid Feng 186f4fc5f8dSKever Yang #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_IRQ) 1870ae76531SDavid Feng /* 1880ae76531SDavid Feng * do_irq handles the Irq exception. 1890ae76531SDavid Feng */ 1900ae76531SDavid Feng void do_irq(struct pt_regs *pt_regs, unsigned int esr) 1910ae76531SDavid Feng { 19264982915SAlexander Graf efi_restore_gd(); 1930ae76531SDavid Feng printf("\"Irq\" handler, esr 0x%08x\n", esr); 1940ae76531SDavid Feng show_regs(pt_regs); 1950ae76531SDavid Feng panic("Resetting CPU ...\n"); 1960ae76531SDavid Feng } 197fa40f8a0SJoseph Chen #endif 1980ae76531SDavid Feng 1990ae76531SDavid Feng /* 2000ae76531SDavid Feng * do_fiq handles the Fiq exception. 2010ae76531SDavid Feng */ 2020ae76531SDavid Feng void do_fiq(struct pt_regs *pt_regs, unsigned int esr) 2030ae76531SDavid Feng { 20464982915SAlexander Graf efi_restore_gd(); 2050ae76531SDavid Feng printf("\"Fiq\" handler, esr 0x%08x\n", esr); 2060ae76531SDavid Feng show_regs(pt_regs); 2070ae76531SDavid Feng panic("Resetting CPU ...\n"); 2080ae76531SDavid Feng } 2090ae76531SDavid Feng 2100ae76531SDavid Feng /* 2110ae76531SDavid Feng * do_error handles the Error exception. 2120ae76531SDavid Feng * Errors are more likely to be processor specific, 2130ae76531SDavid Feng * it is defined with weak attribute and can be redefined 2140ae76531SDavid Feng * in processor specific code. 2150ae76531SDavid Feng */ 2160ae76531SDavid Feng void __weak do_error(struct pt_regs *pt_regs, unsigned int esr) 2170ae76531SDavid Feng { 21864982915SAlexander Graf efi_restore_gd(); 2190ae76531SDavid Feng printf("\"Error\" handler, esr 0x%08x\n", esr); 2200ae76531SDavid Feng show_regs(pt_regs); 2210ae76531SDavid Feng panic("Resetting CPU ...\n"); 2220ae76531SDavid Feng } 223