uboot/arch/powerpc/cpu/mpc86xx/traps.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
   4 *
   5 * Modified by Cort Dougan (cort@cs.nmt.edu)
   6 * and Paul Mackerras (paulus@cs.anu.edu.au)
   7 *
   8 * (C) Copyright 2000
   9 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  10 */
  11
  12/*
  13 * This file handles the architecture-dependent parts of hardware exceptions
  14 */
  15
  16#include <common.h>
  17#include <command.h>
  18#include <kgdb.h>
  19#include <asm/processor.h>
  20
  21DECLARE_GLOBAL_DATA_PTR;
  22
  23/* Returns 0 if exception not found and fixup otherwise.  */
  24extern unsigned long search_exception_table(unsigned long);
  25
  26/*
  27 * End of addressable memory.  This may be less than the actual
  28 * amount of memory on the system if we're unable to keep all
  29 * the memory mapped in.
  30 */
  31#define END_OF_MEM (gd->bd->bi_memstart + get_effective_memsize())
  32
  33/*
  34 * Trap & Exception support
  35 */
  36
  37static void print_backtrace(unsigned long *sp)
  38{
  39        int cnt = 0;
  40        unsigned long i;
  41
  42        printf("Call backtrace: ");
  43        while (sp) {
  44                if ((uint) sp > END_OF_MEM)
  45                        break;
  46
  47                i = sp[1];
  48                if (cnt++ % 7 == 0)
  49                        printf("\n");
  50                printf("%08lX ", i);
  51                if (cnt > 32)
  52                        break;
  53                sp = (unsigned long *)*sp;
  54        }
  55        printf("\n");
  56}
  57
  58void show_regs(struct pt_regs *regs)
  59{
  60        int i;
  61
  62        printf("NIP: %08lX XER: %08lX LR: %08lX REGS:"
  63               " %p TRAP: %04lx DAR: %08lX\n",
  64               regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
  65        printf("MSR: %08lx EE: %01x PR: %01x FP:"
  66               " %01x ME: %01x IR/DR: %01x%01x\n",
  67               regs->msr, regs->msr & MSR_EE ? 1 : 0,
  68               regs->msr & MSR_PR ? 1 : 0, regs->msr & MSR_FP ? 1 : 0,
  69               regs->msr & MSR_ME ? 1 : 0, regs->msr & MSR_IR ? 1 : 0,
  70               regs->msr & MSR_DR ? 1 : 0);
  71
  72        printf("\n");
  73        for (i = 0; i < 32; i++) {
  74                if ((i % 8) == 0) {
  75                        printf("GPR%02d: ", i);
  76                }
  77
  78                printf("%08lX ", regs->gpr[i]);
  79                if ((i % 8) == 7) {
  80                        printf("\n");
  81                }
  82        }
  83}
  84
  85
  86static void _exception(int signr, struct pt_regs *regs)
  87{
  88        show_regs(regs);
  89        print_backtrace((unsigned long *)regs->gpr[1]);
  90        panic("Exception in kernel pc %lx signal %d", regs->nip, signr);
  91}
  92
  93void MachineCheckException(struct pt_regs *regs)
  94{
  95        unsigned long fixup;
  96
  97        /* Probing PCI using config cycles cause this exception
  98         * when a device is not present.  Catch it and return to
  99         * the PCI exception handler.
 100         */
 101        if ((fixup = search_exception_table(regs->nip)) != 0) {
 102                regs->nip = fixup;
 103                return;
 104        }
 105
 106#if defined(CONFIG_CMD_KGDB)
 107        if (debugger_exception_handler && (*debugger_exception_handler) (regs))
 108                return;
 109#endif
 110
 111        printf("Machine check in kernel mode.\n");
 112        printf("Caused by (from msr): ");
 113        printf("regs %p ", regs);
 114        switch ( regs->msr & 0x001F0000) {
 115        case (0x80000000>>11):
 116                printf("MSS error. MSSSR0: %08x\n", mfspr(SPRN_MSSSR0));
 117                break;
 118        case (0x80000000>>12):
 119                printf("Machine check signal - probably due to mm fault\n"
 120                       "with mmu off\n");
 121                break;
 122        case (0x80000000 >> 13):
 123                printf("Transfer error ack signal\n");
 124                break;
 125        case (0x80000000 >> 14):
 126                printf("Data parity signal\n");
 127                break;
 128        case (0x80000000 >> 15):
 129                printf("Address parity signal\n");
 130                break;
 131        default:
 132                printf("Unknown values in msr\n");
 133        }
 134        show_regs(regs);
 135        print_backtrace((unsigned long *)regs->gpr[1]);
 136        panic("machine check");
 137}
 138
 139void AlignmentException(struct pt_regs *regs)
 140{
 141#if defined(CONFIG_CMD_KGDB)
 142        if (debugger_exception_handler && (*debugger_exception_handler) (regs))
 143                return;
 144#endif
 145        show_regs(regs);
 146        print_backtrace((unsigned long *)regs->gpr[1]);
 147        panic("Alignment Exception");
 148}
 149
 150void ProgramCheckException(struct pt_regs *regs)
 151{
 152        unsigned char *p = regs ? (unsigned char *)(regs->nip) : NULL;
 153        int i, j;
 154
 155#if defined(CONFIG_CMD_KGDB)
 156        if (debugger_exception_handler && (*debugger_exception_handler) (regs))
 157                return;
 158#endif
 159        show_regs(regs);
 160
 161        p = (unsigned char *)((unsigned long)p & 0xFFFFFFE0);
 162        p -= 32;
 163        for (i = 0; i < 256; i += 16) {
 164                printf("%08x: ", (unsigned int)p + i);
 165                for (j = 0; j < 16; j++) {
 166                        printf("%02x ", p[i + j]);
 167                }
 168                printf("\n");
 169        }
 170
 171        print_backtrace((unsigned long *)regs->gpr[1]);
 172        panic("Program Check Exception");
 173}
 174
 175void SoftEmuException(struct pt_regs *regs)
 176{
 177#if defined(CONFIG_CMD_KGDB)
 178        if (debugger_exception_handler && (*debugger_exception_handler) (regs))
 179                return;
 180#endif
 181        show_regs(regs);
 182        print_backtrace((unsigned long *)regs->gpr[1]);
 183        panic("Software Emulation Exception");
 184}
 185
 186void UnknownException(struct pt_regs *regs)
 187{
 188#if defined(CONFIG_CMD_KGDB)
 189        if (debugger_exception_handler && (*debugger_exception_handler) (regs))
 190                return;
 191#endif
 192        printf("UnknownException regs@%lx\n", (ulong)regs);
 193        printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
 194               regs->nip, regs->msr, regs->trap);
 195        _exception(0, regs);
 196}
 197