uboot/arch/mips/lib/traps.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 1994 - 1999, 2000, 01, 06 Ralf Baechle
   4 * Copyright (C) 1995, 1996 Paul M. Antoine
   5 * Copyright (C) 1998 Ulf Carlsson
   6 * Copyright (C) 1999 Silicon Graphics, Inc.
   7 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
   8 * Copyright (C) 2002, 2003, 2004, 2005, 2007  Maciej W. Rozycki
   9 * Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc.  All rights reserved.
  10 * Copyright (C) 2014, Imagination Technologies Ltd.
  11 */
  12
  13#include <common.h>
  14#include <asm/mipsregs.h>
  15#include <asm/addrspace.h>
  16#include <asm/system.h>
  17
  18DECLARE_GLOBAL_DATA_PTR;
  19
  20static void show_regs(const struct pt_regs *regs)
  21{
  22        const int field = 2 * sizeof(unsigned long);
  23        unsigned int cause = regs->cp0_cause;
  24        unsigned int exccode;
  25        int i;
  26
  27        /*
  28         * Saved main processor registers
  29         */
  30        for (i = 0; i < 32; ) {
  31                if ((i % 4) == 0)
  32                        printf("$%2d   :", i);
  33                if (i == 0)
  34                        printf(" %0*lx", field, 0UL);
  35                else if (i == 26 || i == 27)
  36                        printf(" %*s", field, "");
  37                else
  38                        printf(" %0*lx", field, regs->regs[i]);
  39
  40                i++;
  41                if ((i % 4) == 0)
  42                        puts("\n");
  43        }
  44
  45        printf("Hi    : %0*lx\n", field, regs->hi);
  46        printf("Lo    : %0*lx\n", field, regs->lo);
  47
  48        /*
  49         * Saved cp0 registers
  50         */
  51        printf("epc   : %0*lx (text %0*lx)\n", field, regs->cp0_epc,
  52               field, regs->cp0_epc - gd->reloc_off);
  53        printf("ra    : %0*lx (text %0*lx)\n", field, regs->regs[31],
  54               field, regs->regs[31] - gd->reloc_off);
  55
  56        printf("Status: %08x\n", (uint32_t) regs->cp0_status);
  57
  58        exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
  59        printf("Cause : %08x (ExcCode %02x)\n", cause, exccode);
  60
  61        if (1 <= exccode && exccode <= 5)
  62                printf("BadVA : %0*lx\n", field, regs->cp0_badvaddr);
  63
  64        printf("PrId  : %08x\n", read_c0_prid());
  65}
  66
  67void do_reserved(const struct pt_regs *regs)
  68{
  69        puts("\nOoops:\n");
  70        show_regs(regs);
  71        hang();
  72}
  73
  74void do_ejtag_debug(const struct pt_regs *regs)
  75{
  76        const int field = 2 * sizeof(unsigned long);
  77        unsigned long depc;
  78        unsigned int debug;
  79
  80        depc = read_c0_depc();
  81        debug = read_c0_debug();
  82
  83        printf("SDBBP EJTAG debug exception: c0_depc = %0*lx, DEBUG = %08x\n",
  84               field, depc, debug);
  85}
  86
  87static void set_handler(unsigned long offset, void *addr, unsigned long size)
  88{
  89        unsigned long ebase = gd->irq_sp;
  90
  91        memcpy((void *)(ebase + offset), addr, size);
  92        flush_cache(ebase + offset, size);
  93}
  94
  95void trap_init(ulong reloc_addr)
  96{
  97        unsigned long ebase = gd->irq_sp;
  98
  99        set_handler(0x180, &except_vec3_generic, 0x80);
 100        set_handler(0x280, &except_vec_ejtag_debug, 0x80);
 101
 102        write_c0_ebase(ebase);
 103        clear_c0_status(ST0_BEV);
 104        execution_hazard_barrier();
 105}
 106