int kgdb_arch_handle_exception(int exceptionVector, int signo, int err_code, char *remcom_in_buffer, char *remcom_out_buffer, struct pt_regs *linux_regs) { long addr; long breakno; char *ptr; int newPC; int wp_status; switch (remcom_in_buffer[0]) { case 'c': case 's': if (kgdb_contthread && kgdb_contthread != current) { strcpy(remcom_out_buffer, "E00"); break; } kgdb_contthread = NULL; /* try to read optional parameter, pc unchanged if no parm */ ptr = &remcom_in_buffer[1]; if (kgdb_hex2long(&ptr, &addr)) { linux_regs->retx = addr; } newPC = linux_regs->retx; /* clear the trace bit */ linux_regs->syscfg &= 0xfffffffe; /* set the trace bit if we're stepping */ if (remcom_in_buffer[0] == 's') { linux_regs->syscfg |= 0x1; debugger_step = 1; } wp_status = bfin_read_WPSTAT(); CSYNC(); if (exceptionVector == VEC_WATCH) { for (breakno = 0; breakno < 6; ++breakno) { if (wp_status & (1 << breakno)) { breakinfo->skip = 1; break; } } } kgdb_correct_hw_break(); bfin_write_WPSTAT(0); return 0; } /* switch */ return -1; /* this means that we do not want to exit from the handler */ }
/** * kgdb_arch_handle_exception - Handle architecture specific GDB packets. * @vector: The error vector of the exception that happened. * @signo: The signal number of the exception that happened. * @err_code: The error code of the exception that happened. * @remcom_in_buffer: The buffer of the packet we have read. * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into. * @regs: The &struct pt_regs of the current process. * * This function MUST handle the 'c' and 's' command packets, * as well packets to set / remove a hardware breakpoint, if used. * If there are additional packets which the hardware needs to handle, * they are handled here. The code should return -1 if it wants to * process more packets, and a %0 or %1 if it wants to exit from the * kgdb callback. */ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code, char *remcomInBuffer, char *remcomOutBuffer, struct pt_regs *linux_regs) { unsigned long addr; unsigned long dr6; char *ptr; int newPC; switch (remcomInBuffer[0]) { case 'c': case 's': /* try to read optional parameter, pc unchanged if no parm */ ptr = &remcomInBuffer[1]; if (kgdb_hex2long(&ptr, &addr)) linux_regs->ip = addr; case 'D': case 'k': newPC = linux_regs->ip; /* clear the trace bit */ linux_regs->flags &= ~X86_EFLAGS_TF; atomic_set(&kgdb_cpu_doing_single_step, -1); /* set the trace bit if we're stepping */ if (remcomInBuffer[0] == 's') { linux_regs->flags |= X86_EFLAGS_TF; atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id()); } get_debugreg(dr6, 6); if (!(dr6 & 0x4000)) { int breakno; for (breakno = 0; breakno < 4; breakno++) { if (dr6 & (1 << breakno) && breakinfo[breakno].type == 0) { /* Set restore flag: */ linux_regs->flags |= X86_EFLAGS_RF; break; } } } set_debugreg(0UL, 6); kgdb_correct_hw_break(); return 0; } /* this means that we do not want to exit from the handler: */ return -1; }