diff options
| author | Stefan Roese <sr@denx.de> | 2007-08-15 14:51:27 +0200 | 
|---|---|---|
| committer | Stefan Roese <sr@denx.de> | 2007-08-15 14:51:27 +0200 | 
| commit | d61ea14885631e58a25feaa81ee82eb464c62d6a (patch) | |
| tree | 27927975039d0a15e6c6d4dfe8f765a76a12820a /cpu/mpc85xx/traps.c | |
| parent | 3ba4c2d68f6541db4677b4aea12071f56e6ff6e6 (diff) | |
| parent | 594e79838ce5078a90d0c27abb2b2d61d5f8e8a7 (diff) | |
| download | olio-uboot-2014.01-d61ea14885631e58a25feaa81ee82eb464c62d6a.tar.xz olio-uboot-2014.01-d61ea14885631e58a25feaa81ee82eb464c62d6a.zip | |
Merge with git://www.denx.de/git/u-boot.git
Diffstat (limited to 'cpu/mpc85xx/traps.c')
| -rw-r--r-- | cpu/mpc85xx/traps.c | 113 | 
1 files changed, 86 insertions, 27 deletions
| diff --git a/cpu/mpc85xx/traps.c b/cpu/mpc85xx/traps.c index 904f05233..efc80c7ae 100644 --- a/cpu/mpc85xx/traps.c +++ b/cpu/mpc85xx/traps.c @@ -1,6 +1,7 @@  /*   * linux/arch/ppc/kernel/traps.c   * + * Copyright 2007 Freescale Semiconductor.   * Copyright (C) 2003 Motorola   * Modified by Xianghua Xiao(x.xiao@motorola.com)   * @@ -41,7 +42,7 @@  DECLARE_GLOBAL_DATA_PTR; -#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#if defined(CONFIG_CMD_KGDB)  int (*debugger_exception_handler)(struct pt_regs *) = 0;  #endif @@ -74,7 +75,7 @@ static __inline__ unsigned long get_esr(void)  #define ESR_DIZ 0x00400000  #define ESR_U0F 0x00008000 -#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) +#if defined(CONFIG_CMD_BEDBUG)  extern void do_bedbug_breakpoint(struct pt_regs *);  #endif @@ -145,10 +146,13 @@ CritcalInputException(struct pt_regs *regs)  	panic("Critical Input Exception");  } +int machinecheck_count = 0; +int machinecheck_error = 0;  void  MachineCheckException(struct pt_regs *regs)  {  	unsigned long fixup; +	unsigned int mcsr, mcsrr0, mcsrr1, mcar;  	/* Probing PCI using config cycles cause this exception  	 * when a device is not present.  Catch it and return to @@ -159,40 +163,68 @@ MachineCheckException(struct pt_regs *regs)  		return;  	} -#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +	mcsrr0 = mfspr(SPRN_MCSRR0); +	mcsrr1 = mfspr(SPRN_MCSRR1); +	mcsr = mfspr(SPRN_MCSR); +	mcar = mfspr(SPRN_MCAR); + +	machinecheck_count++; +	machinecheck_error=1; + +#if defined(CONFIG_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"); -	} +	printf("Caused by (from mcsr): "); +	printf("mcsr = 0x%08x\n", mcsr); +	if (mcsr & 0x80000000) +		printf("Machine check input pin\n"); +	if (mcsr & 0x40000000) +		printf("Instruction cache parity error\n"); +	if (mcsr & 0x20000000) +		printf("Data cache push parity error\n"); +	if (mcsr & 0x10000000) +		printf("Data cache parity error\n"); +	if (mcsr & 0x00000080) +		printf("Bus instruction address error\n"); +	if (mcsr & 0x00000040) +		printf("Bus Read address error\n"); +	if (mcsr & 0x00000020) +		printf("Bus Write address error\n"); +	if (mcsr & 0x00000010) +		printf("Bus Instruction data bus error\n"); +	if (mcsr & 0x00000008) +		printf("Bus Read data bus error\n"); +	if (mcsr & 0x00000004) +		printf("Bus Write bus error\n"); +	if (mcsr & 0x00000002) +		printf("Bus Instruction parity error\n"); +	if (mcsr & 0x00000001) +		printf("Bus Read parity error\n"); +  	show_regs(regs); +	printf("MCSR=0x%08x \tMCSRR0=0x%08x \nMCSRR1=0x%08x \tMCAR=0x%08x\n", +	       mcsr, mcsrr0, mcsrr1, mcar);  	print_backtrace((unsigned long *)regs->gpr[1]); -	panic("machine check"); +	if (machinecheck_count > 10) { +		panic("machine check count too high\n"); +	} + +	if (machinecheck_count > 1) { +		regs->nip += 4; /* skip offending instruction */ +		printf("Skipping current instr, Returning to 0x%08x\n", +		       regs->nip); +	} else { +		printf("Returning back to 0x%08x\n",regs->nip); +	}  }  void  AlignmentException(struct pt_regs *regs)  { -#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#if defined(CONFIG_CMD_KGDB)  	if (debugger_exception_handler && (*debugger_exception_handler)(regs))  		return;  #endif @@ -207,7 +239,7 @@ ProgramCheckException(struct pt_regs *regs)  {  	long esr_val; -#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#if defined(CONFIG_CMD_KGDB)  	if (debugger_exception_handler && (*debugger_exception_handler)(regs))  		return;  #endif @@ -244,7 +276,7 @@ PITException(struct pt_regs *regs)  void  UnknownException(struct pt_regs *regs)  { -#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#if defined(CONFIG_CMD_KGDB)  	if (debugger_exception_handler && (*debugger_exception_handler)(regs))  		return;  #endif @@ -253,13 +285,40 @@ UnknownException(struct pt_regs *regs)  	       regs->nip, regs->msr, regs->trap);  	_exception(0, regs);  } +void +ExtIntException(struct pt_regs *regs) +{ +	volatile immap_t *immap = (immap_t *)CFG_IMMR; +	volatile ccsr_pic_t *pic = &immap->im_pic; +	uint vect; + +#if defined(CONFIG_CMD_KGDB) +	if (debugger_exception_handler && (*debugger_exception_handler)(regs)) +		return; +#endif + +	printf("External Interrupt Exception at PC: %lx, SR: %lx, vector=%lx", +	       regs->nip, regs->msr, regs->trap); +	vect = pic->iack0; +	printf(" irq IACK0@%05x=%d\n",&pic->iack0,vect); +	show_regs(regs); +	print_backtrace((unsigned long *)regs->gpr[1]); +	machinecheck_count++; +#ifdef EXTINT_NOSKIP +	printf("Returning back to 0x%08x\n",regs->nip); +#else +	regs->nip += 4; /* skip offending instruction */ +	printf("Skipping current instr, Returning to 0x%08x\n",regs->nip); +#endif + +}  void  DebugException(struct pt_regs *regs)  {  	printf("Debugger trap at @ %lx\n", regs->nip );  	show_regs(regs); -#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) +#if defined(CONFIG_CMD_BEDBUG)  	do_bedbug_breakpoint( regs );  #endif  } |