X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fcore.c;h=31909964fc210d671f7d374d165b429f5d204316;hp=7ed5976ccac8fc24711566ca66bcae64f3af6f04;hb=53d605e12c3765aeedabf2bfe0c5cc338dc95d5a;hpb=8551803eb52db94ae3c1c9d4a7871d3e0986185a diff --git a/src/jtag/core.c b/src/jtag/core.c index 7ed5976cca..31909964fc 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -58,9 +58,11 @@ static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const s */ static int jtag_error = ERROR_OK; -static char* jtag_event_strings[] = +static const char *jtag_event_strings[] = { - "JTAG controller reset (RESET or TRST)" + [JTAG_TRST_ASSERTED] = "JTAG controller reset (RESET or TRST)", + [JTAG_TAP_EVENT_ENABLE] = "TAP enabled", + [JTAG_TAP_EVENT_DISABLE] = "TAP disabled", }; static int jtag_trst = 0; @@ -140,7 +142,7 @@ unsigned jtag_tap_count_enabled(void) { jtag_tap_t *t = jtag_all_taps(); unsigned n = 0; - while(t) + while (t) { if (t->enabled) n++; @@ -155,7 +157,7 @@ void jtag_tap_add(struct jtag_tap_s *t) t->abs_chain_position = jtag_num_taps++; jtag_tap_t **tap = &__jtag_all_taps; - while(*tap != NULL) + while (*tap != NULL) tap = &(*tap)->next_tap; *tap = t; } @@ -243,24 +245,30 @@ int jtag_register_event_callback(jtag_event_handler_t callback, void *priv) return ERROR_OK; } -int jtag_unregister_event_callback(jtag_event_handler_t callback) +int jtag_unregister_event_callback(jtag_event_handler_t callback, void *priv) { - jtag_event_callback_t **callbacks_p = &jtag_event_callbacks; + jtag_event_callback_t **callbacks_p; + jtag_event_callback_t **next; if (callback == NULL) { return ERROR_INVALID_ARGUMENTS; } - while (*callbacks_p) + for (callbacks_p = &jtag_event_callbacks; + *callbacks_p != NULL; + callbacks_p = next) { - jtag_event_callback_t **next = &((*callbacks_p)->next); + next = &((*callbacks_p)->next); + + if ((*callbacks_p)->priv != priv) + continue; + if ((*callbacks_p)->callback == callback) { free(*callbacks_p); *callbacks_p = *next; } - callbacks_p = next; } return ERROR_OK; @@ -274,8 +282,12 @@ int jtag_call_event_callbacks(enum jtag_event event) while (callback) { + jtag_event_callback_t *next; + + /* callback may remove itself */ + next = callback->next; callback->callback(event, callback->priv); - callback = callback->next; + callback = next; } return ERROR_OK; @@ -290,7 +302,7 @@ static void jtag_prelude(tap_state_t state) { jtag_checks(); - assert(state!=TAP_INVALID); + assert(state != TAP_INVALID); cmd_queue_cur_state = state; } @@ -341,23 +353,23 @@ void jtag_add_plain_ir_scan(int in_num_fields, const scan_field_t *in_fields, jtag_set_error(retval); } -void jtag_add_callback(jtag_callback1_t f, u8 *in) +void jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0) { - interface_jtag_add_callback(f, in); + interface_jtag_add_callback(f, data0); } -void jtag_add_callback4(jtag_callback_t f, u8 *in, +void jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) { - interface_jtag_add_callback4(f, in, data1, data2, data3); + interface_jtag_add_callback4(f, data0, data1, data2, data3); } -int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits); +int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, uint8_t *in_check_mask, int num_bits); -static int jtag_check_value_mask_callback(u8 *in, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) +static int jtag_check_value_mask_callback(jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3) { - return jtag_check_value_inner(in, (u8 *)data1, (u8 *)data2, (int)data3); + 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 scan_field_t *in_fields, tap_state_t state), @@ -381,7 +393,7 @@ static void jtag_add_scan_check(void (*jtag_add_scan)(int in_num_fields, const s if ((in_fields[i].check_value != NULL) && (in_fields[i].in_value != NULL)) { /* this is synchronous for a minidriver */ - jtag_add_callback4(jtag_check_value_mask_callback, in_fields[i].in_value, + jtag_add_callback4(jtag_check_value_mask_callback, (jtag_callback_data_t)in_fields[i].in_value, (jtag_callback_data_t)in_fields[i].check_value, (jtag_callback_data_t)in_fields[i].check_mask, (jtag_callback_data_t)in_fields[i].num_bits); @@ -430,7 +442,7 @@ void jtag_add_plain_dr_scan(int in_num_fields, const scan_field_t *in_fields, } void jtag_add_dr_out(jtag_tap_t* tap, - int num_fields, const int* num_bits, const u32* value, + int num_fields, const int* num_bits, const uint32_t* value, tap_state_t end_state) { assert(end_state != TAP_INVALID); @@ -498,11 +510,11 @@ int jtag_add_statemove(tap_state_t goal_state) if (goal_state==cur_state ) ; /* nothing to do */ - else if( goal_state==TAP_RESET ) + else if ( goal_state==TAP_RESET ) { jtag_add_tlr(); } - else if( tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state) ) + else if ( tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state) ) { unsigned tms_bits = tap_get_tms_path(cur_state, goal_state); unsigned tms_count = tap_get_tms_path_len(cur_state, goal_state); @@ -519,7 +531,7 @@ int jtag_add_statemove(tap_state_t goal_state) jtag_add_pathmove(tms_count, moves); } - else if( tap_state_transition(cur_state, true) == goal_state + else if ( tap_state_transition(cur_state, true) == goal_state || tap_state_transition(cur_state, false) == goal_state ) { jtag_add_pathmove(1, &goal_state); @@ -664,7 +676,7 @@ tap_state_t jtag_set_end_state(tap_state_t state) LOG_ERROR("BUG: TAP_DRSHIFT/IRSHIFT can't be end state. Calling code should use a larger scan field"); } - if (state!=TAP_INVALID) + if (state != TAP_INVALID) cmd_queue_end_state = state; return cmd_queue_end_state; } @@ -674,14 +686,14 @@ tap_state_t jtag_get_end_state(void) return cmd_queue_end_state; } -void jtag_add_sleep(u32 us) +void jtag_add_sleep(uint32_t us) { /// @todo Here, keep_alive() appears to be a layering violation!!! keep_alive(); jtag_set_error(interface_jtag_add_sleep(us)); } -int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, int num_bits) +int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value, uint8_t *in_check_mask, int num_bits) { int retval = ERROR_OK; @@ -730,7 +742,7 @@ int jtag_check_value_inner(u8 *captured, u8 *in_check_value, u8 *in_check_mask, return retval; } -void jtag_check_value_mask(scan_field_t *field, u8 *value, u8 *mask) +void jtag_check_value_mask(scan_field_t *field, uint8_t *value, uint8_t *mask) { assert(field->in_value != NULL); @@ -786,6 +798,8 @@ static int jtag_reset_callback(enum jtag_event event, void *priv) if (event == JTAG_TRST_ASSERTED) { + tap->enabled = !tap->disabled_after_reset; + buf_set_ones(tap->cur_instr, tap->ir_length); tap->bypass = 1; } @@ -793,7 +807,7 @@ static int jtag_reset_callback(enum jtag_event event, void *priv) return ERROR_OK; } -void jtag_sleep(u32 us) +void jtag_sleep(uint32_t us) { alive_sleep(us/1000); } @@ -805,7 +819,7 @@ void jtag_sleep(u32 us) #define EXTRACT_PART(X) (((X) & 0xffff000) >> 12) #define EXTRACT_VER(X) (((X) & 0xf0000000) >> 28) -static int jtag_examine_chain_execute(u8 *idcode_buffer, unsigned num_idcode) +static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcode) { scan_field_t field = { .tap = NULL, @@ -822,10 +836,10 @@ static int jtag_examine_chain_execute(u8 *idcode_buffer, unsigned num_idcode) return jtag_execute_queue(); } -static bool jtag_examine_chain_check(u8 *idcodes, unsigned count) +static bool jtag_examine_chain_check(uint8_t *idcodes, unsigned count) { - u8 zero_check = 0x0; - u8 one_check = 0xff; + uint8_t zero_check = 0x0; + uint8_t one_check = 0xff; for (unsigned i = 0; i < count * 4; i++) { @@ -845,16 +859,19 @@ static bool jtag_examine_chain_check(u8 *idcodes, unsigned count) } static void jtag_examine_chain_display(enum log_levels level, const char *msg, - const char *name, u32 idcode) + const char *name, uint32_t idcode) { log_printf_lf(level, __FILE__, __LINE__, __FUNCTION__, - "JTAG tap: %s %16.16s: 0x%08x " - "(mfg: 0x%3.3x, part: 0x%4.4x, ver: 0x%1.1x)", - name, msg, idcode, - EXTRACT_MFG(idcode), EXTRACT_PART(idcode), EXTRACT_VER(idcode) ); + "JTAG tap: %s %16.16s: 0x%08x " + "(mfg: 0x%3.3x, part: 0x%4.4x, ver: 0x%1.1x)", + name, msg, + (unsigned int)idcode, + (unsigned int)EXTRACT_MFG(idcode), + (unsigned int)EXTRACT_PART(idcode), + (unsigned int)EXTRACT_VER(idcode) ); } -static bool jtag_idcode_is_final(u32 idcode) +static bool jtag_idcode_is_final(uint32_t idcode) { return idcode == 0x000000FF || idcode == 0xFFFFFFFF; } @@ -865,17 +882,17 @@ static bool jtag_idcode_is_final(u32 idcode) * read back correctly. This can help identify and diagnose problems * with the JTAG chain earlier, gives more helpful/explicit error messages. */ -static void jtag_examine_chain_end(u8 *idcodes, unsigned count, unsigned max) +static void jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned max) { bool triggered = false; for ( ; count < max - 31; count += 32) { - u32 idcode = buf_get_u32(idcodes, count, 32); + uint32_t idcode = buf_get_u32(idcodes, count, 32); // do not trigger the warning if the data looks good if (!triggered && jtag_idcode_is_final(idcode)) continue; LOG_WARNING("Unexpected idcode after end of chain: %d 0x%08x", - count, idcode); + count, (unsigned int)idcode); triggered = true; } } @@ -893,7 +910,7 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap_s *tap) } /* Loop over the expected identification codes and test for a match */ - u8 ii; + uint8_t ii; for (ii = 0; ii < tap->expected_ids_cnt; ii++) { if (tap->idcode == tap->expected_ids[ii]) @@ -923,7 +940,7 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap_s *tap) */ int jtag_examine_chain(void) { - u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4]; + uint8_t idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4]; unsigned device_count = 0; jtag_examine_chain_execute(idcode_buffer, JTAG_MAX_CHAIN_SIZE); @@ -941,7 +958,7 @@ int jtag_examine_chain(void) for (unsigned bit_count = 0; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;) { - u32 idcode = buf_get_u32(idcode_buffer, bit_count, 32); + uint32_t idcode = buf_get_u32(idcode_buffer, bit_count, 32); if ((idcode & 1) == 0) { /* LSB must not be 0, this indicates a device in bypass */ @@ -1001,15 +1018,15 @@ int jtag_validate_chain(void) { jtag_tap_t *tap; int total_ir_length = 0; - u8 *ir_test = NULL; + uint8_t *ir_test = NULL; scan_field_t field; int chain_pos = 0; tap = NULL; total_ir_length = 0; - for(;;){ + for (;;){ tap = jtag_tap_next_enabled(tap); - if( tap == NULL ){ + if ( tap == NULL ){ break; } total_ir_length += tap->ir_length; @@ -1031,9 +1048,9 @@ int jtag_validate_chain(void) tap = NULL; chain_pos = 0; int val; - for(;;){ + for (;;){ tap = jtag_tap_next_enabled(tap); - if( tap == NULL ){ + if ( tap == NULL ){ break; } @@ -1086,12 +1103,14 @@ void jtag_tap_init(jtag_tap_t *tap) LOG_DEBUG("Created Tap: %s @ abs position %d, " "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name, tap->abs_chain_position, tap->ir_length, - tap->ir_capture_value, tap->ir_capture_mask); + (unsigned int)(tap->ir_capture_value), (unsigned int)(tap->ir_capture_mask)); jtag_tap_add(tap); } void jtag_tap_free(jtag_tap_t *tap) { + jtag_unregister_event_callback(&jtag_reset_callback, tap); + /// @todo is anything missing? no memory leaks please free((void *)tap->expected_ids); free((void *)tap->chip); @@ -1111,7 +1130,7 @@ int jtag_interface_init(struct command_context_s *cmd_ctx) LOG_ERROR("JTAG interface has to be specified, see \"interface\" command"); return ERROR_JTAG_INVALID_INTERFACE; } - if(hasKHz) + if (hasKHz) { jtag_interface->khz(jtag_get_speed_khz(), &jtag_speed); hasKHz = false; @@ -1132,13 +1151,13 @@ static int jtag_init_inner(struct command_context_s *cmd_ctx) LOG_DEBUG("Init JTAG chain"); tap = jtag_tap_next_enabled(NULL); - if( tap == NULL ){ + if ( tap == NULL ){ LOG_ERROR("There are no enabled taps?"); return ERROR_JTAG_INIT_FAILED; } jtag_add_tlr(); - if ((retval=jtag_execute_queue())!=ERROR_OK) + if ((retval=jtag_execute_queue()) != ERROR_OK) return retval; /* examine chain first, as this could discover the real chain layout */