diff options
Diffstat (limited to 'src/target')
-rw-r--r-- | src/target/arm7tdmi.c | 20 | ||||
-rw-r--r-- | src/target/arm920t.c | 3 | ||||
-rw-r--r-- | src/target/arm9tdmi.c | 14 | ||||
-rw-r--r-- | src/target/armv4_5.h | 13 |
4 files changed, 35 insertions, 15 deletions
diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index 0a6caeac..11595244 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -347,8 +347,14 @@ void arm7tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc) /* nothing fetched, STR r0, [r0] in Execute (2) */ arm7tdmi_clock_data_in(jtag_info, pc); - /* fetch MOV */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV_IM(0, 0x0), NULL, 0); + /* 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); @@ -702,11 +708,9 @@ void arm7tdmi_branch_resume_thumb(target_t *target) /* target is now in Thumb state */ embeddedice_read_reg(dbg_stat); - /* clean r0 bits to avoid alignment problems */ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV_IM(0, 0x0), NULL, 0); - /* load r0 value, MOV_IM in Decode*/ - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR(0, 0), NULL, 0); - /* fetch NOP, LDR in Decode, MOV_IM in Execute */ + /* load r0 value */ + arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0); + /* fetch NOP, LDR in Decode */ arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); /* fetch NOP, LDR in Execute */ arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); @@ -721,7 +725,7 @@ void arm7tdmi_branch_resume_thumb(target_t *target) embeddedice_read_reg(dbg_stat); arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 1); - arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), NULL, 0); + arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f8), NULL, 0); } diff --git a/src/target/arm920t.c b/src/target/arm920t.c index 91dbb29b..97a08811 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -454,6 +454,9 @@ void arm920t_post_debug_entry(target_t *target) arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr); arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far); arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far); + + DEBUG("D FSR: 0x%8.8x, D FAR: 0x%8.8x, I FSR: 0x%8.8x, I FAR: 0x%8.8x", + arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far); if (arm920t->preserve_cache) { diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index c99fcb2a..7584a8bb 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -393,9 +393,13 @@ void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc) /* nothing fetched, STR r0, [r0] in Memory */ arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0); - /* fetch MOV */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV_IM(0, 0x0), 0, NULL, 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 */ @@ -754,10 +758,8 @@ void arm9tdmi_branch_resume_thumb(target_t *target) /* target is now in Thumb state */ embeddedice_read_reg(dbg_stat); - /* clean r0 bits to avoid alignment problems */ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV_IM(0, 0x0), 0, NULL, 0); /* load r0 value, MOV_IM in Decode*/ - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR(0, 0), 0, NULL, 0); + arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0); /* fetch NOP, LDR in Decode, MOV_IM in Execute */ arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); /* fetch NOP, LDR in Execute */ @@ -772,7 +774,7 @@ void arm9tdmi_branch_resume_thumb(target_t *target) embeddedice_read_reg(dbg_stat); - arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f6), 0, NULL, 1); + arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), 0, NULL, 1); arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); } diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h index ee37723e..0472155b 100644 --- a/src/target/armv4_5.h +++ b/src/target/armv4_5.h @@ -229,6 +229,17 @@ extern int armv4_5_invalidate_core_regs(target_t *target); */ #define ARMV4_5_T_LDR(Rd, Rn) ((0x6800 | (Rn << 3) | Rd) | ((0x6800 | (Rn << 3) | Rd) << 16)) +/* Load multiple (Thumb state) + * Rn: base register + * List: for each bit in list: store register + */ +#define ARMV4_5_T_LDMIA(Rn, List) ((0xc800 | (Rn << 8) | List) | ((0xc800 | (Rn << 8) | List) << 16)) + +/* Load register with PC relative addressing + * Rd: register to load + */ +#define ARMV4_5_T_LDR_PCREL(Rd) ((0x4800 | (Rd << 8)) | ((0x4800 | (Rd << 8)) << 16)) + /* Move hi register (Thumb mode) * Rd: destination register * Rm: source register @@ -237,7 +248,7 @@ extern int armv4_5_invalidate_core_regs(target_t *target); /* No operation (Thumb mode) */ -#define ARMV4_5_T_NOP (0x1c3f | (0x1c3f << 16)) +#define ARMV4_5_T_NOP (0x46c0 | (0x46c0 << 16)) /* Move immediate to register (Thumb state) * Rd: destination register |