target/arc: Add initial stepping functions
Change-Id: I84845f2ec6f1cff975990f0a495165a02de33227 Signed-off-by: Evgeniy Didin <didin@synopsys.com> Reviewed-on: http://openocd.zylin.com/5643 Tested-by: jenkins Reviewed-by: Oleksij Rempel <linux@rempel-privat.de>
This commit is contained in:
parent
05eb9a357c
commit
0af37282c7
103
src/target/arc.c
103
src/target/arc.c
|
@ -1286,6 +1286,107 @@ static int arc_target_create(struct target *target, Jim_Interp *interp)
|
|||
}
|
||||
|
||||
|
||||
/* Helper function which swiches core to single_step mode by
|
||||
* doing aux r/w operations. */
|
||||
int arc_config_step(struct target *target, int enable_step)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
struct arc_common *arc = target_to_arc(target);
|
||||
|
||||
/* enable core debug step mode */
|
||||
if (enable_step) {
|
||||
CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG,
|
||||
&value));
|
||||
value &= ~SET_CORE_AE_BIT; /* clear the AE bit */
|
||||
CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG,
|
||||
value));
|
||||
LOG_DEBUG(" [status32:0x%08" PRIx32 "]", value);
|
||||
|
||||
/* Doing read-modify-write, because DEBUG might contain manually set
|
||||
* bits like UB or ED, which should be preserved. */
|
||||
CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info,
|
||||
AUX_DEBUG_REG, &value));
|
||||
value |= SET_CORE_SINGLE_INSTR_STEP; /* set the IS bit */
|
||||
CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG,
|
||||
value));
|
||||
LOG_DEBUG("core debug step mode enabled [debug-reg:0x%08" PRIx32 "]", value);
|
||||
|
||||
} else { /* disable core debug step mode */
|
||||
CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG,
|
||||
&value));
|
||||
value &= ~SET_CORE_SINGLE_INSTR_STEP; /* clear the IS bit */
|
||||
CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG,
|
||||
value));
|
||||
LOG_DEBUG("core debug step mode disabled");
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int arc_step(struct target *target, int current, target_addr_t address,
|
||||
int handle_breakpoints)
|
||||
{
|
||||
/* get pointers to arch-specific information */
|
||||
struct arc_common *arc = target_to_arc(target);
|
||||
struct breakpoint *breakpoint = NULL;
|
||||
struct reg *pc = &(arc->core_and_aux_cache->reg_list[arc->pc_index_in_cache]);
|
||||
|
||||
if (target->state != TARGET_HALTED) {
|
||||
LOG_WARNING("target not halted");
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
/* current = 1: continue on current pc, otherwise continue at <address> */
|
||||
if (!current) {
|
||||
buf_set_u32(pc->value, 0, 32, address);
|
||||
pc->dirty = 1;
|
||||
pc->valid = 1;
|
||||
}
|
||||
|
||||
LOG_DEBUG("Target steps one instruction from PC=0x%" PRIx32,
|
||||
buf_get_u32(pc->value, 0, 32));
|
||||
|
||||
/* the front-end may request us not to handle breakpoints */
|
||||
if (handle_breakpoints) {
|
||||
breakpoint = breakpoint_find(target, buf_get_u32(pc->value, 0, 32));
|
||||
if (breakpoint)
|
||||
CHECK_RETVAL(arc_unset_breakpoint(target, breakpoint));
|
||||
}
|
||||
|
||||
/* restore context */
|
||||
CHECK_RETVAL(arc_restore_context(target));
|
||||
|
||||
target->debug_reason = DBG_REASON_SINGLESTEP;
|
||||
|
||||
CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
|
||||
|
||||
/* disable interrupts while stepping */
|
||||
CHECK_RETVAL(arc_enable_interrupts(target, 0));
|
||||
|
||||
/* do a single step */
|
||||
CHECK_RETVAL(arc_config_step(target, 1));
|
||||
|
||||
/* make sure we done our step */
|
||||
alive_sleep(1);
|
||||
|
||||
/* registers are now invalid */
|
||||
register_cache_invalidate(arc->core_and_aux_cache);
|
||||
|
||||
if (breakpoint)
|
||||
CHECK_RETVAL(arc_set_breakpoint(target, breakpoint));
|
||||
|
||||
LOG_DEBUG("target stepped ");
|
||||
|
||||
target->state = TARGET_HALTED;
|
||||
|
||||
/* Saving context */
|
||||
CHECK_RETVAL(arc_debug_entry(target));
|
||||
CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* ARC v2 target */
|
||||
struct target_type arcv2_target = {
|
||||
.name = "arcv2",
|
||||
|
@ -1300,7 +1401,7 @@ struct target_type arcv2_target = {
|
|||
|
||||
.halt = arc_halt,
|
||||
.resume = arc_resume,
|
||||
.step = NULL,
|
||||
.step = arc_step,
|
||||
|
||||
.assert_reset = arc_assert_reset,
|
||||
.deassert_reset = arc_deassert_reset,
|
||||
|
|
|
@ -33,9 +33,14 @@
|
|||
#define AUX_PC_REG 0x6
|
||||
#define AUX_STATUS32_REG 0xA
|
||||
|
||||
|
||||
#define SET_CORE_FORCE_HALT BIT(1)
|
||||
#define SET_CORE_HALT_BIT BIT(0) /* STATUS32[0] = H field */
|
||||
#define SET_CORE_ENABLE_INTERRUPTS BIT(31)
|
||||
#define SET_CORE_ENABLE_INTERRUPTS BIT(31)
|
||||
/* STATUS32[5] or AE bit indicates if the processor is in exception state */
|
||||
#define SET_CORE_AE_BIT BIT(5)
|
||||
/* Single instruction step bit in Debug register */
|
||||
#define SET_CORE_SINGLE_INSTR_STEP BIT(11)
|
||||
|
||||
#define AUX_STATUS32_REG_HALT_BIT BIT(0)
|
||||
#define AUX_STATUS32_REG_IE_BIT BIT(31) /* STATUS32[31] = IE field */
|
||||
|
|
Loading…
Reference in New Issue