Example #1
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();
}
Example #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;
}
Example #3
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;
    }
}
Example #4
0
/** Write JTAG instruction register
 *
 * \param arm11		Target state variable.
 * \param instr		An ARM11 DBGTAP instruction. Use enum #arm11_instructions.
 * \param state		Pass the final TAP state or ARM11_TAP_DEFAULT for the default value (Pause-IR).
 *
 * \remarks			This adds to the JTAG command queue but does \em not execute it.
 */
void arm11_add_IR(struct arm11_common * arm11, uint8_t instr, tap_state_t state)
{
	struct jtag_tap *tap = arm11->arm.target->tap;

	if (buf_get_u32(tap->cur_instr, 0, 5) == instr)
	{
		JTAG_DEBUG("IR <= 0x%02x SKIPPED", instr);
		return;
	}

	JTAG_DEBUG("IR <= %s (0x%02x)", arm11_ir_to_string(instr), instr);

	struct scan_field field;

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

	arm11_add_ir_scan_vc(1, &field, state == ARM11_TAP_DEFAULT ? TAP_IRPAUSE : state);
}
Example #5
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;
}
Example #6
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);
}
Example #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);
}
Example #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);
}
Example #9
0
/** Verify shifted out data from Scan Chain Register (SCREG)
 *  Used as parameter to scan_field_t::in_handler in
 *  arm11_add_debug_SCAN_N().
 *
 */
static int arm11_in_handler_SCAN_N(u8 *in_value, void *priv, struct scan_field_s *field)
{
    /** \todo TODO: clarify why this isnt properly masked in jtag.c jtag_read_buffer() */
    u8 v = *in_value & 0x1F;

    if (v != 0x10)
    {
	LOG_ERROR("'arm11 target' JTAG communication error SCREG SCAN OUT 0x%02x (expected 0x10)", v);
	return ERROR_FAIL;
    }

    JTAG_DEBUG("SCREG SCAN OUT 0x%02x", v);
    return ERROR_OK;
}
Example #10
0
/** Write JTAG instruction register
 *
 * \param arm11 Target state variable.
 * \param instr An ARM11 DBGTAP instruction. Use enum #arm11_instructions.
 * \param state Pass the final TAP state or -1 for the default value (Pause-IR).
 *
 * \remarks This adds to the JTAG command queue but does \em not execute it.
 */
void arm11_add_IR(arm11_common_t * arm11, u8 instr, tap_state_t state)
{
	jtag_tap_t *tap;
	tap = arm11->jtag_info.tap;
	if(  tap == NULL ){
	/* FIX!!!! error is logged, but not propagated back up the call stack... */
		LOG_ERROR( "tap is null here! This is bad!");
		return;
    }

    if (buf_get_u32(tap->cur_instr, 0, 5) == instr){
		JTAG_DEBUG("IR <= 0x%02x SKIPPED", instr);
		return;
    }

    JTAG_DEBUG("IR <= 0x%02x", instr);

    scan_field_t field;

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

    arm11_add_ir_scan_vc(1, &field, state == -1 ? TAP_IRPAUSE : state);
}
Example #11
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();
}
Example #12
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;
}
Example #13
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;
}
Example #14
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;
}
Example #15
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);
    }}
}