From 8d73c2a9b0c00c870694a57f7cfbc23e354855ac Mon Sep 17 00:00:00 2001 From: oharboe Date: Sun, 24 Aug 2008 18:20:49 +0000 Subject: [PATCH] duan ellis target tcl work in progress converts a number of 'simple string lookup tables' into NVP tables. These NVP tables will be used by various commands coming in the next patch. git-svn-id: svn://svn.berlios.de/openocd/trunk@962 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/server/gdb_server.c | 20 +- src/target/arm11.c | 16 +- src/target/arm720t.c | 2 +- src/target/arm7_9_common.c | 10 +- src/target/arm7tdmi.c | 25 ++- src/target/arm7tdmi.h | 2 +- src/target/arm920t.c | 2 +- src/target/arm926ejs.c | 2 +- src/target/armv4_5.c | 2 +- src/target/armv7m.c | 2 +- src/target/cortex_m3.c | 17 +- src/target/mips32.c | 2 +- src/target/mips_m4k.c | 14 +- src/target/target.c | 318 ++++++++++++++++++++++---------- src/target/target.h | 96 ++++++++-- src/target/target_request.c | 20 +- src/target/xscale.c | 8 +- src/tcl/chip/atmel/at91/rtt.tcl | 4 +- 18 files changed, 405 insertions(+), 157 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 8ebe94395f..8fb3b64f95 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -649,7 +649,7 @@ int gdb_target_callback_event_handler(struct target_s *target, enum target_event case TARGET_EVENT_HALTED: gdb_frontend_halted(target, connection); break; - case TARGET_EVENT_GDB_PROGRAM: + case TARGET_EVENT_GDB_FLASH_ERASE_START: gdb_program_handler(target, event, connection->cmd_ctx); break; default: @@ -1769,7 +1769,7 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p flash_set_dirty(); /* perform any target specific operations before the erase */ - target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_PROGRAM); + target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_FLASH_ERASE_START); /* perform erase */ if ((result = flash_erase_address_range(gdb_service->target, addr, length)) != ERROR_OK) @@ -2063,8 +2063,7 @@ int gdb_input(connection_t *connection) int gdb_init(void) { gdb_service_t *gdb_service; - target_t *target = targets; - int i = 0; + target_t *target = all_targets; if (!target) { @@ -2082,16 +2081,21 @@ int gdb_init(void) { char service_name[8]; - snprintf(service_name, 8, "gdb-%2.2i", i); + snprintf(service_name, 8, "gdb-%2.2i", target->target_number); gdb_service = malloc(sizeof(gdb_service_t)); gdb_service->target = target; - add_service("gdb", CONNECTION_GDB, gdb_port + i, 1, gdb_new_connection, gdb_input, gdb_connection_closed, gdb_service); + add_service("gdb", CONNECTION_GDB, + gdb_port + target->target_number, + 1, gdb_new_connection, gdb_input, + gdb_connection_closed, + gdb_service); - LOG_DEBUG("gdb service for target %s at port %i", target->type->name, gdb_port + i); + LOG_DEBUG("gdb service for target %s at port %i", + target->type->name, + gdb_port + target->target_number); - i++; target = target->next; } diff --git a/src/target/arm11.c b/src/target/arm11.c index 23fb71bb74..3398b14b8d 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -726,7 +726,8 @@ int arm11_halt(struct target_s *target) arm11_common_t * arm11 = target->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_UNKNOWN) { @@ -782,7 +783,9 @@ int arm11_resume(struct target_s *target, int current, u32 address, int handle_b arm11_common_t * arm11 = target->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) { @@ -877,7 +880,8 @@ int arm11_step(struct target_s *target, int current, u32 address, int handle_bre { FNC_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) { @@ -1012,7 +1016,9 @@ int arm11_deassert_reset(struct target_s *target) FNC_INFO; #if 0 - 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 ); + /* deassert reset lines */ jtag_add_reset(0, 0); @@ -1667,7 +1673,7 @@ arm11_common_t * arm11_find_target(const char * arg) size_t jtag_target = strtoul(arg, NULL, 0); {target_t * t; - for (t = targets; t; t = t->next) + for (t = all_targets; t; t = t->next) { if (t->type != &arm11_target) continue; diff --git a/src/target/arm720t.c b/src/target/arm720t.c index 48a6032e03..fab553cfe6 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -321,7 +321,7 @@ int arm720t_arch_state(struct target_s *target) "cpsr: 0x%8.8x pc: 0x%8.8x\n" "MMU: %s, Cache: %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), diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index c79e19b96c..dab16cfcdb 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -734,7 +734,8 @@ int arm7_9_assert_reset(target_t *target) { armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = 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 (!(jtag_reset_config & RESET_HAS_SRST)) { @@ -795,7 +796,9 @@ int arm7_9_assert_reset(target_t *target) int arm7_9_deassert_reset(target_t *target) { int retval=ERROR_OK; - 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); + /* deassert reset lines */ jtag_add_reset(0, 0); @@ -969,7 +972,8 @@ int arm7_9_halt(target_t *target) arm7_9_common_t *arm7_9 = armv4_5->arch_info; reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; - 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) { diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index 6d5f606ddb..f3e9fd5f9e 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -45,6 +45,7 @@ int arm7tdmi_register_commands(struct command_context_s *cmd_ctx); /* forward declarations */ int arm7tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target); +int arm7tdmi_target_create(Jim_Interp *interp, struct target_s *target); int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target); int arm7tdmi_quit(void); @@ -86,6 +87,7 @@ target_type_t arm7tdmi_target = .register_commands = arm7tdmi_register_commands, .target_command = arm7tdmi_target_command, + // .target_create = arm7tdmi_target_create, .init_target = arm7tdmi_init_target, .examine = arm7tdmi_examine, .quit = arm7tdmi_quit @@ -759,7 +761,7 @@ int arm7tdmi_quit(void) return ERROR_OK; } -int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, int chain_pos, char *variant) +int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, int chain_pos, const char *variant) { armv4_5_common_t *armv4_5; arm7_9_common_t *arm7_9; @@ -851,6 +853,20 @@ int arm7tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char * return ERROR_OK; } +int arm7tdmi_target_create(Jim_Interp *interp, + struct target_s *target) +{ + arm7tdmi_common_t *arm7tdmi; + + arm7tdmi = calloc(1,sizeof(arm7tdmi_common_t)); + + arm7tdmi_init_arch_info(target, arm7tdmi, target->chain_position, target->variant); + + return ERROR_OK; +} + + + int arm7tdmi_register_commands(struct command_context_s *cmd_ctx) { int retval; @@ -861,3 +877,10 @@ int arm7tdmi_register_commands(struct command_context_s *cmd_ctx) } + +/* + * Local Variables: *** + * c-basic-offset: 4 *** + * tab-width: 4 *** + * End: *** + */ diff --git a/src/target/arm7tdmi.h b/src/target/arm7tdmi.h index a9b41da2ff..6e4da7a778 100644 --- a/src/target/arm7tdmi.h +++ b/src/target/arm7tdmi.h @@ -38,7 +38,7 @@ typedef struct arm7tdmi_common_s } arm7tdmi_common_t; int arm7tdmi_register_commands(struct command_context_s *cmd_ctx); -int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, int chain_pos, char *variant); +int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, int chain_pos, const char *variant); int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target); int arm7tdmi_examine(struct target_s *target); diff --git a/src/target/arm920t.c b/src/target/arm920t.c index 781f624aa2..29228d8c82 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -566,7 +566,7 @@ int arm920t_arch_state(struct target_s *target) "cpsr: 0x%8.8x pc: 0x%8.8x\n" "MMU: %s, D-Cache: %s, I-Cache: %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), diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index 4e15095ae2..51a666533c 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -562,7 +562,7 @@ int arm926ejs_arch_state(struct target_s *target) "cpsr: 0x%8.8x pc: 0x%8.8x\n" "MMU: %s, D-Cache: %s, I-Cache: %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), diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 48a45865d5..3812496edf 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -302,7 +302,7 @@ int armv4_5_arch_state(struct target_s *target) LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8x pc: 0x%8.8x", 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)); diff --git a/src/target/armv7m.c b/src/target/armv7m.c index f4e8062c0a..ad8f487df8 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -439,7 +439,7 @@ int armv7m_arch_state(struct target_s *target) armv7m_common_t *armv7m = target->arch_info; LOG_USER("target halted due to %s, current mode: %s %s\nxPSR: 0x%8.8x pc: 0x%8.8x", - target_debug_reason_strings[target->debug_reason], + Jim_Nvp_value2name_simple( nvp_target_debug_reason,target->debug_reason)->name, armv7m_mode_strings[armv7m->core_mode], armv7m_exception_string(armv7m->exception_number), buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32), diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 12574c66af..dd9c699253 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -359,8 +359,10 @@ int cortex_m3_debug_entry(target_t *target) cortex_m3_examine_exception_reason(target); } - LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s", armv7m_mode_strings[armv7m->core_mode], \ - *(u32*)(armv7m->core_cache->reg_list[15].value), target_state_strings[target->state]); + LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s", + armv7m_mode_strings[armv7m->core_mode], + *(u32*)(armv7m->core_cache->reg_list[15].value), + Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name); if (armv7m->post_debug_entry) armv7m->post_debug_entry(target); @@ -436,7 +438,7 @@ int cortex_m3_poll(target_t *target) #if 0 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */ ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr); - LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, target_state_strings[target->state]); + LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, Jim_Nvp_value2name( nvp_target_state, target->state )->name ); #endif return ERROR_OK; @@ -449,7 +451,8 @@ int cortex_m3_halt(target_t *target) cortex_m3_common_t *cortex_m3 = armv7m->arch_info; swjdp_common_t *swjdp = &cortex_m3->swjdp_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) { @@ -676,7 +679,8 @@ int cortex_m3_assert_reset(target_t *target) swjdp_common_t *swjdp = &cortex_m3->swjdp_info; int assert_srst = 1; - 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 (!(jtag_reset_config & RESET_HAS_SRST)) { @@ -774,7 +778,8 @@ int cortex_m3_assert_reset(target_t *target) int cortex_m3_deassert_reset(target_t *target) { - 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); /* deassert reset lines */ jtag_add_reset(0, 0); diff --git a/src/target/mips32.c b/src/target/mips32.c index f338c1db0b..5870ae692b 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -266,7 +266,7 @@ int mips32_arch_state(struct target_s *target) } LOG_USER("target halted due to %s, pc: 0x%8.8x", - target_debug_reason_strings[target->debug_reason], + Jim_Nvp_value2name_simple( nvp_target_debug_reason, target->debug_reason )->name , buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32)); return ERROR_OK; diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index 7cca55de61..599b215954 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -119,8 +119,9 @@ int mips_m4k_debug_entry(target_t *target) mips32_save_context(target); - LOG_DEBUG("entered debug state at PC 0x%x, target->state: %s", \ - *(u32*)(mips32->core_cache->reg_list[MIPS32_PC].value), target_state_strings[target->state]); + LOG_DEBUG("entered debug state at PC 0x%x, target->state: %s", + *(u32*)(mips32->core_cache->reg_list[MIPS32_PC].value), + Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name); return ERROR_OK; } @@ -187,7 +188,8 @@ int mips_m4k_halt(struct target_s *target) mips32_common_t *mips32 = target->arch_info; mips_ejtag_t *ejtag_info = &mips32->ejtag_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) { @@ -231,7 +233,8 @@ int mips_m4k_assert_reset(target_t *target) mips32_common_t *mips32 = target->arch_info; mips_ejtag_t *ejtag_info = &mips32->ejtag_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 (!(jtag_reset_config & RESET_HAS_SRST)) { @@ -279,7 +282,8 @@ int mips_m4k_assert_reset(target_t *target) int mips_m4k_deassert_reset(target_t *target) { - 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); /* deassert reset lines */ jtag_add_reset(0, 0); diff --git a/src/target/target.c b/src/target/target.c index d91928d1dc..aaad831700 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -80,6 +80,11 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv); static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv); +static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv); +static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv); + + + /* targets */ extern target_type_t arm7tdmi_target; extern target_type_t arm720t_target; @@ -109,32 +114,105 @@ target_type_t *target_types[] = NULL, }; -target_t *targets = NULL; +target_t *all_targets = NULL; target_event_callback_t *target_event_callbacks = NULL; target_timer_callback_t *target_timer_callbacks = NULL; -char *target_state_strings[] = -{ - "unknown", - "running", - "halted", - "reset", - "debug_running", +const Jim_Nvp nvp_assert[] = { + { .name = "assert", NVP_ASSERT }, + { .name = "deassert", NVP_DEASSERT }, + { .name = "T", NVP_ASSERT }, + { .name = "F", NVP_DEASSERT }, + { .name = "t", NVP_ASSERT }, + { .name = "f", NVP_DEASSERT }, + { .name = NULL, .value = -1 } }; -char *target_debug_reason_strings[] = -{ - "debug request", "breakpoint", "watchpoint", - "watchpoint and breakpoint", "single step", - "target not halted", "undefined" +const Jim_Nvp nvp_target_event[] = { + { .value = TARGET_EVENT_HALTED, .name = "halted" }, + { .value = TARGET_EVENT_RESUMED, .name = "resumed" }, + { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" }, + { .value = TARGET_EVENT_RESUME_END, .name = "resume-end" }, + + /* historical name */ + { .value = TARGET_EVENT_RESET_START , .name = "pre_reset" }, + { .value = TARGET_EVENT_RESET_START, .name = "reset-start" }, + /* historical name */ + { .value = TARGET_EVENT_RESET , .name = "reset" }, + { .value = TARGET_EVENT_RESET_INIT , .name = "reset-init" }, + { .value = TARGET_EVENT_RESET_END, .name = "reset-end" }, + + { .value = TARGET_EVENT_DEBUG_HALTED, .name = "debug-halted" }, + { .value = TARGET_EVENT_DEBUG_RESUMED, .name = "debug-resumed" }, + + { .value = TARGET_EVENT_GDB_ATTACH, .name = "gdb-attach" }, + { .value = TARGET_EVENT_GDB_DETACH, .name = "gdb-detach" }, + + { .value = TARGET_EVENT_GDB_FLASH_WRITE_START, .name = "gdb-flash-write-start" }, + { .value = TARGET_EVENT_GDB_FLASH_WRITE_END , .name = "gdb-flash-write-end" }, + + { .value = TARGET_EVENT_GDB_FLASH_ERASE_START , .name = "gdb_program_config" }, + + { .value = TARGET_EVENT_GDB_FLASH_ERASE_START, .name = "gdb-flash-erase-start" }, + { .value = TARGET_EVENT_GDB_FLASH_ERASE_END , .name = "gdb-flash-erase-end" }, + + { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" }, + { .value = TARGET_EVENT_RESUMED , .name = "resume-ok" }, + { .value = TARGET_EVENT_RESUME_END , .name = "resume-end" }, + + { .name = NULL, .value = -1 } }; -char *target_endianess_strings[] = -{ - "big endian", - "little endian", +const Jim_Nvp nvp_target_state[] = { + { .name = "unknown", .value = TARGET_UNKNOWN }, + { .name = "running", .value = TARGET_RUNNING }, + { .name = "halted", .value = TARGET_HALTED }, + { .name = "reset", .value = TARGET_RESET }, + { .name = "debug-running", .value = TARGET_DEBUG_RUNNING }, + { .name = NULL, .value = -1 }, }; + +const Jim_Nvp nvp_target_debug_reason [] = { + { .name = "debug-request" , .value = DBG_REASON_DBGRQ }, + { .name = "breakpoint" , .value = DBG_REASON_BREAKPOINT }, + { .name = "watchpoint" , .value = DBG_REASON_WATCHPOINT }, + { .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT }, + { .name = "single-step" , .value = DBG_REASON_SINGLESTEP }, + { .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED }, + { .name = "undefined" , .value = DBG_REASON_UNDEFINED }, + { .name = NULL, .value = -1 }, +}; + + +const Jim_Nvp nvp_target_endian[] = { + { .name = "big", .value = TARGET_BIG_ENDIAN }, + { .name = "little", .value = TARGET_LITTLE_ENDIAN }, + { .name = "be", .value = TARGET_BIG_ENDIAN }, + { .name = "le", .value = TARGET_LITTLE_ENDIAN }, + { .name = NULL, .value = -1 }, +}; + + +/* determine the number of the new target */ +static int +new_target_number( void ) +{ + target_t *t; + int x; + + /* number is 0 based */ + x = -1; + t = all_targets; + while(t){ + if( x < t->target_number ){ + x = t->target_number; + } + t = t->next; + } + return x+1; +} + static int target_continous_poll = 1; /* read a u32 from a buffer in target memory endianness */ @@ -155,6 +233,12 @@ u16 target_buffer_get_u16(target_t *target, u8 *buffer) return be_to_h_u16(buffer); } +/* read a u8 from a buffer in target memory endianness */ +u8 target_buffer_get_u8(target_t *target, u8 *buffer) +{ + return *buffer & 0x0ff; +} + /* write a u32 to a buffer in target memory endianness */ void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value) { @@ -173,18 +257,22 @@ void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value) h_u16_to_be(buffer, value); } +/* write a u8 to a buffer in target memory endianness */ +void target_buffer_set_u8(target_t *target, u8 *buffer, u8 value) +{ + *buffer = value; +} + /* returns a pointer to the n-th configured target */ target_t* get_target_by_num(int num) { - target_t *target = targets; - int i = 0; + target_t *target = all_targets; - while (target) - { - if (num == i) + while (target){ + if( target->target_number == num ){ return target; + } target = target->next; - i++; } return NULL; @@ -192,18 +280,7 @@ target_t* get_target_by_num(int num) int get_num_by_target(target_t *query_target) { - target_t *target = targets; - int i = 0; - - while (target) - { - if (target == query_target) - return i; - target = target->next; - i++; - } - - return -1; + return query_target->target_number; } target_t* get_current_target(command_context_t *cmd_ctx) @@ -268,7 +345,7 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo int retval = ERROR_OK; target_t *target; - target = targets; + target = all_targets; while (target) { target_invoke_script(cmd_ctx, target, "pre_reset"); @@ -295,7 +372,7 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo keep_alive(); /* we might be running on a very slow JTAG clk */ - target = targets; + target = all_targets; while (target) { /* we have no idea what state the target is in, so we @@ -308,7 +385,7 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo target = target->next; } - target = targets; + target = all_targets; while (target) { if ((retval = target->type->deassert_reset(target))!=ERROR_OK) @@ -316,7 +393,7 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo target = target->next; } - target = targets; + target = all_targets; while (target) { /* We can fail to bring the target into the halted state, try after reset has been deasserted */ @@ -340,14 +417,15 @@ int target_process_reset(struct command_context_s *cmd_ctx, enum target_reset_mo if ((reset_mode == RESET_HALT) || (reset_mode == RESET_INIT)) { - target = targets; + target = all_targets; while (target) { /* Wait for reset to complete, maximum 5 seconds. */ if (((retval=target_wait_state(target, TARGET_HALTED, 5000)))==ERROR_OK) { - if (reset_mode == RESET_INIT) + if (reset_mode == RESET_INIT) target_invoke_script(cmd_ctx, target, "post_reset"); + } target = target->next; } @@ -386,7 +464,7 @@ static int default_examine(struct target_s *target) int target_examine(void) { int retval = ERROR_OK; - target_t *target = targets; + target_t *target = all_targets; while (target) { if ((retval = target->type->examine(target))!=ERROR_OK) @@ -438,7 +516,7 @@ static int target_run_algorithm_imp(struct target_s *target, int num_mem_params, int target_init(struct command_context_s *cmd_ctx) { - target_t *target = targets; + target_t *target = all_targets; while (target) { @@ -480,7 +558,7 @@ int target_init(struct command_context_s *cmd_ctx) target = target->next; } - if (targets) + if (all_targets) { target_register_user_commands(cmd_ctx); target_register_timer_callback(handle_target, 100, 1, NULL); @@ -612,6 +690,7 @@ int target_call_event_callbacks(target_t *target, enum target_event event) LOG_DEBUG("target event %i", event); + while (callback) { next_callback = callback->next; @@ -831,6 +910,7 @@ int target_register_commands(struct command_context_s *cmd_ctx) register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "PRELIMINARY! - profile "); + /* script procedures */ register_jim(cmd_ctx, "ocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing"); register_jim(cmd_ctx, "ocd_array2mem", jim_array2mem, "convert a TCL array to memory locations and write the values"); @@ -846,7 +926,8 @@ int target_arch_state(struct target_s *target) return ERROR_OK; } - LOG_USER("target state: %s", target_state_strings[target->state]); + LOG_USER("target state: %s", + Jim_Nvp_value2name_simple(nvp_target_state,target->state)->name); if (target->state!=TARGET_HALTED) return ERROR_OK; @@ -1228,30 +1309,51 @@ int target_register_user_commands(struct command_context_s *cmd_ctx) int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - target_t *target = targets; - int count = 0; + char *cp; + target_t *target = all_targets; if (argc == 1) { - int num = strtoul(args[0], NULL, 0); - - while (target) - { - count++; - target = target->next; - } - - if (num < count) - cmd_ctx->current_target = num; - else - command_print(cmd_ctx, "%i is out of bounds, only %i targets are configured", num, count); - + /* try as tcltarget name */ + for( target = all_targets ; target ; target++ ){ + if( target->cmd_name ){ + if( 0 == strcmp( args[0], target->cmd_name ) ){ + /* MATCH */ + goto Match; + } + } + } + /* no match, try as number */ + + int num = strtoul(args[0], &cp, 0 ); + if( *cp != 0 ){ + /* then it was not a number */ + command_print( cmd_ctx, "Target: %s unknown, try one of:\n", args[0] ); + goto DumpTargets; + } + + target = get_target_by_num( num ); + if( target == NULL ){ + command_print(cmd_ctx,"Target: %s is unknown, try one of:\n", args[0] ); + goto DumpTargets; + } + Match: + cmd_ctx->current_target = target->target_number; return ERROR_OK; } + DumpTargets: + command_print(cmd_ctx, " CmdName Type Endian State "); + command_print(cmd_ctx, "-- ---------- ---------- ---------- ----------"); while (target) { - command_print(cmd_ctx, "%i: %s (%s), state: %s", count++, target->type->name, target_endianess_strings[target->endianness], target_state_strings[target->state]); + /* XX: abcdefghij abcdefghij abcdefghij abcdefghij */ + command_print(cmd_ctx, "%2d: %-10s %-10s %-10s %s", + target->target_number, + "", // future: target->cmd_name + target->type->name, + Jim_Nvp_value2name_simple( nvp_target_endian, target->endianness )->name, + Jim_Nvp_value2name_simple( nvp_target_state, target->state )->name ); target = target->next; } @@ -1275,7 +1377,7 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a { if (strcmp(args[0], target_types[i]->name) == 0) { - target_t **last_target_p = &targets; + target_t **last_target_p = &all_targets; /* register target specific commands */ if (target_types[i]->register_commands(cmd_ctx) != ERROR_OK) @@ -1291,7 +1393,13 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a last_target_p = &((*last_target_p)->next); } - *last_target_p = malloc(sizeof(target_t)); + // get target number *before* adding new target to the list */ + i = new_target_number(); + // calloc will init the memory to zero for us + *last_target_p = calloc(1,sizeof(target_t)); + // save target number. + (*last_target_p)->cmd_name = NULL; + (*last_target_p)->target_number = i; /* allocate memory for each unique target type */ (*last_target_p)->type = (target_type_t*)malloc(sizeof(target_type_t)); @@ -1434,7 +1542,7 @@ int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, ch /* process target state changes */ int handle_target(void *priv) { - target_t *target = targets; + target_t *target = all_targets; while (target) { @@ -1642,13 +1750,15 @@ int target_wait_state(target_t *target, enum target_state state, int ms) if (once) { once=0; - LOG_DEBUG("waiting for target %s...", target_state_strings[state]); + LOG_DEBUG("waiting for target %s...", + Jim_Nvp_value2name_simple(nvp_target_state,state)->name); } gettimeofday(&now, NULL); if ((now.tv_sec > timeout.tv_sec) || ((now.tv_sec == timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec))) { - LOG_ERROR("timed out while waiting for target %s", target_state_strings[state]); + LOG_ERROR("timed out while waiting for target %s", + Jim_Nvp_value2name_simple(nvp_target_state,state)->name); return ERROR_FAIL; } } @@ -2571,8 +2681,27 @@ static int new_int_array_element(Jim_Interp * interp, const char *varname, int i static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - target_t *target; command_context_t *context; + target_t *target; + + context = Jim_GetAssocData(interp, "context"); + if (context == NULL) + { + LOG_ERROR("mem2array: no command context"); + return JIM_ERR; + } + target = get_current_target(context); + if (target == NULL) + { + LOG_ERROR("mem2array: no current target"); + return JIM_ERR; + } + + return target_mem2array(interp, target, argc,argv); +} + +static int target_mem2array(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv) +{ long l; u32 width; u32 len; @@ -2655,19 +2784,6 @@ static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } - context = Jim_GetAssocData(interp, "context"); - if (context == NULL) - { - LOG_ERROR("mem2array: no command context"); - return JIM_ERR; - } - target = get_current_target(context); - if (target == NULL) - { - LOG_ERROR("mem2array: no current target"); - return JIM_ERR; - } - /* Transfer loop */ /* index counter */ @@ -2748,8 +2864,26 @@ static int get_int_array_element(Jim_Interp * interp, const char *varname, int i static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - target_t *target; command_context_t *context; + target_t *target; + + context = Jim_GetAssocData(interp, "context"); + if (context == NULL){ + LOG_ERROR("array2mem: no command context"); + return JIM_ERR; + } + target = get_current_target(context); + if (target == NULL){ + LOG_ERROR("array2mem: no current target"); + return JIM_ERR; + } + + return target_array2mem( interp,target, argc, argv ); +} + + +static int target_array2mem(Jim_Interp *interp, target_t *target, int argc, Jim_Obj *const *argv) +{ long l; u32 width; u32 len; @@ -2832,18 +2966,6 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } - context = Jim_GetAssocData(interp, "context"); - if (context == NULL) - { - LOG_ERROR("array2mem: no command context"); - return JIM_ERR; - } - target = get_current_target(context); - if (target == NULL) - { - LOG_ERROR("array2mem: no current target"); - return JIM_ERR; - } /* Transfer loop */ @@ -2881,7 +3003,7 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv) /* BOO !*/ LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count); Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL); + Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: cannot read memory", NULL); e = JIM_ERR; len = 0; } @@ -2891,3 +3013,11 @@ static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_OK; } + + +/* + * Local Variables: *** + * c-basic-offset: 4 *** + * tab-width: 4 *** + * End: *** + */ diff --git a/src/target/target.h b/src/target/target.h index 621640a9ec..968d7ab8af 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -55,15 +55,25 @@ enum target_state TARGET_DEBUG_RUNNING = 4, }; -extern char *target_state_strings[]; +extern const Jim_Nvp nvp_target_state[]; + +enum nvp_assert { + NVP_DEASSERT, + NVP_ASSERT, +}; + +extern const Jim_Nvp nvp_assert[]; enum target_reset_mode { - RESET_RUN = 0, /* reset and let target run */ - RESET_HALT = 1, /* reset and halt target out of reset */ - RESET_INIT = 2, /* reset and halt target out of reset, then run init script */ + RESET_UNKNOWN = 0, + RESET_RUN = 1, /* reset and let target run */ + RESET_HALT = 2, /* reset and halt target out of reset */ + RESET_INIT = 3, /* reset and halt target out of reset, then run init script */ }; +extern const Jim_Nvp nvp_reset_mode[]; + enum target_debug_reason { DBG_REASON_DBGRQ = 0, @@ -75,14 +85,15 @@ enum target_debug_reason DBG_REASON_UNDEFINED = 6 }; -extern char *target_debug_reason_strings[]; +extern const Jim_Nvp nvp_target_debug_reason[]; enum target_endianess { - TARGET_BIG_ENDIAN = 0, TARGET_LITTLE_ENDIAN = 1 + TARGET_ENDIAN_UNKNOWN=0, + TARGET_BIG_ENDIAN = 1, TARGET_LITTLE_ENDIAN = 2 }; -extern char *target_endianess_strings[]; +extern const Jim_Nvp nvp_target_endian[]; struct target_s; @@ -190,6 +201,19 @@ typedef struct target_type_s int (*run_algorithm)(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_param, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info); int (*register_commands)(struct command_context_s *cmd_ctx); + /* called when target is created */ + int (*target_jim_create)( struct target_s *target, Jim_Interp *interp ); + + /* called for various config parameters */ + /* returns JIM_CONTINUE - if option not understood */ + /* otherwise: JIM_OK, or JIM_ERR, */ + int (*target_jim_configure)( struct target_s *target, Jim_GetOptInfo *goi ); + + /* target commands specifically handled by the target */ + /* returns JIM_OK, or JIM_ERR, or JIM_CONTINUE - if option not understood */ + int (*target_jim_commands)( struct target_s *target, Jim_GetOptInfo *goi ); + + /* old init function */ int (*target_command)(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target); /* invoked after JTAG chain has been examined & validated. During * this stage the target is examined and any additional setup is @@ -211,9 +235,19 @@ typedef struct target_type_s } target_type_t; +// forward decloration +typedef struct target_event_action_s target_event_action_t; + typedef struct target_s { target_type_t *type; /* target type definition (name, access functions) */ + const char *cmd_name; /* tcl Name of target */ + int target_number; /* generaly, target index but may not be in order */ + int chain_position; /* where on the jtag chain is this */ + const char *variant; /* what varient of this chip is it? */ + enum target_reset_mode reset_mode; /* how should this target be reset */ + target_event_action_t *event_action; + int reset_halt; /* attempt resetting the CPU into the halted mode? */ u32 working_area; /* working area (initialized RAM). Evaluated upon first allocation from virtual/physical address. */ @@ -237,14 +271,36 @@ typedef struct target_s enum target_event { - TARGET_EVENT_HALTED, /* target entered debug state from normal execution or reset */ - TARGET_EVENT_RESUMED, /* target resumed to normal execution */ - TARGET_EVENT_RESET, /* target entered reset */ - TARGET_EVENT_DEBUG_HALTED, /* target entered debug state, but was executing on behalf of the debugger */ - TARGET_EVENT_DEBUG_RESUMED, /* target resumed to execute on behalf of the debugger */ - TARGET_EVENT_GDB_PROGRAM /* target about to be be programmed by gdb */ + TARGET_EVENT_HALTED, /* target entered debug state from normal execution or reset */ + TARGET_EVENT_RESUMED, /* target resumed to normal execution */ + TARGET_EVENT_RESUME_START, + TARGET_EVENT_RESUME_END, + + TARGET_EVENT_RESET_START, + TARGET_EVENT_RESET, /* target entered reset */ + TARGET_EVENT_RESET_INIT, + TARGET_EVENT_RESET_END, + + TARGET_EVENT_DEBUG_HALTED, /* target entered debug state, but was executing on behalf of the debugger */ + TARGET_EVENT_DEBUG_RESUMED, /* target resumed to execute on behalf of the debugger */ + + TARGET_EVENT_GDB_ATTACH, + TARGET_EVENT_GDB_DETACH, + + TARGET_EVENT_GDB_FLASH_ERASE_START, + TARGET_EVENT_GDB_FLASH_ERASE_END, + TARGET_EVENT_GDB_FLASH_WRITE_START, + TARGET_EVENT_GDB_FLASH_WRITE_END, }; +extern const Jim_Nvp nvp_target_event[]; + +struct target_event_action_s { + enum target_event event; + Jim_Obj *body; + target_event_action_t *next; + }; + typedef struct target_event_callback_s { int (*callback)(struct target_s *target, enum target_event event, void *priv); @@ -314,15 +370,17 @@ extern int target_free_working_area_restore(struct target_s *target, working_are extern int target_free_all_working_areas(struct target_s *target); extern int target_free_all_working_areas_restore(struct target_s *target, int restore); -extern target_t *targets; +extern target_t *all_targets; extern target_event_callback_t *target_event_callbacks; extern target_timer_callback_t *target_timer_callbacks; extern u32 target_buffer_get_u32(target_t *target, u8 *buffer); extern u16 target_buffer_get_u16(target_t *target, u8 *buffer); +extern u8 target_buffer_get_u8 (target_t *target, u8 *buffer); extern void target_buffer_set_u32(target_t *target, u8 *buffer, u32 value); extern void target_buffer_set_u16(target_t *target, u8 *buffer, u16 value); +extern void target_buffer_set_u8 (target_t *target, u8 *buffer, u8 value); int target_read_u32(struct target_s *target, u32 address, u32 *value); int target_read_u16(struct target_s *target, u32 address, u16 *value); @@ -336,6 +394,7 @@ int target_arch_state(struct target_s *target); int target_invoke_script(struct command_context_s *cmd_ctx, target_t *target, char *name); + #define ERROR_TARGET_INVALID (-300) #define ERROR_TARGET_INIT_FAILED (-301) #define ERROR_TARGET_TIMEOUT (-302) @@ -346,5 +405,14 @@ int target_invoke_script(struct command_context_s *cmd_ctx, target_t *target, ch #define ERROR_TARGET_RESOURCE_NOT_AVAILABLE (-308) #define ERROR_TARGET_TRANSLATION_FAULT (-309) #define ERROR_TARGET_NOT_RUNNING (-310) +#define ERROR_TARGET_NOT_EXAMINED (-311) #endif /* TARGET_H */ + + +/* + * Local Variables: *** + * c-basic-offset: 4 *** + * tab-width: 4 *** + * End: *** + */ diff --git a/src/target/target_request.c b/src/target/target_request.c index 4d92704d09..72b29d31ad 100644 --- a/src/target/target_request.c +++ b/src/target/target_request.c @@ -176,18 +176,18 @@ int add_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target) debug_msg_receiver_t* find_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target) { - int all_targets = 0; + int do_all_targets = 0; debug_msg_receiver_t **p = &target->dbgmsg; /* if no target has been specified search all of them */ if (target == NULL) { /* if no targets haven been specified */ - if (targets == NULL) + if (all_targets == NULL) return NULL; - target = targets; - all_targets = 1; + target = all_targets; + do_all_targets = 1; } do @@ -202,7 +202,7 @@ debug_msg_receiver_t* find_debug_msg_receiver(struct command_context_s *cmd_ctx, } target = target->next; - } while (target && all_targets); + } while (target && do_all_targets); return NULL; } @@ -211,17 +211,17 @@ int delete_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *targe { debug_msg_receiver_t **p; debug_msg_receiver_t *c; - int all_targets = 0; + int do_all_targets = 0; /* if no target has been specified search all of them */ if (target == NULL) { /* if no targets haven been specified */ - if (targets == NULL) + if (all_targets == NULL) return ERROR_OK; - target = targets; - all_targets = 1; + target = all_targets; + do_all_targets = 1; } do @@ -248,7 +248,7 @@ int delete_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *targe } target = target->next; - } while (target && all_targets); + } while (target && do_all_targets); return ERROR_OK; } diff --git a/src/target/xscale.c b/src/target/xscale.c index e9ec0cee52..87fb6acd19 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -983,7 +983,7 @@ int xscale_arch_state(struct target_s *target) "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), @@ -1225,7 +1225,8 @@ int xscale_halt(target_t *target) 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) { @@ -1558,7 +1559,8 @@ int xscale_assert_reset(target_t *target) 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 diff --git a/src/tcl/chip/atmel/at91/rtt.tcl b/src/tcl/chip/atmel/at91/rtt.tcl index 56abb29e37..9c60300ee5 100644 --- a/src/tcl/chip/atmel/at91/rtt.tcl +++ b/src/tcl/chip/atmel/at91/rtt.tcl @@ -15,7 +15,9 @@ proc show_RTTC_RTMR_helper { NAME ADDR VAL } { set rtpres 65536; } global AT91C_SLOWOSC_FREQ - set f [expr double($AT91C_SLOWOSC_FREQ) / double($rtpres)] + # Nasty hack, make this a float by tacking a .0 on the end + # otherwise, jim makes the value an integer + set f [expr $AT91C_SLOWOSC_FREQ.0 / $rtpres.0] puts [format "\tPrescale value: 0x%04x (%5d) => %f Hz" $rtpres $rtpres $f] if { $VAL & $BIT16 } { puts "\tBit16 -> Alarm IRQ Enabled" -- 2.30.2