Example #1
0
void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
{
	int retval = ERROR_OK;
	/* 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;

	/* save r0 before using it and put system in ARM state
	 * to allow common handling of ARM and THUMB debugging */

	/* fetch STR r0, [r0] */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
	/* STR r0, [r0] in Memory */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);

	/* MOV r0, r15 fetched, STR in Decode */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
	/* nothing fetched, STR r0, [r0] in Memory */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);

	/* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
	/* LDR in Decode */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
	/* LDR in Execute */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
	/* LDR in Memory (to account for interlock) */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);

	/* fetch BX */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0);
	/* NOP fetched, BX in Decode, MOV in Execute */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
	/* NOP fetched, BX in Execute (1) */
	arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);

	if((retval = jtag_execute_queue()) != ERROR_OK)
	{
		return;
	}

	/* fix program counter:
	 * MOV r0, r15 was the 5th instruction (+8)
	 * reading PC in Thumb state gives address of instruction + 4
	 */
	*pc -= 0xc;
}
Example #2
0
static void arm7tdmi_change_to_arm(struct target *target,
		uint32_t *r0, uint32_t *pc)
{
	struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
	struct arm_jtag *jtag_info = &arm7_9->jtag_info;

	/* save r0 before using it and put system in ARM state
	 * to allow common handling of ARM and THUMB debugging */

	/* fetch STR r0, [r0] */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
	/* nothing fetched, STR r0, [r0] in Execute (2) */
	arm7tdmi_clock_data_in(jtag_info, r0);

	/* MOV r0, r15 fetched, STR in Decode */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), NULL, 0);
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
	/* nothing fetched, STR r0, [r0] in Execute (2) */
	arm7tdmi_clock_data_in(jtag_info, pc);

	/* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
	/* nothing fetched, data for LDR r0, [PC, #0] */
	arm7tdmi_clock_out(jtag_info, 0x0, NULL, 0);
	/* nothing fetched, data from previous cycle is written to register */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);

	/* fetch BX */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), NULL, 0);
	/* NOP fetched, BX in Decode, MOV in Execute */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
	/* NOP fetched, BX in Execute (1) */
	arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);

	jtag_execute_queue();

	/* fix program counter:
	 * MOV r0, r15 was the 4th instruction (+6)
	 * reading PC in Thumb state gives address of instruction + 4
	 */
	*pc -= 0xa;
}