183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2ea0364f1SPeter Tyser /*
3ea0364f1SPeter Tyser * (C) Copyright 2003
4ea0364f1SPeter Tyser * Texas Instruments <www.ti.com>
5ea0364f1SPeter Tyser *
6ea0364f1SPeter Tyser * (C) Copyright 2002
7ea0364f1SPeter Tyser * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
8ea0364f1SPeter Tyser * Marius Groeger <mgroeger@sysgo.de>
9ea0364f1SPeter Tyser *
10ea0364f1SPeter Tyser * (C) Copyright 2002
11ea0364f1SPeter Tyser * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
12ea0364f1SPeter Tyser * Alex Zuepke <azu@sysgo.de>
13ea0364f1SPeter Tyser *
14ea0364f1SPeter Tyser * (C) Copyright 2002-2004
15ea0364f1SPeter Tyser * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
16ea0364f1SPeter Tyser *
17ea0364f1SPeter Tyser * (C) Copyright 2004
18ea0364f1SPeter Tyser * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
19ea0364f1SPeter Tyser */
20ea0364f1SPeter Tyser
21ea0364f1SPeter Tyser #include <common.h>
2299b8db72SHeinrich Schuchardt #include <efi_loader.h>
23ea0364f1SPeter Tyser #include <asm/proc-armv/ptrace.h>
2449c4bc3aSJeroen Hofstee #include <asm/u-boot-arm.h>
25ea0364f1SPeter Tyser
26ea0364f1SPeter Tyser DECLARE_GLOBAL_DATA_PTR;
27ea0364f1SPeter Tyser
interrupt_init(void)28f1d2b313SHeiko Schocher int interrupt_init (void)
29f1d2b313SHeiko Schocher {
30f1d2b313SHeiko Schocher /*
31f1d2b313SHeiko Schocher * setup up stacks if necessary
32f1d2b313SHeiko Schocher */
33f1d2b313SHeiko Schocher IRQ_STACK_START_IN = gd->irq_sp + 8;
34f1d2b313SHeiko Schocher
35f1d2b313SHeiko Schocher return 0;
36f1d2b313SHeiko Schocher }
37f1d2b313SHeiko Schocher
enable_interrupts(void)38ea0364f1SPeter Tyser void enable_interrupts (void)
39ea0364f1SPeter Tyser {
40ea0364f1SPeter Tyser return;
41ea0364f1SPeter Tyser }
disable_interrupts(void)42ea0364f1SPeter Tyser int disable_interrupts (void)
43ea0364f1SPeter Tyser {
44ea0364f1SPeter Tyser return 0;
45ea0364f1SPeter Tyser }
46ea0364f1SPeter Tyser
bad_mode(void)47ea0364f1SPeter Tyser void bad_mode (void)
48ea0364f1SPeter Tyser {
49ea0364f1SPeter Tyser panic ("Resetting CPU ...\n");
50ea0364f1SPeter Tyser reset_cpu (0);
51ea0364f1SPeter Tyser }
52ea0364f1SPeter Tyser
show_efi_loaded_images(struct pt_regs * regs)5399b8db72SHeinrich Schuchardt static void show_efi_loaded_images(struct pt_regs *regs)
5499b8db72SHeinrich Schuchardt {
5599b8db72SHeinrich Schuchardt efi_print_image_infos((void *)instruction_pointer(regs));
5699b8db72SHeinrich Schuchardt }
5799b8db72SHeinrich Schuchardt
dump_instr(struct pt_regs * regs)58*bd2a13f3SHeinrich Schuchardt static void dump_instr(struct pt_regs *regs)
59*bd2a13f3SHeinrich Schuchardt {
60*bd2a13f3SHeinrich Schuchardt unsigned long addr = instruction_pointer(regs);
61*bd2a13f3SHeinrich Schuchardt const int thumb = thumb_mode(regs);
62*bd2a13f3SHeinrich Schuchardt const int width = thumb ? 4 : 8;
63*bd2a13f3SHeinrich Schuchardt int i;
64*bd2a13f3SHeinrich Schuchardt
65*bd2a13f3SHeinrich Schuchardt if (thumb)
66*bd2a13f3SHeinrich Schuchardt addr &= ~1L;
67*bd2a13f3SHeinrich Schuchardt else
68*bd2a13f3SHeinrich Schuchardt addr &= ~3L;
69*bd2a13f3SHeinrich Schuchardt printf("Code: ");
70*bd2a13f3SHeinrich Schuchardt for (i = -4; i < 1 + !!thumb; i++) {
71*bd2a13f3SHeinrich Schuchardt unsigned int val;
72*bd2a13f3SHeinrich Schuchardt
73*bd2a13f3SHeinrich Schuchardt if (thumb)
74*bd2a13f3SHeinrich Schuchardt val = ((u16 *)addr)[i];
75*bd2a13f3SHeinrich Schuchardt else
76*bd2a13f3SHeinrich Schuchardt val = ((u32 *)addr)[i];
77*bd2a13f3SHeinrich Schuchardt printf(i == 0 ? "(%0*x) " : "%0*x ", width, val);
78*bd2a13f3SHeinrich Schuchardt }
79*bd2a13f3SHeinrich Schuchardt printf("\n");
80*bd2a13f3SHeinrich Schuchardt }
81*bd2a13f3SHeinrich Schuchardt
show_regs(struct pt_regs * regs)82ea0364f1SPeter Tyser void show_regs (struct pt_regs *regs)
83ea0364f1SPeter Tyser {
8480402f34SHeiko Schocher unsigned long __maybe_unused flags;
8580402f34SHeiko Schocher const char __maybe_unused *processor_modes[] = {
86ea0364f1SPeter Tyser "USER_26", "FIQ_26", "IRQ_26", "SVC_26",
87ea0364f1SPeter Tyser "UK4_26", "UK5_26", "UK6_26", "UK7_26",
88ea0364f1SPeter Tyser "UK8_26", "UK9_26", "UK10_26", "UK11_26",
89ea0364f1SPeter Tyser "UK12_26", "UK13_26", "UK14_26", "UK15_26",
90ea0364f1SPeter Tyser "USER_32", "FIQ_32", "IRQ_32", "SVC_32",
91ea0364f1SPeter Tyser "UK4_32", "UK5_32", "UK6_32", "ABT_32",
92b726d22dSMarc Zyngier "UK8_32", "UK9_32", "HYP_32", "UND_32",
93ea0364f1SPeter Tyser "UK12_32", "UK13_32", "UK14_32", "SYS_32",
94ea0364f1SPeter Tyser };
95ea0364f1SPeter Tyser
96ea0364f1SPeter Tyser flags = condition_codes (regs);
97ea0364f1SPeter Tyser
9823d184d2SSimon Glass printf("pc : [<%08lx>] lr : [<%08lx>]\n",
9923d184d2SSimon Glass instruction_pointer(regs), regs->ARM_lr);
10023d184d2SSimon Glass if (gd->flags & GD_FLG_RELOC) {
10123d184d2SSimon Glass printf("reloc pc : [<%08lx>] lr : [<%08lx>]\n",
10223d184d2SSimon Glass instruction_pointer(regs) - gd->reloc_off,
10323d184d2SSimon Glass regs->ARM_lr - gd->reloc_off);
10423d184d2SSimon Glass }
10523d184d2SSimon Glass printf("sp : %08lx ip : %08lx fp : %08lx\n",
10623d184d2SSimon Glass regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
107ea0364f1SPeter Tyser printf ("r10: %08lx r9 : %08lx r8 : %08lx\n",
108ea0364f1SPeter Tyser regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
109ea0364f1SPeter Tyser printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
110ea0364f1SPeter Tyser regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
111ea0364f1SPeter Tyser printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
112ea0364f1SPeter Tyser regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
113ea0364f1SPeter Tyser printf ("Flags: %c%c%c%c",
114ea0364f1SPeter Tyser flags & CC_N_BIT ? 'N' : 'n',
115ea0364f1SPeter Tyser flags & CC_Z_BIT ? 'Z' : 'z',
116ea0364f1SPeter Tyser flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
117ea0364f1SPeter Tyser printf (" IRQs %s FIQs %s Mode %s%s\n",
118ea0364f1SPeter Tyser interrupts_enabled (regs) ? "on" : "off",
119ea0364f1SPeter Tyser fast_interrupts_enabled (regs) ? "on" : "off",
120ea0364f1SPeter Tyser processor_modes[processor_mode (regs)],
121ea0364f1SPeter Tyser thumb_mode (regs) ? " (T)" : "");
122*bd2a13f3SHeinrich Schuchardt dump_instr(regs);
123ea0364f1SPeter Tyser }
124ea0364f1SPeter Tyser
125c8882361SLothar Waßmann /* fixup PC to point to the instruction leading to the exception */
fixup_pc(struct pt_regs * regs,int offset)126c8882361SLothar Waßmann static inline void fixup_pc(struct pt_regs *regs, int offset)
127c8882361SLothar Waßmann {
128c8882361SLothar Waßmann uint32_t pc = instruction_pointer(regs) + offset;
129c8882361SLothar Waßmann regs->ARM_pc = pc | (regs->ARM_pc & PCMASK);
130c8882361SLothar Waßmann }
131c8882361SLothar Waßmann
do_undefined_instruction(struct pt_regs * pt_regs)132ea0364f1SPeter Tyser void do_undefined_instruction (struct pt_regs *pt_regs)
133ea0364f1SPeter Tyser {
134cc4a4748SAlexander Graf efi_restore_gd();
135ea0364f1SPeter Tyser printf ("undefined instruction\n");
136c8882361SLothar Waßmann fixup_pc(pt_regs, -4);
137ea0364f1SPeter Tyser show_regs (pt_regs);
13899b8db72SHeinrich Schuchardt show_efi_loaded_images(pt_regs);
139ea0364f1SPeter Tyser bad_mode ();
140ea0364f1SPeter Tyser }
141ea0364f1SPeter Tyser
do_software_interrupt(struct pt_regs * pt_regs)142ea0364f1SPeter Tyser void do_software_interrupt (struct pt_regs *pt_regs)
143ea0364f1SPeter Tyser {
144cc4a4748SAlexander Graf efi_restore_gd();
145ea0364f1SPeter Tyser printf ("software interrupt\n");
146c8882361SLothar Waßmann fixup_pc(pt_regs, -4);
147ea0364f1SPeter Tyser show_regs (pt_regs);
14899b8db72SHeinrich Schuchardt show_efi_loaded_images(pt_regs);
149ea0364f1SPeter Tyser bad_mode ();
150ea0364f1SPeter Tyser }
151ea0364f1SPeter Tyser
do_prefetch_abort(struct pt_regs * pt_regs)152ea0364f1SPeter Tyser void do_prefetch_abort (struct pt_regs *pt_regs)
153ea0364f1SPeter Tyser {
154cc4a4748SAlexander Graf efi_restore_gd();
155ea0364f1SPeter Tyser printf ("prefetch abort\n");
156c8882361SLothar Waßmann fixup_pc(pt_regs, -8);
157ea0364f1SPeter Tyser show_regs (pt_regs);
15899b8db72SHeinrich Schuchardt show_efi_loaded_images(pt_regs);
159ea0364f1SPeter Tyser bad_mode ();
160ea0364f1SPeter Tyser }
161ea0364f1SPeter Tyser
do_data_abort(struct pt_regs * pt_regs)162ea0364f1SPeter Tyser void do_data_abort (struct pt_regs *pt_regs)
163ea0364f1SPeter Tyser {
164cc4a4748SAlexander Graf efi_restore_gd();
1651551df35STom Rini printf ("data abort\n");
166c8882361SLothar Waßmann fixup_pc(pt_regs, -8);
167ea0364f1SPeter Tyser show_regs (pt_regs);
16899b8db72SHeinrich Schuchardt show_efi_loaded_images(pt_regs);
169ea0364f1SPeter Tyser bad_mode ();
170ea0364f1SPeter Tyser }
171ea0364f1SPeter Tyser
do_not_used(struct pt_regs * pt_regs)172ea0364f1SPeter Tyser void do_not_used (struct pt_regs *pt_regs)
173ea0364f1SPeter Tyser {
174cc4a4748SAlexander Graf efi_restore_gd();
175ea0364f1SPeter Tyser printf ("not used\n");
176c8882361SLothar Waßmann fixup_pc(pt_regs, -8);
177ea0364f1SPeter Tyser show_regs (pt_regs);
17899b8db72SHeinrich Schuchardt show_efi_loaded_images(pt_regs);
179ea0364f1SPeter Tyser bad_mode ();
180ea0364f1SPeter Tyser }
181ea0364f1SPeter Tyser
do_fiq(struct pt_regs * pt_regs)182ea0364f1SPeter Tyser void do_fiq (struct pt_regs *pt_regs)
183ea0364f1SPeter Tyser {
184cc4a4748SAlexander Graf efi_restore_gd();
185ea0364f1SPeter Tyser printf ("fast interrupt request\n");
186c8882361SLothar Waßmann fixup_pc(pt_regs, -8);
187ea0364f1SPeter Tyser show_regs (pt_regs);
18899b8db72SHeinrich Schuchardt show_efi_loaded_images(pt_regs);
189ea0364f1SPeter Tyser bad_mode ();
190ea0364f1SPeter Tyser }
191ea0364f1SPeter Tyser
do_irq(struct pt_regs * pt_regs)192ea0364f1SPeter Tyser void do_irq (struct pt_regs *pt_regs)
193ea0364f1SPeter Tyser {
194cc4a4748SAlexander Graf efi_restore_gd();
195ea0364f1SPeter Tyser printf ("interrupt request\n");
196c8882361SLothar Waßmann fixup_pc(pt_regs, -8);
197ea0364f1SPeter Tyser show_regs (pt_regs);
19899b8db72SHeinrich Schuchardt show_efi_loaded_images(pt_regs);
199ea0364f1SPeter Tyser bad_mode ();
200ea0364f1SPeter Tyser }
201