示例#1
0
/** Write the Debug Status and Control Register (DSCR)
 *
 * same as CP14 c1
 *
 * \param arm11		Target state variable.
 * \param dscr		DSCR content
 *
 * \remarks			This is a stand-alone function that executes the JTAG command queue.
 */
int arm11_write_DSCR(struct arm11_common * arm11, uint32_t dscr)
{
	int retval;
	retval = arm11_add_debug_SCAN_N(arm11, 0x01, ARM11_TAP_DEFAULT);
	if (retval != ERROR_OK)
		return retval;

	arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);

	struct scan_field		    chain1_field;

	arm11_setup_field(arm11, 32, &dscr, NULL, &chain1_field);

	arm11_add_dr_scan_vc(1, &chain1_field, TAP_DRPAUSE);

	CHECK_RETVAL(jtag_execute_queue());

	JTAG_DEBUG("DSCR <= %08x (OLD %08x)",
			(unsigned) dscr,
			(unsigned) arm11->dscr);

	arm11->dscr = dscr;

	return ERROR_OK;
}
示例#2
0
/** Write the Debug Status and Control Register (DSCR)
 *
 * same as CP14 c1
 *
 * \param arm11 Target state variable.
 * \param dscr DSCR content
 *
 * \remarks This is a stand-alone function that executes the JTAG command queue.
 */
void arm11_write_DSCR(arm11_common_t * arm11, u32 dscr)
{
    arm11_add_debug_SCAN_N(arm11, 0x01, -1);

    arm11_add_IR(arm11, ARM11_EXTEST, -1);

    scan_field_t		    chain1_field;

    arm11_setup_field(arm11, 32, &dscr, NULL, &chain1_field);

    arm11_add_dr_scan_vc(1, &chain1_field, TAP_DRPAUSE);

    jtag_execute_queue();

    JTAG_DEBUG("DSCR <= %08x (OLD %08x)", dscr, arm11->last_dscr);

    arm11->last_dscr = dscr;
}
示例#3
0
/** Read the Debug Status and Control Register (DSCR)
 *
 * same as CP14 c1
 *
 * \param arm11 Target state variable.
 * \return DSCR content
 *
 * \remarks This is a stand-alone function that executes the JTAG command queue.
 */
u32 arm11_read_DSCR(arm11_common_t * arm11)
{
    arm11_add_debug_SCAN_N(arm11, 0x01, -1);

    arm11_add_IR(arm11, ARM11_INTEST, -1);

    u32			dscr;
    scan_field_t	chain1_field;

    arm11_setup_field(arm11, 32, NULL, &dscr, &chain1_field);

    arm11_add_dr_scan_vc(1, &chain1_field, TAP_DRPAUSE);

    jtag_execute_queue();

    if (arm11->last_dscr != dscr)
	JTAG_DEBUG("DSCR  = %08x (OLD %08x)", dscr, arm11->last_dscr);

    arm11->last_dscr = dscr;

    return dscr;
}
示例#4
0
/** Apply reads and writes to scan chain 7
 *
 * \see struct arm11_sc7_action
 *
 * \param arm11		Target state variable.
 * \param actions	A list of read and/or write instructions
 * \param count		Number of instructions in the list.
 *
 */
