diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 91f14b15e..242eb56bf 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -42,6 +42,8 @@ #include #endif +static void jtag_execute_queue_noclear(void); + /* note that this is not marked as static as it must be available from outside jtag.c for those that implement the jtag_xxx() minidriver layer */ @@ -670,6 +672,12 @@ void jtag_add_dr_scan(int num_fields, scan_field_t *fields, tap_state_t state) jtag_error=retval; } +void jtag_add_dr_scan_now(int num_fields, scan_field_t *fields, tap_state_t state) +{ + jtag_add_dr_scan(num_fields, fields, state); + jtag_execute_queue_noclear(); +} + int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, tap_state_t state) { int j; @@ -1438,13 +1446,21 @@ int MINIDRIVER(interface_jtag_execute_queue)(void) return retval; } -int jtag_execute_queue(void) +static void jtag_execute_queue_noclear(void) { int retval=interface_jtag_execute_queue(); - if (retval==ERROR_OK) + /* we keep the first error */ + if ((jtag_error==ERROR_OK)&&(retval!=ERROR_OK)) { - retval=jtag_error; + jtag_error=retval; } +} + +int jtag_execute_queue(void) +{ + int retval; + jtag_execute_queue_noclear(); + retval=jtag_error; jtag_error=ERROR_OK; return retval; } @@ -1485,10 +1501,10 @@ int jtag_examine_chain(void) field.tap = NULL; field.num_bits = sizeof(idcode_buffer) * 8; field.out_value = idcode_buffer; - + field.in_value = idcode_buffer; - - + + field.in_handler = NULL; for (i = 0; i < JTAG_MAX_CHAIN_SIZE; i++) @@ -1662,10 +1678,7 @@ int jtag_validate_chain(void) field.tap = NULL; field.num_bits = total_ir_length; field.out_value = ir_test; - field.in_value = ir_test; - - field.in_handler = NULL; jtag_add_plain_ir_scan(1, &field, TAP_RESET); diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 604692cdd..c0f94856b 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -561,6 +561,10 @@ extern int jtag_register_commands(struct command_context_s* cmd_ctx); extern void jtag_add_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate); extern int interface_jtag_add_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate); extern void jtag_add_dr_scan(int num_fields, scan_field_t* fields, tap_state_t endstate); +/* same as jtag_add_dr_scan but the scan is executed immediately. sets jtag_error if there + * was a failure. + */ +extern void jtag_add_dr_scan_now(int num_fields, scan_field_t* fields, tap_state_t endstate); extern int interface_jtag_add_dr_scan(int num_fields, scan_field_t* fields, tap_state_t endstate); extern void jtag_add_plain_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate); extern int interface_jtag_add_plain_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate); @@ -696,6 +700,16 @@ int interface_jtag_add_clocks(int num_cycles); */ extern int jtag_execute_queue(void); +/* this flag is set when an error occurs while executing the queue. cleared + * by jtag_execute_queue() + * + * this flag can also be set from application code if some error happens + * during processing that should be reported during jtag_execute_queue(). + */ +extern int jtag_error; + + + /* can be implemented by hw+sw */ extern int interface_jtag_execute_queue(void); extern int jtag_power_dropout(int* dropout); diff --git a/src/jtag/zy1000.c b/src/jtag/zy1000.c index f2765c0b6..b17780684 100644 --- a/src/jtag/zy1000.c +++ b/src/jtag/zy1000.c @@ -39,8 +39,6 @@ #define ZYLIN_OPENOCD_VERSION "Zylin JTAG ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE " " ZYLIN_TIME const char *zylin_config_dir="/config/settings"; -extern int jtag_error; - /* low level command set */ int zy1000_read(void); diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index c9deb0ee1..c0446f235 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -5,6 +5,9 @@ * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -111,22 +114,14 @@ int arm7tdmi_examine_debug_reason(target_t *target) fields[0].tap = arm7_9->jtag_info.tap; fields[0].num_bits = 1; fields[0].out_value = NULL; - fields[0].in_value = &breakpoint; - - fields[0].in_handler = NULL; - fields[1].tap = arm7_9->jtag_info.tap; fields[1].num_bits = 32; fields[1].out_value = NULL; - fields[1].in_value = databus; - - fields[1].in_handler = NULL; - if((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1)) != ERROR_OK) { @@ -198,24 +193,23 @@ int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) fields[0].tap = jtag_info->tap; fields[0].num_bits = 1; fields[0].out_value = NULL; - fields[0].in_value = NULL; - - fields[0].in_handler = NULL; - + fields[1].tap = jtag_info->tap; fields[1].num_bits = 32; fields[1].out_value = NULL; - - fields[1].in_value = NULL; - fields[1].in_handler = arm_jtag_buf_to_u32_flip; /* deprecated! invoke this from user code! */ - fields[1].in_handler_priv = in; - - + u8 tmp[4]; + fields[1].in_value = tmp; + fields[1].in_handler = NULL; - jtag_add_dr_scan(2, fields, TAP_INVALID); + jtag_add_dr_scan_now(2, fields, TAP_INVALID); + + if (jtag_error==ERROR_OK) + { + *in=flip_u32(le_to_h_u32(tmp), 32); + } jtag_add_runtest(0, TAP_INVALID); @@ -259,17 +253,13 @@ int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, fields[0].tap = jtag_info->tap; fields[0].num_bits = 1; fields[0].out_value = NULL; - fields[0].in_value = NULL; - - fields[0].in_handler = NULL; - + fields[1].tap = jtag_info->tap; fields[1].num_bits = 32; fields[1].out_value = NULL; - fields[1].in_value = NULL; switch (size) { @@ -284,8 +274,8 @@ int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, break; } fields[1].in_handler_priv = in; - - + + jtag_add_dr_scan(2, fields, TAP_INVALID);