1 /* 2 * (C) Copyright 2003 3 * Texas Instruments <www.ti.com> 4 * 5 * (C) Copyright 2002 6 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 7 * Marius Groeger <mgroeger@sysgo.de> 8 * 9 * (C) Copyright 2002 10 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 11 * Alex Zuepke <azu@sysgo.de> 12 * 13 * (C) Copyright 2002-2004 14 * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> 15 * 16 * (C) Copyright 2004 17 * Philippe Robin, ARM Ltd. <philippe.robin@arm.com> 18 * 19 * SPDX-License-Identifier: GPL-2.0+ 20 */ 21 22 #include <common.h> 23 #include <asm/proc-armv/ptrace.h> 24 #include <asm/u-boot-arm.h> 25 #include <efi_loader.h> 26 #include <iomem.h> 27 28 DECLARE_GLOBAL_DATA_PTR; 29 30 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_IRQ) 31 int interrupt_init (void) 32 { 33 /* 34 * setup up stacks if necessary 35 */ 36 IRQ_STACK_START_IN = gd->irq_sp + 8; 37 38 return 0; 39 } 40 41 void enable_interrupts (void) 42 { 43 return; 44 } 45 int disable_interrupts (void) 46 { 47 return 0; 48 } 49 #endif 50 51 void bad_mode (void) 52 { 53 panic ("Resetting CPU ...\n"); 54 reset_cpu (0); 55 } 56 57 void show_regs (struct pt_regs *regs) 58 { 59 ulong pc, lr; 60 unsigned long __maybe_unused flags; 61 const char __maybe_unused *processor_modes[] = { 62 "USER_26", "FIQ_26", "IRQ_26", "SVC_26", 63 "UK4_26", "UK5_26", "UK6_26", "UK7_26", 64 "UK8_26", "UK9_26", "UK10_26", "UK11_26", 65 "UK12_26", "UK13_26", "UK14_26", "UK15_26", 66 "USER_32", "FIQ_32", "IRQ_32", "SVC_32", 67 "UK4_32", "UK5_32", "UK6_32", "ABT_32", 68 "UK8_32", "UK9_32", "HYP_32", "UND_32", 69 "UK12_32", "UK13_32", "UK14_32", "SYS_32", 70 }; 71 72 flags = condition_codes (regs); 73 74 if (gd->flags & GD_FLG_RELOC) { 75 pc = instruction_pointer(regs) - gd->reloc_off; 76 lr = regs->ARM_lr - gd->reloc_off; 77 } else { 78 pc = instruction_pointer(regs); 79 lr = regs->ARM_lr; 80 } 81 82 printf ("pc : %08lx lr : %08lx\n", pc, lr); 83 printf ("sp : %08lx ip : %08lx fp : %08lx\n", 84 regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); 85 printf ("r10: %08lx r9 : %08lx r8 : %08lx\n", 86 regs->ARM_r10, regs->ARM_r9, regs->ARM_r8); 87 printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", 88 regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4); 89 printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", 90 regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0); 91 printf ("Flags: %c%c%c%c", 92 flags & CC_N_BIT ? 'N' : 'n', 93 flags & CC_Z_BIT ? 'Z' : 'z', 94 flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v'); 95 printf (" IRQs %s FIQs %s Mode %s%s\n\n", 96 interrupts_enabled (regs) ? "on" : "off", 97 fast_interrupts_enabled (regs) ? "on" : "off", 98 processor_modes[processor_mode (regs)], 99 thumb_mode (regs) ? " (T)" : ""); 100 101 iomem_show("sp", regs->ARM_sp, 0x00, 0xfc); 102 } 103 104 /* fixup PC to point to the instruction leading to the exception */ 105 static inline void fixup_pc(struct pt_regs *regs, int offset) 106 { 107 uint32_t pc = instruction_pointer(regs) + offset; 108 regs->ARM_pc = pc | (regs->ARM_pc & PCMASK); 109 } 110 111 void do_undefined_instruction (struct pt_regs *pt_regs) 112 { 113 efi_restore_gd(); 114 printf ("undefined instruction\n"); 115 fixup_pc(pt_regs, -4); 116 show_regs (pt_regs); 117 bad_mode (); 118 } 119 120 void do_software_interrupt (struct pt_regs *pt_regs) 121 { 122 efi_restore_gd(); 123 printf ("software interrupt\n"); 124 fixup_pc(pt_regs, -4); 125 show_regs (pt_regs); 126 bad_mode (); 127 } 128 129 void do_prefetch_abort (struct pt_regs *pt_regs) 130 { 131 efi_restore_gd(); 132 printf ("prefetch abort\n"); 133 fixup_pc(pt_regs, -8); 134 show_regs (pt_regs); 135 bad_mode (); 136 } 137 138 void do_data_abort (struct pt_regs *pt_regs) 139 { 140 efi_restore_gd(); 141 printf ("data abort\n"); 142 fixup_pc(pt_regs, -8); 143 show_regs (pt_regs); 144 bad_mode (); 145 } 146 147 void do_not_used (struct pt_regs *pt_regs) 148 { 149 efi_restore_gd(); 150 printf ("not used\n"); 151 fixup_pc(pt_regs, -8); 152 show_regs (pt_regs); 153 bad_mode (); 154 } 155 156 void do_fiq (struct pt_regs *pt_regs) 157 { 158 efi_restore_gd(); 159 printf ("fast interrupt request\n"); 160 fixup_pc(pt_regs, -8); 161 show_regs (pt_regs); 162 bad_mode (); 163 } 164 165 #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_IRQ) 166 void do_irq (struct pt_regs *pt_regs) 167 { 168 efi_restore_gd(); 169 printf ("interrupt request\n"); 170 fixup_pc(pt_regs, -8); 171 show_regs (pt_regs); 172 bad_mode (); 173 } 174 #endif 175