int arm11_sc7_run(struct arm11_common * arm11, struct arm11_sc7_action * actions, size_t count)
{
	int retval;

	retval = arm11_add_debug_SCAN_N(arm11, 0x07, ARM11_TAP_DEFAULT);
	if (retval != ERROR_OK)
		return retval;

	arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);

	struct scan_field	chain7_fields[3];

	uint8_t				nRW;
	uint32_t				DataOut;
	uint8_t				AddressOut;
	uint8_t				Ready;
	uint32_t				DataIn;
	uint8_t				AddressIn;

	arm11_setup_field(arm11,  1, &nRW,			&Ready,		chain7_fields + 0);
	arm11_setup_field(arm11, 32, &DataOut,		&DataIn,	chain7_fields + 1);
	arm11_setup_field(arm11,  7, &AddressOut,	&AddressIn,	chain7_fields + 2);

	for (size_t i = 0; i < count + 1; i++)
	{
		if (i < count)
		{
			nRW			= actions[i].write ? 1 : 0;
			DataOut		= actions[i].value;
			AddressOut	= actions[i].address;
		}
		else
		{
			nRW			= 1;
			DataOut		= 0;
			AddressOut	= 0;
		}

		/* Timeout here so we don't get stuck. */
		int i = 0;
		while (1)
		{
			JTAG_DEBUG("SC7 <= c%-3d Data %08x %s",
					(unsigned) AddressOut,
					(unsigned) DataOut,
					nRW ? "write" : "read");

			arm11_add_dr_scan_vc(ARRAY_SIZE(chain7_fields),
					chain7_fields, TAP_DRPAUSE);

			CHECK_RETVAL(jtag_execute_queue());

			/* 'nRW' is 'Ready' on read out */
			if (Ready)
				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++;
		}

		if (!nRW)
			JTAG_DEBUG("SC7 => Data %08x", (unsigned) DataIn);

		if (i > 0)
		{
			if (actions[i - 1].address != AddressIn)
			{
				LOG_WARNING("Scan chain 7 shifted out unexpected address");
			}

			if (!actions[i - 1].write)
			{
				actions[i - 1].value = DataIn;
			}
			else
			{
				if (actions[i - 1].value != DataIn)
				{
					LOG_WARNING("Scan chain 7 shifted out unexpected data");
				}
			}
		}
	}
	return ERROR_OK;
}
示例#5
0
/** Cleanup after ITR/DTR operations
 * from the arm11_run_instr... group of functions
 *
 * Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish()
 * around a block of arm11_run_instr_... calls.
 *
 * Any IDLE can lead to an instruction execution when
 * scan chains 4 or 5 are selected and the IR holds
 * INTEST or EXTEST. So we must disable that before
 * any following activities lead to an IDLE.
 *
 * \param arm11		Target state variable.
 *
 */
int arm11_run_instr_data_finish(struct arm11_common * arm11)
{
	return arm11_add_debug_SCAN_N(arm11, 0x00, ARM11_TAP_DEFAULT);
}
示例#6
0
/** Prepare the stage for ITR/DTR operations
 * from the arm11_run_instr... group of functions.
 *
 * Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish()
 * around a block of arm11_run_instr_... calls.
 *
 * Select scan chain 5 to allow quick access to DTR. When scan
 * chain 4 is needed to put in a register the ITRSel instruction
 * shortcut is used instead of actually changing the Scan_N
 * register.
 *
 * \param arm11		Target state variable.
 *
 */
int arm11_run_instr_data_prepare(struct arm11_common * arm11)
{
	return arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);
}
示例#7
0
/**
 * Save processor state.  This is called after a HALT instruction
 * succeeds, and on other occasions the processor enters debug mode
 * (breakpoint, watchpoint, etc).  Caller has updated arm11->dscr.
 */
static int arm11_debug_entry(struct arm11_common *arm11)
{
	int retval;

	arm11->arm.target->state = TARGET_HALTED;
	arm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr);

	/* REVISIT entire cache should already be invalid !!! */
	register_cache_invalidate(arm11->arm.core_cache);

	/* See e.g. ARM1136 TRM, "14.8.4 Entering Debug state" */

	/* maybe save wDTR (pending DCC write to debug SW, e.g. libdcc) */
	arm11->is_wdtr_saved = !!(arm11->dscr & DSCR_DTR_TX_FULL);
	if (arm11->is_wdtr_saved)
	{
		arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);

		arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);

		struct scan_field	chain5_fields[3];

		arm11_setup_field(arm11, 32, NULL,
				&arm11->saved_wdtr, chain5_fields + 0);
		arm11_setup_field(arm11,  1, NULL, NULL,		chain5_fields + 1);
		arm11_setup_field(arm11,  1, NULL, NULL,		chain5_fields + 2);

		arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE);

	}

	/* DSCR: set the Execute ARM instruction enable bit.
	 *
	 * ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode",
	 * but not to issue ITRs(?).  The ARMv7 arch spec says it's required
	 * for executing instructions via ITR.
	 */
	CHECK_RETVAL(arm11_write_DSCR(arm11, DSCR_ITR_EN | arm11->dscr));


	/* From the spec:
	   Before executing any instruction in debug state you have to drain the write buffer.
	   This ensures that no imprecise Data Aborts can return at a later point:*/

	/** \todo TODO: Test drain write buffer. */

