X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fetm.c;h=3b5fa61f33776741935e65bb982bdd7ce8e222ba;hp=795e0564577eced533b2712de771dabfc35b3edd;hb=2861877b32a7a2f4022a1c3d9b66c9b4879878ac;hpb=4b20ed6b5cf6bc73471dec7d1604a4684d1fc2ca diff --git a/src/target/etm.c b/src/target/etm.c index 795e056457..3b5fa61f33 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -21,11 +21,12 @@ #include "config.h" #endif +#include "armv4_5.h" #include "etm.h" #include "etb.h" #include "image.h" -#include "arm7_9_common.h" #include "arm_disassembler.h" +#include "register.h" /* @@ -50,8 +51,6 @@ * ARM IHI 0014O ... Embedded Trace Macrocell, Architecture Specification */ -#define ARRAY_SIZE(x) ((int)(sizeof(x)/sizeof((x)[0]))) - enum { RO, /* read/only */ WO, /* write/only */ @@ -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[] = { @@ -208,28 +214,30 @@ static const struct etm_reg_info etm_outputs[] = { { 0x6f, 32, RO, 0x20, "ETM_contextid_comparator_mask", } #endif -static int etm_reg_arch_type = -1; - -static int etm_get_reg(reg_t *reg); -static int etm_read_reg_w_check(reg_t *reg, +static int etm_get_reg(struct reg *reg); +static int etm_read_reg_w_check(struct reg *reg, uint8_t* check_value, uint8_t* check_mask); -static int etm_register_user_commands(struct command_context_s *cmd_ctx); -static int etm_set_reg_w_exec(reg_t *reg, uint8_t *buf); -static int etm_write_reg(reg_t *reg, uint32_t value); +static int etm_register_user_commands(struct command_context *cmd_ctx); +static int etm_set_reg_w_exec(struct reg *reg, uint8_t *buf); +static int etm_write_reg(struct reg *reg, uint32_t value); -static command_t *etm_cmd; +static struct command *etm_cmd; +static const struct reg_arch_type etm_scan6_type = { + .get = etm_get_reg, + .set = etm_set_reg_w_exec, +}; /* Look up register by ID ... most ETM instances only * support a subset of the possible registers. */ -static reg_t *etm_reg_lookup(etm_context_t *etm_ctx, unsigned id) +static struct reg *etm_reg_lookup(struct etm_context *etm_ctx, unsigned id) { - reg_cache_t *cache = etm_ctx->reg_cache; + struct reg_cache *cache = etm_ctx->reg_cache; int i; for (i = 0; i < cache->num_regs; i++) { - struct etm_reg_s *reg = cache->reg_list[i].arch_info; + struct etm_reg *reg = cache->reg_list[i].arch_info; if (reg->reg_info->addr == id) return &cache->reg_list[i]; @@ -241,11 +249,11 @@ static reg_t *etm_reg_lookup(etm_context_t *etm_ctx, unsigned id) return NULL; } -static void etm_reg_add(unsigned bcd_vers, arm_jtag_t *jtag_info, - reg_cache_t *cache, etm_reg_t *ereg, +static void etm_reg_add(unsigned bcd_vers, struct arm_jtag *jtag_info, + struct reg_cache *cache, struct etm_reg *ereg, const struct etm_reg_info *r, unsigned nreg) { - reg_t *reg = cache->reg_list; + struct reg *reg = cache->reg_list; reg += cache->num_regs; ereg += cache->num_regs; @@ -263,7 +271,7 @@ static void etm_reg_add(unsigned bcd_vers, arm_jtag_t *jtag_info, reg->size = r->size; reg->value = &ereg->value; reg->arch_info = ereg; - reg->arch_type = etm_reg_arch_type; + reg->type = &etm_scan6_type; reg++; cache->num_regs++; @@ -273,22 +281,17 @@ static void etm_reg_add(unsigned bcd_vers, arm_jtag_t *jtag_info, } } -reg_cache_t *etm_build_reg_cache(target_t *target, - arm_jtag_t *jtag_info, etm_context_t *etm_ctx) +struct reg_cache *etm_build_reg_cache(struct target *target, + struct arm_jtag *jtag_info, struct etm_context *etm_ctx) { - reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t)); - reg_t *reg_list = NULL; - etm_reg_t *arch_info = NULL; + struct reg_cache *reg_cache = malloc(sizeof(struct reg_cache)); + struct reg *reg_list = NULL; + struct etm_reg *arch_info = NULL; unsigned bcd_vers, config; - /* register a register arch-type for etm registers only once */ - if (etm_reg_arch_type == -1) - etm_reg_arch_type = register_reg_arch_type(etm_get_reg, - etm_set_reg_w_exec); - /* the actual registers are kept in two arrays */ - reg_list = calloc(128, sizeof(reg_t)); - arch_info = calloc(128, sizeof(etm_reg_t)); + reg_list = calloc(128, sizeof(struct reg)); + arch_info = calloc(128, sizeof(struct etm_reg)); /* fill in values for the reg cache */ reg_cache->name = "etm registers"; @@ -311,10 +314,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: @@ -334,17 +346,14 @@ reg_cache_t *etm_build_reg_cache(target_t *target, break; default: LOG_WARNING("Bad ETMv1 protocol %d", config >> 28); - free(reg_cache); - free(reg_list); - free(arch_info); - return ERROR_OK; + goto fail; } } etm_ctx->bcd_vers = bcd_vers; 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, @@ -376,15 +385,12 @@ reg_cache_t *etm_build_reg_cache(target_t *target, /* the ETM might have an ETB connected */ if (strcmp(etm_ctx->capture_driver->name, "etb") == 0) { - etb_t *etb = etm_ctx->capture_driver_priv; + struct etb *etb = etm_ctx->capture_driver_priv; if (!etb) { LOG_ERROR("etb selected as etm capture driver, but no ETB configured"); - free(reg_cache); - free(reg_list); - free(arch_info); - return ERROR_OK; + goto fail; } reg_cache->next = etb_build_reg_cache(etb); @@ -392,27 +398,33 @@ 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; + +fail: + free(reg_cache); + free(reg_list); + free(arch_info); + return NULL; } -static int etm_read_reg(reg_t *reg) +static int etm_read_reg(struct reg *reg) { return etm_read_reg_w_check(reg, NULL, NULL); } -static int etm_store_reg(reg_t *reg) +static int etm_store_reg(struct reg *reg) { return etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size)); } -int etm_setup(target_t *target) +int etm_setup(struct target *target) { int retval; uint32_t etm_ctrl_value; - struct arm7_9_common_s *arm7_9 = target_to_arm7_9(target); - etm_context_t *etm_ctx = arm7_9->etm_ctx; - reg_t *etm_ctrl_reg; + struct arm *arm = target_to_arm(target); + struct etm_context *etm_ctx = arm->etm; + struct reg *etm_ctrl_reg; etm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL); if (!etm_ctrl_reg) @@ -425,9 +437,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); @@ -436,6 +452,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"); @@ -444,7 +464,7 @@ int etm_setup(target_t *target) return ERROR_OK; } -static int etm_get_reg(reg_t *reg) +static int etm_get_reg(struct reg *reg) { int retval; @@ -463,13 +483,13 @@ static int etm_get_reg(reg_t *reg) return ERROR_OK; } -static int etm_read_reg_w_check(reg_t *reg, +static int etm_read_reg_w_check(struct reg *reg, uint8_t* check_value, uint8_t* check_mask) { - etm_reg_t *etm_reg = reg->arch_info; + struct etm_reg *etm_reg = reg->arch_info; const struct etm_reg_info *r = etm_reg->reg_info; uint8_t reg_addr = r->addr & 0x7f; - scan_field_t fields[3]; + struct scan_field fields[3]; if (etm_reg->reg_info->mode == WO) { LOG_ERROR("BUG: can't read write-only register %s", r->name); @@ -519,7 +539,7 @@ static int etm_read_reg_w_check(reg_t *reg, return ERROR_OK; } -static int etm_set_reg(reg_t *reg, uint32_t value) +static int etm_set_reg(struct reg *reg, uint32_t value) { int retval; @@ -536,7 +556,7 @@ static int etm_set_reg(reg_t *reg, uint32_t value) return ERROR_OK; } -static int etm_set_reg_w_exec(reg_t *reg, uint8_t *buf) +static int etm_set_reg_w_exec(struct reg *reg, uint8_t *buf) { int retval; @@ -550,12 +570,12 @@ static int etm_set_reg_w_exec(reg_t *reg, uint8_t *buf) return ERROR_OK; } -static int etm_write_reg(reg_t *reg, uint32_t value) +static int etm_write_reg(struct reg *reg, uint32_t value) { - etm_reg_t *etm_reg = reg->arch_info; + struct etm_reg *etm_reg = reg->arch_info; const struct etm_reg_info *r = etm_reg->reg_info; uint8_t reg_addr = r->addr & 0x7f; - scan_field_t fields[3]; + struct scan_field fields[3]; if (etm_reg->reg_info->mode == RO) { LOG_ERROR("BUG: can't write read--only register %s", r->name); @@ -598,12 +618,12 @@ static int etm_write_reg(reg_t *reg, uint32_t value) /* ETM trace analysis functionality * */ -extern etm_capture_driver_t etm_dummy_capture_driver; +extern struct etm_capture_driver etm_dummy_capture_driver; #if BUILD_OOCD_TRACE == 1 -extern etm_capture_driver_t oocd_trace_capture_driver; +extern struct etm_capture_driver oocd_trace_capture_driver; #endif -static etm_capture_driver_t *etm_capture_drivers[] = +static struct etm_capture_driver *etm_capture_drivers[] = { &etb_capture_driver, &etm_dummy_capture_driver, @@ -613,11 +633,11 @@ static etm_capture_driver_t *etm_capture_drivers[] = NULL }; -static int etm_read_instruction(etm_context_t *ctx, arm_instruction_t *instruction) +static int etm_read_instruction(struct etm_context *ctx, struct arm_instruction *instruction) { int i; int section = -1; - uint32_t size_read; + size_t size_read; uint32_t opcode; int retval; @@ -681,7 +701,7 @@ static int etm_read_instruction(etm_context_t *ctx, arm_instruction_t *instructi return ERROR_OK; } -static int etmv1_next_packet(etm_context_t *ctx, uint8_t *packet, int apo) +static int etmv1_next_packet(struct etm_context *ctx, uint8_t *packet, int apo) { while (ctx->data_index < ctx->trace_depth) { @@ -746,7 +766,7 @@ static int etmv1_next_packet(etm_context_t *ctx, uint8_t *packet, int apo) return -1; } -static int etmv1_branch_address(etm_context_t *ctx) +static int etmv1_branch_address(struct etm_context *ctx) { int retval; uint8_t packet; @@ -832,7 +852,7 @@ static int etmv1_branch_address(etm_context_t *ctx) return 0; } -static int etmv1_data(etm_context_t *ctx, int size, uint32_t *data) +static int etmv1_data(struct etm_context *ctx, int size, uint32_t *data) { int j; uint8_t buf[4]; @@ -861,10 +881,10 @@ static int etmv1_data(etm_context_t *ctx, int size, uint32_t *data) return 0; } -static int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd_ctx) +static int etmv1_analyze_trace(struct etm_context *ctx, struct command_context *cmd_ctx) { int retval; - arm_instruction_t instruction; + struct arm_instruction instruction; /* read the trace data if it wasn't read already */ if (ctx->trace_depth == 0) @@ -1153,29 +1173,28 @@ static int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd return ERROR_OK; } -static int handle_etm_tracemode_command_update( - struct command_context_s *cmd_ctx, - char **args, etmv1_tracemode_t *mode) +static COMMAND_HELPER(handle_etm_tracemode_command_update, + etmv1_tracemode_t *mode) { etmv1_tracemode_t tracemode; /* what parts of data access are traced? */ - if (strcmp(args[0], "none") == 0) + if (strcmp(CMD_ARGV[0], "none") == 0) tracemode = ETMV1_TRACE_NONE; - else if (strcmp(args[0], "data") == 0) + else if (strcmp(CMD_ARGV[0], "data") == 0) tracemode = ETMV1_TRACE_DATA; - else if (strcmp(args[0], "address") == 0) + else if (strcmp(CMD_ARGV[0], "address") == 0) tracemode = ETMV1_TRACE_ADDR; - else if (strcmp(args[0], "all") == 0) + else if (strcmp(CMD_ARGV[0], "all") == 0) tracemode = ETMV1_TRACE_DATA | ETMV1_TRACE_ADDR; else { - command_print(cmd_ctx, "invalid option '%s'", args[0]); + command_print(CMD_CTX, "invalid option '%s'", CMD_ARGV[0]); return ERROR_INVALID_ARGUMENTS; } uint8_t context_id; - COMMAND_PARSE_NUMBER(u8, args[1], context_id); + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], context_id); switch (context_id) { case 0: @@ -1191,27 +1210,27 @@ static int handle_etm_tracemode_command_update( tracemode |= ETMV1_CONTEXTID_32; break; default: - command_print(cmd_ctx, "invalid option '%s'", args[1]); + command_print(CMD_CTX, "invalid option '%s'", CMD_ARGV[1]); return ERROR_INVALID_ARGUMENTS; } - if (strcmp(args[2], "enable") == 0) + if (strcmp(CMD_ARGV[2], "enable") == 0) tracemode |= ETMV1_CYCLE_ACCURATE; - else if (strcmp(args[2], "disable") == 0) + else if (strcmp(CMD_ARGV[2], "disable") == 0) tracemode |= 0; else { - command_print(cmd_ctx, "invalid option '%s'", args[2]); + command_print(CMD_CTX, "invalid option '%s'", CMD_ARGV[2]); return ERROR_INVALID_ARGUMENTS; } - if (strcmp(args[3], "enable") == 0) + if (strcmp(CMD_ARGV[3], "enable") == 0) tracemode |= ETMV1_BRANCH_OUTPUT; - else if (strcmp(args[3], "disable") == 0) + else if (strcmp(CMD_ARGV[3], "disable") == 0) tracemode |= 0; else { - command_print(cmd_ctx, "invalid option '%s'", args[3]); + command_print(CMD_CTX, "invalid option '%s'", CMD_ARGV[3]); return ERROR_INVALID_ARGUMENTS; } @@ -1225,37 +1244,34 @@ static int handle_etm_tracemode_command_update( return ERROR_OK; } -static int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, - char *cmd, char **args, int argc) +COMMAND_HANDLER(handle_etm_tracemode_command) { - target_t *target = get_current_target(cmd_ctx); - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; - struct etm *etm; + struct target *target = get_current_target(CMD_CTX); + struct arm *arm = target_to_arm(target); + struct etm_context *etm; - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) - { - command_print(cmd_ctx, "ETM: current target isn't an ARM"); + if (!is_arm(arm)) { + 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"); + command_print(CMD_CTX, "current target doesn't have an ETM configured"); return ERROR_FAIL; } etmv1_tracemode_t tracemode = etm->tracemode; - switch (argc) + switch (CMD_ARGC) { case 0: break; case 4: - handle_etm_tracemode_command_update(cmd_ctx, args, &tracemode); + CALL_COMMAND_HANDLER(handle_etm_tracemode_command_update, &tracemode); break; default: - command_print(cmd_ctx, "usage: configure trace mode " + command_print(CMD_CTX, "usage: configure trace mode " " " " "); return ERROR_FAIL; @@ -1266,62 +1282,62 @@ static int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, * or couldn't be written; display actual hardware state... */ - command_print(cmd_ctx, "current tracemode configuration:"); + command_print(CMD_CTX, "current tracemode configuration:"); switch (tracemode & ETMV1_TRACE_MASK) { case ETMV1_TRACE_NONE: - command_print(cmd_ctx, "data tracing: none"); + command_print(CMD_CTX, "data tracing: none"); break; case ETMV1_TRACE_DATA: - command_print(cmd_ctx, "data tracing: data only"); + command_print(CMD_CTX, "data tracing: data only"); break; case ETMV1_TRACE_ADDR: - command_print(cmd_ctx, "data tracing: address only"); + command_print(CMD_CTX, "data tracing: address only"); break; case ETMV1_TRACE_DATA | ETMV1_TRACE_ADDR: - command_print(cmd_ctx, "data tracing: address and data"); + command_print(CMD_CTX, "data tracing: address and data"); break; } switch (tracemode & ETMV1_CONTEXTID_MASK) { case ETMV1_CONTEXTID_NONE: - command_print(cmd_ctx, "contextid tracing: none"); + command_print(CMD_CTX, "contextid tracing: none"); break; case ETMV1_CONTEXTID_8: - command_print(cmd_ctx, "contextid tracing: 8 bit"); + command_print(CMD_CTX, "contextid tracing: 8 bit"); break; case ETMV1_CONTEXTID_16: - command_print(cmd_ctx, "contextid tracing: 16 bit"); + command_print(CMD_CTX, "contextid tracing: 16 bit"); break; case ETMV1_CONTEXTID_32: - command_print(cmd_ctx, "contextid tracing: 32 bit"); + command_print(CMD_CTX, "contextid tracing: 32 bit"); break; } if (tracemode & ETMV1_CYCLE_ACCURATE) { - command_print(cmd_ctx, "cycle-accurate tracing enabled"); + command_print(CMD_CTX, "cycle-accurate tracing enabled"); } else { - command_print(cmd_ctx, "cycle-accurate tracing disabled"); + command_print(CMD_CTX, "cycle-accurate tracing disabled"); } if (tracemode & ETMV1_BRANCH_OUTPUT) { - command_print(cmd_ctx, "full branch address output enabled"); + command_print(CMD_CTX, "full branch address output enabled"); } else { - command_print(cmd_ctx, "full branch address output disabled"); + command_print(CMD_CTX, "full branch address output disabled"); } /* only update ETM_CTRL register if tracemode changed */ if (etm->tracemode != tracemode) { - reg_t *etm_ctrl_reg; + struct reg *etm_ctrl_reg; etm_ctrl_reg = etm_reg_lookup(etm, ETM_CTRL); if (!etm_ctrl_reg) @@ -1350,37 +1366,48 @@ static int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, 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; + struct target *target; struct arm *arm; - arm7_9_common_t *arm7_9; etm_portmode_t portmode = 0x0; - struct etm *etm_ctx; + struct etm_context *etm_ctx; int i; - if (argc != 5) + if (CMD_ARGC != 5) return ERROR_COMMAND_SYNTAX_ERROR; - target = get_target(args[0]); + target = get_target(CMD_ARGV[0]); if (!target) { - LOG_ERROR("target '%s' not defined", args[0]); + LOG_ERROR("target '%s' not defined", CMD_ARGV[0]); return ERROR_FAIL; } - if (arm7_9_get_arch_pointers(target, &arm, &arm7_9) != ERROR_OK) - { - command_print(cmd_ctx, "target '%s' is '%s'; not an ARM", + 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; } + /* 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); + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], port_width); switch (port_width) { + /* before ETMv3.0 */ case 4: portmode |= ETM_PORT_4BIT; break; @@ -1390,44 +1417,64 @@ static int handle_etm_config_command(struct command_context_s *cmd_ctx, 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]); + command_print(CMD_CTX, + "unsupported ETM port width '%s'", CMD_ARGV[1]); return ERROR_FAIL; } - if (strcmp("normal", args[2]) == 0) + if (strcmp("normal", CMD_ARGV[2]) == 0) { portmode |= ETM_PORT_NORMAL; } - else if (strcmp("multiplexed", args[2]) == 0) + else if (strcmp("multiplexed", CMD_ARGV[2]) == 0) { portmode |= ETM_PORT_MUXED; } - else if (strcmp("demultiplexed", args[2]) == 0) + else if (strcmp("demultiplexed", CMD_ARGV[2]) == 0) { portmode |= ETM_PORT_DEMUXED; } else { - command_print(cmd_ctx, "unsupported ETM port mode '%s', must be 'normal', 'multiplexed' or 'demultiplexed'", args[2]); + command_print(CMD_CTX, "unsupported ETM port mode '%s', must be 'normal', 'multiplexed' or 'demultiplexed'", CMD_ARGV[2]); return ERROR_FAIL; } - if (strcmp("half", args[3]) == 0) + if (strcmp("half", CMD_ARGV[3]) == 0) { portmode |= ETM_PORT_HALF_CLOCK; } - else if (strcmp("full", args[3]) == 0) + else if (strcmp("full", CMD_ARGV[3]) == 0) { portmode |= ETM_PORT_FULL_CLOCK; } else { - command_print(cmd_ctx, "unsupported ETM port clocking '%s', must be 'full' or 'half'", args[3]); + command_print(CMD_CTX, "unsupported ETM port clocking '%s', must be 'full' or 'half'", CMD_ARGV[3]); return ERROR_FAIL; } - etm_ctx = calloc(1, sizeof(etm_context_t)); + etm_ctx = calloc(1, sizeof(struct etm_context)); if (!etm_ctx) { LOG_DEBUG("out of memory"); return ERROR_FAIL; @@ -1435,10 +1482,10 @@ static int handle_etm_config_command(struct command_context_s *cmd_ctx, for (i = 0; etm_capture_drivers[i]; i++) { - if (strcmp(args[4], etm_capture_drivers[i]->name) == 0) + if (strcmp(CMD_ARGV[4], etm_capture_drivers[i]->name) == 0) { int retval; - if ((retval = etm_capture_drivers[i]->register_commands(cmd_ctx)) != ERROR_OK) + if ((retval = etm_capture_drivers[i]->register_commands(CMD_CTX)) != ERROR_OK) { free(etm_ctx); return retval; @@ -1454,7 +1501,7 @@ static int handle_etm_config_command(struct command_context_s *cmd_ctx, { /* no supported capture driver found, don't register an ETM */ free(etm_ctx); - LOG_ERROR("trace capture driver '%s' not found", args[4]); + LOG_ERROR("trace capture driver '%s' not found", CMD_ARGV[4]); return ERROR_FAIL; } @@ -1464,63 +1511,63 @@ static int handle_etm_config_command(struct command_context_s *cmd_ctx, etm_ctx->portmode = portmode; etm_ctx->core_state = ARMV4_5_STATE_ARM; - arm7_9->etm_ctx = etm_ctx; arm->etm = etm_ctx; - return etm_register_user_commands(cmd_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; - etm_context_t *etm; - reg_t *etm_sys_config_reg; - + struct target *target; + struct arm *arm; + struct etm_context *etm; + struct reg *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) + target = get_current_target(CMD_CTX); + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "ETM: current target isn't an ARM"); + 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"); + command_print(CMD_CTX, "current target doesn't have an ETM configured"); return ERROR_FAIL; } - command_print(cmd_ctx, "ETM v%d.%d", + command_print(CMD_CTX, "ETM v%d.%d", etm->bcd_vers >> 4, etm->bcd_vers & 0xf); - command_print(cmd_ctx, "pairs of address comparators: %i", + command_print(CMD_CTX, "pairs of address comparators: %i", (int) (etm->config >> 0) & 0x0f); - command_print(cmd_ctx, "data comparators: %i", + command_print(CMD_CTX, "data comparators: %i", (int) (etm->config >> 4) & 0x0f); - command_print(cmd_ctx, "memory map decoders: %i", + command_print(CMD_CTX, "memory map decoders: %i", (int) (etm->config >> 8) & 0x1f); - command_print(cmd_ctx, "number of counters: %i", + command_print(CMD_CTX, "number of counters: %i", (int) (etm->config >> 13) & 0x07); - command_print(cmd_ctx, "sequencer %spresent", + command_print(CMD_CTX, "sequencer %spresent", (int) (etm->config & (1 << 16)) ? "" : "not "); - command_print(cmd_ctx, "number of ext. inputs: %i", + command_print(CMD_CTX, "number of ext. inputs: %i", (int) (etm->config >> 17) & 0x07); - command_print(cmd_ctx, "number of ext. outputs: %i", + command_print(CMD_CTX, "number of ext. outputs: %i", (int) (etm->config >> 20) & 0x07); - command_print(cmd_ctx, "FIFO full %spresent", + command_print(CMD_CTX, "FIFO full %spresent", (int) (etm->config & (1 << 23)) ? "" : "not "); if (etm->bcd_vers < 0x20) - command_print(cmd_ctx, "protocol version: %i", + command_print(CMD_CTX, "protocol version: %i", (int) (etm->config >> 28) & 0x07); else { - command_print(cmd_ctx, "trace start/stop %spresent", + command_print(CMD_CTX, + "coprocessor and memory access %ssupported", (etm->config & (1 << 26)) ? "" : "not "); - command_print(cmd_ctx, "number of context comparators: %i", + command_print(CMD_CTX, "trace start/stop %spresent", + (etm->config & (1 << 26)) ? "" : "not "); + command_print(CMD_CTX, "number of context comparators: %i", (int) (etm->config >> 24) & 0x03); } @@ -1530,9 +1577,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); + + LOG_DEBUG("ETM SYS CONFIG %08x", (unsigned) config); - switch (buf_get_u32(etm_sys_config_reg->value, 0, 3)) + 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; @@ -1542,55 +1596,83 @@ 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"); 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 "); - command_print(cmd_ctx, "FIFO full %ssupported", - (buf_get_u32(etm_sys_config_reg->value, 8, 1) == 1) ? "" : "not "); + command_print(CMD_CTX, "max. port size: %i", max_port_size); + + 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", + (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; - etm_context_t *etm; + struct target *target; + struct arm *arm; + struct etm_context *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) + target = get_current_target(CMD_CTX); + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "ETM: current target isn't an ARM"); + 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"); + command_print(CMD_CTX, "current target doesn't have an ETM configured"); return ERROR_FAIL; } - etm = arm7_9->etm_ctx; /* ETM status */ if (etm->bcd_vers >= 0x11) { - reg_t *reg; + struct reg *reg; reg = etm_reg_lookup(etm, ETM_STATUS); if (!reg) @@ -1598,7 +1680,7 @@ static int handle_etm_status_command(struct command_context_s *cmd_ctx, if (etm_get_reg(reg) == ERROR_OK) { unsigned s = buf_get_u32(reg->value, 0, reg->size); - command_print(cmd_ctx, "etm: %s%s%s%s", + command_print(CMD_CTX, "etm: %s%s%s%s", /* bit(1) == progbit */ (etm->bcd_vers >= 0x12) ? ((s & (1 << 1)) @@ -1617,7 +1699,7 @@ static int handle_etm_status_command(struct command_context_s *cmd_ctx, trace_status = etm->capture_driver->status(etm); if (trace_status == TRACE_IDLE) { - command_print(cmd_ctx, "%s: idle", etm->capture_driver->name); + command_print(CMD_CTX, "%s: idle", etm->capture_driver->name); } else { @@ -1626,7 +1708,7 @@ static int handle_etm_status_command(struct command_context_s *cmd_ctx, static char *overflowed = ", overflowed"; static char *triggered = ", triggered"; - command_print(cmd_ctx, "%s: trace collection%s%s%s", + command_print(CMD_CTX, "%s: trace collection%s%s%s", etm->capture_driver->name, (trace_status & TRACE_RUNNING) ? running : completed, (trace_status & TRACE_OVERFLOWED) ? overflowed : "", @@ -1634,7 +1716,7 @@ static int handle_etm_status_command(struct command_context_s *cmd_ctx, if (etm->trace_depth > 0) { - command_print(cmd_ctx, "%i frames of trace data read", + command_print(CMD_CTX, "%i frames of trace data read", (int)(etm->trace_depth)); } } @@ -1642,31 +1724,30 @@ static int handle_etm_status_command(struct command_context_s *cmd_ctx, 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; - etm_context_t *etm_ctx; + struct target *target; + struct arm *arm; + struct etm_context *etm_ctx; - if (argc < 1) + if (CMD_ARGC < 1) { - command_print(cmd_ctx, "usage: etm image [base address] [type]"); + command_print(CMD_CTX, "usage: etm image [base address] [type]"); return ERROR_FAIL; } - target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + target = get_current_target(CMD_CTX); + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "ETM: current target isn't an ARM"); + 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"); + command_print(CMD_CTX, "current target doesn't have an ETM configured"); return ERROR_FAIL; } @@ -1674,25 +1755,25 @@ static int handle_etm_image_command(struct command_context_s *cmd_ctx, { image_close(etm_ctx->image); free(etm_ctx->image); - command_print(cmd_ctx, "previously loaded image found and closed"); + command_print(CMD_CTX, "previously loaded image found and closed"); } - etm_ctx->image = malloc(sizeof(image_t)); + etm_ctx->image = malloc(sizeof(struct image)); etm_ctx->image->base_address_set = 0; etm_ctx->image->start_address_set = 0; /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */ - if (argc >= 2) + if (CMD_ARGC >= 2) { etm_ctx->image->base_address_set = 1; - COMMAND_PARSE_NUMBER(int, args[1], etm_ctx->image->base_address); + COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], etm_ctx->image->base_address); } else { etm_ctx->image->base_address_set = 0; } - if (image_open(etm_ctx->image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK) + if (image_open(etm_ctx->image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK) { free(etm_ctx->image); etm_ctx->image = NULL; @@ -1702,46 +1783,45 @@ static int handle_etm_image_command(struct command_context_s *cmd_ctx, 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; - target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; - etm_context_t *etm_ctx; + struct fileio file; + struct target *target; + struct arm *arm; + struct etm_context *etm_ctx; uint32_t i; - if (argc != 1) + if (CMD_ARGC != 1) { - command_print(cmd_ctx, "usage: etm dump "); + command_print(CMD_CTX, "usage: etm dump "); return ERROR_FAIL; } - target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + target = get_current_target(CMD_CTX); + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "ETM: current target isn't an ARM"); + 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"); + command_print(CMD_CTX, "current target doesn't have an ETM configured"); return ERROR_FAIL; } if (etm_ctx->capture_driver->status == TRACE_IDLE) { - command_print(cmd_ctx, "trace capture wasn't enabled, no trace data captured"); + command_print(CMD_CTX, "trace capture wasn't enabled, no trace data captured"); return ERROR_OK; } if (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING) { /* TODO: if on-the-fly capture is to be supported, this needs to be changed */ - command_print(cmd_ctx, "trace capture not completed"); + command_print(CMD_CTX, "trace capture not completed"); return ERROR_FAIL; } @@ -1749,7 +1829,7 @@ static int handle_etm_dump_command(struct command_context_s *cmd_ctx, if (etm_ctx->trace_depth == 0) etm_ctx->capture_driver->read_trace(etm_ctx); - if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK) + if (fileio_open(&file, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK) { return ERROR_FAIL; } @@ -1771,50 +1851,49 @@ static int handle_etm_dump_command(struct command_context_s *cmd_ctx, 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; - target_t *target; - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; - etm_context_t *etm_ctx; + struct fileio file; + struct target *target; + struct arm *arm; + struct etm_context *etm_ctx; uint32_t i; - if (argc != 1) + if (CMD_ARGC != 1) { - command_print(cmd_ctx, "usage: etm load "); + command_print(CMD_CTX, "usage: etm load "); return ERROR_FAIL; } - target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + target = get_current_target(CMD_CTX); + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "ETM: current target isn't an ARM"); + 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"); + command_print(CMD_CTX, "current target doesn't have an ETM configured"); return ERROR_FAIL; } if (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING) { - command_print(cmd_ctx, "trace capture running, stop first"); + command_print(CMD_CTX, "trace capture running, stop first"); return ERROR_FAIL; } - if (fileio_open(&file, args[0], FILEIO_READ, FILEIO_BINARY) != ERROR_OK) + if (fileio_open(&file, CMD_ARGV[0], FILEIO_READ, FILEIO_BINARY) != ERROR_OK) { return ERROR_FAIL; } if (file.size % 4) { - command_print(cmd_ctx, "size isn't a multiple of 4, no valid trace data"); + command_print(CMD_CTX, "size isn't a multiple of 4, no valid trace data"); fileio_close(&file); return ERROR_FAIL; } @@ -1832,10 +1911,10 @@ static int handle_etm_load_command(struct command_context_s *cmd_ctx, fileio_read_u32(&file, &tmp); etm_ctx->tracemode = tmp; fileio_read_u32(&file, &etm_ctx->trace_depth); } - etm_ctx->trace_data = malloc(sizeof(etmv1_trace_data_t) * etm_ctx->trace_depth); + etm_ctx->trace_data = malloc(sizeof(struct etmv1_trace_data) * etm_ctx->trace_depth); if (etm_ctx->trace_data == NULL) { - command_print(cmd_ctx, "not enough memory to perform operation"); + command_print(CMD_CTX, "not enough memory to perform operation"); fileio_close(&file); return ERROR_FAIL; } @@ -1856,36 +1935,35 @@ static int handle_etm_load_command(struct command_context_s *cmd_ctx, 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; - etm_context_t *etm_ctx; - - target = get_current_target(cmd_ctx); + struct target *target; + struct arm *arm; + struct etm_context *etm_ctx; - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + target = get_current_target(CMD_CTX); + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "ETM: current target isn't an ARM"); + 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"); + command_print(CMD_CTX, "current target doesn't have an ETM configured"); return ERROR_FAIL; } - if (argc > 0) + if (CMD_ARGC > 0) { uint32_t new_value; - COMMAND_PARSE_NUMBER(u32, args[0], new_value); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], new_value); if ((new_value < 2) || (new_value > 100)) { - command_print(cmd_ctx, "valid settings are 2%% to 100%%"); + command_print(CMD_CTX, "valid settings are 2%% to 100%%"); } else { @@ -1893,32 +1971,30 @@ static int handle_etm_trigger_percent_command(struct command_context_s *cmd_ctx, } } - command_print(cmd_ctx, "%i percent of the tracebuffer reserved for after the trigger", ((int)(etm_ctx->trigger_percent))); + command_print(CMD_CTX, "%i percent of the tracebuffer reserved for after the trigger", ((int)(etm_ctx->trigger_percent))); 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; - etm_context_t *etm_ctx; - reg_t *etm_ctrl_reg; - - target = get_current_target(cmd_ctx); + struct target *target; + struct arm *arm; + struct etm_context *etm_ctx; + struct reg *etm_ctrl_reg; - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + target = get_current_target(CMD_CTX); + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "ETM: current target isn't an ARM"); + command_print(CMD_CTX, "ETM: current target isn't an ARM"); return ERROR_FAIL; } - 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"); + command_print(CMD_CTX, "current target doesn't have an ETM configured"); return ERROR_FAIL; } @@ -1948,26 +2024,25 @@ static int handle_etm_start_command(struct command_context_s *cmd_ctx, 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; - etm_context_t *etm_ctx; - reg_t *etm_ctrl_reg; - - target = get_current_target(cmd_ctx); + struct target *target; + struct arm *arm; + struct etm_context *etm_ctx; + struct reg *etm_ctrl_reg; - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + target = get_current_target(CMD_CTX); + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "ETM: current target isn't an ARM"); + 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"); + command_print(CMD_CTX, "current target doesn't have an ETM configured"); return ERROR_FAIL; } @@ -1988,51 +2063,50 @@ static int handle_etm_stop_command(struct command_context_s *cmd_ctx, 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; - etm_context_t *etm_ctx; + struct target *target; + struct arm *arm; + struct etm_context *etm_ctx; int retval; - target = get_current_target(cmd_ctx); - - if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) + target = get_current_target(CMD_CTX); + arm = target_to_arm(target); + if (!is_arm(arm)) { - command_print(cmd_ctx, "ETM: current target isn't an ARM"); + 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"); + command_print(CMD_CTX, "current target doesn't have an ETM configured"); return ERROR_FAIL; } - if ((retval = etmv1_analyze_trace(etm_ctx, cmd_ctx)) != ERROR_OK) + if ((retval = etmv1_analyze_trace(etm_ctx, CMD_CTX)) != ERROR_OK) { switch (retval) { case ERROR_ETM_ANALYSIS_FAILED: - command_print(cmd_ctx, "further analysis failed (corrupted trace data or just end of data"); + command_print(CMD_CTX, "further analysis failed (corrupted trace data or just end of data"); break; case ERROR_TRACE_INSTRUCTION_UNAVAILABLE: - command_print(cmd_ctx, "no instruction for current address available, analysis aborted"); + command_print(CMD_CTX, "no instruction for current address available, analysis aborted"); break; case ERROR_TRACE_IMAGE_UNAVAILABLE: - command_print(cmd_ctx, "no image available for trace analysis"); + command_print(CMD_CTX, "no image available for trace analysis"); break; default: - command_print(cmd_ctx, "unknown error: %i", retval); + command_print(CMD_CTX, "unknown error: %i", retval); } } return retval; } -int etm_register_commands(struct command_context_s *cmd_ctx) +int etm_register_commands(struct command_context *cmd_ctx) { etm_cmd = register_command(cmd_ctx, NULL, "etm", NULL, COMMAND_ANY, "Embedded Trace Macrocell"); @@ -2042,7 +2116,7 @@ int etm_register_commands(struct command_context_s *cmd_ctx) return ERROR_OK; } -static int etm_register_user_commands(struct command_context_s *cmd_ctx) +static int etm_register_user_commands(struct command_context *cmd_ctx) { register_command(cmd_ctx, etm_cmd, "tracemode", handle_etm_tracemode_command, COMMAND_EXEC, "configure/display trace mode: "