Exemple #1
0
/** Clear VCR and all breakpoints and watchpoints via scan chain 7
 *
 * \param arm11		Target state variable.
 *
 */
void arm11_sc7_clear_vbw(arm11_common_t * arm11)
{
    arm11_sc7_action_t		clear_bw[arm11->brp + arm11->wrp + 1];
    arm11_sc7_action_t *	pos = clear_bw;

    {size_t i;
    for (i = 0; i < asizeof(clear_bw); i++)
    {
	clear_bw[i].write	= true;
	clear_bw[i].value	= 0;
    }}

    {size_t i;
    for (i = 0; i < arm11->brp; i++)
	(pos++)->address = ARM11_SC7_BCR0 + i;
    }

    {size_t i;
    for (i = 0; i < arm11->wrp; i++)
	(pos++)->address = ARM11_SC7_WCR0 + i;
    }

    (pos++)->address = ARM11_SC7_VCR;

    arm11_sc7_run(arm11, clear_bw, asizeof(clear_bw));
}
Exemple #2
0
/** Write VCR register
 *
 * \param arm11		Target state variable.
 * \param value		Value to be written
 */
void arm11_sc7_set_vcr(struct arm11_common * arm11, uint32_t value)
{
	struct arm11_sc7_action		set_vcr;

	set_vcr.write		= true;
	set_vcr.address		= ARM11_SC7_VCR;
	set_vcr.value		= value;

	arm11_sc7_run(arm11, &set_vcr, 1);
}
Exemple #3
0
/** Write VCR register
 *
 * \param arm11		Target state variable.
 * \param value		Value to be written
 */
void arm11_sc7_set_vcr(arm11_common_t * arm11, u32 value)
{
    arm11_sc7_action_t		set_vcr;

    set_vcr.write		= true;
    set_vcr.address		= ARM11_SC7_VCR;
    set_vcr.value		= value;


    arm11_sc7_run(arm11, &set_vcr, 1);
}
Exemple #4
0
/** Flush any pending breakpoint and watchpoint updates. */
int arm11_bpwp_flush(struct arm11_common *arm11)
{
	int retval;

	if (!arm11->bpwp_n)
		return ERROR_OK;

	retval = arm11_sc7_run(arm11, arm11->bpwp_actions, arm11->bpwp_n);
	arm11->bpwp_n = 0;

	return retval;
}
Exemple #5
0
/** Clear VCR and all breakpoints and watchpoints via scan chain 7
 *
 * \param arm11		Target state variable.
 *
 */
