]> git.sur5r.net Git - openocd/blobdiff - src/target/etm.c
Reset wip. Just adding hooks. This is just to reduce the size of the actual change...
[openocd] / src / target / etm.c
index cbe3db5932549798a9795b83f8f2aa49fd14d0bc..c6749c5cd1f2c0cc187828188c999209c6a5d13d 100644 (file)
@@ -278,7 +278,7 @@ reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, etm_co
                
                if (!etb)
                {
-                       ERROR("etb selected as etm capture driver, but no ETB configured");
+                       LOG_ERROR("etb selected as etm capture driver, but no ETB configured");
                        return ERROR_OK;
                }
                
@@ -289,7 +289,7 @@ reg_cache_t* etm_build_reg_cache(target_t *target, arm_jtag_t *jtag_info, etm_co
        
        if (etm_ctx->capture_driver->init(etm_ctx) != ERROR_OK)
        {
-               ERROR("ETM capture driver initialization failed");
+               LOG_ERROR("ETM capture driver initialization failed");
                exit(-1);
        }
        
@@ -300,13 +300,13 @@ int etm_get_reg(reg_t *reg)
 {
        if (etm_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;
@@ -318,7 +318,7 @@ int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
        u8 reg_addr = etm_reg->addr & 0x7f;
        scan_field_t fields[3];
        
-       DEBUG("%i", etm_reg->addr);
+       LOG_DEBUG("%i", etm_reg->addr);
 
        jtag_add_end_state(TAP_RTI);
        arm_jtag_scann(etm_reg->jtag_info, 0x6);
@@ -356,13 +356,12 @@ int etm_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);
        
        fields[0].in_value = reg->value;
-       fields[0].in_check_value = check_value;
-       fields[0].in_check_mask = check_mask;
+       jtag_set_check_value(fields+0, check_value, check_mask, NULL);  
                
-       jtag_add_dr_scan(3, fields, -1, NULL);
+       jtag_add_dr_scan(3, fields, -1);
 
        free(fields[1].out_value);
        free(fields[2].out_value);
@@ -379,7 +378,7 @@ int etm_set_reg(reg_t *reg, u32 value)
 {
        if (etm_write_reg(reg, value) != ERROR_OK)
        {
-               ERROR("BUG: error scheduling etm register write");
+               LOG_ERROR("BUG: error scheduling etm register write");
                exit(-1);
        }
        
@@ -396,7 +395,7 @@ int etm_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;
@@ -408,7 +407,7 @@ int etm_write_reg(reg_t *reg, u32 value)
        u8 reg_addr = etm_reg->addr & 0x7f;
        scan_field_t fields[3];
        
-       DEBUG("%i: 0x%8.8x", etm_reg->addr, value);
+       LOG_DEBUG("%i: 0x%8.8x", etm_reg->addr, value);
        
        jtag_add_end_state(TAP_RTI);
        arm_jtag_scann(etm_reg->jtag_info, 0x6);
@@ -447,7 +446,7 @@ int etm_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);
@@ -527,7 +526,7 @@ int etm_read_instruction(etm_context_t *ctx, arm_instruction_t *instruction)
                        ctx->current_pc - ctx->image->sections[section].base_address,
                        4, buf, &size_read)) != ERROR_OK)
                {
-                       ERROR("error while reading instruction: %i", retval);
+                       LOG_ERROR("error while reading instruction: %i", retval);
                        return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
                }
                opcode = target_buffer_get_u32(ctx->target, buf);
@@ -540,7 +539,7 @@ int etm_read_instruction(etm_context_t *ctx, arm_instruction_t *instruction)
                        ctx->current_pc - ctx->image->sections[section].base_address,
                        2, buf, &size_read)) != ERROR_OK)
                {
-                       ERROR("error while reading instruction: %i", retval);
+                       LOG_ERROR("error while reading instruction: %i", retval);
                        return ERROR_TRACE_INSTRUCTION_UNAVAILABLE;
                }
                opcode = target_buffer_get_u16(ctx->target, buf);
@@ -548,12 +547,12 @@ int etm_read_instruction(etm_context_t *ctx, arm_instruction_t *instruction)
        }
        else if (ctx->core_state == ARMV4_5_STATE_JAZELLE)
        {
-               ERROR("BUG: tracing of jazelle code not supported");
+               LOG_ERROR("BUG: tracing of jazelle code not supported");
                exit(-1);
        }
        else
        {
-               ERROR("BUG: unknown core state encountered");
+               LOG_ERROR("BUG: unknown core state encountered");
                exit(-1);
        }
        
