X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fetm.c;h=6d34f6c9ca89471226f0259643d1dfa2a1e1e2ff;hp=51065817dc413fb87281ea3d6d0872218417f5b5;hb=9f212b01be20da43ba534ad33b20419779c89335;hpb=344bed2f7eab5f4ff05fd944b1c476fc8a2103ba diff --git a/src/target/etm.c b/src/target/etm.c index 51065817dc..6d34f6c9ca 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -21,10 +21,9 @@ #include "config.h" #endif -#include "etm.h" +#include "armv4_5.h" #include "etb.h" #include "image.h" -#include "arm7_9_common.h" #include "arm_disassembler.h" @@ -73,11 +72,15 @@ struct etm_reg_info { * provide definitions for some previously-unused bits. */ -/* basic registers that are always there given the right ETM version */ +/* core registers used to version/configure the ETM */ static const struct etm_reg_info etm_core[] = { - /* NOTE: we "know" ETM_CONFIG is listed first */ + /* NOTE: we "know" the order here ... */ { ETM_CONFIG, 32, RO, 0x10, "ETM_config", }, + { ETM_ID, 32, RO, 0x20, "ETM_id", }, +}; +/* basic registers that are always there given the right ETM version */ +static const struct etm_reg_info etm_basic[] = { /* ETM Trace Registers */ { ETM_CTRL, 32, RW, 0x10, "ETM_ctrl", }, { ETM_TRIG_EVENT, 17, WO, 0x10, "ETM_trig_event", }, @@ -100,7 +103,10 @@ static const struct etm_reg_info etm_core[] = { /* REVISIT exclude VIEWDATA_CTRL2 when it's not there */ { 0x78, 12, WO, 0x20, "ETM_sync_freq", }, - { 0x79, 32, RO, 0x20, "ETM_id", }, + { 0x7a, 22, RO, 0x31, "ETM_config_code_ext", }, + { 0x7b, 32, WO, 0x31, "ETM_ext_input_select", }, + { 0x7c, 32, WO, 0x34, "ETM_trace_start_stop", }, + { 0x7d, 8, WO, 0x34, "ETM_behavior_control", }, }; static const struct etm_reg_info etm_fifofull[] = { @@ -311,10 +317,19 @@ reg_cache_t *etm_build_reg_cache(target_t *target, bcd_vers = 0x20; LOG_WARNING("ETMv2+ support is incomplete"); - /* REVISIT read ID register, distinguish ETMv3.3 etc; + /* REVISIT more registers may exist; they may now be + * readable; more register bits have defined meanings; * don't presume trace start/stop support is present; * and include any context ID comparator registers. */ + etm_reg_add(0x20, jtag_info, reg_cache, arch_info, + etm_core + 1, 1); + etm_get_reg(reg_list + 1); + etm_ctx->id = buf_get_u32( + (void *)&arch_info[1].value, 0, 32); + LOG_DEBUG("ETM ID: %08x", (unsigned) etm_ctx->id); + bcd_vers = 0x10 + (((etm_ctx->id) >> 4) & 0xff); + } else { switch (config >> 28) { case 7: @@ -344,7 +359,7 @@ reg_cache_t *etm_build_reg_cache(target_t *target, LOG_INFO("ETM v%d.%d", bcd_vers >> 4, bcd_vers & 0xf); etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info, - etm_core + 1, ARRAY_SIZE(etm_core) - 1); + etm_basic, ARRAY_SIZE(etm_basic)); /* address and data comparators; counters; outputs */ etm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info, @@ -392,7 +407,7 @@ reg_cache_t *etm_build_reg_cache(target_t *target, etb->reg_cache = reg_cache->next; } - + etm_ctx->reg_cache = reg_cache; return reg_cache; } @@ -410,9 +425,8 @@ int etm_setup(target_t *target) { int retval; uint32_t etm_ctrl_value; - armv4_5_common_t *armv4_5 = target->arch_info; - arm7_9_common_t *arm7_9 = armv4_5->arch_info; - etm_context_t *etm_ctx = arm7_9->etm_ctx; + struct arm *arm = target_to_arm(target); + etm_context_t *etm_ctx = arm->etm; reg_t *etm_ctrl_reg; etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL); @@ -426,9 +440,13 @@ int etm_setup(target_t *target) /* clear the ETM powerdown bit (0) */ etm_ctrl_value &= ~0x1; - /* configure port width (6:4), mode (17:16) and clocking (13) */ - etm_ctrl_value = (etm_ctrl_value & - ~ETM_PORT_WIDTH_MASK & ~ETM_PORT_MODE_MASK & ~ETM_PORT_CLOCK_MASK) + /* configure port width (21,6:4), mode (13,17:16) and + * for older modules clocking (13) + */ + etm_ctrl_value = (etm_ctrl_value + & ~ETM_PORT_WIDTH_MASK + & ~ETM_PORT_MODE_MASK + & ~ETM_PORT_CLOCK_MASK) | etm_ctx->portmode; buf_set_u32(etm_ctrl_reg->value, 0, etm_ctrl_reg->size, etm_ctrl_value); @@ -437,6 +455,10 @@ int etm_setup(target_t *target) if ((retval = jtag_execute_queue()) != ERROR_OK) return retval; + /* REVISIT for ETMv3.0 and later, read ETM_sys_config to + * verify that those width and mode settings are OK ... + */ + if ((retval = etm_ctx->capture_driver->init(etm_ctx)) != ERROR_OK) { LOG_ERROR("ETM capture driver initialization failed"); @@ -671,12 +693,12 @@ static int etm_read_instruction(etm_context_t *ctx, arm_instruction_t *instructi else if (ctx->core_state == ARMV4_5_STATE_JAZELLE) { LOG_ERROR("BUG: tracing of jazelle code not supported"); - exit(-1); + return ERROR_FAIL; } else { LOG_ERROR("BUG: unknown core state encountered"); - exit(-1); + return ERROR_FAIL; } return ERROR_OK; @@ -977,8 +999,7 @@ static int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd break; default: /* reserved */ LOG_ERROR("BUG: branch reason code 0x%" PRIx32 " is reserved", ctx->last_branch_reason); - exit(-1); - break; + return ERROR_FAIL; } /* if we got here the branch was a normal PC change @@ -1155,113 +1176,115 @@ static int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd return ERROR_OK; } -static int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +static COMMAND_HELPER(handle_etm_tracemode_command_update, + etmv1_tracemode_t *mode) { - target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; etmv1_tracemode_t tracemode; - target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + /* what parts of data access are traced? */ + if (strcmp(args[0], "none") == 0) + tracemode = ETMV1_TRACE_NONE; + else if (strcmp(args[0], "data") == 0) + tracemode = ETMV1_TRACE_DATA; + else if (strcmp(args[0], "address") == 0) + tracemode = ETMV1_TRACE_ADDR; + else if (strcmp(args[0], "all") == 0) + tracemode = ETMV1_TRACE_DATA | ETMV1_TRACE_ADDR; + else { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - return ERROR_OK; + command_print(cmd_ctx, "invalid option '%s'", args[0]); + return ERROR_INVALID_ARGUMENTS; } - if (!arm7_9->etm_ctx) - { - command_print(cmd_ctx, "current target doesn't have an ETM configured"); - return ERROR_OK; + uint8_t context_id; + COMMAND_PARSE_NUMBER(u8, args[1], context_id); + switch (context_id) + { + case 0: + tracemode |= ETMV1_CONTEXTID_NONE; + break; + case 8: + tracemode |= ETMV1_CONTEXTID_8; + break; + case 16: + tracemode |= ETMV1_CONTEXTID_16; + break; + case 32: + tracemode |= ETMV1_CONTEXTID_32; + break; + default: + command_print(cmd_ctx, "invalid option '%s'", args[1]); + return ERROR_INVALID_ARGUMENTS; } - tracemode = arm7_9->etm_ctx->tracemode; + if (strcmp(args[2], "enable") == 0) + tracemode |= ETMV1_CYCLE_ACCURATE; + else if (strcmp(args[2], "disable") == 0) + tracemode |= 0; + else + { + command_print(cmd_ctx, "invalid option '%s'", args[2]); + return ERROR_INVALID_ARGUMENTS; + } - if (argc == 4) + if (strcmp(args[3], "enable") == 0) + tracemode |= ETMV1_BRANCH_OUTPUT; + else if (strcmp(args[3], "disable") == 0) + tracemode |= 0; + else { - /* what parts of data access are traced? */ - if (strcmp(args[0], "none") == 0) - { - tracemode = ETMV1_TRACE_NONE; - } - else if (strcmp(args[0], "data") == 0) - { - tracemode = ETMV1_TRACE_DATA; - } - else if (strcmp(args[0], "address") == 0) - { - tracemode = ETMV1_TRACE_ADDR; - } - else if (strcmp(args[0], "all") == 0) - { - tracemode = ETMV1_TRACE_DATA | ETMV1_TRACE_ADDR; - } - else - { - command_print(cmd_ctx, "invalid option '%s'", args[0]); - return ERROR_OK; - } + command_print(cmd_ctx, "invalid option '%s'", args[3]); + return ERROR_INVALID_ARGUMENTS; + } - switch (strtol(args[1], NULL, 0)) - { - case 0: - tracemode |= ETMV1_CONTEXTID_NONE; - break; - case 8: - tracemode |= ETMV1_CONTEXTID_8; - break; - case 16: - tracemode |= ETMV1_CONTEXTID_16; - break; - case 32: - tracemode |= ETMV1_CONTEXTID_32; - break; - default: - command_print(cmd_ctx, "invalid option '%s'", args[1]); - return ERROR_OK; - } + /* IGNORED: + * - CPRT tracing (coprocessor register transfers) + * - debug request (causes debug entry on trigger) + * - stall on FIFOFULL (preventing tracedata lossage) + */ + *mode = tracemode; - if (strcmp(args[2], "enable") == 0) - { - tracemode |= ETMV1_CYCLE_ACCURATE; - } - else if (strcmp(args[2], "disable") == 0) - { - tracemode |= 0; - } - else - { - command_print(cmd_ctx, "invalid option '%s'", args[2]); - return ERROR_OK; - } + return ERROR_OK; +} - if (strcmp(args[3], "enable") == 0) - { - tracemode |= ETMV1_BRANCH_OUTPUT; - } - else if (strcmp(args[3], "disable") == 0) - { - tracemode |= 0; - } - else - { - command_print(cmd_ctx, "invalid option '%s'", args[2]); - return ERROR_OK; - } +COMMAND_HANDLER(handle_etm_tracemode_command) +{ + target_t *target = get_current_target(cmd_ctx); + struct arm *arm = target_to_arm(target); + struct etm *etm; - /* IGNORED: - * - CPRT tracing (coprocessor register transfers) - * - debug request (causes debug entry on trigger) - * - stall on FIFOFULL (preventing tracedata lossage) - */ + if (!is_arm(arm)) { + command_print(cmd_ctx, "ETM: current target isn't an ARM"); + return ERROR_FAIL; + } + + etm = arm->etm; + if (!etm) { + command_print(cmd_ctx, "current target doesn't have an ETM configured"); + return ERROR_FAIL; } - else if (argc != 0) + + etmv1_tracemode_t tracemode = etm->tracemode; + + switch (argc) { - command_print(cmd_ctx, "usage: configure trace mode "); - return ERROR_OK; + case 0: + break; + case 4: + CALL_COMMAND_HANDLER(handle_etm_tracemode_command_update, &tracemode); + break; + default: + command_print(cmd_ctx, "usage: configure trace mode " + " " + " "); + return ERROR_FAIL; } + /** + * todo: fail if parameters were invalid for this hardware, + * or couldn't be written; display actual hardware state... + */ + command_print(cmd_ctx, "current tracemode configuration:"); switch (tracemode & ETMV1_TRACE_MASK) @@ -1315,13 +1338,13 @@ static int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char } /* only update ETM_CTRL register if tracemode changed */ - if (arm7_9->etm_ctx->tracemode != tracemode) + if (etm->tracemode != tracemode) { reg_t *etm_ctrl_reg; - etm_ctrl_reg = etm_reg_lookup(arm7_9->etm_ctx, ETM_CTRL); + etm_ctrl_reg = etm_reg_lookup(etm, ETM_CTRL); if (!etm_ctrl_reg) - return ERROR_OK; + return ERROR_FAIL; etm_get_reg(etm_ctrl_reg); @@ -1331,53 +1354,63 @@ static int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char buf_set_u32(etm_ctrl_reg->value, 8, 1, (tracemode & ETMV1_BRANCH_OUTPUT) >> 9); etm_store_reg(etm_ctrl_reg); - arm7_9->etm_ctx->tracemode = tracemode; + etm->tracemode = tracemode; /* invalidate old trace data */ - arm7_9->etm_ctx->capture_status = TRACE_IDLE; - if (arm7_9->etm_ctx->trace_depth > 0) + etm->capture_status = TRACE_IDLE; + if (etm->trace_depth > 0) { - free(arm7_9->etm_ctx->trace_data); - arm7_9->etm_ctx->trace_data = NULL; + free(etm->trace_data); + etm->trace_data = NULL; } - arm7_9->etm_ctx->trace_depth = 0; + etm->trace_depth = 0; } return ERROR_OK; } -static int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_config_command) { target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; + struct arm *arm; etm_portmode_t portmode = 0x0; - etm_context_t *etm_ctx = malloc(sizeof(etm_context_t)); + struct etm *etm_ctx; int i; if (argc != 5) - { - free(etm_ctx); return ERROR_COMMAND_SYNTAX_ERROR; - } target = get_target(args[0]); if (!target) { LOG_ERROR("target '%s' not defined", args[0]); - free(etm_ctx); return ERROR_FAIL; } - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) - { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - free(etm_ctx); + arm = target_to_arm(target); + if (!is_arm(arm)) { + command_print(cmd_ctx, "target '%s' is '%s'; not an ARM", + target->cmd_name, target_get_name(target)); return ERROR_FAIL; } - switch (strtoul(args[1], NULL, 0)) + /* FIXME for ETMv3.0 and above -- and we don't yet know what ETM + * version we'll be using!! -- so we can't know how to validate + * params yet. "etm config" should likely be *AFTER* hookup... + * + * - Many more widths might be supported ... and we can easily + * check whether our setting "took". + * + * - The "clock" and "mode" bits are interpreted differently. + * See ARM IHI 0014O table 2-17 for the old behavior, and + * table 2-18 for the new. With ETB it's best to specify + * "normal full" ... + */ + uint8_t port_width; + COMMAND_PARSE_NUMBER(u8, args[1], port_width); + switch (port_width) { + /* before ETMv3.0 */ case 4: portmode |= ETM_PORT_4BIT; break; @@ -1387,9 +1420,28 @@ static int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cm case 16: portmode |= ETM_PORT_16BIT; break; + /* ETMv3.0 and later*/ + case 24: + portmode |= ETM_PORT_24BIT; + break; + case 32: + portmode |= ETM_PORT_32BIT; + break; + case 48: + portmode |= ETM_PORT_48BIT; + break; + case 64: + portmode |= ETM_PORT_64BIT; + break; + case 1: + portmode |= ETM_PORT_1BIT; + break; + case 2: + portmode |= ETM_PORT_2BIT; + break; default: - command_print(cmd_ctx, "unsupported ETM port width '%s', must be 4, 8 or 16", args[1]); - free(etm_ctx); + command_print(cmd_ctx, + "unsupported ETM port width '%s'", args[1]); return ERROR_FAIL; } @@ -1408,7 +1460,6 @@ static int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cm else { command_print(cmd_ctx, "unsupported ETM port mode '%s', must be 'normal', 'multiplexed' or 'demultiplexed'", args[2]); - free(etm_ctx); return ERROR_FAIL; } @@ -1423,7 +1474,12 @@ static int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cm else { command_print(cmd_ctx, "unsupported ETM port clocking '%s', must be 'full' or 'half'", args[3]); - free(etm_ctx); + return ERROR_FAIL; + } + + etm_ctx = calloc(1, sizeof(etm_context_t)); + if (!etm_ctx) { + LOG_DEBUG("out of memory"); return ERROR_FAIL; } @@ -1455,50 +1511,36 @@ static int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cm etm_ctx->target = target; etm_ctx->trigger_percent = 50; etm_ctx->trace_data = NULL; - etm_ctx->trace_depth = 0; etm_ctx->portmode = portmode; - etm_ctx->tracemode = 0x0; etm_ctx->core_state = ARMV4_5_STATE_ARM; - etm_ctx->image = NULL; - etm_ctx->pipe_index = 0; - etm_ctx->data_index = 0; - etm_ctx->current_pc = 0x0; - etm_ctx->pc_ok = 0; - etm_ctx->last_branch = 0x0; - etm_ctx->last_branch_reason = 0x0; - etm_ctx->last_ptr = 0x0; - etm_ctx->ptr_ok = 0x0; - etm_ctx->last_instruction = 0; - - arm7_9->etm_ctx = etm_ctx; + + arm->etm = etm_ctx; return etm_register_user_commands(cmd_ctx); } -static int handle_etm_info_command(struct command_context_s *cmd_ctx, - char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_info_command) { target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; + struct arm *arm; etm_context_t *etm; reg_t *etm_sys_config_reg; - int max_port_size; + uint32_t config; target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - return ERROR_OK; + command_print(cmd_ctx, "ETM: current target isn't an ARM"); + return ERROR_FAIL; } - etm = arm7_9->etm_ctx; + etm = arm->etm; if (!etm) { command_print(cmd_ctx, "current target doesn't have an ETM configured"); - return ERROR_OK; + return ERROR_FAIL; } command_print(cmd_ctx, "ETM v%d.%d", @@ -1523,6 +1565,9 @@ static int handle_etm_info_command(struct command_context_s *cmd_ctx, command_print(cmd_ctx, "protocol version: %i", (int) (etm->config >> 28) & 0x07); else { + command_print(cmd_ctx, + "coprocessor and memory access %ssupported", + (etm->config & (1 << 26)) ? "" : "not "); command_print(cmd_ctx, "trace start/stop %spresent", (etm->config & (1 << 26)) ? "" : "not "); command_print(cmd_ctx, "number of context comparators: %i", @@ -1535,9 +1580,16 @@ static int handle_etm_info_command(struct command_context_s *cmd_ctx, return ERROR_OK; etm_get_reg(etm_sys_config_reg); + config = buf_get_u32(etm_sys_config_reg->value, 0, 32); - switch (buf_get_u32(etm_sys_config_reg->value, 0, 3)) + LOG_DEBUG("ETM SYS CONFIG %08x", (unsigned) config); + + max_port_size = config & 0x7; + if (etm->bcd_vers >= 0x30) + max_port_size |= (config >> 6) & 0x08; + switch (max_port_size) { + /* before ETMv3.0 */ case 0: max_port_size = 4; break; @@ -1547,50 +1599,79 @@ static int handle_etm_info_command(struct command_context_s *cmd_ctx, case 2: max_port_size = 16; break; + /* ETMv3.0 and later*/ + case 3: + max_port_size = 24; + break; + case 4: + max_port_size = 32; + break; + case 5: + max_port_size = 48; + break; + case 6: + max_port_size = 64; + break; + case 8: + max_port_size = 1; + break; + case 9: + max_port_size = 2; + break; default: LOG_ERROR("Illegal max_port_size"); - exit(-1); + return ERROR_FAIL; } command_print(cmd_ctx, "max. port size: %i", max_port_size); - command_print(cmd_ctx, "half-rate clocking %ssupported", - (buf_get_u32(etm_sys_config_reg->value, 3, 1) == 1) ? "" : "not "); - command_print(cmd_ctx, "full-rate clocking %ssupported", - (buf_get_u32(etm_sys_config_reg->value, 4, 1) == 1) ? "" : "not "); - command_print(cmd_ctx, "normal trace format %ssupported", - (buf_get_u32(etm_sys_config_reg->value, 5, 1) == 1) ? "" : "not "); - command_print(cmd_ctx, "multiplex trace format %ssupported", - (buf_get_u32(etm_sys_config_reg->value, 6, 1) == 1) ? "" : "not "); - command_print(cmd_ctx, "demultiplex trace format %ssupported", - (buf_get_u32(etm_sys_config_reg->value, 7, 1) == 1) ? "" : "not "); + if (etm->bcd_vers < 0x30) { + command_print(cmd_ctx, "half-rate clocking %ssupported", + (config & (1 << 3)) ? "" : "not "); + command_print(cmd_ctx, "full-rate clocking %ssupported", + (config & (1 << 4)) ? "" : "not "); + command_print(cmd_ctx, "normal trace format %ssupported", + (config & (1 << 5)) ? "" : "not "); + command_print(cmd_ctx, "multiplex trace format %ssupported", + (config & (1 << 6)) ? "" : "not "); + command_print(cmd_ctx, "demultiplex trace format %ssupported", + (config & (1 << 7)) ? "" : "not "); + } else { + /* REVISIT show which size and format are selected ... */ + command_print(cmd_ctx, "current port size %ssupported", + (config & (1 << 10)) ? "" : "not "); + command_print(cmd_ctx, "current trace format %ssupported", + (config & (1 << 11)) ? "" : "not "); + } + if (etm->bcd_vers >= 0x21) + command_print(cmd_ctx, "fetch comparisons %ssupported", + (config & (1 << 17)) ? "not " : ""); command_print(cmd_ctx, "FIFO full %ssupported", - (buf_get_u32(etm_sys_config_reg->value, 8, 1) == 1) ? "" : "not "); + (config & (1 << 8)) ? "" : "not "); return ERROR_OK; } -static int handle_etm_status_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_status_command) { target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; + struct arm *arm; etm_context_t *etm; trace_status_t trace_status; target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - return ERROR_OK; + command_print(cmd_ctx, "ETM: current target isn't an ARM"); + return ERROR_FAIL; } - if (!arm7_9->etm_ctx) + etm = arm->etm; + if (!etm) { command_print(cmd_ctx, "current target doesn't have an ETM configured"); - return ERROR_OK; + return ERROR_FAIL; } - etm = arm7_9->etm_ctx; /* ETM status */ if (etm->bcd_vers >= 0x11) { @@ -1598,7 +1679,7 @@ static int handle_etm_status_command(struct command_context_s *cmd_ctx, char *cm reg = etm_reg_lookup(etm, ETM_STATUS); if (!reg) - return ERROR_OK; + return ERROR_FAIL; if (etm_get_reg(reg) == ERROR_OK) { unsigned s = buf_get_u32(reg->value, 0, reg->size); @@ -1646,31 +1727,31 @@ static int handle_etm_status_command(struct command_context_s *cmd_ctx, char *cm return ERROR_OK; } -static int handle_etm_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_image_command) { target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; + struct arm *arm; etm_context_t *etm_ctx; if (argc < 1) { command_print(cmd_ctx, "usage: etm image [base address] [type]"); - return ERROR_OK; + return ERROR_FAIL; } target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - return ERROR_OK; + command_print(cmd_ctx, "ETM: current target isn't an ARM"); + return ERROR_FAIL; } - if (!(etm_ctx = arm7_9->etm_ctx)) + etm_ctx = arm->etm; + if (!etm_ctx) { command_print(cmd_ctx, "current target doesn't have an ETM configured"); - return ERROR_OK; + return ERROR_FAIL; } if (etm_ctx->image) @@ -1688,7 +1769,7 @@ static int handle_etm_image_command(struct command_context_s *cmd_ctx, char *cmd if (argc >= 2) { etm_ctx->image->base_address_set = 1; - etm_ctx->image->base_address = strtoul(args[1], NULL, 0); + COMMAND_PARSE_NUMBER(int, args[1], etm_ctx->image->base_address); } else { @@ -1699,39 +1780,39 @@ static int handle_etm_image_command(struct command_context_s *cmd_ctx, char *cmd { free(etm_ctx->image); etm_ctx->image = NULL; - return ERROR_OK; + return ERROR_FAIL; } return ERROR_OK; } -static int handle_etm_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_dump_command) { - fileio_t file; + struct fileio file; target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; + struct arm *arm; etm_context_t *etm_ctx; uint32_t i; if (argc != 1) { command_print(cmd_ctx, "usage: etm dump "); - return ERROR_OK; + return ERROR_FAIL; } target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - return ERROR_OK; + command_print(cmd_ctx, "ETM: current target isn't an ARM"); + return ERROR_FAIL; } - if (!(etm_ctx = arm7_9->etm_ctx)) + etm_ctx = arm->etm; + if (!etm_ctx) { command_print(cmd_ctx, "current target doesn't have an ETM configured"); - return ERROR_OK; + return ERROR_FAIL; } if (etm_ctx->capture_driver->status == TRACE_IDLE) @@ -1744,7 +1825,7 @@ static int handle_etm_dump_command(struct command_context_s *cmd_ctx, char *cmd, { /* TODO: if on-the-fly capture is to be supported, this needs to be changed */ command_print(cmd_ctx, "trace capture not completed"); - return ERROR_OK; + return ERROR_FAIL; } /* read the trace data if it wasn't read already */ @@ -1753,7 +1834,7 @@ static int handle_etm_dump_command(struct command_context_s *cmd_ctx, char *cmd, if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK) { - return ERROR_OK; + return ERROR_FAIL; } fileio_write_u32(&file, etm_ctx->capture_status); @@ -1773,51 +1854,51 @@ static int handle_etm_dump_command(struct command_context_s *cmd_ctx, char *cmd, return ERROR_OK; } -static int handle_etm_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_load_command) { - fileio_t file; + struct fileio file; target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; + struct arm *arm; etm_context_t *etm_ctx; uint32_t i; if (argc != 1) { command_print(cmd_ctx, "usage: etm load "); - return ERROR_OK; + return ERROR_FAIL; } target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - return ERROR_OK; + command_print(cmd_ctx, "ETM: current target isn't an ARM"); + return ERROR_FAIL; } - if (!(etm_ctx = arm7_9->etm_ctx)) + etm_ctx = arm->etm; + if (!etm_ctx) { command_print(cmd_ctx, "current target doesn't have an ETM configured"); - return ERROR_OK; + return ERROR_FAIL; } if (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING) { command_print(cmd_ctx, "trace capture running, stop first"); - return ERROR_OK; + return ERROR_FAIL; } if (fileio_open(&file, args[0], FILEIO_READ, FILEIO_BINARY) != ERROR_OK) { - return ERROR_OK; + return ERROR_FAIL; } if (file.size % 4) { command_print(cmd_ctx, "size isn't a multiple of 4, no valid trace data"); fileio_close(&file); - return ERROR_OK; + return ERROR_FAIL; } if (etm_ctx->trace_depth > 0) @@ -1838,7 +1919,7 @@ static int handle_etm_load_command(struct command_context_s *cmd_ctx, char *cmd, { command_print(cmd_ctx, "not enough memory to perform operation"); fileio_close(&file); - return ERROR_OK; + return ERROR_FAIL; } for (i = 0; i < etm_ctx->trace_depth; i++) @@ -1857,30 +1938,31 @@ static int handle_etm_load_command(struct command_context_s *cmd_ctx, char *cmd, return ERROR_OK; } -static int handle_etm_trigger_percent_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_trigger_percent_command) { target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; + struct arm *arm; etm_context_t *etm_ctx; target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - return ERROR_OK; + command_print(cmd_ctx, "ETM: current target isn't an ARM"); + return ERROR_FAIL; } - if (!(etm_ctx = arm7_9->etm_ctx)) + etm_ctx = arm->etm; + if (!etm_ctx) { command_print(cmd_ctx, "current target doesn't have an ETM configured"); - return ERROR_OK; + return ERROR_FAIL; } if (argc > 0) { - uint32_t new_value = strtoul(args[0], NULL, 0); + uint32_t new_value; + COMMAND_PARSE_NUMBER(u32, args[0], new_value); if ((new_value < 2) || (new_value > 100)) { @@ -1897,40 +1979,40 @@ static int handle_etm_trigger_percent_command(struct command_context_s *cmd_ctx, return ERROR_OK; } -static int handle_etm_start_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_start_command) { target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; + struct arm *arm; etm_context_t *etm_ctx; reg_t *etm_ctrl_reg; target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - return ERROR_OK; + command_print(cmd_ctx, "ETM: current target isn't an ARM"); + return ERROR_FAIL; } - if (!(etm_ctx = arm7_9->etm_ctx)) + etm_ctx = arm->etm; + if (!etm_ctx) { command_print(cmd_ctx, "current target doesn't have an ETM configured"); - return ERROR_OK; + return ERROR_FAIL; } /* invalidate old tracing data */ - arm7_9->etm_ctx->capture_status = TRACE_IDLE; - if (arm7_9->etm_ctx->trace_depth > 0) + etm_ctx->capture_status = TRACE_IDLE; + if (etm_ctx->trace_depth > 0) { - free(arm7_9->etm_ctx->trace_data); - arm7_9->etm_ctx->trace_data = NULL; + free(etm_ctx->trace_data); + etm_ctx->trace_data = NULL; } - arm7_9->etm_ctx->trace_depth = 0; + etm_ctx->trace_depth = 0; etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL); if (!etm_ctrl_reg) - return ERROR_OK; + return ERROR_FAIL; etm_get_reg(etm_ctrl_reg); @@ -1945,31 +2027,31 @@ static int handle_etm_start_command(struct command_context_s *cmd_ctx, char *cmd return ERROR_OK; } -static int handle_etm_stop_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_stop_command) { target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; + struct arm *arm; etm_context_t *etm_ctx; reg_t *etm_ctrl_reg; target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - return ERROR_OK; + command_print(cmd_ctx, "ETM: current target isn't an ARM"); + return ERROR_FAIL; } - if (!(etm_ctx = arm7_9->etm_ctx)) + etm_ctx = arm->etm; + if (!etm_ctx) { command_print(cmd_ctx, "current target doesn't have an ETM configured"); - return ERROR_OK; + return ERROR_FAIL; } etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL); if (!etm_ctrl_reg) - return ERROR_OK; + return ERROR_FAIL; etm_get_reg(etm_ctrl_reg); @@ -1984,26 +2066,26 @@ static int handle_etm_stop_command(struct command_context_s *cmd_ctx, char *cmd, return ERROR_OK; } -static int handle_etm_analyze_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_analyze_command) { target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; + struct arm *arm; etm_context_t *etm_ctx; int retval; target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); - return ERROR_OK; + command_print(cmd_ctx, "ETM: current target isn't an ARM"); + return ERROR_FAIL; } - if (!(etm_ctx = arm7_9->etm_ctx)) + etm_ctx = arm->etm; + if (!etm_ctx) { command_print(cmd_ctx, "current target doesn't have an ETM configured"); - return ERROR_OK; + return ERROR_FAIL; } if ((retval = etmv1_analyze_trace(etm_ctx, cmd_ctx)) != ERROR_OK) @@ -2024,7 +2106,7 @@ static int handle_etm_analyze_command(struct command_context_s *cmd_ctx, char *c } } - return ERROR_OK; + return retval; } int etm_register_commands(struct command_context_s *cmd_ctx)