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