@@ -724,13 +723,18 @@ int etmv1_data(etm_context_t *ctx, int size, u32 *data)
        }
        
        if (size == 8)
-               ERROR("TODO: add support for 64-bit values");
+       {
+               LOG_ERROR("TODO: add support for 64-bit values");
+               return -1;
+       }
        else if (size == 4)
                *data = target_buffer_get_u32(ctx->target, buf);
        else if (size == 2)
                *data = target_buffer_get_u16(ctx->target, buf);
        else if (size == 1)
                *data = buf[0];
+       else
+               return -1;
                
        return 0;
 }
@@ -762,6 +766,7 @@ int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd_ctx)
                u32 old_index = ctx->pipe_index;
                u32 last_instruction = ctx->last_instruction;
                u32 cycles = 0;
+               int current_pc_ok = ctx->pc_ok;
                
                if (ctx->trace_data[ctx->pipe_index].flags & ETMV1_TRIGGER_CYCLE)
                {
@@ -803,7 +808,7 @@ int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd_ctx)
                                /* a positive return values means the current branch was abandoned,
                                 * and a new branch was encountered in cycle ctx->pipe_index + retval;
                                 */
-                               WARNING("abandoned branch encountered, correctnes of analysis uncertain");
+                               LOG_WARNING("abandoned branch encountered, correctnes of analysis uncertain");
                                ctx->pipe_index += retval;
                                continue;
                        }
@@ -836,9 +841,19 @@ int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd_ctx)
                                        break;
                                case 0x4:       /* periodic synchronization point */
                                        next_pc = ctx->last_branch;
+                                       /* if we had no valid PC prior to this synchronization point,
+                                        * we have to move on with the next trace cycle
+                                        */
+                                       if (!current_pc_ok)
+                                       {
+                                               command_print(cmd_ctx, "--- periodic synchronization point at 0x%8.8x ---", next_pc);
+                                               ctx->current_pc = next_pc;
+                                               ctx->pipe_index++;
+                                               continue;
+                                       }
                                        break;
                                default:        /* reserved */
-                                       ERROR("BUG: branch reason code 0x%x is reserved", ctx->last_branch_reason);             
+                                       LOG_ERROR("BUG: branch reason code 0x%x is reserved", ctx->last_branch_reason);         
                                        exit(-1);
                                        break;
                        }
@@ -883,7 +898,9 @@ int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd_ctx)
                                }
                                else if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE)
                                {
-                                       /* TODO: handle incomplete images */
+                                       /* TODO: handle incomplete images 
+                                        * for now we just quit the analsysis*/
+                                       return retval;
                                }
                        }
                        
@@ -910,7 +927,7 @@ int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd_ctx)
                                
                                do {
                                        if ((retval = etmv1_next_packet(ctx, &packet, 0)) != 0)
-                                               return -1;
+                                               return ERROR_ETM_ANALYSIS_FAILED;
                                        ctx->last_ptr &= ~(0x7f << shift);
                                        ctx->last_ptr |= (packet & 0x7f) << shift;
                                        shift += 7;
@@ -936,7 +953,7 @@ int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd_ctx)
                                                {
                                                        u32 data;
                                                        if (etmv1_data(ctx, 4, &data) != 0)
-                                                               return -1;
+                                                               return ERROR_ETM_ANALYSIS_FAILED;
                                                        command_print(cmd_ctx, "data: 0x%8.8x", data);
                                                }
                                        }
@@ -945,7 +962,7 @@ int etmv1_analyze_trace(etm_context_t *ctx, struct command_context_s *cmd_ctx)
                                {
                                        u32 data;
                                        if (etmv1_data(ctx, arm_access_size(&instruction), &data) != 0)
-                                               return -1;
+                                               return ERROR_ETM_ANALYSIS_FAILED;
                                        command_print(cmd_ctx, "data: 0x%8.8x", data);
                                }
                        }
@@ -1187,6 +1204,7 @@ int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char *cmd, c
                if (arm7_9->etm_ctx->trace_depth > 0)
                {
                        free(arm7_9->etm_ctx->trace_data);
+                       arm7_9->etm_ctx->trace_data = NULL;
                }
                arm7_9->etm_ctx->trace_depth = 0;
        }
@@ -1205,7 +1223,7 @@ int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cmd, char
        
        if (argc != 5)
        {
-               ERROR("incomplete 'etm config <target> <port_width> <port_mode> <clocking> <capture_driver>' command");
+               LOG_ERROR("incomplete 'etm config <target> <port_width> <port_mode> <clocking> <capture_driver>' command");
                exit(-1);
        }
        
