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>
int common_magic;
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. */
struct reg *cpsr;
static uint32_t
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)
buf_set_u32(value, 0, 32, address);
armv4_5->cpsr->dirty = 1;
/* start fetching from 0x0 */
- buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
- armv4_5->core_cache->reg_list[15].dirty = 1;
- armv4_5->core_cache->reg_list[15].valid = 1;
+ buf_set_u32(armv4_5->pc->value, 0, 32, 0x0);
+ armv4_5->pc->dirty = 1;
+ armv4_5->pc->valid = 1;
arm720t_disable_mmu_caches(target, 1, 1, 1);
arm720t->armv4_5_mmu.mmu_enabled = 0;
armv4_5->cpsr->dirty = 1;
/* start fetching from 0x0 */
- buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
- armv4_5->core_cache->reg_list[15].dirty = 1;
- armv4_5->core_cache->reg_list[15].valid = 1;
+ buf_set_u32(armv4_5->pc->value, 0, 32, 0x0);
+ armv4_5->pc->dirty = 1;
+ armv4_5->pc->valid = 1;
/* reset registers */
for (i = 0; i <= 14; i++)
}
/* 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));
- arm7_9->write_pc(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
- armv4_5->core_cache->reg_list[15].dirty = 0;
+ LOG_DEBUG("writing PC with value 0x%8.8" PRIx32,
+ buf_get_u32(armv4_5->pc->value, 0, 32));
+ 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)
arm7_9->post_restore_context(target);
/* current = 1: continue on current pc, otherwise continue at <address> */
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;
- 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 */
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 );
if ((retval = arm7_9_unset_breakpoint(target, breakpoint)) != ERROR_OK)
}
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);
if ((retval = arm7_9_set_breakpoint(target, breakpoint)) != ERROR_OK)
struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
struct arm *armv4_5 = &arm7_9->armv4_5_common;
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)
{
/* current = 1: continue on current pc, otherwise continue at <address> */
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;
- current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
+ uint32_t current_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
/* the front-end may request us not to handle breakpoints */
if (handle_breakpoints)
- if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
- if ((retval = arm7_9_unset_breakpoint(target, breakpoint)) != ERROR_OK)
- {
- return retval;
- }
+ breakpoint = breakpoint_find(target, current_pc);
+ if (breakpoint != NULL) {
+ retval = arm7_9_unset_breakpoint(target, breakpoint);
+ if (retval != ERROR_OK)
+ return retval;
+ }
target->debug_reason = DBG_REASON_SINGLESTEP;
/* fetch NOP, LDM in EXECUTE stage (1st cycle) */
arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
/* 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) */
arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
armv4_5->cpsr->dirty = 1;
/* start fetching from 0x0 */
- buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
- armv4_5->core_cache->reg_list[15].dirty = 1;
- armv4_5->core_cache->reg_list[15].valid = 1;
+ buf_set_u32(armv4_5->pc->value, 0, 32, 0x0);
+ armv4_5->pc->dirty = 1;
+ armv4_5->pc->valid = 1;
arm920t_disable_mmu_caches(target, 1, 1, 1);
arm920t->armv4_5_mmu.mmu_enabled = 0;
armv4_5->cpsr->dirty = 1;
/* start fetching from 0x0 */
- buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
- armv4_5->core_cache->reg_list[15].dirty = 1;
- armv4_5->core_cache->reg_list[15].valid = 1;
+ buf_set_u32(armv4_5->pc->value, 0, 32, 0x0);
+ armv4_5->pc->dirty = 1;
+ armv4_5->pc->valid = 1;
arm926ejs_disable_mmu_caches(target, 1, 1, 1);
arm926ejs->armv4_5_mmu.mmu_enabled = 0;
/* fetch NOP, LDM in EXECUTE stage (1st cycle) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
/* 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) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
retval = dpm_modeswitch(dpm, ARM_MODE_ANY);
arm->cpsr->dirty = false;
- retval = dpm_write_reg(dpm, &cache->reg_list[15], 15);
- cache->reg_list[15].dirty = false;
+ retval = dpm_write_reg(dpm, arm->pc, 15);
+ arm->pc->dirty = false;
/* flush R0 -- it's *very* dirty by now */
retval = dpm_write_reg(dpm, &cache->reg_list[0], 0);
armv4_5->core_cache->reg_list[0].dirty = 1;
/* LR --> PC */
- buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, lr);
- armv4_5->core_cache->reg_list[15].dirty = 1;
+ buf_set_u32(armv4_5->pc->value, 0, 32, lr);
+ armv4_5->pc->dirty = 1;
/* saved PSR --> current PSR */
buf_set_u32(armv4_5->cpsr->value, 0, 32, spsr);
return 0;
/* 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);
if (pc != 0x00000008 && pc != 0xffff0008)
return 0;
cache->num_regs++;
}
+ arm->pc = reg_list + 15;
arm->cpsr = reg_list + ARMV4_5_CPSR;
arm->core_cache = cache;
return cache;
debug_reason_name(target),
arm_mode_name(armv4_5->core_mode),
buf_get_u32(armv4_5->cpsr->value, 0, 32),
- buf_get_u32(armv4_5->core_cache->reg_list[15].value,
- 0, 32),
+ buf_get_u32(armv4_5->pc->value, 0, 32),
armv4_5->is_semihosting ? ", semihosting" : "");
return ERROR_OK;
}
/* fast exit: ARMv5+ code can use BKPT */
- if (exit_point && buf_get_u32(armv4_5->core_cache->reg_list[15].value,
- 0, 32) != exit_point)
+ if (exit_point && buf_get_u32(armv4_5->pc->value, 0, 32) != exit_point)
{
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;
}
/* ARMV7M is always in thumb mode, try to make GDB understand this
* if it does not support this arch */
- *((char*)armv7m->core_cache->reg_list[15].value) |= 1;
+ *((char*)armv7m->arm.pc->value) |= 1;
#else
(*reg_list)[25] = &armv7m->core_cache->reg_list[ARMV7M_xPSR];
#endif
armv7m_mode_strings[armv7m->core_mode],
armv7m_exception_string(armv7m->exception_number),
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',
sp);
}
arm->cpsr = reg_list + ARMV7M_xPSR;
+ arm->pc = reg_list + ARMV7M_PC;
arm->core_cache = cache;
return cache;
}
int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found)
{
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;
#endif
/* current = 1: continue on current pc, otherwise continue at <address> */
- resume_pc = buf_get_u32(
- armv4_5->core_cache->reg_list[15].value,
- 0, 32);
+ resume_pc = buf_get_u32(armv4_5->pc->value, 0, 32);
if (!current)
resume_pc = address;
return ERROR_FAIL;
}
LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
- buf_set_u32(armv4_5->core_cache->reg_list[15].value,
- 0, 32, resume_pc);
- armv4_5->core_cache->reg_list[15].dirty = 1;
- armv4_5->core_cache->reg_list[15].valid = 1;
+ buf_set_u32(armv4_5->pc->value, 0, 32, resume_pc);
+ armv4_5->pc->dirty = 1;
+ armv4_5->pc->valid = 1;
cortex_a8_restore_context(target, handle_breakpoints);
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]);
reg->dirty = reg->valid;
}
}
/* current = 1: continue on current pc, otherwise continue at <address> */
- r = armv4_5->core_cache->reg_list + 15;
+ r = armv4_5->pc;
if (!current)
{
buf_set_u32(r->value, 0, 32, address);
LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s",
armv7m_mode_strings[armv7m->core_mode],
- *(uint32_t*)(armv7m->core_cache->reg_list[15].value),
+ *(uint32_t*)(arm->pc->value),
target_state_name(target));
if (armv7m->post_debug_entry)
}
/* current = 1: continue on current pc, otherwise continue at <address> */
- r = armv7m->core_cache->reg_list + 15;
+ r = armv7m->arm.pc;
if (!current)
{
buf_set_u32(r->value, 0, 32, address);
struct armv7m_common *armv7m = &cortex_m3->armv7m;
struct swjdp_common *swjdp = &armv7m->swjdp_info;
struct breakpoint *breakpoint = NULL;
- struct reg *pc = armv7m->core_cache->reg_list + 15;
+ struct reg *pc = armv7m->arm.pc;
bool bkpt_inst_found = false;
if (target->state != TARGET_HALTED)
struct arm7_9_common *arm7_9 = armv4_5->arch_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 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);
/* backup clobbered processor state */
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[15].value, 0, 32);
+ save[i] = buf_get_u32(armv4_5->pc->value, 0, 32);
/* set up target address in r0 */
buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, address);
armv4_5->core_cache->reg_list[i].valid = 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]);
- armv4_5->core_cache->reg_list[15].valid = 1;
- armv4_5->core_cache->reg_list[15].dirty = 1;
+ buf_set_u32(armv4_5->pc->value, 0, 32, save[i]);
+ armv4_5->pc->valid = 1;
+ armv4_5->pc->dirty = 1;
armv4_5->core_state = core_state;
return retval;
LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]);
/* move pc from buffer to register cache */
- buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, buffer[1]);
- armv4_5->core_cache->reg_list[15].dirty = 1;
- armv4_5->core_cache->reg_list[15].valid = 1;
+ buf_set_u32(armv4_5->pc->value, 0, 32, buffer[1]);
+ armv4_5->pc->dirty = 1;
+ armv4_5->pc->valid = 1;
LOG_DEBUG("pc: 0x%8.8" PRIx32 "", buffer[1]);
/* move data from buffer to register cache */
moe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3);
/* 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)
{
}
/* 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 */
if (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1)
/* current = 1: continue on current pc, otherwise continue at <address> */
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 (current_pc == 0x0)
{
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 */
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;
}
/* send PC */
- xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].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));
+ 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->pc->value, 0, 32));
/* wait for and process debug entry */
xscale_debug_entry(target);
}
/* send PC */
- xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].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));
+ xscale_send_u32(target, buf_get_u32(armv4_5->pc->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;
if ((retval = arm_simulate_step(target, &next_pc)) != ERROR_OK)
{
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);
LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8" PRIx32 "", current_opcode);
}
/* 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;
- 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);
uint32_t address, int handle_breakpoints)
{
struct arm *armv4_5 = target_to_arm(target);
- struct breakpoint *breakpoint = target->breakpoints;
+ struct breakpoint *breakpoint = NULL;
uint32_t current_pc;
int retval;
/* current = 1: continue on current pc, otherwise continue at <address> */
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 (current_pc == 0x0)
{
if ((retval = arm_simulate_step(target, NULL)) != ERROR_OK)
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_call_event_callbacks(target, TARGET_EVENT_HALTED);
/* the front-end may request us not to handle breakpoints */
if (handle_breakpoints)
- if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32))))
- {
- if ((retval = xscale_unset_breakpoint(target, breakpoint)) != ERROR_OK)
- return retval;
- }
+ breakpoint = breakpoint_find(target,
+ buf_get_u32(armv4_5->pc->value, 0, 32));
+ if (breakpoint != NULL) {
+ retval = xscale_unset_breakpoint(target, breakpoint);
+ if (retval != ERROR_OK)
+ return retval;
+ }
retval = xscale_step_inner(target, current, address, handle_breakpoints);
(*trace_data_p)->next = NULL;
(*trace_data_p)->chkpt0 = trace_buffer[256];
(*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)->depth = 256 - j;
/* if we enable the trace buffer in fill-once
* mode we know the address of the first instruction */
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
{