Esempio n. 1
0
/** Execute one instruction via ITR repeatedly while
 *  reading data from the core via DTR on each execution.
 *
 *  The executed instruction \em must write data to DTR.
 *
 * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
 *
 * \param arm11		Target state variable.
 * \param opcode	ARM opcode
 * \param data		Pointer to an array that receives the data words from the core
 * \param count		Number of data words and instruction repetitions
 *
 */
void arm11_run_instr_data_from_core(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count)
{
    arm11_add_IR(arm11, ARM11_ITRSEL, -1);

    arm11_add_debug_INST(arm11, opcode, NULL, TAP_IDLE);

    arm11_add_IR(arm11, ARM11_INTEST, -1);

    scan_field_t	chain5_fields[3];

    u32			Data;
    u8			Ready;
    u8			nRetry;

    arm11_setup_field(arm11, 32,    NULL,	&Data,	    chain5_fields + 0);
    arm11_setup_field(arm11,  1,    NULL,	&Ready,	    chain5_fields + 1);
    arm11_setup_field(arm11,  1,    NULL,	&nRetry,    chain5_fields + 2);

    while (count--)
    {
	do
	{
	    arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, count ? TAP_IDLE : TAP_DRPAUSE);
	    jtag_execute_queue();

	    JTAG_DEBUG("DTR  Data %08x  Ready %d  nRetry %d", Data, Ready, nRetry);
	}
	while (!Ready);

	*data++ = Data;
    }
}
Esempio n. 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.
 */
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;
}
Esempio n. 3
0
int arm11_add_debug_SCAN_N(struct arm11_common *arm11,
		uint8_t chain, tap_state_t state)
{
	/* Don't needlessly switch the scan chain.
	 * NOTE:  the ITRSEL instruction fakes SCREG changing;
	 * but leaves its actual value unchanged.
	 */
	if (arm11->jtag_info.cur_scan_chain == chain) {
		JTAG_DEBUG("SCREG <= %d SKIPPED", chain);
		return jtag_add_statemove((state == ARM11_TAP_DEFAULT)
					? TAP_DRPAUSE : state);
	}
	JTAG_DEBUG("SCREG <= %d", chain);

	arm11_add_IR(arm11, ARM11_SCAN_N, ARM11_TAP_DEFAULT);

	struct scan_field		field;

	uint8_t tmp[1];
	arm11_setup_field(arm11, 5, &chain, &tmp, &field);

	arm11_add_dr_scan_vc(1, &field, state == ARM11_TAP_DEFAULT ? TAP_DRPAUSE : state);

	jtag_execute_queue_noclear();

	arm11_in_handler_SCAN_N(tmp);

	arm11->jtag_info.cur_scan_chain = chain;

	return jtag_execute_queue();
}
Esempio n. 4
0
/** Execute one instruction via ITR repeatedly while
 *  passing data to the core via DTR on each execution.
 *
 *  No Ready check during transmission.
 *
 *  The executed instruction \em must read data from DTR.
 *
 * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
 *
 * \param arm11		Target state variable.
 * \param opcode	ARM opcode
 * \param data		Pointer to the data words to be passed to the core
 * \param count		Number of data words and instruction repetitions
 *
 */
