summaryrefslogblamecommitdiffstats
path: root/c/src/librdbg/src/m68k/excep_f.c
blob: aadf23387b9410871d7b6d6f5071c0548f9f1739 (plain) (tree)











































































































































































                                                                            
/*
 **************************************************************************
 *
 * Component =   
 * 
 * Synopsis  =   rdbg/m68k/excep_f.c
 *
 * $Id$
 *
 **************************************************************************
 */

#include <rtems.h>
#include <rtems/error.h>
#include <assert.h>
#include <errno.h>
#include <rdbg/rdbg.h>
#include <rdbg/servrpc.h>

int
ExcepToSig (Exception_context *ctx)
{
  int excep = getExcNum (ctx);
  
  switch (excep) {
    case 2 : return 10; break; /* bus error           */
    case 3 : return 10; break; /* address error       */
    case 4 : return 4;  break; /* illegal instruction */
    case 5 : return 8;  break; /* zero divide         */
    case 6 : return 8; break; /* chk instruction     */
    case 7 : return 8; break; /* trapv instruction   */
    case 8 : return 11; break; /* privilege violation */
    case 9 : return 5;  break; /* trace trap          */
    case 10: return 4;  break; /* line 1010 emulator  */
    case 11: return 4;  break; /* line 1111 emulator  */

      /* Coprocessor protocol violation.  Using a standard MMU or FPU
         this cannot be triggered by software.  Call it a SIGBUS.  */
    case 13: return 10;  break;

    case 31: return 2;  break; /* interrupt           */
    case 33: return 5;  break; /* monitor breakpoint  */
    case 34: return 2;  break; /* lets use this for SCC1 interrupt */
    case 35: return 5;  break; /* rdbg breakpoint  */
    case 36: return 2;  break; /* enter RDBG */
      /* This is a trap #8 instruction.  Apparently it is someone's software
         convention for some sort of SIGFPE condition.  Whose?  How many
         people are being screwed by having this code the way it is?
         Is there a clean solution?  */
    case 40: return 8;  break; /* floating point err  */

    case 47: return 5;  break; /* rdbg breakpoint  */

    case 48: return 8;  break; /* floating point err  */
    case 49: return 8;  break; /* floating point err  */
    case 50: return 8;  break; /* zero divide         */
    case 51: return 8;  break; /* underflow           */
    case 52: return 8;  break; /* operand error       */
    case 53: return 8;  break; /* overflow            */
    case 54: return 8;  break; /* NAN                 */
    default: 
      return 7;         /* "software generated"*/
    }
    return SIGKILL;
}

  
/*----- Breakpoint Exception management -----*/

    /*
     *  Handler for Breakpoint Exceptions :
     *  software breakpoints.
     */

void
BreakPointExcHdl(CPU_Exception_frame *ctx) 
{
  rtems_status_code status;
  rtems_id continueSemId;

  connect_rdbg_exception(); /* monitor stub changes trace vector */
  if ( (justSaveContext) && (ctx->vecnum == 47) ) { /* break */
    PushSavedExceptCtx (_Thread_Executing->Object.id, ctx);
    justSaveContext = 0;
  }
  else {
    if (ctx->vecnum != 9) { /* trace */
      NbSerializedCtx++;
      rtems_semaphore_obtain(serializeSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
      NbSerializedCtx--;
    }
      
    currentTargetThread = _Thread_Executing->Object.id;

#ifdef DDEBUG
    printk("----------------------------------------------------------\n");
    printk("Exception %d caught at PC %x by thread %d\n",
	   ctx->vecnum,
	   ctx->pc,
	   _Thread_Executing->Object.id);
    printk("----------------------------------------------------------\n");
    printk("Processor execution context at time of the fault was  :\n");
    printk("----------------------------------------------------------\n");
    printk("\t A0 = %x\n", ctx->a0);
    printk("\t A1 = %x\n", ctx->a1);
    printk("\t A2 = %x\n", ctx->a2);
    printk("\t A3 = %x\n", ctx->a3);
    printk("\t A4 = %x\n", ctx->a4);
    printk("\t A5 = %x\n", ctx->a5);
    printk("\t A6 = %x\n", ctx->a6);
    printk("\t A7 = %x\n", ctx->a7);
    printk("\t D0 = %x\n", ctx->d0);
    printk("\t D1 = %x\n", ctx->d1);
    printk("\t D2 = %x\n", ctx->d2);
    printk("\t D3 = %x\n", ctx->d3);
    printk("\t D4 = %x\n", ctx->d4);
    printk("\t D5 = %x\n", ctx->d5);
    printk("\t D6 = %x\n", ctx->d6);
    printk("\t D7 = %x\n", ctx->d7);
    printk("\t SR = %x\n", ctx->sr);
#endif

    status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'c'),
				     0,
				     RTEMS_FIFO |
				     RTEMS_COUNTING_SEMAPHORE |
				     RTEMS_NO_INHERIT_PRIORITY |
				     RTEMS_NO_PRIORITY_CEILING |
				     RTEMS_LOCAL,
				     0,
				     &continueSemId);
    if (status != RTEMS_SUCCESSFUL)
      rtems_panic ("Can't create continue semaphore: `%s'\n",
		   rtems_status_text(status));

    PushExceptCtx (_Thread_Executing->Object.id, continueSemId, ctx);
  
    switch (ctx->vecnum){
    case 9 : /* trace */
      DPRINTF((" TRACE EXCEPTION !!!\n"));
      ctx->sr &= ~(1 << 15);
      ExitForSingleStep-- ;
      rtems_semaphore_release( wakeupEventSemId );
    break;

    case 47 : /* trap #15 */
      DPRINTF((" BREAKPOINT EXCEPTION !!!\n"));
      rtems_semaphore_release( wakeupEventSemId );
    break;

    case 36 : /* trap #4 */
      DPRINTF((" ENTER RDBG !!!\n"));
      rtems_semaphore_release( wakeupEventSemId );
      break;

    default:
      DPRINTF((" OTHER EXCEPTION !!!\n"));
      rtems_semaphore_release( wakeupEventSemId );
      break;
    }

    rtems_semaphore_obtain(continueSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    
    PopExceptCtx (_Thread_Executing->Object.id);
    rtems_semaphore_delete(continueSemId);
  }

  connect_rdbg_exception(); /* monitor stub changes trace vector */
}