diff options
Diffstat (limited to '')
-rw-r--r-- | c/src/librdbg/src/i386/excep.c | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/c/src/librdbg/src/i386/excep.c b/c/src/librdbg/src/i386/excep.c new file mode 100644 index 0000000000..5ca1fd8df6 --- /dev/null +++ b/c/src/librdbg/src/i386/excep.c @@ -0,0 +1,233 @@ +/* + ************************************************************************** + * + * Component = + * + * Synopsis = rdbg/i386/excep.c + * + ************************************************************************** + */ + +#include <rtems.h> +#include <rtems/error.h> +#include <rdbg/rdbg_f.h> +#include <assert.h> +#include <errno.h> +#include <rdbg/rdbg.h> +#include <rdbg/servrpc.h> + + +extern rtems_id serializeSemId; +extern rtems_id wakeupEventSemId; + + +unsigned int NbExceptCtx; +volatile unsigned int NbSerializedCtx; +Exception_context *FirstCtx = NULL; +Exception_context *LastCtx = NULL; + +CPU_Exception_frame SavedContext; + + +/********* Save an exception context at the end of a list *****/ + +int PushExceptCtx ( Objects_Id Id, Objects_Id semId, CPU_Exception_frame *ctx ) { + + Exception_context *SaveCtx; + + SaveCtx = (Exception_context *)malloc(sizeof(Exception_context)); + if (SaveCtx == NULL) + rtems_panic("Can't allocate memory to save Exception context"); + + SaveCtx->id = Id; + SaveCtx->ctx = ctx; + SaveCtx->semaphoreId = semId; + SaveCtx->previous = NULL; + SaveCtx->next = NULL; + + if (FirstCtx == NULL){ /* initialization */ + FirstCtx = SaveCtx; + LastCtx = SaveCtx; + NbExceptCtx = 1; + } + else { + NbExceptCtx ++; + LastCtx->next = SaveCtx; + SaveCtx->previous = LastCtx; + LastCtx = SaveCtx; + } + return 0; +} + +/********* Save an temporary exception context in a ******/ +/********* global variable ******/ + +int PushSavedExceptCtx ( Objects_Id Id, CPU_Exception_frame *ctx ) { + + memcpy (&(SavedContext), ctx, sizeof(CPU_Exception_frame)); + return 0; +} + + +/****** Remove the context of the specified Id thread *********/ +/****** If Id = -1, then return the first context *********/ + + +int PopExceptCtx ( Objects_Id Id ) { + + Exception_context *ExtractCtx; + + if (FirstCtx == NULL) return -1; + + if (Id == -1) { + ExtractCtx = LastCtx; + LastCtx = LastCtx->previous; + free(ExtractCtx); + NbExceptCtx --; + return 0; + } + + ExtractCtx = LastCtx; + + while (ExtractCtx->id != Id && ExtractCtx != NULL) { + ExtractCtx = ExtractCtx->previous; + } + + if (ExtractCtx == NULL) + return -1; + + if ( ExtractCtx->previous != NULL) + (ExtractCtx->previous)->next = ExtractCtx->next; + + if ( ExtractCtx->next != NULL) + (ExtractCtx->next)->previous = ExtractCtx->previous; + + if (ExtractCtx == FirstCtx) + FirstCtx = FirstCtx->next; + else + if (ExtractCtx == LastCtx) + LastCtx = LastCtx->previous; + + free(ExtractCtx); + NbExceptCtx --; + return 0; +} + +/****** Return the context of the specified Id thread *********/ +/****** If Id = -1, then return the first context *********/ + + +Exception_context *GetExceptCtx ( Objects_Id Id ) { + + Exception_context *ExtractCtx; + + if (FirstCtx == NULL) return NULL; + + if (Id == -1) { + return LastCtx; + } + + ExtractCtx = LastCtx; + + while (ExtractCtx->id != Id && ExtractCtx != NULL) { + ExtractCtx = ExtractCtx->previous; + } + + if (ExtractCtx == NULL) + return NULL; + + return ExtractCtx; +} + +/*----- Breakpoint Exception management -----*/ + + /* + * Handler for Breakpoint Exceptions : + * software breakpoints. + */ + +void +BreakPointExcHdl(CPU_Exception_frame *ctx) +{ + rtems_status_code status; + rtems_id continueSemId; + + if ( (justSaveContext) && (ctx->idtIndex == I386_EXCEPTION_ENTER_RDBG) ) { + PushSavedExceptCtx (_Thread_Executing->Object.id, ctx); + justSaveContext = 0; + } + else { + if (ctx->idtIndex != DEBUG){ + 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->idtIndex, + ctx->eip, + _Thread_Executing->Object.id); + printk("----------------------------------------------------------\n"); + printk("Processor execution context at time of the fault was :\n"); + printk("----------------------------------------------------------\n"); + printk(" EAX = %x EBX = %x ECX = %x EDX = %x\n", + ctx->eax, ctx->ebx, ctx->ecx, ctx->edx); + printk(" ESI = %x EDI = %x EBP = %x ESP = %x\n", + ctx->esi, ctx->edi, ctx->ebp, ctx->esp0); + printk("----------------------------------------------------------\n"); + printk("Error code pushed by processor itself (if not 0) = %x\n", + ctx->faultCode); + printk("----------------------------------------------------------\n\n"); +#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->idtIndex){ + case I386_EXCEPTION_DEBUG: + DPRINTF((" DEBUG EXCEPTION !!!\n")); + ctx->eflags &= ~EFLAGS_TF; + ExitForSingleStep-- ; + rtems_semaphore_release( wakeupEventSemId ); + break; + + case I386_EXCEPTION_BREAKPOINT: + DPRINTF((" BREAKPOINT EXCEPTION !!!\n")); + rtems_semaphore_release( wakeupEventSemId ); + break; + + case I386_EXCEPTION_ENTER_RDBG: + 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); + } +} + + + |