summaryrefslogtreecommitdiff
path: root/src/target/etb.c
diff options
context:
space:
mode:
authordrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2007-04-25 20:15:59 +0000
committerdrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2007-04-25 20:15:59 +0000
commit22bc5194ae101282cf5c30d681d7f4720bec2534 (patch)
tree9269026fda66ddf15fdfaeaf8acd8433767ea82e /src/target/etb.c
parent04dc98916d9acb57e0f5595534151a24ba4dc684 (diff)
downloadopenocd_libswd-22bc5194ae101282cf5c30d681d7f4720bec2534.tar.gz
openocd_libswd-22bc5194ae101282cf5c30d681d7f4720bec2534.tar.bz2
openocd_libswd-22bc5194ae101282cf5c30d681d7f4720bec2534.tar.xz
openocd_libswd-22bc5194ae101282cf5c30d681d7f4720bec2534.zip
- added support for error handlers to JTAG scan commands (jtag_[plain_][ir|dr]_scan)
- catch apparently broken JTAG IR scan after ARM926EJ-S CP15 operations - added "arm7_9 dump_etb" command git-svn-id: svn://svn.berlios.de/openocd/trunk@142 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/target/etb.c')
-rw-r--r--src/target/etb.c74
1 files changed, 68 insertions, 6 deletions
diff --git a/src/target/etb.c b/src/target/etb.c
index 3ac1adf4..0b480e39 100644
--- a/src/target/etb.c
+++ b/src/target/etb.c
@@ -21,6 +21,7 @@
#include "config.h"
#endif
+#include "arm7_9_common.h"
#include "etb.h"
#include "log.h"
@@ -54,6 +55,9 @@ int etb_set_reg_w_exec(reg_t *reg, u8 *buf);
int etb_write_reg(reg_t *reg, u32 value);
int etb_read_reg(reg_t *reg);
+int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int handle_arm7_9_etb_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+
int etb_set_instr(etb_t *etb, u32 new_instr)
{
jtag_device_t *device = jtag_get_device(etb->chain_pos);
@@ -72,8 +76,8 @@ int etb_set_instr(etb_t *etb, u32 new_instr)
field.in_check_mask = NULL;
field.in_handler = NULL;
field.in_handler_priv = NULL;
-
- jtag_add_ir_scan(1, &field, -1);
+
+ jtag_add_ir_scan(1, &field, -1, NULL);
free(field.out_value);
}
@@ -100,7 +104,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);
+ jtag_add_dr_scan(1, &field, -1, NULL);
etb->cur_scan_chain = new_scan_chain;
@@ -212,13 +216,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);
+ jtag_add_dr_scan(3, fields, -1, NULL);
+ /* 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);
+ jtag_add_dr_scan(3, fields, -1, NULL);
free(fields[1].out_value);
free(fields[2].out_value);
@@ -303,7 +311,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);
+ jtag_add_dr_scan(3, fields, -1, NULL);
free(fields[0].out_value);
free(fields[1].out_value);
@@ -317,3 +325,57 @@ int etb_store_reg(reg_t *reg)
return etb_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));
}
+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;
+}