uboot/arch/powerpc/cpu/mpc85xx/traps.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * linux/arch/powerpc/kernel/traps.c
   4 *
   5 * Copyright 2007 Freescale Semiconductor.
   6 * Copyright (C) 2003 Motorola
   7 * Modified by Xianghua Xiao(x.xiao@motorola.com)
   8 *
   9 * Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
  10 *
  11 * Modified by Cort Dougan (cort@cs.nmt.edu)
  12 * and Paul Mackerras (paulus@cs.anu.edu.au)
  13 *
  14 * (C) Copyright 2000
  15 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  16 */
  17
  18/*
  19 * This file handles the architecture-dependent parts of hardware exceptions
  20 */
  21
  22#include <common.h>
  23#include <command.h>
  24#include <kgdb.h>
  25#include <asm/processor.h>
  26
  27DECLARE_GLOBAL_DATA_PTR;
  28
  29/* Returns 0 if exception not found and fixup otherwise.  */
  30extern unsigned long search_exception_table(unsigned long);
  31
  32/*
  33 * End of addressable memory.  This may be less than the actual
  34 * amount of memory on the system if we're unable to keep all
  35 * the memory mapped in.
  36 */
  37#define END_OF_MEM (gd->bd->bi_memstart + get_effective_memsize())
  38
  39static __inline__ void set_tsr(unsigned long val)
  40{
  41        asm volatile("mtspr 0x150, %0" : : "r" (val));
  42}
  43
  44static __inline__ unsigned long get_esr(void)
  45{
  46        unsigned long val;
  47        asm volatile("mfspr %0, 0x03e" : "=r" (val) :);
  48        return val;
  49}
  50
  51#define ESR_MCI 0x80000000
  52#define ESR_PIL 0x08000000
  53#define ESR_PPR 0x04000000
  54#define ESR_PTR 0x02000000
  55#define ESR_DST 0x00800000
  56#define ESR_DIZ 0x00400000
  57#define ESR_U0F 0x00008000
  58
  59#if defined(CONFIG_CMD_BEDBUG)
  60extern void do_bedbug_breakpoint(struct pt_regs *);
  61#endif
  62
  63/*
  64 * Trap & Exception support
  65 */
  66
  67static void print_backtrace(unsigned long *sp)
  68{
  69        int cnt = 0;
  70        unsigned long i;
  71
  72        printf("Call backtrace: ");
  73        while (sp) {
  74                if ((uint)sp > END_OF_MEM)
  75                        break;
  76
  77                i = sp[1];
  78                if (cnt++ % 7 == 0)
  79                        printf("\n");
  80                printf("%08lX ", i);
  81                if (cnt > 32) break;
  82                sp = (unsigned long *)*sp;
  83        }
  84        printf("\n");
  85}
  86
  87void show_regs(struct pt_regs *regs)
  88{
  89        int i;
  90
  91        printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
  92               regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
  93        printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
  94               regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
  95               regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
  96               regs->msr&MSR_IR ? 1 : 0,
  97               regs->msr&MSR_DR ? 1 : 0);
  98
  99        printf("\n");
 100        for (i = 0;  i < 32;  i++) {
 101                if ((i % 8) == 0)
 102                {
 103                        printf("GPR%02d: ", i);
 104                }
 105
 106                printf("%08lX ", regs->gpr[i]);
 107                if ((i % 8) == 7)
 108                {
 109                        printf("\n");
 110                }
 111        }
 112}
 113
 114
 115static void _exception(int signr, struct pt_regs *regs)
 116{
 117        show_regs(regs);
 118        print_backtrace((unsigned long *)regs->gpr[1]);
 119        panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
 120}
 121
 122void CritcalInputException(struct pt_regs *regs)
 123{
 124        panic("Critical Input Exception");
 125}
 126
 127int machinecheck_count = 0;
 128int machinecheck_error = 0;
 129void MachineCheckException(struct pt_regs *regs)
 130{
 131        unsigned long fixup;
 132        unsigned int mcsr, mcsrr0, mcsrr1, mcar;
 133
 134        /* Probing PCI using config cycles cause this exception
 135         * when a device is not present.  Catch it and return to
 136         * the PCI exception handler.
 137         */
 138        if ((fixup = search_exception_table(regs->nip)) != 0) {
 139                regs->nip = fixup;
 140                return;
 141        }
 142
 143        mcsrr0 = mfspr(SPRN_MCSRR0);
 144        mcsrr1 = mfspr(SPRN_MCSRR1);
 145        mcsr = mfspr(SPRN_MCSR);
 146        mcar = mfspr(SPRN_MCAR);
 147
 148        machinecheck_count++;
 149        machinecheck_error=1;
 150
 151#if defined(CONFIG_CMD_KGDB)
 152        if (debugger_exception_handler && (*debugger_exception_handler)(regs))
 153                return;
 154#endif
 155
 156        printf("Machine check in kernel mode.\n");
 157        printf("Caused by (from mcsr): ");
 158        printf("mcsr = 0x%08x\n", mcsr);
 159        if (mcsr & 0x80000000)
 160                printf("Machine check input pin\n");
 161        if (mcsr & 0x40000000)
 162                printf("Instruction cache parity error\n");
 163        if (mcsr & 0x20000000)
 164                printf("Data cache push parity error\n");
 165        if (mcsr & 0x10000000)
 166                printf("Data cache parity error\n");
 167        if (mcsr & 0x00000080)
 168                printf("Bus instruction address error\n");
 169        if (mcsr & 0x00000040)
 170                printf("Bus Read address error\n");
 171        if (mcsr & 0x00000020)
 172                printf("Bus Write address error\n");
 173        if (mcsr & 0x00000010)
 174                printf("Bus Instruction data bus error\n");
 175        if (mcsr & 0x00000008)
 176                printf("Bus Read data bus error\n");
 177        if (mcsr & 0x00000004)
 178                printf("Bus Write bus error\n");
 179        if (mcsr & 0x00000002)
 180                printf("Bus Instruction parity error\n");
 181        if (mcsr & 0x00000001)
 182                printf("Bus Read parity error\n");
 183
 184        show_regs(regs);
 185        printf("MCSR=0x%08x \tMCSRR0=0x%08x \nMCSRR1=0x%08x \tMCAR=0x%08x\n",
 186               mcsr, mcsrr0, mcsrr1, mcar);
 187        print_backtrace((unsigned long *)regs->gpr[1]);
 188        if (machinecheck_count > 10) {
 189                panic("machine check count too high\n");
 190        }
 191
 192        if (machinecheck_count > 1) {
 193                regs->nip += 4; /* skip offending instruction */
 194                printf("Skipping current instr, Returning to 0x%08lx\n",
 195                       regs->nip);
 196        } else {
 197                printf("Returning back to 0x%08lx\n",regs->nip);
 198        }
 199}
 200
 201void AlignmentException(struct pt_regs *regs)
 202{
 203#if defined(CONFIG_CMD_KGDB)
 204        if (debugger_exception_handler && (*debugger_exception_handler)(regs))
 205                return;
 206#endif
 207
 208        show_regs(regs);
 209        print_backtrace((unsigned long *)regs->gpr[1]);
 210        panic("Alignment Exception");
 211}
 212
 213void ProgramCheckException(struct pt_regs *regs)
 214{
 215        long esr_val;
 216
 217#if defined(CONFIG_CMD_KGDB)
 218        if (debugger_exception_handler && (*debugger_exception_handler)(regs))
 219                return;
 220#endif
 221
 222        show_regs(regs);
 223
 224        esr_val = get_esr();
 225        if( esr_val & ESR_PIL )
 226                printf( "** Illegal Instruction **\n" );
 227        else if( esr_val & ESR_PPR )
 228                printf( "** Privileged Instruction **\n" );
 229        else if( esr_val & ESR_PTR )
 230                printf( "** Trap Instruction **\n" );
 231
 232        print_backtrace((unsigned long *)regs->gpr[1]);
 233        panic("Program Check Exception");
 234}
 235
 236void PITException(struct pt_regs *regs)
 237{
 238        /*
 239         * Reset PIT interrupt
 240         */
 241        set_tsr(0x0c000000);
 242
 243        /*
 244         * Call timer_interrupt routine in interrupts.c
 245         */
 246        timer_interrupt(NULL);
 247}
 248
 249void UnknownException(struct pt_regs *regs)
 250{
 251#if defined(CONFIG_CMD_KGDB)
 252        if (debugger_exception_handler && (*debugger_exception_handler)(regs))
 253                return;
 254#endif
 255
 256        printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
 257               regs->nip, regs->msr, regs->trap);
 258        _exception(0, regs);
 259}
 260
 261void ExtIntException(struct pt_regs *regs)
 262{
 263        volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR);
 264
 265        uint vect;
 266
 267#if defined(CONFIG_CMD_KGDB)
 268        if (debugger_exception_handler && (*debugger_exception_handler)(regs))
 269                return;
 270#endif
 271
 272        printf("External Interrupt Exception at PC: %lx, SR: %lx, vector=%lx",
 273               regs->nip, regs->msr, regs->trap);
 274        vect = pic->iack0;
 275        printf(" irq IACK0@%05x=%d\n",(int)&pic->iack0,vect);
 276        show_regs(regs);
 277        print_backtrace((unsigned long *)regs->gpr[1]);
 278}
 279
 280void DebugException(struct pt_regs *regs)
 281{
 282        printf("Debugger trap at @ %lx\n", regs->nip );
 283        show_regs(regs);
 284#if defined(CONFIG_CMD_BEDBUG)
 285        do_bedbug_breakpoint( regs );
 286#endif
 287}
 288