/* ************************************************************************** * * Component = * * Synopsis = rdbg/m68k/excep_f.c * * $Id$ * ************************************************************************** */ #include #include #include #include #include #include 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 */ }