Beispiel #1
0
static int or1k_debug_entry(struct target *target)
{
	LOG_DEBUG("-");

	int retval = or1k_save_context(target);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while calling or1k_save_context");
		return retval;
	}

	struct or1k_common *or1k = target_to_or1k(target);
	uint32_t addr = or1k->core_regs[OR1K_REG_NPC];

	if (breakpoint_find(target, addr))
		/* Halted on a breakpoint, step back to permit executing the instruction there */
		retval = or1k_set_core_reg(&or1k->core_cache->reg_list[OR1K_REG_NPC],
					   (uint8_t *)&addr);

	return retval;
}
Beispiel #2
0
int lakemont_resume(struct target *t, int current, uint32_t address,
			int handle_breakpoints, int debug_execution)
{
	struct breakpoint *bp = NULL;
	struct x86_32_common *x86_32 = target_to_x86_32(t);

	if (check_not_halted(t))
		return ERROR_TARGET_NOT_HALTED;
	/* TODO lakemont_enable_breakpoints(t); */
	if (t->state == TARGET_HALTED) {

		/* running away for a software breakpoint needs some special handling */
		uint32_t eip = buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32);
		bp = breakpoint_find(t, eip);
		if (bp != NULL /*&& bp->type == BKPT_SOFT*/) {
			/* the step will step over the breakpoint */
			if (lakemont_step(t, 0, 0, 1) != ERROR_OK) {
				LOG_ERROR("%s stepping over a software breakpoint at 0x%08" PRIx32 " "
						"failed to resume the target", __func__, eip);
				return ERROR_FAIL;
			}
		}

		/* if breakpoints are enabled, we need to redirect these into probe mode */
		struct breakpoint *activeswbp = t->breakpoints;
		while (activeswbp != NULL && activeswbp->set == 0)
			activeswbp = activeswbp->next;
		struct watchpoint *activehwbp = t->watchpoints;
		while (activehwbp != NULL && activehwbp->set == 0)
			activehwbp = activehwbp->next;
		if (activeswbp != NULL || activehwbp != NULL)
			buf_set_u32(x86_32->cache->reg_list[PMCR].value, 0, 32, 1);

		if (do_resume(t) != ERROR_OK)
			return ERROR_FAIL;
	} else {
		LOG_USER("target not halted");
		return ERROR_FAIL;
	}
	return ERROR_OK;
}
Beispiel #3
0
static int avr32_ap7k_resume(struct target *target, int current,
	uint32_t address, int handle_breakpoints, int debug_execution)
{
	struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
	struct breakpoint *breakpoint = NULL;
	uint32_t resume_pc;
	int retval;

	if (target->state != TARGET_HALTED) {
		LOG_WARNING("target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	if (!debug_execution) {
		target_free_all_working_areas(target);
		/*
		avr32_ap7k_enable_breakpoints(target);
		avr32_ap7k_enable_watchpoints(target);
		*/
	}

	/* current = 1: continue on current pc, otherwise continue at <address> */
	if (!current) {
#if 0
		if (retval != ERROR_OK)
			return retval;
#endif
	}

	resume_pc = buf_get_u32(ap7k->core_cache->reg_list[AVR32_REG_PC].value, 0, 32);
	avr32_ap7k_restore_context(target);

	/* the front-end may request us not to handle breakpoints */
	if (handle_breakpoints) {
		/* Single step past breakpoint at current address */
		breakpoint = breakpoint_find(target, resume_pc);
		if (breakpoint) {
			LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
#if 0
			avr32_ap7k_unset_breakpoint(target, breakpoint);
			avr32_ap7k_single_step_core(target);
			avr32_ap7k_set_breakpoint(target, breakpoint);
#endif
		}
	}

#if 0
	/* enable interrupts if we are running */
	avr32_ap7k_enable_interrupts(target, !debug_execution);

	/* exit debug mode */
	mips_ejtag_exit_debug(ejtag_info);
#endif


	retval = avr32_ocd_clearbits(&ap7k->jtag, AVR32_OCDREG_DC,
			OCDREG_DC_DBR);
	if (retval != ERROR_OK)
		return retval;

	retval = avr32_jtag_exec(&ap7k->jtag, RETD);
	if (retval != ERROR_OK)
		return retval;

	target->debug_reason = DBG_REASON_NOTHALTED;

	/* registers are now invalid */
	register_cache_invalidate(ap7k->core_cache);

	if (!debug_execution) {
		target->state = TARGET_RUNNING;
		target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
		LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
	} else {
		target->state = TARGET_DEBUG_RUNNING;
		target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
		LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
	}

	return ERROR_OK;
}
Beispiel #4
0
static int or1k_resume_or_step(struct target *target, int current,
			       uint32_t address, int handle_breakpoints,
			       int debug_execution, int step)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);
	struct breakpoint *breakpoint = NULL;
	uint32_t resume_pc;
	uint32_t debug_reg_list[OR1K_DEBUG_REG_NUM];

	LOG_DEBUG("Addr: 0x%" PRIx32 ", stepping: %s, handle breakpoints %s\n",
		  address, step ? "yes" : "no", handle_breakpoints ? "yes" : "no");

	if (target->state != TARGET_HALTED) {
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	if (!debug_execution)
		target_free_all_working_areas(target);

	/* current ? continue on current pc : continue at <address> */
	if (!current)
		buf_set_u32(or1k->core_cache->reg_list[OR1K_REG_NPC].value, 0,
			    32, address);

	int retval = or1k_restore_context(target);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while calling or1k_restore_context");
		return retval;
	}

	/* read debug registers (starting from DMR1 register) */
	retval = du_core->or1k_jtag_read_cpu(&or1k->jtag, OR1K_DMR1_CPU_REG_ADD,
					     OR1K_DEBUG_REG_NUM, debug_reg_list);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while reading debug registers");
		return retval;
	}

	/* Clear Debug Reason Register (DRR) */
	debug_reg_list[OR1K_DEBUG_REG_DRR] = 0;

	/* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) */
	debug_reg_list[OR1K_DEBUG_REG_DMR2] &= ~OR1K_DMR2_WGB;
	if (step)
		/* Set the single step trigger in Debug Mode Register 1 (DMR1) */
		debug_reg_list[OR1K_DEBUG_REG_DMR1] |= OR1K_DMR1_ST | OR1K_DMR1_BT;
	else
		/* Clear the single step trigger in Debug Mode Register 1 (DMR1) */
		debug_reg_list[OR1K_DEBUG_REG_DMR1] &= ~(OR1K_DMR1_ST | OR1K_DMR1_BT);

	/* Set traps to be handled by the debug unit in the Debug Stop
	   Register (DSR). Check if we have any software breakpoints in
	   place before setting this value - the kernel, for instance,
	   relies on l.trap instructions not stalling the processor ! */
	if (is_any_soft_breakpoint(target) == true)
		debug_reg_list[OR1K_DEBUG_REG_DSR] |= OR1K_DSR_TE;

	/* Write debug registers (starting from DMR1 register) */
	retval = du_core->or1k_jtag_write_cpu(&or1k->jtag, OR1K_DMR1_CPU_REG_ADD,
					      OR1K_DEBUG_REG_NUM, debug_reg_list);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while writing back debug registers");
		return retval;
	}

	resume_pc = buf_get_u32(or1k->core_cache->reg_list[OR1K_REG_NPC].value,
				0, 32);

	/* The front-end may request us not to handle breakpoints */
	if (handle_breakpoints) {
		/* Single step past breakpoint at current address */
		breakpoint = breakpoint_find(target, resume_pc);
		if (breakpoint) {
			LOG_DEBUG("Unset breakpoint at 0x%08" PRIx32, breakpoint->address);
			retval = or1k_remove_breakpoint(target, breakpoint);
			if (retval != ERROR_OK)
				return retval;
		}
	}

	/* Unstall time */
	retval = du_core->or1k_cpu_stall(&or1k->jtag, CPU_UNSTALL);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while unstalling the CPU");
		return retval;
	}

	if (step)
		target->debug_reason = DBG_REASON_SINGLESTEP;
	else
		target->debug_reason = DBG_REASON_NOTHALTED;

	/* Registers are now invalid */
	register_cache_invalidate(or1k->core_cache);

	if (!debug_execution) {
		target->state = TARGET_RUNNING;
		target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
		LOG_DEBUG("Target resumed at 0x%08" PRIx32, resume_pc);
	} else {
		target->state = TARGET_DEBUG_RUNNING;
		target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
		LOG_DEBUG("Target debug resumed at 0x%08" PRIx32, resume_pc);
	}

	return ERROR_OK;
}
Beispiel #5
0
static VALUE
Breakpoint_find(VALUE self, VALUE breakpoints, VALUE source, VALUE pos)
{
  return breakpoint_find(breakpoints, source, pos);
}
Beispiel #6
0
int lakemont_poll(struct target *t)
{
	/* LMT1 PMCR register currently allows code breakpoints, data breakpoints,
	 * single stepping and shutdowns to be redirected to PM but does not allow
	 * redirecting into PM as a result of SMM enter and SMM exit
	 */
	uint32_t ts = get_tapstatus(t);

	if (ts == 0xFFFFFFFF && t->state != TARGET_DEBUG_RUNNING) {
		/* something is wrong here */
		LOG_ERROR("tapstatus invalid - scan_chain serialization or locked JTAG access issues");
		/* TODO: Give a hint that unlocking is wrong or maybe a
		 * 'jtag arp_init' helps
		 */
		t->state = TARGET_DEBUG_RUNNING;
		return ERROR_OK;
	}

	if ((!(ts & TS_PM_BIT))) {
		if (t->state == TARGET_HALTED) {
			LOG_USER("target running for unknown reason");
		} else if (t->state == TARGET_DEBUG_RUNNING) {
			LOG_USER("Debug running tapstatus=0x%08" PRIx32, ts);
		}
		LOG_DEBUG("tapstatus=0x%08" PRIx32, ts);
		t->state = TARGET_RUNNING;
	}


	if (t->state == TARGET_RUNNING ||
		t->state == TARGET_DEBUG_RUNNING) {

		if (ts & TS_PM_BIT) {

			LOG_USER("redirect to PM, tapstatus=0x%08" PRIx32, get_tapstatus(t));

			t->state = TARGET_DEBUG_RUNNING;
			if (save_context(t) != ERROR_OK)
				return ERROR_FAIL;
			if (halt_prep(t) != ERROR_OK)
				return ERROR_FAIL;
			t->state = TARGET_HALTED;
			t->debug_reason = DBG_REASON_UNDEFINED;

			struct x86_32_common *x86_32 = target_to_x86_32(t);
			uint32_t eip = buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32);
			uint32_t dr6 = buf_get_u32(x86_32->cache->reg_list[DR6].value, 0, 32);
			uint32_t hwbreakpoint = (uint32_t)-1;

			if (dr6 & DR6_BRKDETECT_0)
				hwbreakpoint = 0;
			if (dr6 & DR6_BRKDETECT_1)
				hwbreakpoint = 1;
			if (dr6 & DR6_BRKDETECT_2)
				hwbreakpoint = 2;
			if (dr6 & DR6_BRKDETECT_3)
				hwbreakpoint = 3;

			if (hwbreakpoint != (uint32_t)-1) {
				uint32_t dr7 = buf_get_u32(x86_32->cache->reg_list[DR7].value, 0, 32);
				uint32_t type = dr7 & (0x03 << (DR7_RW_SHIFT + hwbreakpoint*DR7_RW_LEN_SIZE));
				if (type == DR7_BP_EXECUTE) {
					LOG_USER("hit hardware breakpoint (hwreg=%" PRIu32 ") at 0x%08" PRIx32, hwbreakpoint, eip);
				} else {
					uint32_t address = 0;
					switch (hwbreakpoint) {
					default:
					case 0:
						address = buf_get_u32(x86_32->cache->reg_list[DR0].value, 0, 32);
					break;
					case 1:
						address = buf_get_u32(x86_32->cache->reg_list[DR1].value, 0, 32);
					break;
					case 2:
						address = buf_get_u32(x86_32->cache->reg_list[DR2].value, 0, 32);
					break;
					case 3:
						address = buf_get_u32(x86_32->cache->reg_list[DR3].value, 0, 32);
					break;
					}
					LOG_USER("hit '%s' watchpoint for 0x%08" PRIx32 " (hwreg=%" PRIu32 ") at 0x%08" PRIx32,
								type == DR7_BP_WRITE ? "write" : "access", address,
								hwbreakpoint, eip);
				}
				t->debug_reason = DBG_REASON_BREAKPOINT;
			} else {
				/* Check if the target hit a software breakpoint.
				 * ! Watch out: EIP is currently pointing after the breakpoint opcode
				 */
				struct breakpoint *bp = NULL;
				bp = breakpoint_find(t, eip-1);
				if (bp != NULL) {
					t->debug_reason = DBG_REASON_BREAKPOINT;
					if (bp->type == BKPT_SOFT) {
						/* The EIP is now pointing the the next byte after the
						 * breakpoint instruction. This needs to be corrected.
						 */
						buf_set_u32(x86_32->cache->reg_list[EIP].value, 0, 32, eip-1);
						x86_32->cache->reg_list[EIP].dirty = 1;
						x86_32->cache->reg_list[EIP].valid = 1;
						LOG_USER("hit software breakpoint at 0x%08" PRIx32, eip-1);
					} else {
						/* it's not a hardware breakpoint (checked already in DR6 state)
						 * and it's also not a software breakpoint ...
						 */
						LOG_USER("hit unknown breakpoint at 0x%08" PRIx32, eip);
					}
				} else {

					/* There is also the case that we hit an breakpoint instruction,
					 * which was not set by us. This needs to be handled be the
					 * application that introduced the breakpoint.
					 */

					LOG_USER("unknown break reason at 0x%08" PRIx32, eip);
				}
			}

			return target_call_event_callbacks(t, TARGET_EVENT_HALTED);
		}
	}
	return ERROR_OK;
}
Beispiel #7
0
int lakemont_step(struct target *t, int current,
			uint32_t address, int handle_breakpoints)
{
	struct x86_32_common *x86_32 = target_to_x86_32(t);
	uint32_t eflags = buf_get_u32(x86_32->cache->reg_list[EFLAGS].value, 0, 32);
	uint32_t eip = buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32);
	uint32_t pmcr = buf_get_u32(x86_32->cache->reg_list[PMCR].value, 0, 32);
	struct breakpoint *bp = NULL;
	int retval = ERROR_OK;
	uint32_t tapstatus = 0;

	if (check_not_halted(t))
		return ERROR_TARGET_NOT_HALTED;
	bp = breakpoint_find(t, eip);
	if (retval == ERROR_OK && bp != NULL/*&& bp->type == BKPT_SOFT*/) {
		/* TODO: This should only be done for software breakpoints.
		 * Stepping from hardware breakpoints should be possible with the resume flag
		 * Needs testing.
		 */
		retval = x86_32_common_remove_breakpoint(t, bp);
	}

	/* Set EFLAGS[TF] and PMCR[IR], exit pm and wait for PRDY# */
	LOG_DEBUG("modifying PMCR = 0x%08" PRIx32 " and EFLAGS = 0x%08" PRIx32, pmcr, eflags);
	eflags = eflags | (EFLAGS_TF | EFLAGS_RF);
	buf_set_u32(x86_32->cache->reg_list[EFLAGS].value, 0, 32, eflags);
	buf_set_u32(x86_32->cache->reg_list[PMCR].value, 0, 32, 1);
	LOG_DEBUG("EFLAGS [TF] [RF] bits set=0x%08" PRIx32 ", PMCR=0x%08" PRIx32 ", EIP=0x%08" PRIx32,
			eflags, pmcr, eip);

	tapstatus = get_tapstatus(t);

	t->debug_reason = DBG_REASON_SINGLESTEP;
	t->state = TARGET_DEBUG_RUNNING;
	if (restore_context(t) != ERROR_OK)
		return ERROR_FAIL;
	if (exit_probemode(t) != ERROR_OK)
		return ERROR_FAIL;

	target_call_event_callbacks(t, TARGET_EVENT_RESUMED);

	tapstatus = get_tapstatus(t);
	if (tapstatus & (TS_PM_BIT | TS_EN_PM_BIT | TS_PRDY_BIT | TS_PMCR_BIT)) {
		/* target has stopped */
		if (save_context(t) != ERROR_OK)
			return ERROR_FAIL;
		if (halt_prep(t) != ERROR_OK)
			return ERROR_FAIL;
		t->state = TARGET_HALTED;

		LOG_USER("step done from EIP 0x%08" PRIx32 " to 0x%08" PRIx32, eip,
				buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32));
		target_call_event_callbacks(t, TARGET_EVENT_HALTED);
	} else {
		/* target didn't stop
		 * I hope the poll() will catch it, but the deleted breakpoint is gone
		 */
		LOG_ERROR("%s target didn't stop after executing a single step", __func__);
		t->state = TARGET_RUNNING;
		return ERROR_FAIL;
	}

	/* try to re-apply the breakpoint, even of step failed
	 * TODO: When a bp was set, we should try to stop the target - fix the return above
	 */
	if (bp != NULL/*&& bp->type == BKPT_SOFT*/) {
		/* TODO: This should only be done for software breakpoints.
		 * Stepping from hardware breakpoints should be possible with the resume flag
		 * Needs testing.
		 */
		retval = x86_32_common_add_breakpoint(t, bp);
	}

	return retval;
}
Beispiel #8
0
static int or1k_resume_or_step(struct target *target, int current,
			       uint32_t address, int handle_breakpoints, 
			       int debug_execution, int step)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct breakpoint *breakpoint = NULL;
	uint32_t resume_pc;
	int retval;

	LOG_DEBUG(" - ");
	LOG_DEBUG(" addr: 0x%x, stepping: %d, handle breakpoints %d\n",
		  address, step, handle_breakpoints);

	if (target->state != TARGET_HALTED)
	{
		LOG_WARNING("target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	if (!debug_execution)
	{
		target_free_all_working_areas(target);
	}

	/* current ? continue on current pc : continue at <address> */
	if (!current)
	{
		buf_set_u32(or1k->core_cache->reg_list[OR1K_REG_NPC].value, 0,
			    32, address);
	}

	if (!step) {
		or1k_restore_context(target);
	}

	uint32_t debug_reg_list[OR1K_DEBUG_REG_NUM];
	/* read debug registers (starting from DMR1 register) */
	or1k_jtag_read_cpu(&or1k->jtag, OR1K_DMR1_CPU_REG_ADD, OR1K_DEBUG_REG_NUM, debug_reg_list);
	/* Clear Debug Reason Register (DRR) */
	debug_reg_list[OR1K_DEBUG_REG_DRR] = 0;
	/* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) */
	debug_reg_list[OR1K_DEBUG_REG_DMR2] &= ~OR1K_DMR2_WGB;
	if (step)
		/* Set the single step trigger in Debug Mode Register 1 (DMR1) */
		debug_reg_list[OR1K_DEBUG_REG_DMR1] |= OR1K_DMR1_ST | OR1K_DMR1_BT;
	else
		/* Clear the single step trigger in Debug Mode Register 1 (DMR1) */
		debug_reg_list[OR1K_DEBUG_REG_DMR1] &= ~(OR1K_DMR1_ST | OR1K_DMR1_BT);

	/* Set traps to be handled by the debug unit in the Debug Stop 
	   Register (DSR) */
	/* TODO - check if we have any software breakpoints in place before
	   setting this value - the kernel, for instance, relies on l.trap
	   instructions not stalling the processor! */
	debug_reg_list[OR1K_DEBUG_REG_DSR] |= OR1K_DSR_TE;
	/* write debug registers (starting from DMR1 register) */
	or1k_jtag_write_cpu(&or1k->jtag, OR1K_DMR1_CPU_REG_ADD, OR1K_DEBUG_REG_NUM, debug_reg_list);

	resume_pc = buf_get_u32(or1k->core_cache->reg_list[OR1K_REG_NPC].value,
				0, 32);
	/* the front-end may request us not to handle breakpoints */
	if (handle_breakpoints)
	{
		/* Single step past breakpoint at current address */
		if ((breakpoint = breakpoint_find(target, resume_pc)))
		{
			LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
#if 0
			/* Do appropriate things here to remove breakpoint. */
#endif
		}
	}
	/* Unstall time */

	/* Mohor debug if, clearing control register unstalls */
	retval = or1k_jtag_write_cpu_cr(&or1k->jtag, 0, 0);
	if (retval != ERROR_OK)
		return retval;

	if (step)
		target->debug_reason = DBG_REASON_SINGLESTEP;
	else
		target->debug_reason = DBG_REASON_NOTHALTED;

	/* registers are now invalid */
	register_cache_invalidate(or1k->core_cache);

	if (!debug_execution)
	{
		target->state = TARGET_RUNNING;
		target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
		LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
	}
	else
	{
		target->state = TARGET_DEBUG_RUNNING;
		target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
		LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
	}
	
	return ERROR_OK;
}