#if 0
	while (1)
	{
		/* MRC p14,0,R0,c5,c10,0 */
		//	arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000);

		/* mcr	   15, 0, r0, cr7, cr10, {4} */
		arm11_run_instr_no_data1(arm11, 0xee070f9a);

		uint32_t dscr = arm11_read_DSCR(arm11);

		LOG_DEBUG("DRAIN, DSCR %08x", dscr);

		if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT)
		{
			arm11_run_instr_no_data1(arm11, 0xe320f000);

			dscr = arm11_read_DSCR(arm11);

			LOG_DEBUG("DRAIN, DSCR %08x (DONE)", dscr);

			break;
		}
	}
#endif

	/* Save registers.
	 *
	 * NOTE:  ARM1136 TRM suggests saving just R0 here now, then
	 * CPSR and PC after the rDTR stuff.  We do it all at once.
	 */
	retval = arm_dpm_read_current_registers(&arm11->dpm);
	if (retval != ERROR_OK)
		LOG_ERROR("DPM REG READ -- fail");

	retval = arm11_run_instr_data_prepare(arm11);
	if (retval != ERROR_OK)
		return retval;

	/* maybe save rDTR (pending DCC read from debug SW, e.g. libdcc) */
	arm11->is_rdtr_saved = !!(arm11->dscr & DSCR_DTR_RX_FULL);
	if (arm11->is_rdtr_saved)
	{
		/* MRC p14,0,R0,c0,c5,0 (move rDTR -> r0 (-> wDTR -> local var)) */
		retval = arm11_run_instr_data_from_core_via_r0(arm11,
				0xEE100E15, &arm11->saved_rdtr);
		if (retval != ERROR_OK)
			return retval;
	}

	/* REVISIT Now that we've saved core state, there's may also
	 * be MMU and cache state to care about ...
	 */

	if (arm11->simulate_reset_on_next_halt)
	{
		arm11->simulate_reset_on_next_halt = false;

		LOG_DEBUG("Reset c1 Control Register");

		/* Write 0 (reset value) to Control register 0 to disable MMU/Cache etc. */

		/* MCR p15,0,R0,c1,c0,0 */
		retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0);
		if (retval != ERROR_OK)
			return retval;

	}

	if (arm11->arm.target->debug_reason == DBG_REASON_WATCHPOINT) {
		uint32_t wfar;

		/* MRC p15, 0, <Rd>, c6, c0, 1 ; Read WFAR */
		retval = arm11_run_instr_data_from_core_via_r0(arm11,
				ARMV4_5_MRC(15, 0, 0, 6, 0, 1),
				&wfar);
		if (retval != ERROR_OK)
			return retval;
		arm_dpm_report_wfar(arm11->arm.dpm, wfar);
	}


	retval = arm11_run_instr_data_finish(arm11);
	if (retval != ERROR_OK)
		return retval;

	return ERROR_OK;
}
示例#8
0
/**
 * Restore processor state.  This is called in preparation for
 * the RESTART function.
 */
