X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fcore.c;h=bdf968e95417d68a1e0390ef3e4d8671b135a390;hb=96f9790279f74f39b35fc3ad09340fd03123180c;hp=8a580e9e35e67215d17773debc4bcdd24bddcd3c;hpb=1dad2ee602674de1b97548913dba2d53267d35a3;p=openocd.git diff --git a/src/jtag/core.c b/src/jtag/core.c index 8a580e9e35..bdf968e954 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -42,7 +42,8 @@ /// The number of JTAG queue flushes (for profiling and debugging purposes). static int jtag_flush_queue_count; -static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const struct scan_field *in_fields, tap_state_t state), +static void jtag_add_scan_check(struct jtag_tap *active, + void (*jtag_add_scan)(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, tap_state_t state), int in_num_fields, struct scan_field *in_fields, tap_state_t state); /** @@ -352,17 +353,22 @@ void jtag_alloc_in_value32(struct scan_field *field) interface_jtag_alloc_in_value32(field); } -void jtag_add_ir_scan_noverify(int in_count, const struct scan_field *in_fields, +void jtag_add_ir_scan_noverify(struct jtag_tap *active, const struct scan_field *in_fields, tap_state_t state) { jtag_prelude(state); - int retval = interface_jtag_add_ir_scan(in_count, in_fields, state); + int retval = interface_jtag_add_ir_scan(active, in_fields, state); jtag_set_error(retval); } +static void jtag_add_ir_scan_noverify_callback(struct jtag_tap *active, int dummy, const struct scan_field *in_fields, + tap_state_t state) +{ + jtag_add_ir_scan_noverify(active, in_fields, state); +} -void jtag_add_ir_scan(int in_num_fields, struct scan_field *in_fields, tap_state_t state) +void jtag_add_ir_scan(struct jtag_tap *active, struct scan_field *in_fields, tap_state_t state) { assert(state != TAP_RESET); @@ -370,30 +376,28 @@ void jtag_add_ir_scan(int in_num_fields, struct scan_field *in_fields, tap_state { /* 8 x 32 bit id's is enough for all invocations */ - for (int j = 0; j < in_num_fields; j++) - { - /* if we are to run a verification of the ir scan, we need to get the input back. - * We may have to allocate space if the caller didn't ask for the input back. - */ - in_fields[j].check_value = in_fields[j].tap->expected; - in_fields[j].check_mask = in_fields[j].tap->expected_mask; - } - jtag_add_scan_check(jtag_add_ir_scan_noverify, in_num_fields, in_fields, state); + /* if we are to run a verification of the ir scan, we need to get the input back. + * We may have to allocate space if the caller didn't ask for the input back. + */ + in_fields->check_value = active->expected; + in_fields->check_mask = active->expected_mask; + jtag_add_scan_check(active, jtag_add_ir_scan_noverify_callback, 1, in_fields, state); } else { - jtag_add_ir_scan_noverify(in_num_fields, in_fields, state); + jtag_add_ir_scan_noverify(active, in_fields, state); } } -void jtag_add_plain_ir_scan(int in_num_fields, const struct scan_field *in_fields, +void jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state) { + assert(out_bits != NULL); assert(state != TAP_RESET); jtag_prelude(state); int retval = interface_jtag_add_plain_ir_scan( - in_num_fields, in_fields, state); + num_bits, out_bits, in_bits, state); jtag_set_error(retval); } @@ -405,7 +409,7 @@ static int jtag_check_value_mask_callback(jtag_callback_data_t data0, jtag_callb return jtag_check_value_inner((uint8_t *)data0, (uint8_t *)data1, (uint8_t *)data2, (int)data3); } -static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const struct scan_field *in_fields, tap_state_t state), +static void jtag_add_scan_check(struct jtag_tap *active, void (*jtag_add_scan)(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, tap_state_t state), int in_num_fields, struct scan_field *in_fields, tap_state_t state) { for (int i = 0; i < in_num_fields; i++) @@ -419,7 +423,7 @@ static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const s field->modified = 1; } - jtag_add_scan(in_num_fields, in_fields, state); + jtag_add_scan(active, in_num_fields, in_fields, state); for (int i = 0; i < in_num_fields; i++) { @@ -442,19 +446,19 @@ static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const s } } -void jtag_add_dr_scan_check(int in_num_fields, struct scan_field *in_fields, tap_state_t state) +void jtag_add_dr_scan_check(struct jtag_tap *active, int in_num_fields, struct scan_field *in_fields, tap_state_t state) { if (jtag_verify) { - jtag_add_scan_check(jtag_add_dr_scan, in_num_fields, in_fields, state); + jtag_add_scan_check(active, jtag_add_dr_scan, in_num_fields, in_fields, state); } else { - jtag_add_dr_scan(in_num_fields, in_fields, state); + jtag_add_dr_scan(active, in_num_fields, in_fields, state); } } -void jtag_add_dr_scan(int in_num_fields, const struct scan_field *in_fields, +void jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields, const struct scan_field *in_fields, tap_state_t state) { assert(state != TAP_RESET); @@ -462,19 +466,20 @@ void jtag_add_dr_scan(int in_num_fields, const struct scan_field *in_fields, jtag_prelude(state); int retval; - retval = interface_jtag_add_dr_scan(in_num_fields, in_fields, state); + retval = interface_jtag_add_dr_scan(active, in_num_fields, in_fields, state); jtag_set_error(retval); } -void jtag_add_plain_dr_scan(int in_num_fields, const struct scan_field *in_fields, +void jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state) { + assert(out_bits != NULL); assert(state != TAP_RESET); jtag_prelude(state); int retval; - retval = interface_jtag_add_plain_dr_scan(in_num_fields, in_fields, state); + retval = interface_jtag_add_plain_dr_scan(num_bits, out_bits, in_bits, state); jtag_set_error(retval); } @@ -488,6 +493,35 @@ void jtag_add_tlr(void) jtag_notify_event(JTAG_TRST_ASSERTED); } +/** + * If supported by the underlying adapter, this clocks a raw bit sequence + * onto TMS for switching betwen JTAG and SWD modes. + * + * DO NOT use this to bypass the integrity checks and logging provided + * by the jtag_add_pathmove() and jtag_add_statemove() calls. + * + * @param nbits How many bits to clock out. + * @param seq The bit sequence. The LSB is bit 0 of seq[0]. + * @param state The JTAG tap state to record on completion. Use + * TAP_INVALID to represent being in in SWD mode. + * + * @todo Update naming conventions to stop assuming everything is JTAG. + */ +int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state) +{ + int retval; + + if (!(jtag->supported & DEBUG_CAP_TMS_SEQ)) + return ERROR_JTAG_NOT_IMPLEMENTED; + + jtag_checks(); + cmd_queue_cur_state = state; + + retval = interface_add_tms_seq(nbits, seq, state); + jtag_set_error(retval); + return retval; +} + void jtag_add_pathmove(int num_states, const tap_state_t *path) { tap_state_t cur_state = cmd_queue_cur_state; @@ -865,7 +899,6 @@ void jtag_sleep(uint32_t us) static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcode) { struct scan_field field = { - .tap = NULL, .num_bits = num_idcode * 32, .out_value = idcode_buffer, .in_value = idcode_buffer, @@ -875,7 +908,7 @@ static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcod for (unsigned i = 0; i < JTAG_MAX_CHAIN_SIZE; i++) buf_set_u32(idcode_buffer, i * 32, 32, END_OF_CHAIN_FLAG); - jtag_add_plain_dr_scan(1, &field, TAP_DRPAUSE); + jtag_add_plain_dr_scan(field.num_bits, field.out_value, field.in_value, TAP_DRPAUSE); jtag_add_tlr(); return jtag_execute_queue(); } @@ -1172,12 +1205,11 @@ static int jtag_validate_ircapture(void) /* after this scan, all TAPs will capture BYPASS instructions */ buf_set_ones(ir_test, total_ir_length); - field.tap = NULL; field.num_bits = total_ir_length; field.out_value = ir_test; field.in_value = ir_test; - jtag_add_plain_ir_scan(1, &field, TAP_IDLE); + jtag_add_plain_ir_scan(field.num_bits, field.out_value, field.in_value, TAP_IDLE); LOG_DEBUG("IR capture validation scan"); retval = jtag_execute_queue(); @@ -1314,7 +1346,11 @@ void jtag_tap_free(struct jtag_tap *tap) free(tap); } -int jtag_interface_init(struct command_context *cmd_ctx) +/** + * Do low-level setup like initializing registers, output signals, + * and clocking. + */ +int adapter_init(struct command_context *cmd_ctx) { if (jtag) return ERROR_OK; @@ -1322,7 +1358,8 @@ int jtag_interface_init(struct command_context *cmd_ctx) if (!jtag_interface) { /* nothing was previously specified by "interface" command */ - LOG_ERROR("JTAG interface has to be specified, see \"interface\" command"); + LOG_ERROR("Debug Adapter has to be specified, " + "see \"interface\" command"); return ERROR_JTAG_INVALID_INTERFACE; } @@ -1337,9 +1374,10 @@ int jtag_interface_init(struct command_context *cmd_ctx) int actual_khz = requested_khz; int retval = jtag_get_speed_readable(&actual_khz); if (ERROR_OK != retval) - LOG_INFO("interface specific clock speed value %d", jtag_get_speed()); + LOG_INFO("adapter-specific clock speed value %d", jtag_get_speed()); else if (actual_khz) { + /* Adaptive clocking -- JTAG-specific */ if ((CLOCK_MODE_RCLK == clock_mode) || ((CLOCK_MODE_KHZ == clock_mode) && !requested_khz)) { @@ -1427,7 +1465,7 @@ int jtag_init_inner(struct command_context *cmd_ctx) return ERROR_OK; } -int jtag_interface_quit(void) +int adapter_quit(void) { if (!jtag || !jtag->quit) return ERROR_OK; @@ -1445,7 +1483,7 @@ int jtag_init_reset(struct command_context *cmd_ctx) { int retval; - if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK) + if ((retval = adapter_init(cmd_ctx)) != ERROR_OK) return retval; LOG_DEBUG("Initializing with hard TRST+SRST reset"); @@ -1499,7 +1537,7 @@ int jtag_init(struct command_context *cmd_ctx) { int retval; - if ((retval = jtag_interface_init(cmd_ctx)) != ERROR_OK) + if ((retval = adapter_init(cmd_ctx)) != ERROR_OK) return retval; /* guard against oddball hardware: force resets to be inactive */ @@ -1518,7 +1556,7 @@ unsigned jtag_get_speed_khz(void) return speed_khz; } -static int jtag_khz_to_speed(unsigned khz, int* speed) +static int adapter_khz_to_speed(unsigned khz, int* speed) { LOG_DEBUG("convert khz to interface specific speed value"); speed_khz = khz; @@ -1538,11 +1576,11 @@ static int jtag_khz_to_speed(unsigned khz, int* speed) static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int* speed) { - int retval = jtag_khz_to_speed(0, speed); + int retval = adapter_khz_to_speed(0, speed); if ((ERROR_OK != retval) && fallback_speed_khz) { LOG_DEBUG("trying fallback speed..."); - retval = jtag_khz_to_speed(fallback_speed_khz, speed); + retval = adapter_khz_to_speed(fallback_speed_khz, speed); } return retval; } @@ -1560,7 +1598,7 @@ int jtag_config_khz(unsigned khz) LOG_DEBUG("handle jtag khz"); clock_mode = CLOCK_MODE_KHZ; int speed = 0; - int retval = jtag_khz_to_speed(khz, &speed); + int retval = adapter_khz_to_speed(khz, &speed); return (ERROR_OK != retval) ? retval : jtag_set_speed(speed); } @@ -1583,7 +1621,7 @@ int jtag_get_speed(void) speed = jtag_speed; break; case CLOCK_MODE_KHZ: - jtag_khz_to_speed(jtag_get_speed_khz(), &speed); + adapter_khz_to_speed(jtag_get_speed_khz(), &speed); break; case CLOCK_MODE_RCLK: jtag_rclk_to_speed(rclk_fallback_speed_khz, &speed); @@ -1623,6 +1661,13 @@ bool jtag_will_verify_capture_ir() int jtag_power_dropout(int *dropout) { + if (jtag == NULL) + { + /* TODO: as the jtag interface is not valid all + * we can do at the moment is exit OpenOCD */ + LOG_ERROR("No Valid JTAG Interface Configured."); + exit(-1); + } return jtag->power_dropout(dropout); }