/****************************************************************************/
/* Copyright 2016 MBARI														*/
/****************************************************************************/
/* Summary  : Exception and Assertion Routines for BEDS2 on PIC32MX470F512L	*/
/* Filename : exceptn.c														*/
/* Author   : Robert Herlien (rah)                                          */
/* Project  : OASIS Mooring Replacement (OASIS5)                            */
/* Revision : 1.0                                                           */
/* Created  : 07/27/2016													*/
/*                                                                          */
/* MBARI provides this documentation and code "as is", with no warranty,    */
/* express or implied, of its quality or consistency. It is provided without*/
/* support and without obligation on the part of the Monterey Bay Aquarium  */
/* Research Institute to assist in its use, correction, modification, or    */
/* enhancement. This information should not be published or distributed to  */
/* third parties without specific written permission from MBARI.            */
/*                                                                          */
/****************************************************************************/
/* Modification History:                                                    */
/* 27jul2016 rah - created													*/
/* 28feb2018 rah - Ported to BEDS2 on PIC32MX470							*/
/****************************************************************************/

#include <xc.h>
#include <mbariTypes.h>
#include <beds.h>
#include <picConfig.h>
#include <syslog.h>
#include <clock.h>
#include <time.h>


// declared static in case exception condition would prevent
// auto variable being created
static enum {
	EXCEP_IRQ = 0,			// interrupt
	EXCEP_AdEL = 4,			// address error exception (load or ifetch)
	EXCEP_AdES,				// address error exception (store)
	EXCEP_IBE,				// bus error (ifetch)
	EXCEP_DBE,				// bus error (load/store)
	EXCEP_Sys,				// syscall
	EXCEP_Bp,				// breakpoint
	EXCEP_RI,				// reserved instruction
	EXCEP_CpU,				// coprocessor unusable
	EXCEP_Overflow,			// arithmetic overflow
	EXCEP_Trap,				// trap (possible divide by zero)
	EXCEP_IS1 = 16,			// implementation specfic 1
	EXCEP_CEU,				// CorExtend Unuseable
	EXCEP_C2E				// coprocessor 2
} _excep_code;

static unsigned int _excep_code;
static unsigned int _excep_addr;


/************************************************************************/
/* Function    : _general_exception_handler								*/
/* Purpose     : General Exception Handler								*/
/* Input       : None                                                   */
/* Outputs     : None                                                   */
/* Comment     : this function overrides the normal _weak_ generic handler*/
/************************************************************************/
void _general_exception_handler(void)
{
	asm volatile("mfc0 %0,$13" : "=r" (_excep_code));
	asm volatile("mfc0 %0,$14" : "=r" (_excep_addr));

	_excep_code = (_excep_code & 0x0000007C) >> 2;

#ifdef __DEBUG	
	__builtin_software_breakpoint();
#else
	sysLogPrintf("Exception at addr 0x%x code %u",
				 _excep_addr, _excep_code);
	picSoftReset();
#endif
}