static int arm11_leave_debug_state(struct arm11_common *arm11, bool bpwp)
{
	int retval;

	/* See e.g. ARM1136 TRM, "14.8.5 Leaving Debug state" */

	/* NOTE:  the ARM1136 TRM suggests restoring all registers
	 * except R0/PC/CPSR right now.  Instead, we do them all
	 * at once, just a bit later on.
	 */

	/* REVISIT once we start caring about MMU and cache state,
	 * address it here ...
	 */

	/* spec says clear wDTR and rDTR; we assume they are clear as
	   otherwise our programming would be sloppy */
	{
		CHECK_RETVAL(arm11_read_DSCR(arm11));

		if (arm11->dscr & (DSCR_DTR_RX_FULL | DSCR_DTR_TX_FULL))
		{
			/*
			The wDTR/rDTR two registers that are used to send/receive data to/from
			the core in tandem with corresponding instruction codes that are
			written into the core. The RDTR FULL/WDTR FULL flag indicates that the
			registers hold data that was written by one side (CPU or JTAG) and not
			read out by the other side.
			*/
			LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08x)",
					(unsigned) arm11->dscr);
			return ERROR_FAIL;
		}
	}

	/* maybe restore original wDTR */
	if (arm11->is_wdtr_saved)
	{
		retval = arm11_run_instr_data_prepare(arm11);
		if (retval != ERROR_OK)
			return retval;

		/* MCR p14,0,R0,c0,c5,0 */
		retval = arm11_run_instr_data_to_core_via_r0(arm11,
				0xee000e15, arm11->saved_wdtr);
		if (retval != ERROR_OK)
			return retval;

		retval = arm11_run_instr_data_finish(arm11);
		if (retval != ERROR_OK)
			return retval;
	}

	/* restore CPSR, PC, and R0 ... after flushing any modified
	 * registers.
	 */
	CHECK_RETVAL(arm_dpm_write_dirty_registers(&arm11->dpm, bpwp));

	CHECK_RETVAL(arm11_bpwp_flush(arm11));

	register_cache_invalidate(arm11->arm.core_cache);

	/* restore DSCR */
	CHECK_RETVAL(arm11_write_DSCR(arm11, arm11->dscr));

	/* maybe restore rDTR */
	if (arm11->is_rdtr_saved)
	{
		arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);

		arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);

		struct scan_field	chain5_fields[3];

		uint8_t			Ready		= 0;	/* ignored */
		uint8_t			Valid		= 0;	/* ignored */

		arm11_setup_field(arm11, 32, &arm11->saved_rdtr,
				NULL, chain5_fields + 0);
		arm11_setup_field(arm11,  1, &Ready,	NULL, chain5_fields + 1);
		arm11_setup_field(arm11,  1, &Valid,	NULL, chain5_fields + 2);

		arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE);
	}

	/* now processor is ready to RESTART */

	return ERROR_OK;
}
示例#9
0
/* talk to the target and set things up */
static int arm11_examine(struct target *target)
{
	int retval;
	char *type;
	struct arm11_common *arm11 = target_to_arm11(target);
	uint32_t didr, device_id;
	uint8_t implementor;

	/* FIXME split into do-first-time and do-every-time logic ... */

	/* check IDCODE */

	arm11_add_IR(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT);

	struct scan_field		idcode_field;

	arm11_setup_field(arm11, 32, NULL, &device_id, &idcode_field);

	arm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &idcode_field, TAP_DRPAUSE);

	/* check DIDR */

	arm11_add_debug_SCAN_N(arm11, 0x00, ARM11_TAP_DEFAULT);

	arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);

	struct scan_field		chain0_fields[2];

	arm11_setup_field(arm11, 32, NULL, &didr, chain0_fields + 0);
	arm11_setup_field(arm11,  8, NULL, &implementor, chain0_fields + 1);

	arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain0_fields), chain0_fields, TAP_IDLE);

	CHECK_RETVAL(jtag_execute_queue());

	/* assume the manufacturer id is ok; check the part # */
	switch ((device_id >> 12) & 0xFFFF)
	{
	case 0x7B36:
		type = "ARM1136";
		break;
	case 0x7B37:
		type = "ARM11 MPCore";
		break;
	case 0x7B56:
		type = "ARM1156";
		break;
	case 0x7B76:
		arm11->arm.core_type = ARM_MODE_MON;
		/* NOTE: could default arm11->hardware_step to true */
		type = "ARM1176";
		break;
	default:
		LOG_ERROR("unexpected ARM11 ID code");
		return ERROR_FAIL;
	}
	LOG_INFO("found %s", type);

	/* unlikely this could ever fail, but ... */
	switch ((didr >> 16) & 0x0F) {
	case ARM11_DEBUG_V6:
	case ARM11_DEBUG_V61:		/* supports security extensions */
		break;
	default:
		LOG_ERROR("Only ARM v6 and v6.1 debug supported.");
		return ERROR_FAIL;
	}

	arm11->brp = ((didr >> 24) & 0x0F) + 1;

	/** \todo TODO: reserve one brp slot if we allow breakpoints during step */
	arm11->free_brps = arm11->brp;

	LOG_DEBUG("IDCODE %08" PRIx32 " IMPLEMENTOR %02x DIDR %08" PRIx32,
			device_id, implementor, didr);

	/* as a side-effect this reads DSCR and thus
	 * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag
	 * as suggested by the spec.
	 */

	retval = arm11_check_init(arm11);
	if (retval != ERROR_OK)
		return retval;

	/* Build register cache "late", after target_init(), since we
	 * want to know if this core supports Secure Monitor mode.
	 */
	if (!target_was_examined(target))
		CHECK_RETVAL(arm11_dpm_init(arm11, didr));

	/* ETM on ARM11 still uses original scanchain 6 access mode */
	if (arm11->arm.etm && !target_was_examined(target)) {
		*register_get_last_cache_p(&target->reg_cache) =
			etm_build_reg_cache(target, &arm11->jtag_info,
					arm11->arm.etm);
		CHECK_RETVAL(etm_setup(target));
	}

	target_set_examined(target);

	return ERROR_OK;
}
示例#10
0
/** Apply reads and writes to scan chain 7
 *
 * \see arm11_sc7_action_t
 *
 * \param arm11		Target state variable.
 * \param actions	A list of read and/or write instructions
 * \param count		Number of instructions in the list.
 *
 */
