示例#1
0
文件: kgdb.c 项目: 274914765/C
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 */
}
示例#2
0
文件: kgdb.c 项目: Aircell/asp-kernel
/**
 *	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;
}