* Copyright (C) 2006, 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
- * Copyright (C) 2007,2008 Øyvind Harboe *
+ * Copyright (C) 2007,2008 Øyvind Harboe *
* oyvind.harboe@zylin.com *
* *
* This program is free software; you can redistribute it and/or modify *
int xscale_register_commands(struct command_context_s *cmd_ctx);
/* forward declarations */
-int xscale_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
+int xscale_target_create(struct target_s *target, Jim_Interp *interp);
int xscale_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
-int xscale_quit();
+int xscale_quit(void);
int xscale_arch_state(struct target_s *target);
int xscale_poll(target_t *target);
.remove_watchpoint = xscale_remove_watchpoint,
.register_commands = xscale_register_commands,
- .target_command = xscale_target_command,
+ .target_create = xscale_target_create,
.init_target = xscale_init_target,
.quit = xscale_quit,
for (;;)
{
- int i;
- for (i=0; i<100; i++)
+ /* if we want to consume the register content (i.e. clear TX_READY),
+ * we have to go straight from Capture-DR to Shift-DR
+ * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
+ */
+ if (consume)
+ jtag_add_pathmove(3, path);
+ else
{
- /* if we want to consume the register content (i.e. clear TX_READY),
- * we have to go straight from Capture-DR to Shift-DR
- * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR
- */
- if (consume)
- jtag_add_pathmove(3, path);
- else
- {
- jtag_add_pathmove(sizeof(noconsume_path)/sizeof(*noconsume_path), noconsume_path);
- }
-
- jtag_add_dr_scan(3, fields, TAP_RTI);
-
- if ((retval = jtag_execute_queue()) != ERROR_OK)
- {
- LOG_ERROR("JTAG error while reading TX");
- return ERROR_TARGET_TIMEOUT;
- }
-
- gettimeofday(&now, NULL);
- if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
- {
- LOG_ERROR("time out reading TX register");
- return ERROR_TARGET_TIMEOUT;
- }
- if (!((!(field0_in & 1)) && consume))
- {
- goto done;
- }
+ jtag_add_pathmove(sizeof(noconsume_path)/sizeof(*noconsume_path), noconsume_path);
+ }
+
+ jtag_add_dr_scan(3, fields, TAP_RTI);
+
+ if ((retval = jtag_execute_queue()) != ERROR_OK)
+ {
+ LOG_ERROR("JTAG error while reading TX");
+ return ERROR_TARGET_TIMEOUT;
+ }
+
+ gettimeofday(&now, NULL);
+ if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
+ {
+ LOG_ERROR("time out reading TX register");
+ return ERROR_TARGET_TIMEOUT;
+ }
+ if (!((!(field0_in & 1)) && consume))
+ {
+ goto done;
+ }
+ if (debug_level>=3)
+ {
+ LOG_DEBUG("waiting 100ms");
+ alive_sleep(100); /* avoid flooding the logs */
+ } else
+ {
+ keep_alive();
}
- LOG_DEBUG("waiting 10ms");
- usleep(10*1000); /* avoid flooding the logs */
}
done:
LOG_DEBUG("polling RX");
for (;;)
{
- int i;
- for (i=0; i<10; i++)
+ jtag_add_dr_scan(3, fields, TAP_RTI);
+
+ if ((retval = jtag_execute_queue()) != ERROR_OK)
{
- jtag_add_dr_scan(3, fields, TAP_RTI);
-
- if ((retval = jtag_execute_queue()) != ERROR_OK)
- {
- LOG_ERROR("JTAG error while writing RX");
- return retval;
- }
-
- gettimeofday(&now, NULL);
- if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
- {
- LOG_ERROR("time out writing RX register");
- return ERROR_TARGET_TIMEOUT;
- }
- if (!(field0_in & 1))
- goto done;
+ LOG_ERROR("JTAG error while writing RX");
+ return retval;
+ }
+
+ gettimeofday(&now, NULL);
+ if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec)&& (now.tv_usec > timeout.tv_usec)))
+ {
+ LOG_ERROR("time out writing RX register");
+ return ERROR_TARGET_TIMEOUT;
+ }
+ if (!(field0_in & 1))
+ goto done;
+ if (debug_level>=3)
+ {
+ LOG_DEBUG("waiting 100ms");
+ alive_sleep(100); /* avoid flooding the logs */
+ } else
+ {
+ keep_alive();
}
- LOG_DEBUG("waiting 10ms");
- usleep(10*1000); /* wait 10ms to avoid flooding the logs */
}
done:
"MMU: %s, D-Cache: %s, I-Cache: %s"
"%s",
armv4_5_state_strings[armv4_5->core_state],
- target_debug_reason_strings[target->debug_reason],
+ Jim_Nvp_value2name_simple( nvp_target_debug_reason, target->debug_reason )->name ,
armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
armv4_5_common_t *armv4_5 = target->arch_info;
xscale_common_t *xscale = armv4_5->arch_info;
- LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
+ LOG_DEBUG("target->state: %s",
+ Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
if (target->state == TARGET_HALTED)
{
armv4_5_common_t *armv4_5 = target->arch_info;
xscale_common_t *xscale= armv4_5->arch_info;
reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
+ int retval;
if (xscale->ibcr0_used)
{
}
}
- xscale_set_reg_u32(ibcr0, next_pc | 0x1);
+ if ((retval=xscale_set_reg_u32(ibcr0, next_pc | 0x1))!=ERROR_OK)
+ return retval;
return ERROR_OK;
}
armv4_5_common_t *armv4_5 = target->arch_info;
xscale_common_t *xscale= armv4_5->arch_info;
reg_t *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];
+ int retval;
- xscale_set_reg_u32(ibcr0, 0x0);
+ if ((retval=xscale_set_reg_u32(ibcr0, 0x0))!=ERROR_OK)
+ return retval;
return ERROR_OK;
}
return ERROR_OK;
}
-int xscale_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
+static int xscale_step_inner(struct target_s *target, int current, u32 address, int handle_breakpoints)
{
armv4_5_common_t *armv4_5 = target->arch_info;
xscale_common_t *xscale = armv4_5->arch_info;
- breakpoint_t *breakpoint = target->breakpoints;
u32 current_pc, next_pc;
- int i;
int retval;
+ int i;
- 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(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
-
- current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
-
- /* if we're at the reset vector, we have to simulate the step */
- if (current_pc == 0x0)
- {
- arm_simulate_step(target, NULL);
- current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32);
-
- target->debug_reason = DBG_REASON_SINGLESTEP;
- target_call_event_callbacks(target, TARGET_EVENT_HALTED);
-
- return ERROR_OK;
- }
-
- /* 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))))
- {
- xscale_unset_breakpoint(target, breakpoint);
- }
target->debug_reason = DBG_REASON_SINGLESTEP;
u32 current_opcode;
target_read_u32(target, current_pc, ¤t_opcode);
LOG_ERROR("BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8x", current_opcode);
+ return retval;
}
LOG_DEBUG("enable single-step");
- xscale_enable_single_step(target, next_pc);
+ if ((retval=xscale_enable_single_step(target, next_pc))!=ERROR_OK)
+ return retval;
/* restore banked registers */
- xscale_restore_context(target);
+ if ((retval=xscale_restore_context(target))!=ERROR_OK)
+ return retval;
/* send resume request (command 0x30 or 0x31)
* clean the trace buffer if it is to be enabled (0x62) */
if (xscale->trace.buffer_enabled)
{
- xscale_send_u32(target, 0x62);
- xscale_send_u32(target, 0x31);
+ if ((retval=xscale_send_u32(target, 0x62))!=ERROR_OK)
+ return retval;
+ if ((retval=xscale_send_u32(target, 0x31))!=ERROR_OK)
+ return retval;
}
else
- xscale_send_u32(target, 0x30);
+ if ((retval=xscale_send_u32(target, 0x30))!=ERROR_OK)
+ return retval;
/* send CPSR */
- xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
+ if ((retval=xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32)))!=ERROR_OK)
+ return retval;
LOG_DEBUG("writing cpsr with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32));
for (i = 7; i >= 0; i--)
{
/* send register */
- xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
+ if ((retval=xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32)))!=ERROR_OK)
+ return retval;
LOG_DEBUG("writing r%i with value 0x%8.8x", i, buf_get_u32(armv4_5->core_cache->reg_list[i].value, 0, 32));
}
/* send PC */
- xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
+ if ((retval=xscale_send_u32(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)))!=ERROR_OK)
+ return retval;
LOG_DEBUG("writing PC with value 0x%8.8x", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
/* registers are now invalid */
- armv4_5_invalidate_core_regs(target);
+ if ((retval=armv4_5_invalidate_core_regs(target))!=ERROR_OK)
+ return retval;
/* wait for and process debug entry */
- xscale_debug_entry(target);
+ if ((retval=xscale_debug_entry(target))!=ERROR_OK)
+ return retval;
LOG_DEBUG("disable single-step");
- xscale_disable_single_step(target);
+ if ((retval=xscale_disable_single_step(target))!=ERROR_OK)
+ return retval;
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+ return ERROR_OK;
+}
+
+int xscale_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
+{
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ breakpoint_t *breakpoint = target->breakpoints;
+
+ u32 current_pc;
+ int retval;
+
+ 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(armv4_5->core_cache->reg_list[15].value, 0, 32, address);
+
+ current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].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);
+
+ target->debug_reason = DBG_REASON_SINGLESTEP;
+ target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+
+ return ERROR_OK;
+ }
+
+ /* 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;
+ }
+
+ retval = xscale_step_inner(target, current, address, handle_breakpoints);
+
if (breakpoint)
{
xscale_set_breakpoint(target, breakpoint);
armv4_5_common_t *armv4_5 = target->arch_info;
xscale_common_t *xscale = armv4_5->arch_info;
- LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
+ LOG_DEBUG("target->state: %s",
+ Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name);
/* select DCSR instruction (set endstate to R-T-I to ensure we don't
* end up in T-L-R, which would reset JTAG
target->state = TARGET_RESET;
+ if (target->reset_halt)
+ {
+ int retval;
+ if ((retval = target_halt(target))!=ERROR_OK)
+ return retval;
+ }
+
return ERROR_OK;
}
int xscale_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
{
+ int retval;
armv4_5_common_t *armv4_5 = target->arch_info;
xscale_common_t *xscale = armv4_5->arch_info;
return ERROR_TARGET_NOT_HALTED;
}
- if (xscale->force_hw_bkpts)
- breakpoint->type = BKPT_HARD;
-
if (breakpoint->set)
{
LOG_WARNING("breakpoint already set");
if (breakpoint->length == 4)
{
/* keep the original instruction in target endianness */
- target->type->read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
+ if((retval = target->type->read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
+ {
+ return retval;
+ }
/* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
- target_write_u32(target, breakpoint->address, xscale->arm_bkpt);
+ if((retval = target_write_u32(target, breakpoint->address, xscale->arm_bkpt)) != ERROR_OK)
+ {
+ return retval;
+ }
}
else
{
/* keep the original instruction in target endianness */
- target->type->read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
+ if((retval = target->type->read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
+ {
+ return retval;
+ }
/* write the original instruction in target endianness (arm7_9->arm_bkpt is host endian) */
- target_write_u32(target, breakpoint->address, xscale->thumb_bkpt);
+ if((retval = target_write_u32(target, breakpoint->address, xscale->thumb_bkpt)) != ERROR_OK)
+ {
+ return retval;
+ }
}
breakpoint->set = 1;
}
return ERROR_TARGET_NOT_HALTED;
}
- if (xscale->force_hw_bkpts)
- {
- LOG_DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint->address);
- breakpoint->type = BKPT_HARD;
- }
-
if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
{
LOG_INFO("no breakpoint unit available for hardware breakpoint");
int xscale_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
{
+ int retval;
armv4_5_common_t *armv4_5 = target->arch_info;
xscale_common_t *xscale = armv4_5->arch_info;
/* restore original instruction (kept in target endianness) */
if (breakpoint->length == 4)
{
- target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
+ if((retval = target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
+ {
+ return retval;
+ }
}
else
{
- target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
+ if((retval = target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
+ {
+ return retval;
+ }
}
breakpoint->set = 0;
}
return ERROR_OK;
}
-int xscale_quit()
+int xscale_quit(void)
{
return ERROR_OK;
}
-int xscale_init_arch_info(target_t *target, xscale_common_t *xscale, int chain_pos, char *variant)
+int xscale_init_arch_info(target_t *target, xscale_common_t *xscale, int chain_pos, const char *variant)
{
armv4_5_common_t *armv4_5;
u32 high_reset_branch, low_reset_branch;
xscale->hold_rst = 0;
xscale->external_debug_break = 0;
- xscale->force_hw_bkpts = 1;
-
xscale->ibcr_available = 2;
xscale->ibcr0_used = 0;
xscale->ibcr1_used = 0;
}
/* target xscale <endianess> <startup_mode> <chain_pos> <variant> */
-int xscale_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
+int xscale_target_create(struct target_s *target, Jim_Interp *interp)
{
- int chain_pos;
- char *variant = NULL;
- xscale_common_t *xscale = malloc(sizeof(xscale_common_t));
- memset(xscale, 0, sizeof(*xscale));
+ xscale_common_t *xscale = calloc(1,sizeof(xscale_common_t));
- if (argc < 5)
- {
- LOG_ERROR("'target xscale' requires four arguments: <endianess> <startup_mode> <chain_pos> <variant>");
- return ERROR_OK;
- }
-
- chain_pos = strtoul(args[3], NULL, 0);
-
- variant = args[4];
-
- xscale_init_arch_info(target, xscale, chain_pos, variant);
+ xscale_init_arch_info(target, xscale, target->chain_position, target->variant);
xscale_build_reg_cache(target);
return ERROR_OK;
return ERROR_OK;
}
-int xscale_handle_force_hw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
- target_t *target = get_current_target(cmd_ctx);
- armv4_5_common_t *armv4_5;
- xscale_common_t *xscale;
-
- if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
- {
- return ERROR_OK;
- }
-
- if ((argc >= 1) && (strcmp("enable", args[0]) == 0))
- {
- xscale->force_hw_bkpts = 1;
- }
- else if ((argc >= 1) && (strcmp("disable", args[0]) == 0))
- {
- xscale->force_hw_bkpts = 0;
- }
- else
- {
- command_print(cmd_ctx, "usage: xscale force_hw_bkpts <enable|disable>");
- }
-
- command_print(cmd_ctx, "force hardware breakpoints %s", (xscale->force_hw_bkpts) ? "enabled" : "disabled");
-
- return ERROR_OK;
-}
int xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
target_t *target = get_current_target(cmd_ctx);
armv4_5_common_t *armv4_5;
xscale_common_t *xscale;
-
+
if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
{
return ERROR_OK;
}
-
+
if (target->state != TARGET_HALTED)
{
command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);