Beispiel #1
0
/* wait for execution to complete and check exit point */
static int armv4_5_run_algorithm_completion(struct target *target,
	uint32_t exit_point,
	int timeout_ms,
	void *arch_info)
{
	int retval;
	struct arm *arm = target_to_arm(target);

	retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
	if (retval != ERROR_OK)
		return retval;
	if (target->state != TARGET_HALTED) {
		retval = target_halt(target);
		if (retval != ERROR_OK)
			return retval;
		retval = target_wait_state(target, TARGET_HALTED, 500);
		if (retval != ERROR_OK)
			return retval;
		return ERROR_TARGET_TIMEOUT;
	}

	/* fast exit: ARMv5+ code can use BKPT */
	if (exit_point && buf_get_u32(arm->pc->value, 0, 32) != exit_point) {
		LOG_WARNING(
			"target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
			buf_get_u32(arm->pc->value, 0, 32));
		return ERROR_TARGET_TIMEOUT;
	}

	return ERROR_OK;
}
Beispiel #2
0
/* run to exit point. return error if exit point was not reached. */
static int mips32_run_and_wait(struct target *target, uint32_t entry_point,
		int timeout_ms, uint32_t exit_point, struct mips32_common *mips32)
{
	uint32_t pc;
	int retval;
	/* This code relies on the target specific  resume() and  poll()->debug_entry()
	 * sequence to write register values to the processor and the read them back */
	if ((retval = target_resume(target, 0, entry_point, 0, 1)) != ERROR_OK)
	{
		return retval;
	}

	retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
	/* If the target fails to halt due to the breakpoint, force a halt */
	if (retval != ERROR_OK || target->state != TARGET_HALTED)
	{
		if ((retval = target_halt(target)) != ERROR_OK)
			return retval;
		if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
		{
			return retval;
		}
		return ERROR_TARGET_TIMEOUT;
	}

	pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
	if (exit_point && (pc != exit_point))
	{
		LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
		return ERROR_TARGET_TIMEOUT;
	}

	return ERROR_OK;
}
Beispiel #3
0
/* run to exit point. return error if exit point was not reached. */
static int armv7m_run_and_wait(struct target *target, uint32_t entry_point, int timeout_ms, uint32_t exit_point, struct armv7m_common *armv7m)
{
	uint32_t pc;
	int retval;
	/* This code relies on the target specific  resume() and  poll()->debug_entry()
	 * sequence to write register values to the processor and the read them back */
	if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
	{
		return retval;
	}

	retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
	/* If the target fails to halt due to the breakpoint, force a halt */
	if (retval != ERROR_OK || target->state != TARGET_HALTED)
	{
		if ((retval = target_halt(target)) != ERROR_OK)
			return retval;
		if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
		{
			return retval;
		}
		return ERROR_TARGET_TIMEOUT;
	}

	armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc);
	if (exit_point && (pc != exit_point))
	{
		LOG_DEBUG("failed algoritm halted at 0x%" PRIx32 " ", pc);
		return ERROR_TARGET_TIMEOUT;
	}

	return ERROR_OK;
}
Beispiel #4
0
/** Waits for an algorithm in the target. */
int armv7m_wait_algorithm(struct target *target,
	int num_mem_params, struct mem_param *mem_params,
	int num_reg_params, struct reg_param *reg_params,
	uint32_t exit_point, int timeout_ms,
	void *arch_info)
{
	struct armv7m_common *armv7m = target_to_armv7m(target);
	struct armv7m_algorithm *armv7m_algorithm_info = arch_info;
	int retval = ERROR_OK;
	uint32_t pc;

	/* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint
	 * at the exit point */

	if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC)
	{
		LOG_ERROR("current target isn't an ARMV7M target");
		return ERROR_TARGET_INVALID;
	}

	retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
	/* If the target fails to halt due to the breakpoint, force a halt */
	if (retval != ERROR_OK || target->state != TARGET_HALTED)
	{
		if ((retval = target_halt(target)) != ERROR_OK)
			return retval;
		if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
		{
			return retval;
		}
		return ERROR_TARGET_TIMEOUT;
	}

	armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc);
	if (exit_point && (pc != exit_point))
	{
		LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" PRIx32 , pc, exit_point);
		return ERROR_TARGET_TIMEOUT;
	}

	/* Read memory values to mem_params[] */
	for (int i = 0; i < num_mem_params; i++)
	{
		if (mem_params[i].direction != PARAM_OUT)
			if ((retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
			{
				return retval;
			}
	}

	/* Copy core register values to reg_params[] */
	for (int i = 0; i < num_reg_params; i++)
	{
		if (reg_params[i].direction != PARAM_OUT)
		{
			struct reg *reg = register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0);

			if (!reg)
			{
				LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
				return ERROR_INVALID_ARGUMENTS;
			}

			if (reg->size != reg_params[i].size)
			{
				LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
				return ERROR_INVALID_ARGUMENTS;
			}

			buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
		}
	}

	for (int i = ARMV7M_NUM_REGS - 1; i >= 0; i--)
	{
		uint32_t regvalue;
		regvalue = buf_get_u32(armv7m->core_cache->reg_list[i].value, 0, 32);
		if (regvalue != armv7m_algorithm_info->context[i])
		{
			LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
				armv7m->core_cache->reg_list[i].name, armv7m_algorithm_info->context[i]);
			buf_set_u32(armv7m->core_cache->reg_list[i].value,
					0, 32, armv7m_algorithm_info->context[i]);
			armv7m->core_cache->reg_list[i].valid = 1;
			armv7m->core_cache->reg_list[i].dirty = 1;
		}
	}

	armv7m->core_mode = armv7m_algorithm_info->core_mode;

	return retval;
}