@@ -1213,7 +1231,7 @@ int handle_etm_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);
        }
        
@@ -1291,7 +1309,7 @@ int handle_etm_config_command(struct command_context_s *cmd_ctx, char *cmd, char
        {
                /* no supported capture driver found, don't register an ETM */
                free(etm_ctx);
-               ERROR("trace capture driver '%s' not found", args[4]);
+               LOG_ERROR("trace capture driver '%s' not found", args[4]);
                return ERROR_OK;
        }
        
@@ -1351,8 +1369,8 @@ int handle_etm_info_command(struct command_context_s *cmd_ctx, char *cmd, char *
        etm_get_reg(etm_config_reg);
        command_print(cmd_ctx, "pairs of address comparators: %i", buf_get_u32(etm_config_reg->value, 0, 4));
        command_print(cmd_ctx, "pairs of data comparators: %i", buf_get_u32(etm_config_reg->value, 4, 4));
-       command_print(cmd_ctx, "memory map decoders: %i", buf_get_u32(etm_config_reg->value, 8, 4));
-       command_print(cmd_ctx, "number of counters: %i", buf_get_u32(etm_config_reg->value, 12, 4));
+       command_print(cmd_ctx, "memory map decoders: %i", buf_get_u32(etm_config_reg->value, 8, 5));
+       command_print(cmd_ctx, "number of counters: %i", buf_get_u32(etm_config_reg->value, 13, 3));
        command_print(cmd_ctx, "sequencer %spresent",
                        (buf_get_u32(etm_config_reg->value, 16, 1) == 1) ? "" : "not ");
        command_print(cmd_ctx, "number of ext. inputs: %i", buf_get_u32(etm_config_reg->value, 17, 3));
@@ -1374,6 +1392,9 @@ int handle_etm_info_command(struct command_context_s *cmd_ctx, char *cmd, char *
                case 2:
                        max_port_size = 16;
                        break;
+               default:
+                       LOG_ERROR("Illegal max_port_size");
+                       exit(-1);
        }
        command_print(cmd_ctx, "max. port size: %i", max_port_size);
        
@@ -1492,7 +1513,6 @@ int handle_etm_image_command(struct command_context_s *cmd_ctx, char *cmd, char
                
        if (image_open(etm_ctx->image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
        {
-               command_print(cmd_ctx, "image opening error: %s", etm_ctx->image->error_str);
                free(etm_ctx->image);
                etm_ctx->image = NULL;
                return ERROR_OK;
@@ -1549,7 +1569,6 @@ int handle_etm_dump_command(struct command_context_s *cmd_ctx, char *cmd, char *
        
        if (fileio_open(&file, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
        {
-               command_print(cmd_ctx, "file open error: %s", file.error_str);
                return ERROR_OK;
        }
        
@@ -1607,7 +1626,6 @@ int handle_etm_load_command(struct command_context_s *cmd_ctx, char *cmd, char *
        
        if (fileio_open(&file, args[0], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
        {
-               command_print(cmd_ctx, "file open error: %s", file.error_str);
                return ERROR_OK;
        }
        
@@ -1712,6 +1730,7 @@ int handle_etm_start_command(struct command_context_s *cmd_ctx, char *cmd, char
        if (arm7_9->etm_ctx->trace_depth > 0)
        {
                free(arm7_9->etm_ctx->trace_data);
+               arm7_9->etm_ctx->trace_data = NULL;
        }
        arm7_9->etm_ctx->trace_depth = 0;
                
@@ -1771,6 +1790,7 @@ int handle_etm_analyze_command(struct command_context_s *cmd_ctx, char *cmd, cha
        armv4_5_common_t *armv4_5;
        arm7_9_common_t *arm7_9;
        etm_context_t *etm_ctx;
+       int retval;
 
        target = get_current_target(cmd_ctx);
        
@@ -1786,7 +1806,23 @@ int handle_etm_analyze_command(struct command_context_s *cmd_ctx, char *cmd, cha
                return ERROR_OK;
        }
        
-       etmv1_analyze_trace(etm_ctx, cmd_ctx);
+       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");
+                               break;
+                       case ERROR_TRACE_INSTRUCTION_UNAVAILABLE:
+                               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");
+                               break;
+                       default:
+                               command_print(cmd_ctx, "unknown error: %i", retval);
+               }
+       }
        
        return ERROR_OK;
 }