void arm11_run_instr_data_to_core_noack(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count)
{
    arm11_add_IR(arm11, ARM11_ITRSEL, -1);

    arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE);

    arm11_add_IR(arm11, ARM11_EXTEST, -1);

    scan_field_t	chain5_fields[3];

    arm11_setup_field(arm11, 32,    NULL/*&Data*/,  NULL,	chain5_fields + 0);
    arm11_setup_field(arm11,  1,    NULL,   NULL /*&Ready*/,	chain5_fields + 1);
    arm11_setup_field(arm11,  1,    NULL,   NULL,	chain5_fields + 2);

    u8			Readies[count + 1];
    u8	*		ReadyPos	    = Readies;

    while (count--)
    {
	chain5_fields[0].out_value	= (void *)(data++);
	chain5_fields[1].in_value	= ReadyPos++;

	if (count)
	{
	    jtag_add_dr_scan(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);
	    jtag_add_pathmove(asizeof(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay),
		arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay);
	}
	else
	{
	    jtag_add_dr_scan(asizeof(chain5_fields), chain5_fields, TAP_IDLE);
	}
    }

    arm11_add_IR(arm11, ARM11_INTEST, -1);

    chain5_fields[0].out_value	= 0;
    chain5_fields[1].in_value   = ReadyPos++;

    arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE);

    jtag_execute_queue();

    size_t error_count = 0;

    {size_t i;
    for (i = 0; i < asizeof(Readies); i++)
    {
	if (Readies[i] != 1)
	{
	    error_count++;
	}
    }}

    if (error_count)
	LOG_ERROR("Transfer errors " ZU, error_count);
}
Esempio n. 5
0
/** Write an instruction into the ITR register
 *
 * \param arm11	Target state variable.
 * \param inst	An ARM11 processor instruction/opcode.
 * \param flag	Optional parameter to retrieve the InstCompl flag
 *		(this will be written when the JTAG chain is executed).
 * \param state	Pass the final TAP state or -1 for the default
 *		value (Run-Test/Idle).
 *
 * \remarks By default this ends with Run-Test/Idle state
 * and causes the instruction to be executed. If
 * a subsequent write to DTR is needed before
 * executing the instruction then TAP_DRPAUSE should be
 * passed to \p state.
 *
 * \remarks This adds to the JTAG command queue but does \em not execute it.
 */
void arm11_add_debug_INST(arm11_common_t * arm11, u32 inst, u8 * flag, tap_state_t state)
{
    JTAG_DEBUG("INST <= 0x%08x", inst);

    scan_field_t		itr[2];

    arm11_setup_field(arm11, 32,    &inst,	NULL, itr + 0);
    arm11_setup_field(arm11, 1,	    NULL,	flag, itr + 1);

    arm11_add_dr_scan_vc(asizeof(itr), itr, state == -1 ? TAP_IDLE : state);
}
Esempio n. 6
0
/** Execute one instruction via ITR repeatedly while
 *  reading data from the core via DTR on each execution.
 *
 * Caller guarantees that processor is in debug state, that DSCR_ITR_EN
 * is set, the ITR Ready flag is set (as seen on the previous entry to
 * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear.
 *
 *  The executed instruction \em must write data to DTR.
 *
 * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
 *
 * \param arm11		Target state variable.
 * \param opcode	ARM opcode
 * \param data		Pointer to an array that receives the data words from the core
 * \param count		Number of data words and instruction repetitions
 *
 */
int arm11_run_instr_data_from_core(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count)
{
	arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);

	arm11_add_debug_INST(arm11, opcode, NULL, TAP_IDLE);

	arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);

	struct scan_field	chain5_fields[3];

	uint32_t			Data;
	uint8_t			Ready;
	uint8_t			nRetry;

	arm11_setup_field(arm11, 32,    NULL,	&Data,	    chain5_fields + 0);
	arm11_setup_field(arm11,  1,    NULL,	&Ready,	    chain5_fields + 1);
	arm11_setup_field(arm11,  1,    NULL,	&nRetry,    chain5_fields + 2);

	while (count--)
	{
		int i = 0;
		do
		{
			arm11_add_dr_scan_vc(ARRAY_SIZE(chain5_fields), chain5_fields, count ? TAP_IDLE : TAP_DRPAUSE);

			CHECK_RETVAL(jtag_execute_queue());

			JTAG_DEBUG("DTR  Data %08x  Ready %d  nRetry %d",
					(unsigned) Data, Ready, nRetry);

			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++;
		}
		while (!Ready);

		*data++ = Data;
	}

	return ERROR_OK;
}
Esempio n. 7
0
/**
 * Queue a DR scan of the ITR register.  Caller must have selected
 * scan chain 4 (ITR), possibly using ITRSEL.
 *
 * \param arm11		Target state variable.
 * \param inst		An ARM11 processor instruction/opcode.
 * \param flag		Optional parameter to retrieve the Ready flag;
 *	this address will be written when the JTAG chain is scanned.
 * \param state		The TAP state to enter after the DR scan.
 *
 * Going through the TAP_DRUPDATE state writes ITR only if Ready was
 * previously set.  Only the Ready flag is readable by the scan.
 *
 * An instruction loaded into ITR is executed when going through the
 * TAP_IDLE state only if Ready was previously set and the debug state
 * is properly set up.  Depending on the instruction, you may also need
 * to ensure that the rDTR is ready before that Run-Test/Idle state.
 */
