From debb7354d1ea4f694154818df5e5b523f5c1cc1d Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Wed, 26 Apr 2006 17:58:56 -0500 Subject: Initial support for MPC8641 HPCN board. --- cpu/mpc86xx/traps.c | 253 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 cpu/mpc86xx/traps.c (limited to 'cpu/mpc86xx/traps.c') diff --git a/cpu/mpc86xx/traps.c b/cpu/mpc86xx/traps.c new file mode 100644 index 0000000000..fdfc95dfc5 --- /dev/null +++ b/cpu/mpc86xx/traps.c @@ -0,0 +1,253 @@ +/* + * linux/arch/ppc/kernel/traps.c + * + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modified by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras (paulus@cs.anu.edu.au) + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * This file handles the architecture-dependent parts of hardware exceptions + */ + +#include +#include +#include + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +int (*debugger_exception_handler)(struct pt_regs *) = 0; +#endif + +/* Returns 0 if exception not found and fixup otherwise. */ +extern unsigned long search_exception_table(unsigned long); + +#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize) + +/* + * Trap & Exception support + */ + +void +print_backtrace(unsigned long *sp) +{ + DECLARE_GLOBAL_DATA_PTR; + + int cnt = 0; + unsigned long i; + + printf("Call backtrace: "); + while (sp) { + if ((uint)sp > END_OF_MEM) + break; + + i = sp[1]; + if (cnt++ % 7 == 0) + printf("\n"); + printf("%08lX ", i); + if (cnt > 32) break; + sp = (unsigned long *)*sp; + } + printf("\n"); +} + +void +show_regs(struct pt_regs * regs) +{ + int i; + + printf("NIP: %08lX XER: %08lX LR: %08lX REGS:" + " %p TRAP: %04lx DAR: %08lX\n", + regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar); + printf("MSR: %08lx EE: %01x PR: %01x FP:" + " %01x ME: %01x IR/DR: %01x%01x\n", + regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, + regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, + regs->msr&MSR_IR ? 1 : 0, + regs->msr&MSR_DR ? 1 : 0); + + printf("\n"); + for (i = 0; i < 32; i++) { + if ((i % 8) == 0) + { + printf("GPR%02d: ", i); + } + + printf("%08lX ", regs->gpr[i]); + if ((i % 8) == 7) + { + printf("\n"); + } + } +} + + +void +_exception(int signr, struct pt_regs *regs) +{ + show_regs(regs); + print_backtrace((unsigned long *)regs->gpr[1]); + panic("Exception in kernel pc %lx signal %d",regs->nip,signr); +} + +void +MachineCheckException(struct pt_regs *regs) +{ + unsigned long fixup; + + /* Probing PCI using config cycles cause this exception + * when a device is not present. Catch it and return to + * the PCI exception handler. + */ + if ((fixup = search_exception_table(regs->nip)) != 0) { + regs->nip = fixup; + return; + } + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + + printf("Machine check in kernel mode.\n"); + printf("Caused by (from msr): "); + printf("regs %p ",regs); + switch( regs->msr & 0x000F0000) { + case (0x80000000>>12): + printf("Machine check signal - probably due to mm fault\n" + "with mmu off\n"); + break; + case (0x80000000>>13): + printf("Transfer error ack signal\n"); + break; + case (0x80000000>>14): + printf("Data parity signal\n"); + break; + case (0x80000000>>15): + printf("Address parity signal\n"); + break; + default: + printf("Unknown values in msr\n"); + } + show_regs(regs); + print_backtrace((unsigned long *)regs->gpr[1]); + panic("machine check"); +} + +void +AlignmentException(struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + show_regs(regs); + print_backtrace((unsigned long *)regs->gpr[1]); + panic("Alignment Exception"); +} + +void +ProgramCheckException(struct pt_regs *regs) +{ + unsigned char *p = regs ? (unsigned char *)(regs->nip) : NULL; + int i, j; + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + show_regs(regs); + + p = (unsigned char *) ((unsigned long)p & 0xFFFFFFE0); + p -= 32; + for (i = 0; i < 256; i+=16) { + printf("%08x: ", (unsigned int)p+i); + for (j = 0; j < 16; j++) { + printf("%02x ", p[i+j]); + } + printf("\n"); + } + + print_backtrace((unsigned long *)regs->gpr[1]); + panic("Program Check Exception"); +} + +void +SoftEmuException(struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + show_regs(regs); + print_backtrace((unsigned long *)regs->gpr[1]); + panic("Software Emulation Exception"); +} + + +void +UnknownException(struct pt_regs *regs) +{ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) + if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + return; +#endif + printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", + regs->nip, regs->msr, regs->trap); + _exception(0, regs); +} + +/* Probe an address by reading. If not present, return -1, otherwise + * return 0. + */ +int +addr_probe(uint *addr) +{ +#if 0 + int retval; + + __asm__ __volatile__( \ + "1: lwz %0,0(%1)\n" \ + " eieio\n" \ + " li %0,0\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: li %0,-1\n" \ + " b 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 2\n" \ + " .long 1b,3b\n" \ + ".text" \ + : "=r" (retval) : "r"(addr)); + + return (retval); +#endif + return 0; +} + + + + + + -- cgit From 5c9efb36a6b5431423f52888a0e3b4b515fe7eca Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Thu, 27 Apr 2006 10:15:16 -0500 Subject: Cleanup whitespaces and style issues. Removed //-style comments. Use 80-column lines. Remove trailing whitespace. Remove dead code and debug cruft. --- cpu/mpc86xx/traps.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'cpu/mpc86xx/traps.c') diff --git a/cpu/mpc86xx/traps.c b/cpu/mpc86xx/traps.c index fdfc95dfc5..8113dfbcc3 100644 --- a/cpu/mpc86xx/traps.c +++ b/cpu/mpc86xx/traps.c @@ -1,6 +1,4 @@ /* - * linux/arch/ppc/kernel/traps.c - * * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Modified by Cort Dougan (cort@cs.nmt.edu) -- cgit From ffff3ae56f5842ca3679e4ce7922b819a87aad9f Mon Sep 17 00:00:00 2001 From: Jon Loeliger Date: Tue, 22 Aug 2006 12:06:18 -0500 Subject: General indent and whitespace cleanups. --- cpu/mpc86xx/traps.c | 89 +++++++++++++++++++---------------------------------- 1 file changed, 32 insertions(+), 57 deletions(-) (limited to 'cpu/mpc86xx/traps.c') diff --git a/cpu/mpc86xx/traps.c b/cpu/mpc86xx/traps.c index 8113dfbcc3..8ea14e575f 100644 --- a/cpu/mpc86xx/traps.c +++ b/cpu/mpc86xx/traps.c @@ -57,21 +57,22 @@ print_backtrace(unsigned long *sp) printf("Call backtrace: "); while (sp) { - if ((uint)sp > END_OF_MEM) + if ((uint) sp > END_OF_MEM) break; i = sp[1]; if (cnt++ % 7 == 0) printf("\n"); printf("%08lX ", i); - if (cnt > 32) break; + if (cnt > 32) + break; sp = (unsigned long *)*sp; } printf("\n"); } void -show_regs(struct pt_regs * regs) +show_regs(struct pt_regs *regs) { int i; @@ -80,21 +81,19 @@ show_regs(struct pt_regs * regs) regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar); printf("MSR: %08lx EE: %01x PR: %01x FP:" " %01x ME: %01x IR/DR: %01x%01x\n", - regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, - regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, - regs->msr&MSR_IR ? 1 : 0, - regs->msr&MSR_DR ? 1 : 0); + regs->msr, regs->msr & MSR_EE ? 1 : 0, + regs->msr & MSR_PR ? 1 : 0, regs->msr & MSR_FP ? 1 : 0, + regs->msr & MSR_ME ? 1 : 0, regs->msr & MSR_IR ? 1 : 0, + regs->msr & MSR_DR ? 1 : 0); printf("\n"); - for (i = 0; i < 32; i++) { - if ((i % 8) == 0) - { + for (i = 0; i < 32; i++) { + if ((i % 8) == 0) { printf("GPR%02d: ", i); } printf("%08lX ", regs->gpr[i]); - if ((i % 8) == 7) - { + if ((i % 8) == 7) { printf("\n"); } } @@ -106,7 +105,7 @@ _exception(int signr, struct pt_regs *regs) { show_regs(regs); print_backtrace((unsigned long *)regs->gpr[1]); - panic("Exception in kernel pc %lx signal %d",regs->nip,signr); + panic("Exception in kernel pc %lx signal %d", regs->nip, signr); } void @@ -124,25 +123,25 @@ MachineCheckException(struct pt_regs *regs) } #if (CONFIG_COMMANDS & CFG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + if (debugger_exception_handler && (*debugger_exception_handler) (regs)) return; #endif printf("Machine check in kernel mode.\n"); printf("Caused by (from msr): "); - printf("regs %p ",regs); - switch( regs->msr & 0x000F0000) { - case (0x80000000>>12): + printf("regs %p ", regs); + switch (regs->msr & 0x000F0000) { + case (0x80000000 >> 12): printf("Machine check signal - probably due to mm fault\n" - "with mmu off\n"); + "with mmu off\n"); break; - case (0x80000000>>13): + case (0x80000000 >> 13): printf("Transfer error ack signal\n"); break; - case (0x80000000>>14): + case (0x80000000 >> 14): printf("Data parity signal\n"); break; - case (0x80000000>>15): + case (0x80000000 >> 15): printf("Address parity signal\n"); break; default: @@ -157,7 +156,7 @@ void AlignmentException(struct pt_regs *regs) { #if (CONFIG_COMMANDS & CFG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + if (debugger_exception_handler && (*debugger_exception_handler) (regs)) return; #endif show_regs(regs); @@ -172,17 +171,17 @@ ProgramCheckException(struct pt_regs *regs) int i, j; #if (CONFIG_COMMANDS & CFG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + if (debugger_exception_handler && (*debugger_exception_handler) (regs)) return; #endif show_regs(regs); - p = (unsigned char *) ((unsigned long)p & 0xFFFFFFE0); + p = (unsigned char *)((unsigned long)p & 0xFFFFFFE0); p -= 32; - for (i = 0; i < 256; i+=16) { - printf("%08x: ", (unsigned int)p+i); + for (i = 0; i < 256; i += 16) { + printf("%08x: ", (unsigned int)p + i); for (j = 0; j < 16; j++) { - printf("%02x ", p[i+j]); + printf("%02x ", p[i + j]); } printf("\n"); } @@ -195,7 +194,7 @@ void SoftEmuException(struct pt_regs *regs) { #if (CONFIG_COMMANDS & CFG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + if (debugger_exception_handler && (*debugger_exception_handler) (regs)) return; #endif show_regs(regs); @@ -203,12 +202,11 @@ SoftEmuException(struct pt_regs *regs) panic("Software Emulation Exception"); } - void UnknownException(struct pt_regs *regs) { #if (CONFIG_COMMANDS & CFG_CMD_KGDB) - if (debugger_exception_handler && (*debugger_exception_handler)(regs)) + if (debugger_exception_handler && (*debugger_exception_handler) (regs)) return; #endif printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", @@ -216,36 +214,13 @@ UnknownException(struct pt_regs *regs) _exception(0, regs); } -/* Probe an address by reading. If not present, return -1, otherwise - * return 0. +/* + * Probe an address by reading. + * If not present, return -1, + * otherwise return 0. */ int addr_probe(uint *addr) { -#if 0 - int retval; - - __asm__ __volatile__( \ - "1: lwz %0,0(%1)\n" \ - " eieio\n" \ - " li %0,0\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: li %0,-1\n" \ - " b 2b\n" \ - ".section __ex_table,\"a\"\n" \ - " .align 2\n" \ - " .long 1b,3b\n" \ - ".text" \ - : "=r" (retval) : "r"(addr)); - - return (retval); -#endif return 0; } - - - - - - -- cgit