void arm11_sc7_clear_vbw(struct arm11_common * arm11)
{
	size_t clear_bw_size = arm11->brp + 1;
	struct arm11_sc7_action		*clear_bw = malloc(sizeof(struct arm11_sc7_action) * clear_bw_size);
	struct arm11_sc7_action *	pos = clear_bw;

	for (size_t i = 0; i < clear_bw_size; i++)
	{
		clear_bw[i].write	= true;
		clear_bw[i].value	= 0;
	}

	for (size_t i = 0; i < arm11->brp; i++)
		(pos++)->address = ARM11_SC7_BCR0 + i;

	(pos++)->address = ARM11_SC7_VCR;

	arm11_sc7_run(arm11, clear_bw, clear_bw_size);

	free (clear_bw);
}
Exemple #6
0
static int arm11_step(struct target *target, int current,
		uint32_t address, int handle_breakpoints)
{
	LOG_DEBUG("target->state: %s",
		target_state_name(target));

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

	struct arm11_common *arm11 = target_to_arm11(target);

	address = arm11_nextpc(arm11, current, address);

	LOG_DEBUG("STEP PC %08" PRIx32 "%s", address, !current ? "!" : "");


	/** \todo TODO: Thumb not supported here */

	uint32_t	next_instruction;

	CHECK_RETVAL(arm11_read_memory_word(arm11, address, &next_instruction));

	/* skip over BKPT */
	if ((next_instruction & 0xFFF00070) == 0xe1200070)
	{
		address = arm11_nextpc(arm11, 0, address + 4);
		LOG_DEBUG("Skipping BKPT");
	}
	/* skip over Wait for interrupt / Standby */
	/* mcr	15, 0, r?, cr7, cr0, {4} */
	else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90)
	{
		address = arm11_nextpc(arm11, 0, address + 4);
		LOG_DEBUG("Skipping WFI");
	}
	/* ignore B to self */
	else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)
	{
		LOG_DEBUG("Not stepping jump to self");
	}
	else
	{
		/** \todo TODO: check if break-/watchpoints make any sense at all in combination
		* with this. */

		/** \todo TODO: check if disabling IRQs might be a good idea here. Alternatively
		* the VCR might be something worth looking into. */


		/* Set up breakpoint for stepping */

		struct arm11_sc7_action	brp[2];

		brp[0].write	= 1;
		brp[0].address	= ARM11_SC7_BVR0;
		brp[1].write	= 1;
		brp[1].address	= ARM11_SC7_BCR0;

		if (arm11->hardware_step)
		{
			/* Hardware single stepping ("instruction address
			 * mismatch") is used if enabled.  It's not quite
			 * exactly "run one instruction"; "branch to here"
			 * loops won't break, neither will some other cases,
			 * but it's probably the best default.
			 *
			 * Hardware single stepping isn't supported on v6
			 * debug modules.  ARM1176 and v7 can support it...
			 *
			 * FIXME Thumb stepping likely needs to use 0x03
			 * or 0xc0 byte masks, not 0x0f.
			 */
			 brp[0].value	= address;
			 brp[1].value	= 0x1 | (3 << 1) | (0x0F << 5)
					| (0 << 14) | (0 << 16) | (0 << 20)
					| (2 << 21);
		} else
		{
			/* Sets a breakpoint on the next PC, as calculated
			 * by instruction set simulation.
			 *
			 * REVISIT stepping Thumb on ARM1156 requires Thumb2
			 * support from the simulator.
			 */
			uint32_t next_pc;
			int retval;

			retval = arm_simulate_step(target, &next_pc);
			if (retval != ERROR_OK)
				return retval;

			brp[0].value	= next_pc;
			brp[1].value	= 0x1 | (3 << 1) | (0x0F << 5)
					| (0 << 14) | (0 << 16) | (0 << 20)
					| (0 << 21);
		}

		CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));

		/* resume */


		if (arm11->step_irq_enable)
			/* this disable should be redundant ... */
			arm11->dscr &= ~DSCR_INT_DIS;
		else
			arm11->dscr |= DSCR_INT_DIS;


		CHECK_RETVAL(arm11_leave_debug_state(arm11, handle_breakpoints));

		arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);

		CHECK_RETVAL(jtag_execute_queue());

		/* wait for halt */
		int i = 0;

		while (1)
		{
			const uint32_t mask = DSCR_CORE_RESTARTED
					| DSCR_CORE_HALTED;

			CHECK_RETVAL(arm11_read_DSCR(arm11));
			LOG_DEBUG("DSCR %08x e", (unsigned) arm11->dscr);

			if ((arm11->dscr & mask) == mask)
				break;

			long long then = 0;
			if (i == 1000)
			{
				then = timeval_ms();
			}
			if (i >= 1000)
			{
				if ((timeval_ms()-then) > 1000)
				{
					LOG_WARNING("Timeout (1000ms) waiting for instructions to complete");
					return ERROR_FAIL;
				}
			}
			i++;
		}

		/* clear breakpoint */
		CHECK_RETVAL(arm11_sc7_clear_vbw(arm11));

		/* save state */
		CHECK_RETVAL(arm11_debug_entry(arm11));

		/* restore default state */
		arm11->dscr &= ~DSCR_INT_DIS;

	}

	target->debug_reason = DBG_REASON_SINGLESTEP;

	CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));

	return ERROR_OK;
}
Exemple #7
0
static int arm11_resume(struct target *target, int current,
		uint32_t address, int handle_breakpoints, int debug_execution)
{
	//	  LOG_DEBUG("current %d  address %08x  handle_breakpoints %d  debug_execution %d",
	//	current, address, handle_breakpoints, debug_execution);

	struct arm11_common *arm11 = target_to_arm11(target);

	LOG_DEBUG("target->state: %s",
		target_state_name(target));


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

	address = arm11_nextpc(arm11, current, address);

	LOG_DEBUG("RESUME PC %08" PRIx32 "%s", address, !current ? "!" : "");

	/* clear breakpoints/watchpoints and VCR*/
	CHECK_RETVAL(arm11_sc7_clear_vbw(arm11));

	if (!debug_execution)
		target_free_all_working_areas(target);

	/* Should we skip over breakpoints matching the PC? */
	if (handle_breakpoints) {
		struct breakpoint *bp;

		for (bp = target->breakpoints; bp; bp = bp->next)
		{
			if (bp->address == address)
			{
				LOG_DEBUG("must step over %08" PRIx32 "", bp->address);
				arm11_step(target, 1, 0, 0);
				break;
			}
		}
	}

	/* activate all breakpoints */
	if (true) {
		struct breakpoint *bp;
		unsigned brp_num = 0;

		for (bp = target->breakpoints; bp; bp = bp->next)
		{
			struct arm11_sc7_action	brp[2];

			brp[0].write	= 1;
			brp[0].address	= ARM11_SC7_BVR0 + brp_num;
			brp[0].value	= bp->address;
			brp[1].write	= 1;
			brp[1].address	= ARM11_SC7_BCR0 + brp_num;
			brp[1].value	= 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21);

			CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));

			LOG_DEBUG("Add BP %d at %08" PRIx32, brp_num,
					bp->address);

			brp_num++;
		}

		if (arm11->vcr)
			CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr));
	}

	/* activate all watchpoints and breakpoints */
	CHECK_RETVAL(arm11_leave_debug_state(arm11, true));

	arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);

	CHECK_RETVAL(jtag_execute_queue());

	int i = 0;
	while (1)
	{
		CHECK_RETVAL(arm11_read_DSCR(arm11));

		LOG_DEBUG("DSCR %08x", (unsigned) arm11->dscr);

		if (arm11->dscr & DSCR_CORE_RESTARTED)
			break;


		long long then = 0;
		if (i == 1000)
		{
			then = timeval_ms();
		}
		if (i >= 1000)
		{
			if ((timeval_ms()-then) > 1000)
			{
				LOG_WARNING("Timeout (1000ms) waiting for instructions to complete");
				return ERROR_FAIL;
			}
		}
		i++;
	}

	target->debug_reason = DBG_REASON_NOTHALTED;
	if (!debug_execution)
		target->state = TARGET_RUNNING;
	else
		target->state = TARGET_DEBUG_RUNNING;
	CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));

	return ERROR_OK;
}