X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fetb.c;h=e81049d34a8ec02ab574df8d574d0c37722ff220;hp=81e20af01c23b86e7015f0cc5a655dfbb572a2d6;hb=d47e1b8f362379d8a2307f49e2b42115a3f40524;hpb=53d1f9b2ca5718e4996e9cf3406f857d0ed26df2 diff --git a/src/target/etb.c b/src/target/etb.c index 81e20af01c..e81049d34a 100644 --- a/src/target/etb.c +++ b/src/target/etb.c @@ -79,7 +79,7 @@ int etb_set_instr(etb_t *etb, u32 new_instr) field.in_handler = NULL; field.in_handler_priv = NULL; - jtag_add_ir_scan(1, &field, -1, NULL); + jtag_add_ir_scan(1, &field, -1); free(field.out_value); } @@ -106,7 +106,7 @@ int etb_scann(etb_t *etb, u32 new_scan_chain) /* select INTEST instruction */ etb_set_instr(etb, 0x2); - jtag_add_dr_scan(1, &field, -1, NULL); + jtag_add_dr_scan(1, &field, -1); etb->cur_scan_chain = new_scan_chain; @@ -162,13 +162,13 @@ int etb_get_reg(reg_t *reg) { if (etb_read_reg(reg) != ERROR_OK) { - ERROR("BUG: error scheduling etm register read"); + LOG_ERROR("BUG: error scheduling etm register read"); exit(-1); } if (jtag_execute_queue() != ERROR_OK) { - ERROR("register read failed"); + LOG_ERROR("register read failed"); } return ERROR_OK; @@ -215,7 +215,7 @@ int etb_read_ram(etb_t *etb, u32 *data, int num_frames) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1, NULL); + jtag_add_dr_scan(3, fields, -1); fields[0].in_handler = buf_to_u32_handler; @@ -231,7 +231,7 @@ int etb_read_ram(etb_t *etb, u32 *data, int num_frames) buf_set_u32(fields[1].out_value, 0, 7, 0); fields[0].in_handler_priv = &data[i]; - jtag_add_dr_scan(3, fields, -1, NULL); + jtag_add_dr_scan(3, fields, -1); } jtag_execute_queue(); @@ -248,7 +248,7 @@ int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) u8 reg_addr = etb_reg->addr & 0x7f; scan_field_t fields[3]; - DEBUG("%i", etb_reg->addr); + LOG_DEBUG("%i", etb_reg->addr); jtag_add_end_state(TAP_RTI); etb_scann(etb_reg->etb, 0x0); @@ -286,17 +286,17 @@ int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1, NULL); + jtag_add_dr_scan(3, fields, -1); /* read the identification register in the second run, to make sure we * don't read the ETB data register twice, skipping every second entry */ buf_set_u32(fields[1].out_value, 0, 7, 0x0); fields[0].in_value = reg->value; - fields[0].in_check_value = check_value; - fields[0].in_check_mask = check_mask; - - jtag_add_dr_scan(3, fields, -1, NULL); + + jtag_set_check_value(fields+0, check_value, check_mask, NULL); + + jtag_add_dr_scan(3, fields, -1); free(fields[1].out_value); free(fields[2].out_value); @@ -313,7 +313,7 @@ int etb_set_reg(reg_t *reg, u32 value) { if (etb_write_reg(reg, value) != ERROR_OK) { - ERROR("BUG: error scheduling etm register write"); + LOG_ERROR("BUG: error scheduling etm register write"); exit(-1); } @@ -330,7 +330,7 @@ int etb_set_reg_w_exec(reg_t *reg, u8 *buf) if (jtag_execute_queue() != ERROR_OK) { - ERROR("register write failed"); + LOG_ERROR("register write failed"); exit(-1); } return ERROR_OK; @@ -342,7 +342,7 @@ int etb_write_reg(reg_t *reg, u32 value) u8 reg_addr = etb_reg->addr & 0x7f; scan_field_t fields[3]; - DEBUG("%i: 0x%8.8x", etb_reg->addr, value); + LOG_DEBUG("%i: 0x%8.8x", etb_reg->addr, value); jtag_add_end_state(TAP_RTI); etb_scann(etb_reg->etb, 0x0); @@ -381,7 +381,7 @@ int etb_write_reg(reg_t *reg, u32 value) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1, NULL); + jtag_add_dr_scan(3, fields, -1); free(fields[0].out_value); free(fields[1].out_value); @@ -415,7 +415,7 @@ int handle_etb_config_command(struct command_context_s *cmd_ctx, char *cmd, char if (argc != 2) { - ERROR("incomplete 'etb config ' command"); + LOG_ERROR("incomplete 'etb config ' command"); exit(-1); } @@ -423,7 +423,7 @@ int handle_etb_config_command(struct command_context_s *cmd_ctx, char *cmd, char if (!target) { - ERROR("target number '%s' not defined", args[0]); + LOG_ERROR("target number '%s' not defined", args[0]); exit(-1); } @@ -437,7 +437,7 @@ int handle_etb_config_command(struct command_context_s *cmd_ctx, char *cmd, char if (!jtag_device) { - ERROR("jtag device number '%s' not defined", args[1]); + LOG_ERROR("jtag device number '%s' not defined", args[1]); exit(-1); } @@ -455,7 +455,7 @@ int handle_etb_config_command(struct command_context_s *cmd_ctx, char *cmd, char } else { - ERROR("target has no ETM defined, ETB left unconfigured"); + LOG_ERROR("target has no ETM defined, ETB left unconfigured"); } return ERROR_OK; @@ -516,13 +516,13 @@ trace_status_t etb_status(etm_context_t *etm_ctx) if (etb_timeout == 0) { - ERROR("AcqComp set but DFEmpty won't go high, ETB status: 0x%x", + LOG_ERROR("AcqComp set but DFEmpty won't go high, ETB status: 0x%x", buf_get_u32(etb_status_reg->value, 0, etb_status_reg->size)); } if (!(etm_ctx->capture_status && TRACE_TRIGGERED)) { - ERROR("trace completed, but no trigger condition detected"); + LOG_ERROR("trace completed, but no trigger condition detected"); } etm_ctx->capture_status &= ~TRACE_RUNNING; @@ -569,17 +569,66 @@ int etb_read_trace(etm_context_t *etm_ctx) free(etm_ctx->trace_data); } - if ((etm_ctx->portmode & ETM_PORT_MODE_MASK) == ETM_PORT_DEMUXED) + if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) + etm_ctx->trace_depth = num_frames * 3; + else if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT) etm_ctx->trace_depth = num_frames * 2; else etm_ctx->trace_depth = num_frames; - etm_ctx->trace_data= malloc(sizeof(etmv1_trace_data_t) * etm_ctx->trace_depth); + etm_ctx->trace_data = malloc(sizeof(etmv1_trace_data_t) * etm_ctx->trace_depth); for (i = 0, j = 0; i < num_frames; i++) { - if ((etm_ctx->portmode & ETM_PORT_MODE_MASK) == ETM_PORT_DEMUXED) + if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) + { + /* trace word j */ + etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; + etm_ctx->trace_data[j].packet = (trace_data[i] & 0x78) >> 3; + etm_ctx->trace_data[j].flags = 0; + if ((trace_data[i] & 0x80) >> 7) + { + etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; + } + if (etm_ctx->trace_data[j].pipestat == STAT_TR) + { + etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & 0x7; + etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE; + } + + /* trace word j+1 */ + etm_ctx->trace_data[j+1].pipestat = (trace_data[i] & 0x100) >> 8; + etm_ctx->trace_data[j+1].packet = (trace_data[i] & 0x7800) >> 11; + etm_ctx->trace_data[j+1].flags = 0; + if ((trace_data[i] & 0x8000) >> 15) + { + etm_ctx->trace_data[j+1].flags |= ETMV1_TRACESYNC_CYCLE; + } + if (etm_ctx->trace_data[j+1].pipestat == STAT_TR) + { + etm_ctx->trace_data[j+1].pipestat = etm_ctx->trace_data[j+1].packet & 0x7; + etm_ctx->trace_data[j+1].flags |= ETMV1_TRIGGER_CYCLE; + } + + /* trace word j+2 */ + etm_ctx->trace_data[j+2].pipestat = (trace_data[i] & 0x10000) >> 16; + etm_ctx->trace_data[j+2].packet = (trace_data[i] & 0x780000) >> 19; + etm_ctx->trace_data[j+2].flags = 0; + if ((trace_data[i] & 0x800000) >> 23) + { + etm_ctx->trace_data[j+2].flags |= ETMV1_TRACESYNC_CYCLE; + } + if (etm_ctx->trace_data[j+2].pipestat == STAT_TR) + { + etm_ctx->trace_data[j+2].pipestat = etm_ctx->trace_data[j+2].packet & 0x7; + etm_ctx->trace_data[j+2].flags |= ETMV1_TRIGGER_CYCLE; + } + + j += 3; + } + else if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT) { + /* trace word j */ etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; etm_ctx->trace_data[j].packet = (trace_data[i] & 0x7f8) >> 3; etm_ctx->trace_data[j].flags = 0; @@ -593,6 +642,7 @@ int etb_read_trace(etm_context_t *etm_ctx) etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE; } + /* trace word j+1 */ etm_ctx->trace_data[j+1].pipestat = (trace_data[i] & 0x7000) >> 12; etm_ctx->trace_data[j+1].packet = (trace_data[i] & 0x7f8000) >> 15; etm_ctx->trace_data[j+1].flags = 0; @@ -610,6 +660,7 @@ int etb_read_trace(etm_context_t *etm_ctx) } else { + /* trace word j */ etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; etm_ctx->trace_data[j].packet = (trace_data[i] & 0x7fff8) >> 3; etm_ctx->trace_data[j].flags = 0; @@ -636,12 +687,13 @@ int etb_start_capture(etm_context_t *etm_ctx) { etb_t *etb = etm_ctx->capture_driver_priv; u32 etb_ctrl_value = 0x1; + u32 trigger_count; if ((etm_ctx->portmode & ETM_PORT_MODE_MASK) == ETM_PORT_DEMUXED) { - if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) == ETM_PORT_16BIT) + if ((etm_ctx->portmode & ETM_PORT_WIDTH_MASK) != ETM_PORT_8BIT) { - DEBUG("ETB can't run in demultiplexed mode with a 16-bit port"); + LOG_ERROR("ETB can't run in demultiplexed mode with a 4 or 16 bit port"); return ERROR_ETM_PORTMODE_NOT_SUPPORTED; } etb_ctrl_value |= 0x2; @@ -650,7 +702,9 @@ int etb_start_capture(etm_context_t *etm_ctx) if ((etm_ctx->portmode & ETM_PORT_MODE_MASK) == ETM_PORT_MUXED) return ERROR_ETM_PORTMODE_NOT_SUPPORTED; - etb_write_reg(&etb->reg_cache->reg_list[ETB_TRIGGER_COUNTER], 0x600); + trigger_count = (etb->ram_depth * etm_ctx->trigger_percent) / 100; + + etb_write_reg(&etb->reg_cache->reg_list[ETB_TRIGGER_COUNTER], trigger_count); etb_write_reg(&etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER], 0x0); etb_write_reg(&etb->reg_cache->reg_list[ETB_CTRL], etb_ctrl_value); jtag_execute_queue();