예제 #1
0
void
BSP_exceptionHandler(BSP_Exception_frame* excPtr)
{
uint32_t	note;
BSP_ExceptionExtension	ext=0;
rtems_id		id=0;
int			recoverable = 0;
char			*fmt="Uhuuuh, Exception %d in unknown task???\n";
int			quiet=0;

 if (!quiet) printk("In BSP_exceptionHandler()\n");
   /* If we are in interrupt context, we are in trouble - skip the user
    * hook and panic
    */
    if (rtems_interrupt_is_in_progress()) {
      fmt="Aieeh, Exception %d in interrupt handler\n";
    } else if ( !_Thread_Executing) {
      fmt="Aieeh, Exception %d in initialization code\n";
    } else {
    /* retrieve the notepad which possibly holds an extention pointer */
    if (RTEMS_SUCCESSFUL==rtems_task_ident(RTEMS_SELF,RTEMS_LOCAL,&id) &&
#if 0
/* Must not use a notepad due to unknown initial value (notepad memory is allocated from the
 * workspace)!
 */
	        RTEMS_SUCCESSFUL==rtems_task_get_note(id, BSP_EXCEPTION_NOTEPAD, &note)
#else
	        RTEMS_SUCCESSFUL==rtems_task_variable_get(id, (void*)&BSP_exceptionExtension, (void**)&note)
#endif
         ) {
	   ext = (BSP_ExceptionExtension)note;
	   if (ext)
	       quiet=ext->quiet;
	   if (!quiet) {
	      printk("Task (Id 0x%08x) got ",id);
	   }
	   fmt="exception %d\n";
	}
    }

    if (ext && ext->lowlevelHook && ext->lowlevelHook(excPtr,ext,0)) {
		/* they did all the work and want us to do nothing! */
      printk("they did all the work and want us to do nothing!\n");
		return;
    }

    if (!quiet) {
       /* message about exception */
       printk(fmt, excPtr->_EXC_number);
       /* register dump */
       printk("\t Next PC or Address of fault = %x, ", excPtr->EXC_SRR0);
       printk("Mvme5500 Saved MSR = %x\n", excPtr->EXC_SRR1);
       printk("\t R0  = %08x", excPtr->GPR0);
       printk(" R1  = %08x", excPtr->GPR1);
       printk(" R2  = %08x", excPtr->GPR2);
       printk(" R3  = %08x\n", excPtr->GPR3);
       printk("\t R4  = %08x", excPtr->GPR4);
       printk(" R5  = %08x", excPtr->GPR5);
       printk(" R6  = %08x", excPtr->GPR6);
       printk(" R7  = %08x\n", excPtr->GPR7);
       printk("\t R8  = %08x", excPtr->GPR8);
       printk(" R9  = %08x", excPtr->GPR9);
       printk(" R10 = %08x", excPtr->GPR10);
       printk(" R11 = %08x\n", excPtr->GPR11);
       printk("\t R12 = %08x", excPtr->GPR12);
       printk(" R13 = %08x", excPtr->GPR13);
       printk(" R14 = %08x", excPtr->GPR14);
       printk(" R15 = %08x\n", excPtr->GPR15);
       printk("\t R16 = %08x", excPtr->GPR16);
       printk(" R17 = %08x", excPtr->GPR17);
       printk(" R18 = %08x", excPtr->GPR18);
       printk(" R19 = %08x\n", excPtr->GPR19);
       printk("\t R20 = %08x", excPtr->GPR20);
       printk(" R21 = %08x", excPtr->GPR21);
       printk(" R22 = %08x", excPtr->GPR22);
       printk(" R23 = %08x\n", excPtr->GPR23);
       printk("\t R24 = %08x", excPtr->GPR24);
       printk(" R25 = %08x", excPtr->GPR25);
       printk(" R26 = %08x", excPtr->GPR26);
       printk(" R27 = %08x\n", excPtr->GPR27);
       printk("\t R28 = %08x", excPtr->GPR28);
       printk(" R29 = %08x", excPtr->GPR29);
       printk(" R30 = %08x", excPtr->GPR30);
       printk(" R31 = %08x\n", excPtr->GPR31);
       printk("\t CR  = %08x\n", excPtr->EXC_CR);
       printk("\t CTR = %08x\n", excPtr->EXC_CTR);
       printk("\t XER = %08x\n", excPtr->EXC_XER);
       printk("\t LR  = %08x\n", excPtr->EXC_LR);

       BSP_printStackTrace(excPtr);
    }

    if (ASM_MACH_VECTOR == excPtr->_EXC_number) {
       /* ollah , we got a machine check - this could either
	* be a TEA, MCP or internal; let's see and provide more info
	*/
       if (!quiet)
	   printk("Machine check; reason:");
       if ( ! (excPtr->EXC_SRR1 & (SRR1_TEA_EXC | SRR1_MCP_EXC)) ) {
	   if (!quiet)
	       printk("SRR1\n");
       } else {
	   if (excPtr->EXC_SRR1 & (SRR1_TEA_EXC)) {
	      if (!quiet)
		 printk(" TEA");
	   }
	   if (excPtr->EXC_SRR1 & (SRR1_MCP_EXC)) {
	      unsigned long gerr;

	      if (!quiet) printk(" MCP\n");

	      /* it's MCP; gather info from the host bridge */
 	      gerr=_BSP_clear_hostbridge_errors(0,0);
              if (gerr&0x80000000) printk("GT64260 Parity error\n");
              if (gerr&0x40000000) printk("GT64260 SysErr\n");
	      if ((!quiet) && (!gerr)) printk("GT64260 host bridge seems OK\n");
	    }
       }
    } else if (ASM_DEC_VECTOR == excPtr->_EXC_number) {
		recoverable = 1;
    } else if (ASM_SYS_VECTOR == excPtr->_EXC_number) {
#ifdef TEST_RAW_EXCEPTION_CODE
		recoverable = 1;
#else
		recoverable = 0;
#endif
    }

    /* call them for a second time giving a chance to intercept
     * the task_suspend
     */
    if (ext && ext->lowlevelHook && ext->lowlevelHook(excPtr, ext, 1))
		return;

    if (!recoverable) {
		if (id) {
			/* if there's a highlevel hook, install it */
			if (ext && ext->highlevelHook) {
				excPtr->EXC_SRR0 = (uint32_t)ext->highlevelHook;
				excPtr->GPR3     = (uint32_t)ext;
				return;
			}
			if (excPtr->EXC_SRR1 & MSR_FP) {
				/* thread dispatching is _not_ disabled at this point; hence
				 * we must make sure we have the FPU enabled...
				 */
				_write_MSR( _read_MSR() | MSR_FP );
				__asm__ __volatile__("isync");
			}
			printk("unrecoverable exception!!! task %08x suspended\n",id);
			rtems_task_suspend(id);
		} else {
			printk("PANIC, rebooting...\n");
			bsp_reset();
		}
    }
}
예제 #2
0
void C_exception_handler(BSP_Exception_frame *excPtr)
{
  static int nest = 0;

  int recoverable = 0;
  rtems_id id = 0;
  int synch;
  unsigned n;
  rtems_status_code sc;

  /* Catch recursion */
  nest++;

  if (nest > 2) {
    /* maybe printk() or dereferencing excPtr caused an exception;
     * die silently...
     */
    while (1);
  }

  synch = (int) excPtr->_EXC_number >= 0;
  n = excPtr->_EXC_number & 0x7fff;

  printk("Exception handler called for exception %d (0x%x)\n", n, n);
  printk("\t Next PC or Address of fault = %08x\n", excPtr->EXC_SRR0);
  printk("\t Saved MSR = %08x\n", excPtr->EXC_SRR1);

  if (nest > 1) {
    printk("Recursion in the exception handler detected; I'll spin now...\n");
    while (1);
  }

  /* Try to find out more about the context where this happened */
  printk("\t Context: ");
  if (rtems_interrupt_is_in_progress()) {
    printk("ISR");
  } else if (!_Thread_Executing) {
    printk("Initialization (_Thread_Executing not available yet)");
  } else {
    if (RTEMS_SUCCESSFUL != (sc = rtems_task_ident(RTEMS_SELF, RTEMS_LOCAL, &id))) {
      printk("Unable to determine faulting task; rtems_task_ident() returned %u", sc);
      id = 0;
    } else {
      printk("Task ID 0x%08x", id);
    }
  }
  printk("\n");

  /* Dump registers */

  printk("\t R0  = %08x", GET_GPR(excPtr->GPR0));
  if (synch) {
    printk(" R1  = %08x", GET_GPR(excPtr->GPR1));
    printk(" R2  = %08x", GET_GPR(excPtr->GPR2));
  } else {
    printk("               ");
    printk("               ");
  }
  printk(" R3  = %08x\n", GET_GPR(excPtr->GPR3));
  printk("\t R4  = %08x", GET_GPR(excPtr->GPR4));
  printk(" R5  = %08x", GET_GPR(excPtr->GPR5));
  printk(" R6  = %08x", GET_GPR(excPtr->GPR6));
  printk(" R7  = %08x\n", GET_GPR(excPtr->GPR7));
  printk("\t R8  = %08x", GET_GPR(excPtr->GPR8));
  printk(" R9  = %08x", GET_GPR(excPtr->GPR9));
  printk(" R10 = %08x", GET_GPR(excPtr->GPR10));
  printk(" R11 = %08x\n", GET_GPR(excPtr->GPR11));
  printk("\t R12 = %08x", GET_GPR(excPtr->GPR12));
  if (synch) {
    printk(" R13 = %08x", GET_GPR(excPtr->GPR13));
    printk(" R14 = %08x", GET_GPR(excPtr->GPR14));
    printk(" R15 = %08x\n", GET_GPR(excPtr->GPR15));
    printk("\t R16 = %08x", GET_GPR(excPtr->GPR16));
    printk(" R17 = %08x", GET_GPR(excPtr->GPR17));
    printk(" R18 = %08x", GET_GPR(excPtr->GPR18));
    printk(" R19 = %08x\n", GET_GPR(excPtr->GPR19));
    printk("\t R20 = %08x", GET_GPR(excPtr->GPR20));
    printk(" R21 = %08x", GET_GPR(excPtr->GPR21));
    printk(" R22 = %08x", GET_GPR(excPtr->GPR22));
    printk(" R23 = %08x\n", GET_GPR(excPtr->GPR23));
    printk("\t R24 = %08x", GET_GPR(excPtr->GPR24));
    printk(" R25 = %08x", GET_GPR(excPtr->GPR25));
    printk(" R26 = %08x", GET_GPR(excPtr->GPR26));
    printk(" R27 = %08x\n", GET_GPR(excPtr->GPR27));
    printk("\t R28 = %08x", GET_GPR(excPtr->GPR28));
    printk(" R29 = %08x", GET_GPR(excPtr->GPR29));
    printk(" R30 = %08x", GET_GPR(excPtr->GPR30));
    printk(" R31 = %08x\n", GET_GPR(excPtr->GPR31));
  } else {
    printk("\n");
  }
  printk("\t CR  = %08x\n", excPtr->EXC_CR);
  printk("\t CTR = %08x\n", excPtr->EXC_CTR);
  printk("\t XER = %08x\n", excPtr->EXC_XER);
  printk("\t LR  = %08x\n", excPtr->EXC_LR);

  /* Would be great to print DAR but unfortunately,
   * that is not portable across different CPUs.
   * AFAIK on classic PPC DAR is SPR 19, on the
   * 405 we have DEAR = SPR 0x3d5 and booE says
   * DEAR = SPR 61 :-(
   */
  if (ppc_exc_get_DAR) {
    printk("\t DAR = %08x\n", ppc_exc_get_DAR());
  }

  BSP_printStackTrace(excPtr);

  if (excPtr->_EXC_number == ASM_DEC_VECTOR)
    recoverable = 1;
  if (excPtr->_EXC_number == ASM_SYS_VECTOR)
#ifdef TEST_RAW_EXCEPTION_CODE
    recoverable = 1;
#else
    recoverable = 0;
#endif
  if (!recoverable) {
    if (id) {
      printk("Suspending faulting task (0x%08x)\n", id);
      /* Unnest here because rtems_task_suspend() never returns */
      nest--;
      rtems_task_suspend(id);
    } else {
      printk("unrecoverable exception!!! Push reset button\n");
      while (1);
    }
  } else {
    nest--;
  }
}