static void arm11_add_debug_INST(struct arm11_common * arm11,
		uint32_t inst, uint8_t * flag, tap_state_t state)
{
	JTAG_DEBUG("INST <= 0x%08x", (unsigned) inst);

	struct scan_field		itr[2];

	arm11_setup_field(arm11, 32,    &inst,	NULL, itr + 0);
	arm11_setup_field(arm11, 1,	    NULL,	flag, itr + 1);

	arm11_add_dr_scan_vc(ARRAY_SIZE(itr), itr, state);
}
Esempio n. 8
0
void arm11_add_debug_SCAN_N(arm11_common_t * arm11, u8 chain, tap_state_t state)
{
    JTAG_DEBUG("SCREG <= 0x%02x", chain);

    arm11_add_IR(arm11, ARM11_SCAN_N, -1);

    scan_field_t		field;

    arm11_setup_field(arm11, 5, &chain, NULL, &field);

    field.in_handler = arm11_in_handler_SCAN_N;

    arm11_add_dr_scan_vc(1, &field, state == -1 ? TAP_DRPAUSE : state);
}
Esempio n. 9
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;
}
Esempio n. 10
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;
}
Esempio n. 11
0
/** Execute one instruction via ITR repeatedly while
 *  passing data to the core via DTR on each execution.
 *
 * Caller guarantees that processor is in debug state, that DSCR_ITR_EN
 * is set, the ITR Ready flag is set (as seen on the previous entry to
 * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear.
 *
 *  No Ready check during transmission.
 *
 *  The executed instruction \em must read data from DTR.
 *
 * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
 *
 * \param arm11		Target state variable.
 * \param opcode	ARM opcode
 * \param data		Pointer to the data words to be passed to the core
 * \param count		Number of data words and instruction repetitions
 *
 */
