stlink: add missing memory check handlers
[fw/openocd] / src / target / etm.c
index 67dac06fadabb51ed5c16ee102fc113c3700908d..de8bb8a416579eea2609de62a2e83f41677428ca 100644 (file)
@@ -314,7 +314,6 @@ struct reg_cache *etm_build_reg_cache(struct target *target,
 
        /* figure ETM version then add base registers */
        if (config & (1 << 31)) {
-               bcd_vers = 0x20;
                LOG_WARNING("ETMv2+ support is incomplete");
 
                /* REVISIT more registers may exist; they may now be
@@ -496,17 +495,21 @@ static int etm_read_reg_w_check(struct reg *reg,
        const struct etm_reg_info *r = etm_reg->reg_info;
        uint8_t reg_addr = r->addr & 0x7f;
        struct scan_field fields[3];
+       int retval;
 
        if (etm_reg->reg_info->mode == WO) {
                LOG_ERROR("BUG: can't read write-only register %s", r->name);
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        LOG_DEBUG("%s (%u)", r->name, reg_addr);
 
-       jtag_set_end_state(TAP_IDLE);
-       arm_jtag_scann(etm_reg->jtag_info, 0x6);
-       arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
+       retval = arm_jtag_scann(etm_reg->jtag_info, 0x6, TAP_IDLE);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL, TAP_IDLE);
+       if (retval != ERROR_OK)
+               return retval;
 
        fields[0].num_bits = 32;
        fields[0].out_value = reg->value;
@@ -515,29 +518,28 @@ static int etm_read_reg_w_check(struct reg *reg,
        fields[0].check_mask = NULL;
 
        fields[1].num_bits = 7;
-       fields[1].out_value = malloc(1);
-       buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
+       uint8_t temp1;
+       fields[1].out_value = &temp1;
+       buf_set_u32(&temp1, 0, 7, reg_addr);
        fields[1].in_value = NULL;
        fields[1].check_value = NULL;
        fields[1].check_mask = NULL;
 
        fields[2].num_bits = 1;
-       fields[2].out_value = malloc(1);
-       buf_set_u32(fields[2].out_value, 0, 1, 0);
+       uint8_t temp2;
+       fields[2].out_value = &temp2;
+       buf_set_u32(&temp2, 0, 1, 0);
        fields[2].in_value = NULL;
        fields[2].check_value = NULL;
        fields[2].check_mask = NULL;
 
-       jtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE);
 
        fields[0].in_value = reg->value;
        fields[0].check_value = check_value;
        fields[0].check_mask = check_mask;
 
-       jtag_add_dr_scan_check(etm_reg->jtag_info->tap, 3, fields, jtag_get_end_state());
-
-       free(fields[1].out_value);
-       free(fields[2].out_value);
+       jtag_add_dr_scan_check(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE);
 
        return ERROR_OK;
 }
@@ -579,37 +581,41 @@ static int etm_write_reg(struct reg *reg, uint32_t value)
        const struct etm_reg_info *r = etm_reg->reg_info;
        uint8_t reg_addr = r->addr & 0x7f;
        struct scan_field fields[3];
+       int retval;
 
        if (etm_reg->reg_info->mode == RO) {
                LOG_ERROR("BUG: can't write read--only register %s", r->name);
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        LOG_DEBUG("%s (%u): 0x%8.8" PRIx32 "", r->name, reg_addr, value);
 
-       jtag_set_end_state(TAP_IDLE);
-       arm_jtag_scann(etm_reg->jtag_info, 0x6);
-       arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL);
+       retval = arm_jtag_scann(etm_reg->jtag_info, 0x6, TAP_IDLE);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL, TAP_IDLE);
+       if (retval != ERROR_OK)
+               return retval;
 
        fields[0].num_bits = 32;
        uint8_t tmp1[4];
        fields[0].out_value = tmp1;
-       buf_set_u32(fields[0].out_value, 0, 32, value);
+       buf_set_u32(tmp1, 0, 32, value);
        fields[0].in_value = NULL;
 
        fields[1].num_bits = 7;
        uint8_t tmp2;
        fields[1].out_value = &tmp2;
-       buf_set_u32(fields[1].out_value, 0, 7, reg_addr);
+       buf_set_u32(&tmp2, 0, 7, reg_addr);
        fields[1].in_value = NULL;
 
        fields[2].num_bits = 1;
        uint8_t tmp3;
        fields[2].out_value = &tmp3;
-       buf_set_u32(fields[2].out_value, 0, 1, 1);
+       buf_set_u32(&tmp3, 0, 1, 1);
        fields[2].in_value = NULL;
 
-       jtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, jtag_get_end_state());
+       jtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE);
 
        return ERROR_OK;
 }
@@ -662,7 +668,7 @@ static int etm_read_instruction(struct etm_context *ctx, struct arm_instruction
                        ctx->current_pc - ctx->image->sections[section].base_address,
                        4, buf, &size_read)) != ERROR_OK)
                {
-                       LOG_ERROR("error while reading instruction: %i", retval);
+                       LOG_ERROR("error while reading instruction");
                        return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
                }
                opcode = target_buffer_get_u32(ctx->target, buf);
@@ -675,7 +681,7 @@ static int etm_read_instruction(struct etm_context *ctx, struct arm_instruction
                        ctx->current_pc - ctx->image->sections[section].base_address,
                        2, buf, &size_read)) != ERROR_OK)
                {
-                       LOG_ERROR("error while reading instruction: %i", retval);
+                       LOG_ERROR("error while reading instruction");
                        return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
                }
                opcode = target_buffer_get_u16(ctx->target, buf);
@@ -885,6 +891,11 @@ static int etmv1_analyze_trace(struct etm_context *ctx, struct command_context *
        if (ctx->trace_depth == 0)
                ctx->capture_driver->read_trace(ctx);
 
+       if (ctx->trace_depth == 0) {
+               command_print(cmd_ctx, "Trace is empty.");
+               return ERROR_OK;
+       }
+
        /* start at the beginning of the captured trace */
        ctx->pipe_index = 0;
        ctx->data_index = 0;
@@ -1185,7 +1196,7 @@ static COMMAND_HELPER(handle_etm_tracemode_command_update,
        else
        {
                command_print(CMD_CTX, "invalid option '%s'", CMD_ARGV[0]);
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        uint8_t context_id;
@@ -1206,7 +1217,7 @@ static COMMAND_HELPER(handle_etm_tracemode_command_update,
                break;
        default:
                command_print(CMD_CTX, "invalid option '%s'", CMD_ARGV[1]);
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        bool etmv1_cycle_accurate;
@@ -1257,13 +1268,7 @@ COMMAND_HANDLER(handle_etm_tracemode_command)
                                &tracemode);
                break;
        default:
-               command_print(CMD_CTX, "usage: tracemode "
-                               "('none'|'data'|'address'|'all') "
-                               "context_id_bits "
-                               "('enable'|'disable') "
-                               "('enable'|'disable')"
-                               );
-               return ERROR_FAIL;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        /**
@@ -1727,8 +1732,7 @@ COMMAND_HANDLER(handle_etm_image_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "usage: etm image <file> [base address] [type]");
-               return ERROR_FAIL;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        target = get_current_target(CMD_CTX);
@@ -1788,8 +1792,7 @@ COMMAND_HANDLER(handle_etm_dump_command)
 
        if (CMD_ARGC != 1)
        {
-               command_print(CMD_CTX, "usage: etm dump <file>");
-               return ERROR_FAIL;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        target = get_current_target(CMD_CTX);
@@ -1855,8 +1858,7 @@ COMMAND_HANDLER(handle_etm_load_command)
 
        if (CMD_ARGC != 1)
        {
-               command_print(CMD_CTX, "usage: etm load <file>");
-               return ERROR_FAIL;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        target = get_current_target(CMD_CTX);
@@ -1885,7 +1887,15 @@ COMMAND_HANDLER(handle_etm_load_command)
                return ERROR_FAIL;
        }
 
-       if (file.size % 4)
+       int filesize;
+       int retval = fileio_size(&file, &filesize);
+       if (retval != ERROR_OK)
+       {
+               fileio_close(&file);
+               return retval;
+       }
+
+       if (filesize % 4)
        {
                command_print(CMD_CTX, "size isn't a multiple of 4, no valid trace data");
                fileio_close(&file);
@@ -2089,6 +2099,7 @@ COMMAND_HANDLER(handle_etm_analyze_command)
 
        if ((retval = etmv1_analyze_trace(etm_ctx, CMD_CTX)) != ERROR_OK)
        {
+               /* FIX! error should be reported inside etmv1_analyze_trace() */
                switch (retval)
                {
                        case ERROR_ETM_ANALYSIS_FAILED:
@@ -2101,7 +2112,7 @@ COMMAND_HANDLER(handle_etm_analyze_command)
                                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");
                }
        }
 
@@ -2128,6 +2139,7 @@ const struct command_registration etm_command_handlers[] = {
                .name = "etm",
                .mode = COMMAND_ANY,
                .help = "Emebdded Trace Macrocell command group",
+               .usage = "",
                .chain = etm_config_command_handlers,
        },
        COMMAND_REGISTRATION_DONE
@@ -2148,24 +2160,28 @@ static const struct command_registration etm_exec_command_handlers[] = {
                .name = "info",
                .handler = handle_etm_info_command,
                .mode = COMMAND_EXEC,
+               .usage = "",
                .help = "display info about the current target's ETM",
        },
        {
                .name = "status",
                .handler = handle_etm_status_command,
                .mode = COMMAND_EXEC,
+               .usage = "",
                .help = "display current target's ETM status",
        },
        {
                .name = "start",
                .handler = handle_etm_start_command,
                .mode = COMMAND_EXEC,
+               .usage = "",
                .help = "start ETM trace collection",
        },
        {
                .name = "stop",
                .handler = handle_etm_stop_command,
                .mode = COMMAND_EXEC,
+               .usage = "",
                .help = "stop ETM trace collection",
        },
        {
@@ -2179,6 +2195,7 @@ static const struct command_registration etm_exec_command_handlers[] = {
                .name = "analyze",
                .handler = handle_etm_analyze_command,
                .mode = COMMAND_EXEC,
+               .usage = "",
                .help = "analyze collected ETM trace",
        },
        {
@@ -2186,7 +2203,7 @@ static const struct command_registration etm_exec_command_handlers[] = {
                .handler = handle_etm_image_command,
                .mode = COMMAND_EXEC,
                .help = "load image from file with optional offset",
-               .usage = "filename [offset]",
+               .usage = "<file> [base address] [type]",
        },
        {
                .name = "dump",
@@ -2199,6 +2216,7 @@ static const struct command_registration etm_exec_command_handlers[] = {
                .name = "load",
                .handler = handle_etm_load_command,
                .mode = COMMAND_EXEC,
+               .usage = "",
                .help = "load trace data for analysis <file>",
        },
        COMMAND_REGISTRATION_DONE