1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
26c593630SDaniel Schwierzeck /*
36c593630SDaniel Schwierzeck * Copyright (C) 1994 - 1999, 2000, 01, 06 Ralf Baechle
46c593630SDaniel Schwierzeck * Copyright (C) 1995, 1996 Paul M. Antoine
56c593630SDaniel Schwierzeck * Copyright (C) 1998 Ulf Carlsson
66c593630SDaniel Schwierzeck * Copyright (C) 1999 Silicon Graphics, Inc.
76c593630SDaniel Schwierzeck * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
86c593630SDaniel Schwierzeck * Copyright (C) 2002, 2003, 2004, 2005, 2007 Maciej W. Rozycki
96c593630SDaniel Schwierzeck * Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc. All rights reserved.
106c593630SDaniel Schwierzeck * Copyright (C) 2014, Imagination Technologies Ltd.
116c593630SDaniel Schwierzeck */
126c593630SDaniel Schwierzeck
136c593630SDaniel Schwierzeck #include <common.h>
146c593630SDaniel Schwierzeck #include <asm/mipsregs.h>
156c593630SDaniel Schwierzeck #include <asm/addrspace.h>
166c593630SDaniel Schwierzeck #include <asm/system.h>
176c593630SDaniel Schwierzeck
186c593630SDaniel Schwierzeck DECLARE_GLOBAL_DATA_PTR;
196c593630SDaniel Schwierzeck
show_regs(const struct pt_regs * regs)206c593630SDaniel Schwierzeck static void show_regs(const struct pt_regs *regs)
216c593630SDaniel Schwierzeck {
226c593630SDaniel Schwierzeck const int field = 2 * sizeof(unsigned long);
236c593630SDaniel Schwierzeck unsigned int cause = regs->cp0_cause;
246c593630SDaniel Schwierzeck unsigned int exccode;
256c593630SDaniel Schwierzeck int i;
266c593630SDaniel Schwierzeck
276c593630SDaniel Schwierzeck /*
286c593630SDaniel Schwierzeck * Saved main processor registers
296c593630SDaniel Schwierzeck */
306c593630SDaniel Schwierzeck for (i = 0; i < 32; ) {
316c593630SDaniel Schwierzeck if ((i % 4) == 0)
326c593630SDaniel Schwierzeck printf("$%2d :", i);
336c593630SDaniel Schwierzeck if (i == 0)
346c593630SDaniel Schwierzeck printf(" %0*lx", field, 0UL);
356c593630SDaniel Schwierzeck else if (i == 26 || i == 27)
366c593630SDaniel Schwierzeck printf(" %*s", field, "");
376c593630SDaniel Schwierzeck else
386c593630SDaniel Schwierzeck printf(" %0*lx", field, regs->regs[i]);
396c593630SDaniel Schwierzeck
406c593630SDaniel Schwierzeck i++;
416c593630SDaniel Schwierzeck if ((i % 4) == 0)
426c593630SDaniel Schwierzeck puts("\n");
436c593630SDaniel Schwierzeck }
446c593630SDaniel Schwierzeck
456c593630SDaniel Schwierzeck printf("Hi : %0*lx\n", field, regs->hi);
466c593630SDaniel Schwierzeck printf("Lo : %0*lx\n", field, regs->lo);
476c593630SDaniel Schwierzeck
486c593630SDaniel Schwierzeck /*
496c593630SDaniel Schwierzeck * Saved cp0 registers
506c593630SDaniel Schwierzeck */
516c593630SDaniel Schwierzeck printf("epc : %0*lx (text %0*lx)\n", field, regs->cp0_epc,
526c593630SDaniel Schwierzeck field, regs->cp0_epc - gd->reloc_off);
536c593630SDaniel Schwierzeck printf("ra : %0*lx (text %0*lx)\n", field, regs->regs[31],
546c593630SDaniel Schwierzeck field, regs->regs[31] - gd->reloc_off);
556c593630SDaniel Schwierzeck
566c593630SDaniel Schwierzeck printf("Status: %08x\n", (uint32_t) regs->cp0_status);
576c593630SDaniel Schwierzeck
586c593630SDaniel Schwierzeck exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
596c593630SDaniel Schwierzeck printf("Cause : %08x (ExcCode %02x)\n", cause, exccode);
606c593630SDaniel Schwierzeck
616c593630SDaniel Schwierzeck if (1 <= exccode && exccode <= 5)
626c593630SDaniel Schwierzeck printf("BadVA : %0*lx\n", field, regs->cp0_badvaddr);
636c593630SDaniel Schwierzeck
646c593630SDaniel Schwierzeck printf("PrId : %08x\n", read_c0_prid());
656c593630SDaniel Schwierzeck }
666c593630SDaniel Schwierzeck
do_reserved(const struct pt_regs * regs)676c593630SDaniel Schwierzeck void do_reserved(const struct pt_regs *regs)
686c593630SDaniel Schwierzeck {
696c593630SDaniel Schwierzeck puts("\nOoops:\n");
706c593630SDaniel Schwierzeck show_regs(regs);
716c593630SDaniel Schwierzeck hang();
726c593630SDaniel Schwierzeck }
736c593630SDaniel Schwierzeck
do_ejtag_debug(const struct pt_regs * regs)746c593630SDaniel Schwierzeck void do_ejtag_debug(const struct pt_regs *regs)
756c593630SDaniel Schwierzeck {
766c593630SDaniel Schwierzeck const int field = 2 * sizeof(unsigned long);
776c593630SDaniel Schwierzeck unsigned long depc;
786c593630SDaniel Schwierzeck unsigned int debug;
796c593630SDaniel Schwierzeck
806c593630SDaniel Schwierzeck depc = read_c0_depc();
816c593630SDaniel Schwierzeck debug = read_c0_debug();
826c593630SDaniel Schwierzeck
836c593630SDaniel Schwierzeck printf("SDBBP EJTAG debug exception: c0_depc = %0*lx, DEBUG = %08x\n",
846c593630SDaniel Schwierzeck field, depc, debug);
856c593630SDaniel Schwierzeck }
866c593630SDaniel Schwierzeck
set_handler(unsigned long offset,void * addr,unsigned long size)876c593630SDaniel Schwierzeck static void set_handler(unsigned long offset, void *addr, unsigned long size)
886c593630SDaniel Schwierzeck {
896c593630SDaniel Schwierzeck unsigned long ebase = gd->irq_sp;
906c593630SDaniel Schwierzeck
916c593630SDaniel Schwierzeck memcpy((void *)(ebase + offset), addr, size);
926c593630SDaniel Schwierzeck flush_cache(ebase + offset, size);
936c593630SDaniel Schwierzeck }
946c593630SDaniel Schwierzeck
trap_init(ulong reloc_addr)956c593630SDaniel Schwierzeck void trap_init(ulong reloc_addr)
966c593630SDaniel Schwierzeck {
976c593630SDaniel Schwierzeck unsigned long ebase = gd->irq_sp;
986c593630SDaniel Schwierzeck
996c593630SDaniel Schwierzeck set_handler(0x180, &except_vec3_generic, 0x80);
1006c593630SDaniel Schwierzeck set_handler(0x280, &except_vec_ejtag_debug, 0x80);
1016c593630SDaniel Schwierzeck
1026c593630SDaniel Schwierzeck write_c0_ebase(ebase);
1036c593630SDaniel Schwierzeck clear_c0_status(ST0_BEV);
1046c593630SDaniel Schwierzeck execution_hazard_barrier();
1056c593630SDaniel Schwierzeck }
106