int arm11_run_instr_data_to_core_noack(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count)
{
	arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);

	arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE);

	arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);

	int retval = arm11_run_instr_data_to_core_noack_inner(arm11->arm.target->tap, opcode, data, count);

	if (retval != ERROR_OK)
		return retval;

	arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);

	struct scan_field	chain5_fields[3];

	arm11_setup_field(arm11, 32,    NULL/*&Data*/,  NULL,				chain5_fields + 0);
	arm11_setup_field(arm11,  1,    NULL,			NULL /*&Ready*/,	chain5_fields + 1);
	arm11_setup_field(arm11,  1,    NULL,			NULL,				chain5_fields + 2);

	uint8_t ready_flag;
	chain5_fields[1].in_value   = &ready_flag;

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

	retval = jtag_execute_queue();
	if (retval == ERROR_OK)
	{
		if (ready_flag != 1)
		{
			LOG_ERROR("last word not transferred");
			retval = ERROR_FAIL;
		}
	}

	return retval;
}
Esempio n. 12
0
int arm11_add_debug_SCAN_N(struct arm11_common *arm11,
		uint8_t chain, tap_state_t state)
{
	/* Don't needlessly switch the scan chain.
	 * NOTE:  the ITRSEL instruction fakes SCREG changing;
	 * but leaves its actual value unchanged.
	 */
#if 0
	// FIX!!! the optimization below is broken because we do not
	// invalidate the cur_scan_chain upon a TRST/TMS. See arm_jtag.c
	// for example on how to invalidate cur_scan_chain. Tested patches gladly
	// accepted!
	if (arm11->jtag_info.cur_scan_chain == chain) {
		JTAG_DEBUG("SCREG <= %d SKIPPED", chain);
		return jtag_add_statemove((state == ARM11_TAP_DEFAULT)
					? TAP_DRPAUSE : state);
	}
#endif
	JTAG_DEBUG("SCREG <= %d", chain);

	arm11_add_IR(arm11, ARM11_SCAN_N, ARM11_TAP_DEFAULT);

	struct scan_field		field;

	uint8_t tmp[1];
	arm11_setup_field(arm11, 5, &chain, &tmp, &field);

	arm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &field, state == ARM11_TAP_DEFAULT ? TAP_DRPAUSE : state);

	jtag_execute_queue_noclear();

	arm11_in_handler_SCAN_N(tmp);

	arm11->jtag_info.cur_scan_chain = chain;

	return jtag_execute_queue();
}
Esempio n. 13
0
/** Execute one instruction via ITR repeatedly while
 *  passing data to the core via DTR on each execution.
 *
 * Caller guarantees that processor is in debug state, that DSCR_ITR_EN
 * is set, the ITR Ready flag is set (as seen on the previous entry to
 * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear.
 *
 *  No Ready check during transmission.
 *
 *  The executed instruction \em must read data from DTR.
 *
 * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
 *
 * \param arm11		Target state variable.
 * \param opcode	ARM opcode
 * \param data		Pointer to the data words to be passed to the core
 * \param count		Number of data words and instruction repetitions
 *
 */
int arm11_run_instr_data_to_core_noack(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count)
{
	arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);

	arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE);

	arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);

	struct scan_field	chain5_fields[3];

	arm11_setup_field(arm11, 32,    NULL/*&Data*/,  NULL,				chain5_fields + 0);
	arm11_setup_field(arm11,  1,    NULL,			NULL /*&Ready*/,	chain5_fields + 1);
	arm11_setup_field(arm11,  1,    NULL,			NULL,				chain5_fields + 2);

	uint8_t			*Readies;
	unsigned readiesNum = count + 1;
	unsigned bytes = sizeof(*Readies)*readiesNum;

	Readies = (uint8_t *) malloc(bytes);
	if (Readies == NULL)
	{
		LOG_ERROR("Out of memory allocating %u bytes", bytes);
		return ERROR_FAIL;
	}

	uint8_t	*		ReadyPos			= Readies;

	while (count--)
	{
		chain5_fields[0].out_value	= (void *)(data++);
		chain5_fields[1].in_value	= ReadyPos++;

		if (count)
		{
			jtag_add_dr_scan(ARRAY_SIZE(chain5_fields), chain5_fields, jtag_set_end_state(TAP_DRPAUSE));
			jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay),
				arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay);
		}
		else
		{
			jtag_add_dr_scan(ARRAY_SIZE(chain5_fields), chain5_fields, jtag_set_end_state(TAP_IDLE));
		}
	}

	arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);

	chain5_fields[0].out_value	= 0;
	chain5_fields[1].in_value   = ReadyPos++;

	arm11_add_dr_scan_vc(ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE);

	int retval = jtag_execute_queue();
	if (retval == ERROR_OK)
	{
		unsigned error_count = 0;

		for (size_t i = 0; i < readiesNum; i++)
		{
			if (Readies[i] != 1)
			{
				error_count++;
			}
		}

		if (error_count > 0 )
			LOG_ERROR("%u words out of %u not transferred",
				error_count, readiesNum);

	}

	free(Readies);

	return retval;
}
Esempio n. 14
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;
}
Esempio n. 15
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;
}
Esempio n. 16
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);
    }}
}
Esempio n. 17
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;
}
Esempio n. 18
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;
}