1ea0364f1SPeter Tyser /*
2ea0364f1SPeter Tyser * (C) Copyright 2003
3ea0364f1SPeter Tyser * Texas Instruments <www.ti.com>
4ea0364f1SPeter Tyser *
5ea0364f1SPeter Tyser * (C) Copyright 2002
6ea0364f1SPeter Tyser * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7ea0364f1SPeter Tyser * Marius Groeger <mgroeger@sysgo.de>
8ea0364f1SPeter Tyser *
9ea0364f1SPeter Tyser * (C) Copyright 2002
10ea0364f1SPeter Tyser * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
11ea0364f1SPeter Tyser * Alex Zuepke <azu@sysgo.de>
12ea0364f1SPeter Tyser *
13ea0364f1SPeter Tyser * (C) Copyright 2002-2004
14ea0364f1SPeter Tyser * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
15ea0364f1SPeter Tyser *
16ea0364f1SPeter Tyser * (C) Copyright 2004
17ea0364f1SPeter Tyser * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
18ea0364f1SPeter Tyser *
191a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+
20ea0364f1SPeter Tyser */
21ea0364f1SPeter Tyser
22ea0364f1SPeter Tyser #include <common.h>
23ea0364f1SPeter Tyser #include <asm/proc-armv/ptrace.h>
2449c4bc3aSJeroen Hofstee #include <asm/u-boot-arm.h>
25cc4a4748SAlexander Graf #include <efi_loader.h>
26683a8d16SJoseph Chen #include <iomem.h>
27d554a7b2SJoseph Chen #include <stacktrace.h>
28ea0364f1SPeter Tyser
29ea0364f1SPeter Tyser DECLARE_GLOBAL_DATA_PTR;
30ea0364f1SPeter Tyser
31*7cef7918SJoseph Chen #if !CONFIG_IS_ENABLED(IRQ)
interrupt_init(void)32f1d2b313SHeiko Schocher int interrupt_init (void)
33f1d2b313SHeiko Schocher {
34f1d2b313SHeiko Schocher /*
35f1d2b313SHeiko Schocher * setup up stacks if necessary
36f1d2b313SHeiko Schocher */
37f1d2b313SHeiko Schocher IRQ_STACK_START_IN = gd->irq_sp + 8;
38f1d2b313SHeiko Schocher
39f1d2b313SHeiko Schocher return 0;
40f1d2b313SHeiko Schocher }
41f1d2b313SHeiko Schocher
enable_interrupts(void)42ea0364f1SPeter Tyser void enable_interrupts (void)
43ea0364f1SPeter Tyser {
44ea0364f1SPeter Tyser return;
45ea0364f1SPeter Tyser }
disable_interrupts(void)46ea0364f1SPeter Tyser int disable_interrupts (void)
47ea0364f1SPeter Tyser {
48ea0364f1SPeter Tyser return 0;
49ea0364f1SPeter Tyser }
50fa40f8a0SJoseph Chen #endif
51ea0364f1SPeter Tyser
bad_mode(void)52ea0364f1SPeter Tyser void bad_mode (void)
53ea0364f1SPeter Tyser {
54ea0364f1SPeter Tyser panic ("Resetting CPU ...\n");
55ea0364f1SPeter Tyser reset_cpu (0);
56ea0364f1SPeter Tyser }
57ea0364f1SPeter Tyser
show_regs(struct pt_regs * regs)58ea0364f1SPeter Tyser void show_regs (struct pt_regs *regs)
59ea0364f1SPeter Tyser {
60683a8d16SJoseph Chen ulong pc, lr;
6180402f34SHeiko Schocher unsigned long __maybe_unused flags;
6280402f34SHeiko Schocher const char __maybe_unused *processor_modes[] = {
63ea0364f1SPeter Tyser "USER_26", "FIQ_26", "IRQ_26", "SVC_26",
64ea0364f1SPeter Tyser "UK4_26", "UK5_26", "UK6_26", "UK7_26",
65ea0364f1SPeter Tyser "UK8_26", "UK9_26", "UK10_26", "UK11_26",
66ea0364f1SPeter Tyser "UK12_26", "UK13_26", "UK14_26", "UK15_26",
67ea0364f1SPeter Tyser "USER_32", "FIQ_32", "IRQ_32", "SVC_32",
68ea0364f1SPeter Tyser "UK4_32", "UK5_32", "UK6_32", "ABT_32",
69b726d22dSMarc Zyngier "UK8_32", "UK9_32", "HYP_32", "UND_32",
70ea0364f1SPeter Tyser "UK12_32", "UK13_32", "UK14_32", "SYS_32",
71ea0364f1SPeter Tyser };
72ea0364f1SPeter Tyser
73ea0364f1SPeter Tyser flags = condition_codes (regs);
74ea0364f1SPeter Tyser
7523d184d2SSimon Glass if (gd->flags & GD_FLG_RELOC) {
76683a8d16SJoseph Chen pc = instruction_pointer(regs) - gd->reloc_off;
77683a8d16SJoseph Chen lr = regs->ARM_lr - gd->reloc_off;
78683a8d16SJoseph Chen } else {
79683a8d16SJoseph Chen pc = instruction_pointer(regs);
80683a8d16SJoseph Chen lr = regs->ARM_lr;
8123d184d2SSimon Glass }
82683a8d16SJoseph Chen
83683a8d16SJoseph Chen printf ("pc : %08lx lr : %08lx\n", pc, lr);
8423d184d2SSimon Glass printf ("sp : %08lx ip : %08lx fp : %08lx\n",
8523d184d2SSimon Glass regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
86ea0364f1SPeter Tyser printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
87ea0364f1SPeter Tyser regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
88ea0364f1SPeter Tyser printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
89ea0364f1SPeter Tyser regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
90ea0364f1SPeter Tyser printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
91ea0364f1SPeter Tyser regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
92ea0364f1SPeter Tyser printf ("Flags: %c%c%c%c",
93ea0364f1SPeter Tyser flags & CC_N_BIT ? 'N' : 'n',
94ea0364f1SPeter Tyser flags & CC_Z_BIT ? 'Z' : 'z',
95ea0364f1SPeter Tyser flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
96683a8d16SJoseph Chen printf (" IRQs %s FIQs %s Mode %s%s\n\n",
97ea0364f1SPeter Tyser interrupts_enabled (regs) ? "on" : "off",
98ea0364f1SPeter Tyser fast_interrupts_enabled (regs) ? "on" : "off",
99ea0364f1SPeter Tyser processor_modes[processor_mode (regs)],
100ea0364f1SPeter Tyser thumb_mode (regs) ? " (T)" : "");
101683a8d16SJoseph Chen
10274ab8aa2SJoseph Chen #ifdef CONFIG_ROCKCHIP_CRASH_DUMP
10374ab8aa2SJoseph Chen iomem_show_by_compatible("-cru", 0, 0x400);
10474ab8aa2SJoseph Chen iomem_show_by_compatible("-pmucru", 0, 0x400);
10574ab8aa2SJoseph Chen iomem_show_by_compatible("-grf", 0, 0x400);
10674ab8aa2SJoseph Chen iomem_show_by_compatible("-pmugrf", 0, 0x400);
10774ab8aa2SJoseph Chen #endif
10874ab8aa2SJoseph Chen
109d554a7b2SJoseph Chen dump_core_stack(regs);
110ea0364f1SPeter Tyser }
111ea0364f1SPeter Tyser
112c8882361SLothar Waßmann /* fixup PC to point to the instruction leading to the exception */
fixup_pc(struct pt_regs * regs,int offset)113c8882361SLothar Waßmann static inline void fixup_pc(struct pt_regs *regs, int offset)
114c8882361SLothar Waßmann {
115c8882361SLothar Waßmann uint32_t pc = instruction_pointer(regs) + offset;
116c8882361SLothar Waßmann regs->ARM_pc = pc | (regs->ARM_pc & PCMASK);
117c8882361SLothar Waßmann }
118c8882361SLothar Waßmann
do_undefined_instruction(struct pt_regs * pt_regs)119ea0364f1SPeter Tyser void do_undefined_instruction (struct pt_regs *pt_regs)
120ea0364f1SPeter Tyser {
121cc4a4748SAlexander Graf efi_restore_gd();
122ea0364f1SPeter Tyser printf ("undefined instruction\n");
123c8882361SLothar Waßmann fixup_pc(pt_regs, -4);
124ea0364f1SPeter Tyser show_regs (pt_regs);
125ea0364f1SPeter Tyser bad_mode ();
126ea0364f1SPeter Tyser }
127ea0364f1SPeter Tyser
do_software_interrupt(struct pt_regs * pt_regs)128ea0364f1SPeter Tyser void do_software_interrupt (struct pt_regs *pt_regs)
129ea0364f1SPeter Tyser {
130cc4a4748SAlexander Graf efi_restore_gd();
131ea0364f1SPeter Tyser printf ("software interrupt\n");
132c8882361SLothar Waßmann fixup_pc(pt_regs, -4);
133ea0364f1SPeter Tyser show_regs (pt_regs);
134ea0364f1SPeter Tyser bad_mode ();
135ea0364f1SPeter Tyser }
136ea0364f1SPeter Tyser
do_prefetch_abort(struct pt_regs * pt_regs)137ea0364f1SPeter Tyser void do_prefetch_abort (struct pt_regs *pt_regs)
138ea0364f1SPeter Tyser {
139cc4a4748SAlexander Graf efi_restore_gd();
140ea0364f1SPeter Tyser printf ("prefetch abort\n");
141c8882361SLothar Waßmann fixup_pc(pt_regs, -8);
142ea0364f1SPeter Tyser show_regs (pt_regs);
143ea0364f1SPeter Tyser bad_mode ();
144ea0364f1SPeter Tyser }
145ea0364f1SPeter Tyser
do_data_abort(struct pt_regs * pt_regs)146ea0364f1SPeter Tyser void do_data_abort (struct pt_regs *pt_regs)
147ea0364f1SPeter Tyser {
148cc4a4748SAlexander Graf efi_restore_gd();
1491551df35STom Rini printf ("data abort\n");
150c8882361SLothar Waßmann fixup_pc(pt_regs, -8);
151ea0364f1SPeter Tyser show_regs (pt_regs);
152ea0364f1SPeter Tyser bad_mode ();
153ea0364f1SPeter Tyser }
154ea0364f1SPeter Tyser
do_not_used(struct pt_regs * pt_regs)155ea0364f1SPeter Tyser void do_not_used (struct pt_regs *pt_regs)
156ea0364f1SPeter Tyser {
157cc4a4748SAlexander Graf efi_restore_gd();
158ea0364f1SPeter Tyser printf ("not used\n");
159c8882361SLothar Waßmann fixup_pc(pt_regs, -8);
160ea0364f1SPeter Tyser show_regs (pt_regs);
161ea0364f1SPeter Tyser bad_mode ();
162ea0364f1SPeter Tyser }
163ea0364f1SPeter Tyser
do_fiq(struct pt_regs * pt_regs)164ea0364f1SPeter Tyser void do_fiq (struct pt_regs *pt_regs)
165ea0364f1SPeter Tyser {
166cc4a4748SAlexander Graf efi_restore_gd();
167ea0364f1SPeter Tyser printf ("fast interrupt request\n");
168c8882361SLothar Waßmann fixup_pc(pt_regs, -8);
169ea0364f1SPeter Tyser show_regs (pt_regs);
170ea0364f1SPeter Tyser bad_mode ();
171ea0364f1SPeter Tyser }
172ea0364f1SPeter Tyser
173*7cef7918SJoseph Chen #if !CONFIG_IS_ENABLED(IRQ)
do_irq(struct pt_regs * pt_regs)174ea0364f1SPeter Tyser void do_irq (struct pt_regs *pt_regs)
175ea0364f1SPeter Tyser {
176cc4a4748SAlexander Graf efi_restore_gd();
177ea0364f1SPeter Tyser printf ("interrupt request\n");
178c8882361SLothar Waßmann fixup_pc(pt_regs, -8);
179ea0364f1SPeter Tyser show_regs (pt_regs);
180ea0364f1SPeter Tyser bad_mode ();
181ea0364f1SPeter Tyser }
182fa40f8a0SJoseph Chen #endif
183