Ejemplo n.º 1
0
/* just read the register -- rely on the core mode being right */
static int dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
{
	uint32_t value;
	int retval;

	switch (regnum) {
		case 0 ... 14:
			/* return via DCC:  "MCR p14, 0, Rnum, c0, c5, 0" */
			retval = dpm->instr_read_data_dcc(dpm,
				ARMV4_5_MCR(14, 0, regnum, 0, 5, 0),
				&value);
			break;
		case 15:/* PC
			 * "MOV r0, pc"; then return via DCC */
			retval = dpm->instr_read_data_r0(dpm, 0xe1a0000f, &value);

			/* NOTE: this seems like a slightly awkward place to update
			 * this value ... but if the PC gets written (the only way
			 * to change what we compute), the arch spec says subsequent
			 * reads return values which are "unpredictable".  So this
			 * is always right except in those broken-by-intent cases.
			 */
			switch (dpm->arm->core_state) {
				case ARM_STATE_ARM:
					value -= 8;
					break;
				case ARM_STATE_THUMB:
				case ARM_STATE_THUMB_EE:
					value -= 4;
					break;
				case ARM_STATE_JAZELLE:
					/* core-specific ... ? */
					LOG_WARNING("Jazelle PC adjustment unknown");
					break;
			}
			break;
		default:
			/* 16: "MRS r0, CPSR"; then return via DCC
			 * 17: "MRS r0, SPSR"; then return via DCC
			 */
			retval = dpm->instr_read_data_r0(dpm,
				ARMV4_5_MRS(0, regnum & 1),
				&value);
			break;
	}

	if (retval == ERROR_OK) {
		buf_set_u32(r->value, 0, 32, value);
		r->valid = true;
		r->dirty = false;
		LOG_DEBUG("READ: %s, %8.8x", r->name, (unsigned) value);
	}

	return retval;
}
Ejemplo n.º 2
0
/**
 * Read basic registers of the the current context:  R0 to R15, and CPSR;
 * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
 * In normal operation this is called on entry to halting debug state,
 * possibly after some other operations supporting restore of debug state
 * or making sure the CPU is fully idle (drain write buffer, etc).
 */
int arm_dpm_read_current_registers(struct arm_dpm *dpm)
{
	struct arm *arm = dpm->arm;
	uint32_t cpsr;
	int retval;
	struct reg *r;

	retval = dpm->prepare(dpm);
	if (retval != ERROR_OK)
		return retval;

	/* read R0 first (it's used for scratch), then CPSR */
	r = arm->core_cache->reg_list + 0;
	if (!r->valid) {
		retval = dpm_read_reg(dpm, r, 0);
		if (retval != ERROR_OK)
			goto fail;
	}
	r->dirty = true;

	retval = dpm->instr_read_data_r0(dpm, ARMV4_5_MRS(0, 0), &cpsr);
	if (retval != ERROR_OK)
		goto fail;

	/* update core mode and state, plus shadow mapping for R8..R14 */
	arm_set_cpsr(arm, cpsr);

	/* REVISIT we can probably avoid reading R1..R14, saving time... */
	for (unsigned i = 1; i < 16; i++) {
		r = arm_reg_current(arm, i);
		if (r->valid)
			continue;

		retval = dpm_read_reg(dpm, r, i);
		if (retval != ERROR_OK)
			goto fail;
	}

	/* NOTE: SPSR ignored (if it's even relevant). */

	/* REVISIT the debugger can trigger various exceptions.  See the
	 * ARMv7A architecture spec, section C5.7, for more info about
	 * what defenses are needed; v6 debug has the most issues.
	 */

fail:
	/* (void) */ dpm->finish(dpm);
	return retval;
}
Ejemplo n.º 3
0
static void arm7tdmi_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)
{
	struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
	struct arm_jtag *jtag_info = &arm7_9->jtag_info;

	/* MRS r0, cpsr */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), NULL, 0);

	/* STR r0, [r15] */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), NULL, 0);
	/* fetch NOP, STR in DECODE stage */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
	/* fetch NOP, STR in EXECUTE stage (1st cycle) */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
	/* nothing fetched, STR still in EXECUTE (2nd cycle) */
	arm7tdmi_clock_data_in(jtag_info, xpsr);
}
Ejemplo n.º 4
0
void arm9tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
{
	/* get pointers to arch-specific information */
	armv4_5_common_t *armv4_5 = target->arch_info;
	arm7_9_common_t *arm7_9 = armv4_5->arch_info;
	arm_jtag_t *jtag_info = &arm7_9->jtag_info;

	/* MRS r0, cpsr */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);

	/* STR r0, [r15] */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
	/* fetch NOP, STR in DECODE stage */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	/* fetch NOP, STR in EXECUTE stage (1st cycle) */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	/* nothing fetched, STR in MEMORY */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
}
Ejemplo n.º 5
0
static void fa526_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)
{
	struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
	struct arm_jtag *jtag_info = &arm7_9->jtag_info;

	/* MRS r0, cpsr */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);

	/* STR r0, [r15] */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
	/* fetch NOP, STR in DECODE stage */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	/* fetch NOP, STR in SHIFT stage */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	/* fetch NOP, STR in EXECUTE stage (1st cycle) */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
	/* nothing fetched, STR in MEMORY */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
}