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