ARM: keep a handle to the PC
Keep a handle to the PC in "struct arm", and use it. This register is used a fair amount, so this is a net minor code shrink (other than some line length fixes), but mostly it's to make things more readable. For XScale, fix a dodgy sequence while stepping. It was initializing a variable to a non-NULL value, then updating it to handle the step-over-active-breakpoint case, and then later testing for non-NULL to see if it should reverse that step-over-active logic. It should have done like ARM7/ARM9 does: init to NULL. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
This commit is contained in:
parent
a299371a9e
commit
1aac72d243
|
@ -95,6 +95,9 @@ struct arm {
|
||||||
int common_magic;
|
int common_magic;
|
||||||
struct reg_cache *core_cache;
|
struct reg_cache *core_cache;
|
||||||
|
|
||||||
|
/** Handle to the PC; valid in all core modes. */
|
||||||
|
struct reg *pc;
|
||||||
|
|
||||||
/** Handle to the CPSR; valid in all core modes. */
|
/** Handle to the CPSR; valid in all core modes. */
|
||||||
struct reg *cpsr;
|
struct reg *cpsr;
|
||||||
|
|
||||||
|
|
|
@ -451,7 +451,7 @@ static int arm11_halt(struct target *target)
|
||||||
static uint32_t
|
static uint32_t
|
||||||
arm11_nextpc(struct arm11_common *arm11, int current, uint32_t address)
|
arm11_nextpc(struct arm11_common *arm11, int current, uint32_t address)
|
||||||
{
|
{
|
||||||
void *value = arm11->arm.core_cache->reg_list[15].value;
|
void *value = arm11->arm.pc->value;
|
||||||
|
|
||||||
if (!current)
|
if (!current)
|
||||||
buf_set_u32(value, 0, 32, address);
|
buf_set_u32(value, 0, 32, address);
|
||||||
|
|
|
@ -361,9 +361,9 @@ static int arm720t_soft_reset_halt(struct target *target)
|
||||||
armv4_5->cpsr->dirty = 1;
|
armv4_5->cpsr->dirty = 1;
|
||||||
|
|
||||||
/* start fetching from 0x0 */
|
/* start fetching from 0x0 */
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
|
buf_set_u32(armv4_5->pc->value, 0, 32, 0x0);
|
||||||
armv4_5->core_cache->reg_list[15].dirty = 1;
|
armv4_5->pc->dirty = 1;
|
||||||
armv4_5->core_cache->reg_list[15].valid = 1;
|
armv4_5->pc->valid = 1;
|
||||||
|
|
||||||
arm720t_disable_mmu_caches(target, 1, 1, 1);
|
arm720t_disable_mmu_caches(target, 1, 1, 1);
|
||||||
arm720t->armv4_5_mmu.mmu_enabled = 0;
|
arm720t->armv4_5_mmu.mmu_enabled = 0;
|
||||||
|
|
|
@ -1235,9 +1235,9 @@ int arm7_9_soft_reset_halt(struct target *target)
|
||||||
armv4_5->cpsr->dirty = 1;
|
armv4_5->cpsr->dirty = 1;
|
||||||
|
|
||||||
/* start fetching from 0x0 */
|
/* start fetching from 0x0 */
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
|
buf_set_u32(armv4_5->pc->value, 0, 32, 0x0);
|
||||||
armv4_5->core_cache->reg_list[15].dirty = 1;
|
armv4_5->pc->dirty = 1;
|
||||||
armv4_5->core_cache->reg_list[15].valid = 1;
|
armv4_5->pc->valid = 1;
|
||||||
|
|
||||||
/* reset registers */
|
/* reset registers */
|
||||||
for (i = 0; i <= 14; i++)
|
for (i = 0; i <= 14; i++)
|
||||||
|
@ -1721,9 +1721,10 @@ int arm7_9_restore_context(struct target *target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* restore PC */
|
/* restore PC */
|
||||||
LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
LOG_DEBUG("writing PC with value 0x%8.8" PRIx32,
|
||||||
arm7_9->write_pc(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
armv4_5->core_cache->reg_list[15].dirty = 0;
|
arm7_9->write_pc(target, buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
|
armv4_5->pc->dirty = 0;
|
||||||
|
|
||||||
if (arm7_9->post_restore_context)
|
if (arm7_9->post_restore_context)
|
||||||
arm7_9->post_restore_context(target);
|
arm7_9->post_restore_context(target);
|
||||||
|
@ -1815,15 +1816,17 @@ int arm7_9_resume(struct target *target, int current, uint32_t address, int hand
|
||||||
|
|
||||||
/* current = 1: continue on current pc, otherwise continue at <address> */
|
/* current = 1: continue on current pc, otherwise continue at <address> */
|
||||||
if (!current)
|
if (!current)
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
|
buf_set_u32(armv4_5->pc->value, 0, 32, address);
|
||||||
|
|
||||||
uint32_t current_pc;
|
uint32_t current_pc;
|
||||||
current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
|
|
||||||
/* the front-end may request us not to handle breakpoints */
|
/* the front-end may request us not to handle breakpoints */
|
||||||
if (handle_breakpoints)
|
if (handle_breakpoints)
|
||||||
{
|
{
|
||||||
if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
|
breakpoint = breakpoint_find(target,
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
|
if (breakpoint != NULL)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (id: %d)", breakpoint->address, breakpoint->unique_id );
|
LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (id: %d)", breakpoint->address, breakpoint->unique_id );
|
||||||
if ((retval = arm7_9_unset_breakpoint(target, breakpoint)) != ERROR_OK)
|
if ((retval = arm7_9_unset_breakpoint(target, breakpoint)) != ERROR_OK)
|
||||||
|
@ -1881,7 +1884,8 @@ int arm7_9_resume(struct target *target, int current, uint32_t address, int hand
|
||||||
}
|
}
|
||||||
|
|
||||||
arm7_9_debug_entry(target);
|
arm7_9_debug_entry(target);
|
||||||
LOG_DEBUG("new PC after step: 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
LOG_DEBUG("new PC after step: 0x%8.8" PRIx32,
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
|
|
||||||
LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
|
LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
|
||||||
if ((retval = arm7_9_set_breakpoint(target, breakpoint)) != ERROR_OK)
|
if ((retval = arm7_9_set_breakpoint(target, breakpoint)) != ERROR_OK)
|
||||||
|
@ -1957,7 +1961,7 @@ void arm7_9_enable_eice_step(struct target *target, uint32_t next_pc)
|
||||||
struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
|
struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
|
||||||
struct arm *armv4_5 = &arm7_9->armv4_5_common;
|
struct arm *armv4_5 = &arm7_9->armv4_5_common;
|
||||||
uint32_t current_pc;
|
uint32_t current_pc;
|
||||||
current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
|
|
||||||
if (next_pc != current_pc)
|
if (next_pc != current_pc)
|
||||||
{
|
{
|
||||||
|
@ -2019,16 +2023,16 @@ int arm7_9_step(struct target *target, int current, uint32_t address, int handle
|
||||||
|
|
||||||
/* current = 1: continue on current pc, otherwise continue at <address> */
|
/* current = 1: continue on current pc, otherwise continue at <address> */
|
||||||
if (!current)
|
if (!current)
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
|
buf_set_u32(armv4_5->pc->value, 0, 32, address);
|
||||||
|
|
||||||
uint32_t current_pc;
|
uint32_t current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
|
||||||
|
|
||||||
/* the front-end may request us not to handle breakpoints */
|
/* the front-end may request us not to handle breakpoints */
|
||||||
if (handle_breakpoints)
|
if (handle_breakpoints)
|
||||||
if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
|
breakpoint = breakpoint_find(target, current_pc);
|
||||||
if ((retval = arm7_9_unset_breakpoint(target, breakpoint)) != ERROR_OK)
|
if (breakpoint != NULL) {
|
||||||
{
|
retval = arm7_9_unset_breakpoint(target, breakpoint);
|
||||||
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -598,7 +598,8 @@ static void arm7tdmi_branch_resume_thumb(struct target *target)
|
||||||
/* fetch NOP, LDM in EXECUTE stage (1st cycle) */
|
/* fetch NOP, LDM in EXECUTE stage (1st cycle) */
|
||||||
arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
|
arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
|
||||||
/* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
|
/* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
|
||||||
arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
|
arm7tdmi_clock_out(jtag_info,
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32) | 1, NULL, 0);
|
||||||
/* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
|
/* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
|
||||||
arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
|
arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
|
||||||
|
|
||||||
|
|
|
@ -777,9 +777,9 @@ int arm920t_soft_reset_halt(struct target *target)
|
||||||
armv4_5->cpsr->dirty = 1;
|
armv4_5->cpsr->dirty = 1;
|
||||||
|
|
||||||
/* start fetching from 0x0 */
|
/* start fetching from 0x0 */
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
|
buf_set_u32(armv4_5->pc->value, 0, 32, 0x0);
|
||||||
armv4_5->core_cache->reg_list[15].dirty = 1;
|
armv4_5->pc->dirty = 1;
|
||||||
armv4_5->core_cache->reg_list[15].valid = 1;
|
armv4_5->pc->valid = 1;
|
||||||
|
|
||||||
arm920t_disable_mmu_caches(target, 1, 1, 1);
|
arm920t_disable_mmu_caches(target, 1, 1, 1);
|
||||||
arm920t->armv4_5_mmu.mmu_enabled = 0;
|
arm920t->armv4_5_mmu.mmu_enabled = 0;
|
||||||
|
|
|
@ -569,9 +569,9 @@ int arm926ejs_soft_reset_halt(struct target *target)
|
||||||
armv4_5->cpsr->dirty = 1;
|
armv4_5->cpsr->dirty = 1;
|
||||||
|
|
||||||
/* start fetching from 0x0 */
|
/* start fetching from 0x0 */
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
|
buf_set_u32(armv4_5->pc->value, 0, 32, 0x0);
|
||||||
armv4_5->core_cache->reg_list[15].dirty = 1;
|
armv4_5->pc->dirty = 1;
|
||||||
armv4_5->core_cache->reg_list[15].valid = 1;
|
armv4_5->pc->valid = 1;
|
||||||
|
|
||||||
arm926ejs_disable_mmu_caches(target, 1, 1, 1);
|
arm926ejs_disable_mmu_caches(target, 1, 1, 1);
|
||||||
arm926ejs->armv4_5_mmu.mmu_enabled = 0;
|
arm926ejs->armv4_5_mmu.mmu_enabled = 0;
|
||||||
|
|
|
@ -677,7 +677,8 @@ static void arm9tdmi_branch_resume_thumb(struct target *target)
|
||||||
/* fetch NOP, LDM in EXECUTE stage (1st cycle) */
|
/* fetch NOP, LDM in EXECUTE stage (1st cycle) */
|
||||||
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
|
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
|
||||||
/* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
|
/* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
|
||||||
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
|
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP,
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32) | 1, NULL, 0);
|
||||||
/* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
|
/* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
|
||||||
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
|
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
|
||||||
|
|
||||||
|
|
|
@ -453,8 +453,8 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
|
||||||
retval = dpm_modeswitch(dpm, ARM_MODE_ANY);
|
retval = dpm_modeswitch(dpm, ARM_MODE_ANY);
|
||||||
arm->cpsr->dirty = false;
|
arm->cpsr->dirty = false;
|
||||||
|
|
||||||
retval = dpm_write_reg(dpm, &cache->reg_list[15], 15);
|
retval = dpm_write_reg(dpm, arm->pc, 15);
|
||||||
cache->reg_list[15].dirty = false;
|
arm->pc->dirty = false;
|
||||||
|
|
||||||
/* flush R0 -- it's *very* dirty by now */
|
/* flush R0 -- it's *very* dirty by now */
|
||||||
retval = dpm_write_reg(dpm, &cache->reg_list[0], 0);
|
retval = dpm_write_reg(dpm, &cache->reg_list[0], 0);
|
||||||
|
|
|
@ -393,8 +393,8 @@ static int do_semihosting(struct target *target)
|
||||||
armv4_5->core_cache->reg_list[0].dirty = 1;
|
armv4_5->core_cache->reg_list[0].dirty = 1;
|
||||||
|
|
||||||
/* LR --> PC */
|
/* LR --> PC */
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, lr);
|
buf_set_u32(armv4_5->pc->value, 0, 32, lr);
|
||||||
armv4_5->core_cache->reg_list[15].dirty = 1;
|
armv4_5->pc->dirty = 1;
|
||||||
|
|
||||||
/* saved PSR --> current PSR */
|
/* saved PSR --> current PSR */
|
||||||
buf_set_u32(armv4_5->cpsr->value, 0, 32, spsr);
|
buf_set_u32(armv4_5->cpsr->value, 0, 32, spsr);
|
||||||
|
@ -429,7 +429,7 @@ int arm_semihosting(struct target *target, int *retval)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */
|
/* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */
|
||||||
r = arm->core_cache->reg_list + 15;
|
r = arm->pc;
|
||||||
pc = buf_get_u32(r->value, 0, 32);
|
pc = buf_get_u32(r->value, 0, 32);
|
||||||
if (pc != 0x00000008 && pc != 0xffff0008)
|
if (pc != 0x00000008 && pc != 0xffff0008)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -577,6 +577,7 @@ struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm)
|
||||||
cache->num_regs++;
|
cache->num_regs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arm->pc = reg_list + 15;
|
||||||
arm->cpsr = reg_list + ARMV4_5_CPSR;
|
arm->cpsr = reg_list + ARMV4_5_CPSR;
|
||||||
arm->core_cache = cache;
|
arm->core_cache = cache;
|
||||||
return cache;
|
return cache;
|
||||||
|
@ -598,8 +599,7 @@ int arm_arch_state(struct target *target)
|
||||||
debug_reason_name(target),
|
debug_reason_name(target),
|
||||||
arm_mode_name(armv4_5->core_mode),
|
arm_mode_name(armv4_5->core_mode),
|
||||||
buf_get_u32(armv4_5->cpsr->value, 0, 32),
|
buf_get_u32(armv4_5->cpsr->value, 0, 32),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[15].value,
|
buf_get_u32(armv4_5->pc->value, 0, 32),
|
||||||
0, 32),
|
|
||||||
armv4_5->is_semihosting ? ", semihosting" : "");
|
armv4_5->is_semihosting ? ", semihosting" : "");
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
@ -1018,11 +1018,10 @@ static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fast exit: ARMv5+ code can use BKPT */
|
/* fast exit: ARMv5+ code can use BKPT */
|
||||||
if (exit_point && buf_get_u32(armv4_5->core_cache->reg_list[15].value,
|
if (exit_point && buf_get_u32(armv4_5->pc->value, 0, 32) != exit_point)
|
||||||
0, 32) != exit_point)
|
|
||||||
{
|
{
|
||||||
LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
|
LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
return ERROR_TARGET_TIMEOUT;
|
return ERROR_TARGET_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -282,7 +282,7 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int
|
||||||
|
|
||||||
/* ARMV7M is always in thumb mode, try to make GDB understand this
|
/* ARMV7M is always in thumb mode, try to make GDB understand this
|
||||||
* if it does not support this arch */
|
* if it does not support this arch */
|
||||||
*((char*)armv7m->core_cache->reg_list[15].value) |= 1;
|
*((char*)armv7m->arm.pc->value) |= 1;
|
||||||
#else
|
#else
|
||||||
(*reg_list)[25] = &armv7m->core_cache->reg_list[ARMV7M_xPSR];
|
(*reg_list)[25] = &armv7m->core_cache->reg_list[ARMV7M_xPSR];
|
||||||
#endif
|
#endif
|
||||||
|
@ -485,7 +485,7 @@ int armv7m_arch_state(struct target *target)
|
||||||
armv7m_mode_strings[armv7m->core_mode],
|
armv7m_mode_strings[armv7m->core_mode],
|
||||||
armv7m_exception_string(armv7m->exception_number),
|
armv7m_exception_string(armv7m->exception_number),
|
||||||
buf_get_u32(arm->cpsr->value, 0, 32),
|
buf_get_u32(arm->cpsr->value, 0, 32),
|
||||||
buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_PC].value, 0, 32),
|
buf_get_u32(arm->pc->value, 0, 32),
|
||||||
(ctrl & 0x02) ? 'p' : 'm',
|
(ctrl & 0x02) ? 'p' : 'm',
|
||||||
sp);
|
sp);
|
||||||
|
|
||||||
|
@ -535,6 +535,7 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target)
|
||||||
}
|
}
|
||||||
|
|
||||||
arm->cpsr = reg_list + ARMV7M_xPSR;
|
arm->cpsr = reg_list + ARMV7M_xPSR;
|
||||||
|
arm->pc = reg_list + ARMV7M_PC;
|
||||||
arm->core_cache = cache;
|
arm->core_cache = cache;
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
@ -708,7 +709,7 @@ int armv7m_blank_check_memory(struct target *target,
|
||||||
int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found)
|
int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found)
|
||||||
{
|
{
|
||||||
struct armv7m_common *armv7m = target_to_armv7m(target);
|
struct armv7m_common *armv7m = target_to_armv7m(target);
|
||||||
struct reg *r = armv7m->core_cache->reg_list + 15;
|
struct reg *r = armv7m->arm.pc;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -695,9 +695,7 @@ static int cortex_a8_resume(struct target *target, int current,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* current = 1: continue on current pc, otherwise continue at <address> */
|
/* current = 1: continue on current pc, otherwise continue at <address> */
|
||||||
resume_pc = buf_get_u32(
|
resume_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
armv4_5->core_cache->reg_list[15].value,
|
|
||||||
0, 32);
|
|
||||||
if (!current)
|
if (!current)
|
||||||
resume_pc = address;
|
resume_pc = address;
|
||||||
|
|
||||||
|
@ -721,10 +719,9 @@ static int cortex_a8_resume(struct target *target, int current,
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
|
LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value,
|
buf_set_u32(armv4_5->pc->value, 0, 32, resume_pc);
|
||||||
0, 32, resume_pc);
|
armv4_5->pc->dirty = 1;
|
||||||
armv4_5->core_cache->reg_list[15].dirty = 1;
|
armv4_5->pc->valid = 1;
|
||||||
armv4_5->core_cache->reg_list[15].valid = 1;
|
|
||||||
|
|
||||||
cortex_a8_restore_context(target, handle_breakpoints);
|
cortex_a8_restore_context(target, handle_breakpoints);
|
||||||
|
|
||||||
|
@ -869,7 +866,7 @@ static int cortex_a8_debug_entry(struct target *target)
|
||||||
regfile[ARM_PC] -= 8;
|
regfile[ARM_PC] -= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = armv4_5->core_cache->reg_list + 15;
|
reg = armv4_5->pc;
|
||||||
buf_set_u32(reg->value, 0, 32, regfile[ARM_PC]);
|
buf_set_u32(reg->value, 0, 32, regfile[ARM_PC]);
|
||||||
reg->dirty = reg->valid;
|
reg->dirty = reg->valid;
|
||||||
}
|
}
|
||||||
|
@ -952,7 +949,7 @@ static int cortex_a8_step(struct target *target, int current, uint32_t address,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* current = 1: continue on current pc, otherwise continue at <address> */
|
/* current = 1: continue on current pc, otherwise continue at <address> */
|
||||||
r = armv4_5->core_cache->reg_list + 15;
|
r = armv4_5->pc;
|
||||||
if (!current)
|
if (!current)
|
||||||
{
|
{
|
||||||
buf_set_u32(r->value, 0, 32, address);
|
buf_set_u32(r->value, 0, 32, address);
|
||||||
|
|
|
@ -427,7 +427,7 @@ static int cortex_m3_debug_entry(struct target *target)
|
||||||
|
|
||||||
LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s",
|
LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s",
|
||||||
armv7m_mode_strings[armv7m->core_mode],
|
armv7m_mode_strings[armv7m->core_mode],
|
||||||
*(uint32_t*)(armv7m->core_cache->reg_list[15].value),
|
*(uint32_t*)(arm->pc->value),
|
||||||
target_state_name(target));
|
target_state_name(target));
|
||||||
|
|
||||||
if (armv7m->post_debug_entry)
|
if (armv7m->post_debug_entry)
|
||||||
|
@ -680,7 +680,7 @@ static int cortex_m3_resume(struct target *target, int current,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* current = 1: continue on current pc, otherwise continue at <address> */
|
/* current = 1: continue on current pc, otherwise continue at <address> */
|
||||||
r = armv7m->core_cache->reg_list + 15;
|
r = armv7m->arm.pc;
|
||||||
if (!current)
|
if (!current)
|
||||||
{
|
{
|
||||||
buf_set_u32(r->value, 0, 32, address);
|
buf_set_u32(r->value, 0, 32, address);
|
||||||
|
@ -749,7 +749,7 @@ static int cortex_m3_step(struct target *target, int current,
|
||||||
struct armv7m_common *armv7m = &cortex_m3->armv7m;
|
struct armv7m_common *armv7m = &cortex_m3->armv7m;
|
||||||
struct swjdp_common *swjdp = &armv7m->swjdp_info;
|
struct swjdp_common *swjdp = &armv7m->swjdp_info;
|
||||||
struct breakpoint *breakpoint = NULL;
|
struct breakpoint *breakpoint = NULL;
|
||||||
struct reg *pc = armv7m->core_cache->reg_list + 15;
|
struct reg *pc = armv7m->arm.pc;
|
||||||
bool bkpt_inst_found = false;
|
bool bkpt_inst_found = false;
|
||||||
|
|
||||||
if (target->state != TARGET_HALTED)
|
if (target->state != TARGET_HALTED)
|
||||||
|
|
|
@ -337,7 +337,7 @@ void feroceon_branch_resume_thumb(struct target *target)
|
||||||
struct arm7_9_common *arm7_9 = armv4_5->arch_info;
|
struct arm7_9_common *arm7_9 = armv4_5->arch_info;
|
||||||
struct arm_jtag *jtag_info = &arm7_9->jtag_info;
|
struct arm_jtag *jtag_info = &arm7_9->jtag_info;
|
||||||
uint32_t r0 = buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32);
|
uint32_t r0 = buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32);
|
||||||
uint32_t pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
uint32_t pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
|
|
||||||
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
|
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
|
||||||
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
|
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
|
||||||
|
@ -519,7 +519,7 @@ int feroceon_bulk_write_memory(struct target *target, uint32_t address, uint32_t
|
||||||
/* backup clobbered processor state */
|
/* backup clobbered processor state */
|
||||||
for (i = 0; i <= 5; i++)
|
for (i = 0; i <= 5; i++)
|
||||||
save[i] = buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32);
|
save[i] = buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32);
|
||||||
save[i] = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
save[i] = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
|
|
||||||
/* set up target address in r0 */
|
/* set up target address in r0 */
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, address);
|
buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, address);
|
||||||
|
@ -572,9 +572,9 @@ int feroceon_bulk_write_memory(struct target *target, uint32_t address, uint32_t
|
||||||
armv4_5->core_cache->reg_list[i].valid = 1;
|
armv4_5->core_cache->reg_list[i].valid = 1;
|
||||||
armv4_5->core_cache->reg_list[i].dirty = 1;
|
armv4_5->core_cache->reg_list[i].dirty = 1;
|
||||||
}
|
}
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, save[i]);
|
buf_set_u32(armv4_5->pc->value, 0, 32, save[i]);
|
||||||
armv4_5->core_cache->reg_list[15].valid = 1;
|
armv4_5->pc->valid = 1;
|
||||||
armv4_5->core_cache->reg_list[15].dirty = 1;
|
armv4_5->pc->dirty = 1;
|
||||||
armv4_5->core_state = core_state;
|
armv4_5->core_state = core_state;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -941,9 +941,9 @@ static int xscale_debug_entry(struct target *target)
|
||||||
LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]);
|
LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]);
|
||||||
|
|
||||||
/* move pc from buffer to register cache */
|
/* move pc from buffer to register cache */
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, buffer[1]);
|
buf_set_u32(armv4_5->pc->value, 0, 32, buffer[1]);
|
||||||
armv4_5->core_cache->reg_list[15].dirty = 1;
|
armv4_5->pc->dirty = 1;
|
||||||
armv4_5->core_cache->reg_list[15].valid = 1;
|
armv4_5->pc->valid = 1;
|
||||||
LOG_DEBUG("pc: 0x%8.8" PRIx32 "", buffer[1]);
|
LOG_DEBUG("pc: 0x%8.8" PRIx32 "", buffer[1]);
|
||||||
|
|
||||||
/* move data from buffer to register cache */
|
/* move data from buffer to register cache */
|
||||||
|
@ -995,7 +995,7 @@ static int xscale_debug_entry(struct target *target)
|
||||||
moe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3);
|
moe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3);
|
||||||
|
|
||||||
/* stored PC (for calculating fixup) */
|
/* stored PC (for calculating fixup) */
|
||||||
pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
|
|
||||||
switch (moe)
|
switch (moe)
|
||||||
{
|
{
|
||||||
|
@ -1042,7 +1042,7 @@ static int xscale_debug_entry(struct target *target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply PC fixup */
|
/* apply PC fixup */
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, pc);
|
buf_set_u32(armv4_5->pc->value, 0, 32, pc);
|
||||||
|
|
||||||
/* on the first debug entry, identify cache type */
|
/* on the first debug entry, identify cache type */
|
||||||
if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1)
|
if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1)
|
||||||
|
@ -1212,21 +1212,23 @@ static int xscale_resume(struct target *target, int current,
|
||||||
|
|
||||||
/* current = 1: continue on current pc, otherwise continue at <address> */
|
/* current = 1: continue on current pc, otherwise continue at <address> */
|
||||||
if (!current)
|
if (!current)
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
|
buf_set_u32(armv4_5->pc->value, 0, 32, address);
|
||||||
|
|
||||||
current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
|
|
||||||
/* if we're at the reset vector, we have to simulate the branch */
|
/* if we're at the reset vector, we have to simulate the branch */
|
||||||
if (current_pc == 0x0)
|
if (current_pc == 0x0)
|
||||||
{
|
{
|
||||||
arm_simulate_step(target, NULL);
|
arm_simulate_step(target, NULL);
|
||||||
current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the front-end may request us not to handle breakpoints */
|
/* the front-end may request us not to handle breakpoints */
|
||||||
if (handle_breakpoints)
|
if (handle_breakpoints)
|
||||||
{
|
{
|
||||||
if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
|
breakpoint = breakpoint_find(target,
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
|
if (breakpoint != NULL)
|
||||||
{
|
{
|
||||||
uint32_t next_pc;
|
uint32_t next_pc;
|
||||||
|
|
||||||
|
@ -1272,8 +1274,10 @@ static int xscale_resume(struct target *target, int current,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send PC */
|
/* send PC */
|
||||||
xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
xscale_send_u32(target,
|
||||||
LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
|
LOG_DEBUG("writing PC with value 0x%8.8" PRIx32,
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
|
|
||||||
/* wait for and process debug entry */
|
/* wait for and process debug entry */
|
||||||
xscale_debug_entry(target);
|
xscale_debug_entry(target);
|
||||||
|
@ -1316,8 +1320,9 @@ static int xscale_resume(struct target *target, int current,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send PC */
|
/* send PC */
|
||||||
xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
xscale_send_u32(target, buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
LOG_DEBUG("wrote PC with value 0x%8.8" PRIx32,
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
|
|
||||||
target->debug_reason = DBG_REASON_NOTHALTED;
|
target->debug_reason = DBG_REASON_NOTHALTED;
|
||||||
|
|
||||||
|
@ -1354,7 +1359,7 @@ static int xscale_step_inner(struct target *target, int current,
|
||||||
if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
|
if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
|
||||||
{
|
{
|
||||||
uint32_t current_opcode, current_pc;
|
uint32_t current_opcode, current_pc;
|
||||||
current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
|
|
||||||
target_read_u32(target, current_pc, ¤t_opcode);
|
target_read_u32(target, current_pc, ¤t_opcode);
|
||||||
LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", current_opcode);
|
LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", current_opcode);
|
||||||
|
@ -1399,9 +1404,12 @@ static int xscale_step_inner(struct target *target, int current,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send PC */
|
/* send PC */
|
||||||
if ((retval = xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))) != ERROR_OK)
|
retval = xscale_send_u32(target,
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
LOG_DEBUG("writing PC with value 0x%8.8" PRIx32, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
LOG_DEBUG("wrote PC with value 0x%8.8" PRIx32,
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
|
|
||||||
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
|
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
|
||||||
|
|
||||||
|
@ -1425,7 +1433,7 @@ static int xscale_step(struct target *target, int current,
|
||||||
uint32_t address, int handle_breakpoints)
|
uint32_t address, int handle_breakpoints)
|
||||||
{
|
{
|
||||||
struct arm *armv4_5 = target_to_arm(target);
|
struct arm *armv4_5 = target_to_arm(target);
|
||||||
struct breakpoint *breakpoint = target->breakpoints;
|
struct breakpoint *breakpoint = NULL;
|
||||||
|
|
||||||
uint32_t current_pc;
|
uint32_t current_pc;
|
||||||
int retval;
|
int retval;
|
||||||
|
@ -1438,16 +1446,16 @@ static int xscale_step(struct target *target, int current,
|
||||||
|
|
||||||
/* current = 1: continue on current pc, otherwise continue at <address> */
|
/* current = 1: continue on current pc, otherwise continue at <address> */
|
||||||
if (!current)
|
if (!current)
|
||||||
buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
|
buf_set_u32(armv4_5->pc->value, 0, 32, address);
|
||||||
|
|
||||||
current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
|
|
||||||
/* if we're at the reset vector, we have to simulate the step */
|
/* if we're at the reset vector, we have to simulate the step */
|
||||||
if (current_pc == 0x0)
|
if (current_pc == 0x0)
|
||||||
{
|
{
|
||||||
if ((retval = arm_simulate_step(target, NULL)) != ERROR_OK)
|
if ((retval = arm_simulate_step(target, NULL)) != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
|
|
||||||
target->debug_reason = DBG_REASON_SINGLESTEP;
|
target->debug_reason = DBG_REASON_SINGLESTEP;
|
||||||
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
|
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
|
||||||
|
@ -1457,9 +1465,11 @@ static int xscale_step(struct target *target, int current,
|
||||||
|
|
||||||
/* the front-end may request us not to handle breakpoints */
|
/* the front-end may request us not to handle breakpoints */
|
||||||
if (handle_breakpoints)
|
if (handle_breakpoints)
|
||||||
if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
|
breakpoint = breakpoint_find(target,
|
||||||
{
|
buf_get_u32(armv4_5->pc->value, 0, 32));
|
||||||
if ((retval = xscale_unset_breakpoint(target, breakpoint)) != ERROR_OK)
|
if (breakpoint != NULL) {
|
||||||
|
retval = xscale_unset_breakpoint(target, breakpoint);
|
||||||
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2568,7 +2578,8 @@ static int xscale_read_trace(struct target *target)
|
||||||
(*trace_data_p)->next = NULL;
|
(*trace_data_p)->next = NULL;
|
||||||
(*trace_data_p)->chkpt0 = trace_buffer[256];
|
(*trace_data_p)->chkpt0 = trace_buffer[256];
|
||||||
(*trace_data_p)->chkpt1 = trace_buffer[257];
|
(*trace_data_p)->chkpt1 = trace_buffer[257];
|
||||||
(*trace_data_p)->last_instruction = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
(*trace_data_p)->last_instruction =
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
(*trace_data_p)->entries = malloc(sizeof(struct xscale_trace_entry) * (256 - j));
|
(*trace_data_p)->entries = malloc(sizeof(struct xscale_trace_entry) * (256 - j));
|
||||||
(*trace_data_p)->depth = 256 - j;
|
(*trace_data_p)->depth = 256 - j;
|
||||||
|
|
||||||
|
@ -3375,7 +3386,8 @@ COMMAND_HANDLER(xscale_handle_trace_buffer_command)
|
||||||
/* if we enable the trace buffer in fill-once
|
/* if we enable the trace buffer in fill-once
|
||||||
* mode we know the address of the first instruction */
|
* mode we know the address of the first instruction */
|
||||||
xscale->trace.pc_ok = 1;
|
xscale->trace.pc_ok = 1;
|
||||||
xscale->trace.current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
|
xscale->trace.current_pc =
|
||||||
|
buf_get_u32(armv4_5->pc->value, 0, 32);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue