X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fetb.c;h=5aa85a1f153720359662611c91c2371a40e7179f;hb=76b3c6ece6f853daca937652df78b61df11c47f3;hp=f145f3021b3834f02c063d1cdd547821514fea2f;hpb=cb6ebced3df72668091d5920fef3fbc46ddbc7ac;p=openocd.git diff --git a/src/target/etb.c b/src/target/etb.c index f145f3021b..5aa85a1f15 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; @@ -160,15 +160,17 @@ reg_cache_t* etb_build_reg_cache(etb_t *etb) int etb_get_reg(reg_t *reg) { - if (etb_read_reg(reg) != ERROR_OK) + int retval; + if ((retval = etb_read_reg(reg)) != ERROR_OK) { - ERROR("BUG: error scheduling etm register read"); - exit(-1); + LOG_ERROR("BUG: error scheduling etm register read"); + return retval; } - if (jtag_execute_queue() != ERROR_OK) + if ((retval = jtag_execute_queue()) != ERROR_OK) { - ERROR("register read failed"); + LOG_ERROR("register read failed"); + return retval; } return ERROR_OK; @@ -215,7 +217,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 +233,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 +250,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 +288,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); @@ -311,10 +313,11 @@ int etb_read_reg(reg_t *reg) int etb_set_reg(reg_t *reg, u32 value) { - if (etb_write_reg(reg, value) != ERROR_OK) + int retval; + if ((retval = etb_write_reg(reg, value)) != ERROR_OK) { - ERROR("BUG: error scheduling etm register write"); - exit(-1); + LOG_ERROR("BUG: error scheduling etm register write"); + return retval; } buf_set_u32(reg->value, 0, reg->size, value); @@ -326,12 +329,13 @@ int etb_set_reg(reg_t *reg, u32 value) int etb_set_reg_w_exec(reg_t *reg, u8 *buf) { + int retval; etb_set_reg(reg, buf_get_u32(buf, 0, reg->size)); - if (jtag_execute_queue() != ERROR_OK) + if ((retval = jtag_execute_queue()) != ERROR_OK) { - ERROR("register write failed"); - exit(-1); + LOG_ERROR("register write failed"); + return retval; } return ERROR_OK; } @@ -342,7 +346,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 +385,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 +419,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 +427,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 +441,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 +459,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 +520,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 +573,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 +646,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 +664,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; @@ -640,9 +695,9 @@ int etb_start_capture(etm_context_t *etm_ctx) 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;