/***************************************************************************
**
**  Name:  emuerror.c
**
**  Description:
**     Michelle error handle processing, there are 4 levels used to
**     indicate the error extent. Each level has the domain to accept
**     the error conditions.
**
**     Two-dimention array to present this error table on the sw site:
**     [0~9][0~31] <--> [level-NO][Error-NO]
**     Transfered from fw's return code <--> U16; High-byte for "level-NO"
**                                                Low-byte for "Error-NO"
**
**     NOTE: should we support multiple-error ? I'll discuss this issue
**           with Matthew to find a reasonable solution then update version
**           of this document in these few days.
**
**  Status:  preliminary
**
**  $Log:   S:/tbird/arcppc/fw/860/emuerror.c_v  $
** 
**    Rev 1.6   29 Oct 1997 14:04:58   kevin
** warning-free version
** 
**    Rev 1.5   26 Sep 1997 15:20:44   kevin
** added Load/store breakpoint case for outputexcept()
** 
**    Rev 1.4   28 Aug 1997 17:24:00   cjchen
** 
**    Rev 1.3   28 Aug 1997 10:23:00   cjchen
** 
**    Rev 1.2   19 Aug 1997 16:02:26   cjchen
** 
**    Rev 1.1   28 Jul 1997 10:13:02   cjchen
** 
**    Rev 1.0   18 Jul 1997 15:12:54   cjchen
** Initial revision.
** 
**    Rev 1.0   11 Feb 1997 16:16:48   kevin
** Initial revision.
** 
**    Rev 1.2   29 Nov 1996 14:24:54   gene
** modify OutputExceptReason for 5204, added 0x80 error code
** 
**    Rev 1.1   25 Jul 1996 18:10:34   gene
** added CANNOT_RESET error
** 
**    Rev 1.0   03 Jun 1996 14:18:52   gene
** Initial revision.
** 
** Copyright (C) 1992 Microtek International, Inc.
**
****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#ifndef _CONSTR_
#include "const.h"
#endif

#ifndef _EMU_ERROR_
#include "emuerror.h"
#endif

#ifndef _EMU_COMM_
#include "emucomm.h"
#endif

#ifndef _EMU_LIB_
#include "emulib.h"
#endif

#ifndef _LLFW_
#include "emullfw.h"
#endif

#ifndef _EMU_EXTERNAL_
#include "emuext.h"
#endif

#include <string.h>
#include <dos.h>

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
U32 brokeReason;
U8 brokeResult;
extern U32 gSDMemAddr[2];

                        /****************************
                         *                          *
                         *    EXTERNAL VARIABLES    *
                         *                          *
                         ****************************/

                        /****************************
                         *                          *
                         *     LOCAL PROTOTYPES     *
                         *                          *
                         ****************************/
VOID GetMemErrAddr(VOID);

                        /****************************
                         *                          *
                         *      EXECUTABLE CODE     *
                         *                          *
                         ****************************/

/**************************************************************************
**
** EmuReportError
**
**  Description: report error by passing/returning an error code to host.
**               This code id included in the status field of
**               the transmiting data record.
**
**  Parameters:
**     input:
**
**
**     output:
**
**
****************************************************************************/
VOID EmuReportError(ERROR_NO errCode) {
   OutputStatus(errCode,ON);
}

/****************************************************************************
**
**  OutputExceptReason
**
**  Description: output the status of executive FW to outputStream
**
**  Parameters:
**     input:
**
**     output:
**
**        return data --
**
****************************************************************************/
VOID OutputExceptReason(BOOLEAN endData) {
U16 typeLen,errNo;
U8 memErrFlag=0;
  switch (brokeResult) {
//     return al -->  1: CPU dead ( DSDO not ready Timeout )
//                    2: no VDD indication
//                   10: CPU is ok in frozen and last broken cause can be
//                       gotten from BrkCausePtr
//                   ---------------------------------------------
//                   20: CPU is ok in running
//                   ---------------------------------------------
//                   30: CPU had been reset, and is in *** frozen ***
//                   31: Memory access fault
//                   32: other fault
//                   33: user abort
//                   ---------------------------------------------
      case 0x1:
         AccessIceFlag(WRITE_ONE,RUNNING,&C_OFF);
         AccessIceFlag(WRITE_ONE,FLYING,&C_OFF);
         errNo=INVALID_CPU;
         break;
      case 0x2:
         errNo=NOT_READY;
         break;
      case 0x10:
         AccessIceFlag(WRITE_ONE,RUNNING,&C_OFF);
         AccessIceFlag(WRITE_ONE,FLYING,&C_OFF);
         switch(brokeReason) {
             case 0x01000000:
             case 0x02000000:
                errNo=HALT_USER;  //user halt
                break;
             case 0x00400000:
                errNo=SW_BKPT_HALT; //SEI
                break;
             case 0x04000000:
                errNo=BKPT1_HALT;   //IBRK ; WHPT
                break;
             case 0x08000000:
                errNo=BKPT2_HALT;   //LBRK ; WHPT
                break;
             default:
                break;
         }
         break;
      case 0x20:
         AccessIceFlag(WRITE_ONE,RUNNING,&C_ON);
         AccessIceFlag(WRITE_ONE,FLYING,&C_ON);
         errNo=GOOD;
         break;
      case 0x30:
         errNo=TARGET_RESET;
         break;
      case 0x31:
         errNo=MEMORY_ACCESS_ERROR;
         GetMemErrAddr();
         memErrFlag=1;
         break;
      case 0x32:
         errNo=OTHER_ERROR;
         break;
      case 0x33:
         errNo=USER_ABORT;
         break;
      default:
         errNo=OTHER_ERROR;
         break;
  }

/*       errNo = BUS_REQUEST;
         errNo = NOT_READY;     *
         errNo = STEP_ERROR;
         errNo = MICE_HALT;
         errNo = CANNOT_RESET;
         errNo = NO_VCC;
         errNo = TARGET_RESET; *
         errNo = SIM_INVALID; */
   typeLen = sizeof(U16);
   memcpy (&outputStream[0],&errNo,typeLen);
   outputStreamLen = typeLen;
   if (memErrFlag==1) {
      OutData(8,gSDMemAddr,ON);
      outputStreamLen=outputStreamLen+8;
   }
   if (endData)
      outputStream[outputStreamLen++] = 0x00;/* Output stream length */
   brokeResult = 0;
   brokeReason = 0;
   gSDMemAddr[0]=gSDMemAddr[1]=0;
}

VOID GetMemErrAddr() {

   GetFailAddr(&gSDMemAddr[0],&gSDMemAddr[1]);
   Swap((U8 *)&gSDMemAddr[0],4);
   Swap((U8 *)&gSDMemAddr[1],4);

}
