+int etb_register_commands(struct command_context_s *cmd_ctx, command_t *arm7_9_cmd)
+{
+ register_command(cmd_ctx, arm7_9_cmd, "etb", handle_arm7_9_etb_command, COMMAND_CONFIG, NULL);
+
+ register_command(cmd_ctx, arm7_9_cmd, "etb_dump", handle_arm7_9_etb_dump_command, COMMAND_EXEC, "dump current ETB content");
+
+ return ERROR_OK;
+}
+
+int handle_arm7_9_etb_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ int retval;
+ target_t *target = get_current_target(cmd_ctx);
+ armv4_5_common_t *armv4_5;
+ arm7_9_common_t *arm7_9;
+ int i;
+
+ if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
+ {
+ command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
+ return ERROR_OK;
+ }
+
+ if (!arm7_9->etb)
+ {
+ command_print(cmd_ctx, "no ETB configured for current target");
+ return ERROR_OK;
+ }
+
+ if (!(arm7_9->etb->RAM_depth && arm7_9->etb->RAM_width))
+ {
+ /* identify ETB RAM depth and width */
+ etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_DEPTH]);
+ etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_WIDTH]);
+ jtag_execute_queue();
+
+ arm7_9->etb->RAM_depth = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DEPTH].value, 0, 32);
+ arm7_9->etb->RAM_width = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_WIDTH].value, 0, 32);
+ }
+
+ /* always start reading from the beginning of the buffer */
+ etb_write_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_READ_POINTER], 0x0);
+ for (i = 0; i < arm7_9->etb->RAM_depth; i++)
+ {
+ u32 trace_data;
+ etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA]);
+ jtag_execute_queue();
+ trace_data = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA].value, 0, 32);
+ command_print(cmd_ctx, "%8.8i: %i %2.2x %2.2x %2.2x (0x%8.8x)",
+ i, (trace_data >> 19) & 1, (trace_data >> 11) & 0xff, (trace_data >> 3) & 0xff, trace_data & 0x7, trace_data);
+ }
+
+ return ERROR_OK;
+}