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> 25ea0364f1SPeter Tyser 26ea0364f1SPeter Tyser DECLARE_GLOBAL_DATA_PTR; 27ea0364f1SPeter Tyser 28f1d2b313SHeiko Schocher #ifdef CONFIG_USE_IRQ 29ea0364f1SPeter Tyser int interrupt_init (void) 30ea0364f1SPeter Tyser { 31*571bdf16SGeorges Savoundararadj unsigned long cpsr; 32*571bdf16SGeorges Savoundararadj 33ea0364f1SPeter Tyser /* 34ea0364f1SPeter Tyser * setup up stacks if necessary 35ea0364f1SPeter Tyser */ 36f1d2b313SHeiko Schocher IRQ_STACK_START = gd->irq_sp - 4; 37f1d2b313SHeiko Schocher IRQ_STACK_START_IN = gd->irq_sp + 8; 38ea0364f1SPeter Tyser FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; 39ea0364f1SPeter Tyser 40*571bdf16SGeorges Savoundararadj 41*571bdf16SGeorges Savoundararadj __asm__ __volatile__("mrs %0, cpsr\n" 42*571bdf16SGeorges Savoundararadj : "=r" (cpsr) 43*571bdf16SGeorges Savoundararadj : 44*571bdf16SGeorges Savoundararadj : "memory"); 45*571bdf16SGeorges Savoundararadj 46*571bdf16SGeorges Savoundararadj __asm__ __volatile__("msr cpsr_c, %0\n" 47*571bdf16SGeorges Savoundararadj "mov sp, %1\n" 48*571bdf16SGeorges Savoundararadj : 49*571bdf16SGeorges Savoundararadj : "r" (IRQ_MODE | I_BIT | F_BIT | (cpsr & ~FIQ_MODE)), 50*571bdf16SGeorges Savoundararadj "r" (IRQ_STACK_START) 51*571bdf16SGeorges Savoundararadj : "memory"); 52*571bdf16SGeorges Savoundararadj 53*571bdf16SGeorges Savoundararadj __asm__ __volatile__("msr cpsr_c, %0\n" 54*571bdf16SGeorges Savoundararadj "mov sp, %1\n" 55*571bdf16SGeorges Savoundararadj : 56*571bdf16SGeorges Savoundararadj : "r" (FIQ_MODE | I_BIT | F_BIT | (cpsr & ~IRQ_MODE)), 57*571bdf16SGeorges Savoundararadj "r" (FIQ_STACK_START) 58*571bdf16SGeorges Savoundararadj : "memory"); 59*571bdf16SGeorges Savoundararadj 60*571bdf16SGeorges Savoundararadj __asm__ __volatile__("msr cpsr_c, %0" 61*571bdf16SGeorges Savoundararadj : 62*571bdf16SGeorges Savoundararadj : "r" (cpsr) 63*571bdf16SGeorges Savoundararadj : "memory"); 64*571bdf16SGeorges Savoundararadj 65ea0364f1SPeter Tyser return arch_interrupt_init(); 66ea0364f1SPeter Tyser } 67ea0364f1SPeter Tyser 68ea0364f1SPeter Tyser /* enable IRQ interrupts */ 69ea0364f1SPeter Tyser void enable_interrupts (void) 70ea0364f1SPeter Tyser { 71ea0364f1SPeter Tyser unsigned long temp; 72ea0364f1SPeter Tyser __asm__ __volatile__("mrs %0, cpsr\n" 73ea0364f1SPeter Tyser "bic %0, %0, #0x80\n" 74ea0364f1SPeter Tyser "msr cpsr_c, %0" 75ea0364f1SPeter Tyser : "=r" (temp) 76ea0364f1SPeter Tyser : 77ea0364f1SPeter Tyser : "memory"); 78ea0364f1SPeter Tyser } 79ea0364f1SPeter Tyser 80ea0364f1SPeter Tyser 81ea0364f1SPeter Tyser /* 82ea0364f1SPeter Tyser * disable IRQ/FIQ interrupts 83ea0364f1SPeter Tyser * returns true if interrupts had been enabled before we disabled them 84ea0364f1SPeter Tyser */ 85ea0364f1SPeter Tyser int disable_interrupts (void) 86ea0364f1SPeter Tyser { 87ea0364f1SPeter Tyser unsigned long old,temp; 88ea0364f1SPeter Tyser __asm__ __volatile__("mrs %0, cpsr\n" 89ea0364f1SPeter Tyser "orr %1, %0, #0xc0\n" 90ea0364f1SPeter Tyser "msr cpsr_c, %1" 91ea0364f1SPeter Tyser : "=r" (old), "=r" (temp) 92ea0364f1SPeter Tyser : 93ea0364f1SPeter Tyser : "memory"); 94ea0364f1SPeter Tyser return (old & 0x80) == 0; 95ea0364f1SPeter Tyser } 96ea0364f1SPeter Tyser #else 97f1d2b313SHeiko Schocher int interrupt_init (void) 98f1d2b313SHeiko Schocher { 99f1d2b313SHeiko Schocher /* 100f1d2b313SHeiko Schocher * setup up stacks if necessary 101f1d2b313SHeiko Schocher */ 102f1d2b313SHeiko Schocher IRQ_STACK_START_IN = gd->irq_sp + 8; 103f1d2b313SHeiko Schocher 104f1d2b313SHeiko Schocher return 0; 105f1d2b313SHeiko Schocher } 106f1d2b313SHeiko Schocher 107ea0364f1SPeter Tyser void enable_interrupts (void) 108ea0364f1SPeter Tyser { 109ea0364f1SPeter Tyser return; 110ea0364f1SPeter Tyser } 111ea0364f1SPeter Tyser int disable_interrupts (void) 112ea0364f1SPeter Tyser { 113ea0364f1SPeter Tyser return 0; 114ea0364f1SPeter Tyser } 115ea0364f1SPeter Tyser #endif 116ea0364f1SPeter Tyser 117ea0364f1SPeter Tyser 118ea0364f1SPeter Tyser void bad_mode (void) 119ea0364f1SPeter Tyser { 120ea0364f1SPeter Tyser panic ("Resetting CPU ...\n"); 121ea0364f1SPeter Tyser reset_cpu (0); 122ea0364f1SPeter Tyser } 123ea0364f1SPeter Tyser 124ea0364f1SPeter Tyser void show_regs (struct pt_regs *regs) 125ea0364f1SPeter Tyser { 126ea0364f1SPeter Tyser unsigned long flags; 127ea0364f1SPeter Tyser const char *processor_modes[] = { 128ea0364f1SPeter Tyser "USER_26", "FIQ_26", "IRQ_26", "SVC_26", 129ea0364f1SPeter Tyser "UK4_26", "UK5_26", "UK6_26", "UK7_26", 130ea0364f1SPeter Tyser "UK8_26", "UK9_26", "UK10_26", "UK11_26", 131ea0364f1SPeter Tyser "UK12_26", "UK13_26", "UK14_26", "UK15_26", 132ea0364f1SPeter Tyser "USER_32", "FIQ_32", "IRQ_32", "SVC_32", 133ea0364f1SPeter Tyser "UK4_32", "UK5_32", "UK6_32", "ABT_32", 134b726d22dSMarc Zyngier "UK8_32", "UK9_32", "HYP_32", "UND_32", 135ea0364f1SPeter Tyser "UK12_32", "UK13_32", "UK14_32", "SYS_32", 136ea0364f1SPeter Tyser }; 137ea0364f1SPeter Tyser 138ea0364f1SPeter Tyser flags = condition_codes (regs); 139ea0364f1SPeter Tyser 140ea0364f1SPeter Tyser printf ("pc : [<%08lx>] lr : [<%08lx>]\n" 141ea0364f1SPeter Tyser "sp : %08lx ip : %08lx fp : %08lx\n", 142ea0364f1SPeter Tyser instruction_pointer (regs), 143ea0364f1SPeter Tyser regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); 144ea0364f1SPeter Tyser printf ("r10: %08lx r9 : %08lx r8 : %08lx\n", 145ea0364f1SPeter Tyser regs->ARM_r10, regs->ARM_r9, regs->ARM_r8); 146ea0364f1SPeter Tyser printf ("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", 147ea0364f1SPeter Tyser regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4); 148ea0364f1SPeter Tyser printf ("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", 149ea0364f1SPeter Tyser regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0); 150ea0364f1SPeter Tyser printf ("Flags: %c%c%c%c", 151ea0364f1SPeter Tyser flags & CC_N_BIT ? 'N' : 'n', 152ea0364f1SPeter Tyser flags & CC_Z_BIT ? 'Z' : 'z', 153ea0364f1SPeter Tyser flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v'); 154ea0364f1SPeter Tyser printf (" IRQs %s FIQs %s Mode %s%s\n", 155ea0364f1SPeter Tyser interrupts_enabled (regs) ? "on" : "off", 156ea0364f1SPeter Tyser fast_interrupts_enabled (regs) ? "on" : "off", 157ea0364f1SPeter Tyser processor_modes[processor_mode (regs)], 158ea0364f1SPeter Tyser thumb_mode (regs) ? " (T)" : ""); 159ea0364f1SPeter Tyser } 160ea0364f1SPeter Tyser 161ea0364f1SPeter Tyser void do_undefined_instruction (struct pt_regs *pt_regs) 162ea0364f1SPeter Tyser { 163ea0364f1SPeter Tyser printf ("undefined instruction\n"); 164ea0364f1SPeter Tyser show_regs (pt_regs); 165ea0364f1SPeter Tyser bad_mode (); 166ea0364f1SPeter Tyser } 167ea0364f1SPeter Tyser 168ea0364f1SPeter Tyser void do_software_interrupt (struct pt_regs *pt_regs) 169ea0364f1SPeter Tyser { 170ea0364f1SPeter Tyser printf ("software interrupt\n"); 171ea0364f1SPeter Tyser show_regs (pt_regs); 172ea0364f1SPeter Tyser bad_mode (); 173ea0364f1SPeter Tyser } 174ea0364f1SPeter Tyser 175ea0364f1SPeter Tyser void do_prefetch_abort (struct pt_regs *pt_regs) 176ea0364f1SPeter Tyser { 177ea0364f1SPeter Tyser printf ("prefetch abort\n"); 178ea0364f1SPeter Tyser show_regs (pt_regs); 179ea0364f1SPeter Tyser bad_mode (); 180ea0364f1SPeter Tyser } 181ea0364f1SPeter Tyser 182ea0364f1SPeter Tyser void do_data_abort (struct pt_regs *pt_regs) 183ea0364f1SPeter Tyser { 1841551df35STom Rini printf ("data abort\n"); 185ea0364f1SPeter Tyser show_regs (pt_regs); 186ea0364f1SPeter Tyser bad_mode (); 187ea0364f1SPeter Tyser } 188ea0364f1SPeter Tyser 189ea0364f1SPeter Tyser void do_not_used (struct pt_regs *pt_regs) 190ea0364f1SPeter Tyser { 191ea0364f1SPeter Tyser printf ("not used\n"); 192ea0364f1SPeter Tyser show_regs (pt_regs); 193ea0364f1SPeter Tyser bad_mode (); 194ea0364f1SPeter Tyser } 195ea0364f1SPeter Tyser 196ea0364f1SPeter Tyser void do_fiq (struct pt_regs *pt_regs) 197ea0364f1SPeter Tyser { 198ea0364f1SPeter Tyser printf ("fast interrupt request\n"); 199ea0364f1SPeter Tyser show_regs (pt_regs); 200ea0364f1SPeter Tyser bad_mode (); 201ea0364f1SPeter Tyser } 202ea0364f1SPeter Tyser 203ea0364f1SPeter Tyser #ifndef CONFIG_USE_IRQ 204ea0364f1SPeter Tyser void do_irq (struct pt_regs *pt_regs) 205ea0364f1SPeter Tyser { 206ea0364f1SPeter Tyser printf ("interrupt request\n"); 207ea0364f1SPeter Tyser show_regs (pt_regs); 208ea0364f1SPeter Tyser bad_mode (); 209ea0364f1SPeter Tyser } 210ea0364f1SPeter Tyser #endif 211