示例#1
0
/** Logs summary of ARMv7-M state for a halted target. */
int armv7m_arch_state(struct target *target)
{
	struct armv7m_common *armv7m = target_to_armv7m(target);
	struct arm *arm = &armv7m->arm;
	uint32_t ctrl, sp;

	/* avoid filling log waiting for fileio reply */
	if (arm->semihosting_hit_fileio)
		return ERROR_OK;

	ctrl = buf_get_u32(arm->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 32);
	sp = buf_get_u32(arm->core_cache->reg_list[ARMV7M_R13].value, 0, 32);

	LOG_USER("target halted due to %s, current mode: %s %s\n"
		"xPSR: %#8.8" PRIx32 " pc: %#8.8" PRIx32 " %csp: %#8.8" PRIx32 "%s%s",
		debug_reason_name(target),
		arm_mode_name(arm->core_mode),
		armv7m_exception_string(armv7m->exception_number),
		buf_get_u32(arm->cpsr->value, 0, 32),
		buf_get_u32(arm->pc->value, 0, 32),
		(ctrl & 0x02) ? 'p' : 'm',
		sp,
		arm->is_semihosting ? ", semihosting" : "",
		arm->is_semihosting_fileio ? " fileio" : "");

	return ERROR_OK;
}
示例#2
0
/**
 * Configures host-side ARM records to reflect the specified CPSR.
 * Later, code can use arm_reg_current() to map register numbers
 * according to how they are exposed by this mode.
 */
void arm_set_cpsr(struct arm *arm, uint32_t cpsr)
{
	enum arm_mode mode = cpsr & 0x1f;
	int num;

	/* NOTE:  this may be called very early, before the register
	 * cache is set up.  We can't defend against many errors, in
	 * particular against CPSRs that aren't valid *here* ...
	 */
	if (arm->cpsr) {
		buf_set_u32(arm->cpsr->value, 0, 32, cpsr);
		arm->cpsr->valid = 1;
		arm->cpsr->dirty = 0;
	}

	arm->core_mode = mode;

	/* mode_to_number() warned; set up a somewhat-sane mapping */
	num = arm_mode_to_number(mode);
	if (num < 0) {
		mode = ARM_MODE_USR;
		num = 0;
	}

	arm->map = &armv4_5_core_reg_map[num][0];
	arm->spsr = (mode == ARM_MODE_USR || mode == ARM_MODE_SYS)
		? NULL
		: arm->core_cache->reg_list + arm->map[16];

	/* Older ARMs won't have the J bit */
	enum arm_state state;

	if (cpsr & (1 << 5)) {	/* T */
		if (cpsr & (1 << 24)) {	/* J */
			LOG_WARNING("ThumbEE -- incomplete support");
			state = ARM_STATE_THUMB_EE;
		} else
			state = ARM_STATE_THUMB;
	} else {
		if (cpsr & (1 << 24)) {	/* J */
			LOG_ERROR("Jazelle state handling is BROKEN!");
			state = ARM_STATE_JAZELLE;
		} else
			state = ARM_STATE_ARM;
	}
	arm->core_state = state;

	LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr,
		arm_mode_name(mode),
		arm_state_strings[arm->core_state]);
}
示例#3
0
int arm_arch_state(struct target *target)
{
	struct arm *arm = target_to_arm(target);

	if (arm->common_magic != ARM_COMMON_MAGIC) {
		LOG_ERROR("BUG: called for a non-ARM target");
		return ERROR_FAIL;
	}

	LOG_USER("target halted in %s state due to %s, current mode: %s\n"
		"cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s",
		arm_state_strings[arm->core_state],
		debug_reason_name(target),
		arm_mode_name(arm->core_mode),
		buf_get_u32(arm->cpsr->value, 0, 32),
		buf_get_u32(arm->pc->value, 0, 32),
		arm->is_semihosting ? ", semihosting" : "");

	return ERROR_OK;
}
示例#4
0
static int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
{
	struct arm_reg *reg_arch_info = reg->arch_info;
	struct target *target = reg_arch_info->target;
	struct arm *armv4_5_target = target_to_arm(target);
	uint32_t value = buf_get_u32(buf, 0, 32);

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

	/* Except for CPSR, the "reg" command exposes a writeback model
	 * for the register cache.
	 */
	if (reg == armv4_5_target->cpsr) {
		arm_set_cpsr(armv4_5_target, value);

		/* Older cores need help to be in ARM mode during halt
		 * mode debug, so we clear the J and T bits if we flush.
		 * For newer cores (v6/v7a/v7r) we don't need that, but
		 * it won't hurt since CPSR is always flushed anyway.
		 */
		if (armv4_5_target->core_mode !=
			(enum arm_mode)(value & 0x1f)) {
			LOG_DEBUG("changing ARM core mode to '%s'",
				arm_mode_name(value & 0x1f));
			value &= ~((1 << 24) | (1 << 5));
			uint8_t t[4];
			buf_set_u32(t, 0, 32, value);
			armv4_5_target->write_core_reg(target, reg,
				16, ARM_MODE_ANY, t);
		}
	} else {
		buf_set_u32(reg->value, 0, 32, value);
		reg->valid = 1;
	}
	reg->dirty = 1;

	return ERROR_OK;
}