void arm11_sc7_run(arm11_common_t * arm11, arm11_sc7_action_t * actions, size_t count)
{
    arm11_add_debug_SCAN_N(arm11, 0x07, -1);

    arm11_add_IR(arm11, ARM11_EXTEST, -1);

    scan_field_t	chain7_fields[3];

    u8		nRW;
    u32		DataOut;
    u8		AddressOut;
    u8		Ready;
    u32		DataIn;
    u8		AddressIn;

    arm11_setup_field(arm11,  1, &nRW,		&Ready,		chain7_fields + 0);
    arm11_setup_field(arm11, 32, &DataOut,	&DataIn,	chain7_fields + 1);
    arm11_setup_field(arm11,  7, &AddressOut,	&AddressIn,	chain7_fields + 2);

    {size_t i;
    for (i = 0; i < count + 1; i++)
    {
	if (i < count)
	{
	    nRW		= actions[i].write ? 1 : 0;
	    DataOut	= actions[i].value;
	    AddressOut	= actions[i].address;
	}
	else
	{
	    nRW		= 0;
	    DataOut	= 0;
	    AddressOut	= 0;
	}

	do
	{
	    JTAG_DEBUG("SC7 <= Address %02x  Data %08x    nRW %d", AddressOut, DataOut, nRW);

	    arm11_add_dr_scan_vc(asizeof(chain7_fields), chain7_fields, TAP_DRPAUSE);
	    jtag_execute_queue();

	    JTAG_DEBUG("SC7 => Address %02x  Data %08x  Ready %d", AddressIn, DataIn, Ready);
	}
	while (!Ready); /* 'nRW' is 'Ready' on read out */

	if (i > 0)
	{
	    if (actions[i - 1].address != AddressIn)
	    {
		LOG_WARNING("Scan chain 7 shifted out unexpected address");
	    }

	    if (!actions[i - 1].write)
	    {
		actions[i - 1].value = DataIn;
	    }
	    else
	    {
		if (actions[i - 1].value != DataIn)
		{
		    LOG_WARNING("Scan chain 7 shifted out unexpected data");
		}
	    }
	}
    }}

    {size_t i;
    for (i = 0; i < count; i++)
    {
	JTAG_DEBUG("SC7 %02d: %02x %s %08x", i, actions[i].address, actions[i].write ? "<=" : "=>", actions[i].value);
    }}
}
示例#11
0
/** Cleanup after ITR/DTR operations
 * from the arm11_run_instr... group of functions
 *
 * Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish()
 * around a block of arm11_run_instr_... calls.
 *
 * Any IDLE can lead to an instruction execution when
 * scan chains 4 or 5 are selected and the IR holds
 * INTEST or EXTEST. So we must disable that before
 * any following activities lead to an IDLE.
 *
 * \param arm11 Target state variable.
 *
 */
void arm11_run_instr_data_finish(arm11_common_t * arm11)
{
    arm11_add_debug_SCAN_N(arm11, 0x00, -1);
}
示例#12
0
/** Prepare the stage for ITR/DTR operations
 * from the arm11_run_instr... group of functions.
 *
 * Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish()
 * around a block of arm11_run_instr_... calls.
 *
 * Select scan chain 5 to allow quick access to DTR. When scan
 * chain 4 is needed to put in a register the ITRSel instruction
 * shortcut is used instead of actually changing the Scan_N
 * register.
 *
 * \param arm11 Target state variable.
 *
 */
void arm11_run_instr_data_prepare(arm11_common_t * arm11)
{
    arm11_add_debug_SCAN_N(arm11, 0x05, -1);
}