Pavel Chromy: the attached patch refines PRESTO support and makes it work with libftdi.
[fw/openocd] / src / jtag / jtag.c
index 985cf8c2df6337040f1930da5749dd9544284cb4..48cd0595646eafdebcb545da92105388f7079464 100644 (file)
 #include "command.h"
 #include "log.h"
 #include "interpreter.h"
+#include "target.h"
 
 #include "stdlib.h"
 #include "string.h"
 #include <unistd.h>
 
-#ifndef MINIDRIVER
-/* this allows JTAG devices to implement the entire jtag_xxx() layer in hw/sw */
-#define MINIDRIVER(a) a
-#endif
 
 
 /* note that this is not marked as static as it must be available from outside jtag.c for those 
@@ -411,7 +408,7 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
        
        cmd_queue_cur_state = cmd_queue_end_state;
        
-       int retval=interface_jtag_add_ir_scan(num_fields, fields, state);
+       int retval=interface_jtag_add_ir_scan(num_fields, fields, cmd_queue_end_state);
        if (retval!=ERROR_OK)
                jtag_error=retval;
        return retval;
@@ -513,7 +510,7 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state
                
        cmd_queue_cur_state = cmd_queue_end_state;
        
-       return interface_jtag_add_plain_ir_scan(num_fields, fields, state);
+       return interface_jtag_add_plain_ir_scan(num_fields, fields, cmd_queue_end_state);
 }
 
 int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
@@ -572,7 +569,7 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
                        
        cmd_queue_cur_state = cmd_queue_end_state;
 
-       return interface_jtag_add_dr_scan(num_fields, fields, state);
+       return interface_jtag_add_dr_scan(num_fields, fields, cmd_queue_end_state);
 }
 
 int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
@@ -629,13 +626,14 @@ int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields,
                }
                if (!found)
                {
+#ifdef _DEBUG_JTAG_IO_
                        /* if a device isn't listed, the BYPASS register should be selected */
                        if (!jtag_get_device(i)->bypass)
                        {
                                ERROR("BUG: no scan data for a device not in BYPASS");
                                exit(-1);
                        }
-       
+#endif 
                        /* program the scan field to 1 bit length, and ignore it's value */
                        (*last_cmd)->cmd.scan->fields[field_count].num_bits = 1;
                        (*last_cmd)->cmd.scan->fields[field_count].out_value = NULL;
@@ -648,16 +646,107 @@ int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields,
                }
                else
                {
+#ifdef _DEBUG_JTAG_IO_
                        /* if a device is listed, the BYPASS register must not be selected */
                        if (jtag_get_device(i)->bypass)
                        {
-                               WARNING("scan data for a device in BYPASS");
+                               ERROR("BUG: scan data for a device in BYPASS");
+                               exit(-1);
                        }
+#endif
                }
        }
        return ERROR_OK;
 }
 
+void MINIDRIVER(interface_jtag_add_dr_out)(int device_num, 
+               int num_fields,
+               int *num_bits,
+               u32 *value,
+               enum tap_state end_state)
+{
+       int i;
+       int field_count = 0;
+       int scan_size;
+       int bypass_devices = 0;
+
+       jtag_command_t **last_cmd = jtag_get_last_command_p();
+       jtag_device_t *device = jtag_devices;
+       /* count devices in bypass */
+       while (device)
+       {
+               if (device->bypass)
+                       bypass_devices++;
+               device = device->next;
+       }
+       
+       /* allocate memory for a new list member */
+       *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
+       last_comand_pointer = &((*last_cmd)->next);
+       (*last_cmd)->next = NULL;
+       (*last_cmd)->type = JTAG_SCAN;
+
+       /* allocate memory for dr scan command */
+       (*last_cmd)->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t));
+       (*last_cmd)->cmd.scan->ir_scan = 0;
+       (*last_cmd)->cmd.scan->num_fields = num_fields + bypass_devices;
+       (*last_cmd)->cmd.scan->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t));
+       (*last_cmd)->cmd.scan->end_state = end_state;
+
+       for (i = 0; i < jtag_num_devices; i++)
+       {
+               (*last_cmd)->cmd.scan->fields[field_count].device = i;
+
+               if (i == device_num)
+               {
+                       int j;
+#ifdef _DEBUG_JTAG_IO_
+                       /* if a device is listed, the BYPASS register must not be selected */
+                       if (jtag_get_device(i)->bypass)
+                       {
+                               ERROR("BUG: scan data for a device in BYPASS");
+                               exit(-1);
+                       }
+#endif
+                       for (j = 0; j < num_fields; j++)
+                       {
+                               u8 out_value[4];
+                               scan_size = num_bits[j];
+                               buf_set_u32(out_value, 0, scan_size, value[j]);
+                               (*last_cmd)->cmd.scan->fields[field_count].num_bits = scan_size;
+                               (*last_cmd)->cmd.scan->fields[field_count].out_value = buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
+                               (*last_cmd)->cmd.scan->fields[field_count].out_mask = NULL;
+                               (*last_cmd)->cmd.scan->fields[field_count].in_value = NULL;
+                               (*last_cmd)->cmd.scan->fields[field_count].in_check_value = NULL;
+                               (*last_cmd)->cmd.scan->fields[field_count].in_check_mask = NULL;
+                               (*last_cmd)->cmd.scan->fields[field_count].in_handler = NULL;
+                               (*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = NULL;
+                       }
+               } else
+               {
+#ifdef _DEBUG_JTAG_IO_
+                       /* if a device isn't listed, the BYPASS register should be selected */
+                       if (!jtag_get_device(i)->bypass)
+                       {
+                               ERROR("BUG: no scan data for a device not in BYPASS");
+                               exit(-1);
+                       }
+#endif 
+                       /* program the scan field to 1 bit length, and ignore it's value */
+                       (*last_cmd)->cmd.scan->fields[field_count].num_bits = 1;
+                       (*last_cmd)->cmd.scan->fields[field_count].out_value = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count].out_mask = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count].in_value = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count].in_check_value = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count].in_check_mask = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count].in_handler = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = NULL;
+               }
+       }
+}
+
+
+
 
 int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
 {
@@ -678,7 +767,7 @@ int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state
                        
        cmd_queue_cur_state = cmd_queue_end_state;
 
-       return interface_jtag_add_plain_dr_scan(num_fields, fields, state);
+       return interface_jtag_add_plain_dr_scan(num_fields, fields, cmd_queue_end_state);
 }
 
 int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
@@ -735,7 +824,7 @@ int jtag_add_statemove(enum tap_state state)
                        
        cmd_queue_cur_state = cmd_queue_end_state;
 
-       return interface_jtag_add_statemove(state);
+       return interface_jtag_add_statemove(cmd_queue_end_state);
 }
 
 int MINIDRIVER(interface_jtag_add_statemove)(enum tap_state state)
@@ -776,6 +865,20 @@ int jtag_add_pathmove(int num_states, enum tap_state *path)
        if (cmd_queue_end_state == TAP_TLR)
                jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
        
+
+       enum tap_state cur_state=cmd_queue_cur_state;
+       int i;
+       for (i=0; i<num_states; i++)
+       {
+               if ((tap_transitions[cur_state].low != path[i])&&
+                               (tap_transitions[cur_state].high != path[i]))
+               {
+                       ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[path[i]]);
+                       exit(-1);
+               }
+               cur_state = path[i];
+       }
+       
        cmd_queue_cur_state = path[num_states - 1];
 
        return interface_jtag_add_pathmove(num_states, path);
@@ -841,7 +944,7 @@ int jtag_add_runtest(int num_cycles, enum tap_state state)
        cmd_queue_cur_state = cmd_queue_end_state;
        
        /* executed by sw or hw fifo */
-       return interface_jtag_add_runtest(num_cycles, state);
+       return interface_jtag_add_runtest(num_cycles, cmd_queue_end_state);
 }
 
 int jtag_add_reset(int req_trst, int req_srst)
@@ -968,9 +1071,9 @@ int MINIDRIVER(interface_jtag_add_end_state)(enum tap_state state)
 
 int jtag_add_end_state(enum tap_state state)
 {
-       int retval = interface_jtag_add_end_state(state);
        if (state != -1)
                cmd_queue_end_state = state;
+       int retval = interface_jtag_add_end_state(cmd_queue_end_state);
        return retval;
 }
 
@@ -1189,17 +1292,16 @@ int MINIDRIVER(interface_jtag_execute_queue)(void)
        jtag_command_queue = NULL;
        last_comand_pointer = &jtag_command_queue;
 
-       jtag_error=ERROR_OK;
-
        return retval;
 }
 
 int jtag_execute_queue(void)
 {
        int retval=interface_jtag_execute_queue();
-       if (retval!=ERROR_OK)
-               return retval;
+       if (retval==ERROR_OK)
+       {
        retval=jtag_error;
+       }
        jtag_error=ERROR_OK;
        return retval;
 }
@@ -1226,11 +1328,10 @@ void jtag_sleep(u32 us)
 
 /* Try to examine chain layout according to IEEE 1149.1 ยง12
  */
-int jtag_examine_chain()
+int jtag_examine_chain(u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4] )
 {
        jtag_device_t *device = jtag_devices;
        scan_field_t field;
-       u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
        int i;
        int bit_count;
        int device_count = 0;
@@ -1432,9 +1533,36 @@ int jtag_interface_init(struct command_context_s *cmd_ctx)
        return ERROR_OK;
 }
 
+extern int jtag_init_chain(struct command_context_s *cmd_ctx);
+
+static int jtag_sense_handler(void *priv)
+{
+       struct command_context_s *cmd_ctx;
+       cmd_ctx=(struct command_context_s *)priv;
+
+       static int scan_complete = 0;
+       if (!scan_complete)
+       {
+               if (jtag_init_chain(cmd_ctx)==ERROR_OK)
+               {
+                       scan_complete = 1;
+               }
+               return ERROR_OK;
+       }
+       
+       return ERROR_OK;
+}
+
+/* OpenOCD will start telnet/gdb servers before the JTAG chain has
+ * been enumerated. This is to allow e.g. GDB init script to
+ * run monitor commands to initialize the target so jtag_init_chain()
+ * will succeed.
+ * 
+ * A timer callback is added where sensing is retried once every second
+ * until it succeeds.
+ */
 int jtag_init(struct command_context_s *cmd_ctx)
 {
-       int validate_tries = 0;
        jtag_device_t *device;
 
        DEBUG("-");
@@ -1455,25 +1583,76 @@ int jtag_init(struct command_context_s *cmd_ctx)
        jtag_add_statemove(TAP_TLR);
        jtag_execute_queue();
 
+       target_register_timer_callback(jtag_sense_handler, 1000, 1, cmd_ctx);
+       
+       return ERROR_OK;
+       }
+       
+static int jtag_test_chain(u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4])
+{
+       jtag_add_statemove(TAP_TLR);
+       jtag_execute_queue();
+
        /* examine chain first, as this could discover the real chain layout */
-       if (jtag_examine_chain() != ERROR_OK)
+       if (jtag_examine_chain(idcode_buffer)!=ERROR_OK)
        {
-               ERROR("trying to validate configured JTAG chain anyway...");
+               WARNING("trying to validate configured JTAG chain anyway...");
        }
        
-       while (jtag_validate_chain() != ERROR_OK)
-       {
-               validate_tries++;
-               if (validate_tries > 5)
+       return jtag_validate_chain();
+}
+
+/* Unless we can do this successfully 10 times, we're not
+ * satisfied with the quality of the JTAG communication.
+ * 
+ * Since we're continously repeating this operation, be a bit
+ * wary of filling the log with megabytes of data.
+ * 
+ * Keep increasing the jtag_divisor until we've got a solid
+ * result.
+ */
+int jtag_init_chain(struct command_context_s *cmd_ctx)
+{
+       int i, j;
+       int retval;
+       for (i=jtag_speed; i<64; i++)
                {
-                       ERROR("Could not validate JTAG chain, exit");
-                       jtag = NULL;
-                       return ERROR_JTAG_INVALID_INTERFACE;
+               u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
+               jtag_speed=i;
+               if ((retval=jtag->speed(jtag_speed))!=ERROR_OK)
+                       continue;
+               for (j=0; j<10; j++)
+               {
+                       u8 idcode_current[JTAG_MAX_CHAIN_SIZE * 4];
+                       enum log_levels save_log_level=debug_level;
+                       /* avoid spamming log */
+                       debug_level=LOG_SILENT;
+                       retval=jtag_test_chain(idcode_current);
+                       if (retval==ERROR_OK)
+                       {
+                               if (j==0)
+                               {
+                                       memcpy(idcode_buffer, idcode_current, sizeof(idcode_buffer));
+                               } else
+                               {
+                                       retval=(memcmp(idcode_buffer, idcode_current, sizeof(idcode_buffer))==0)?ERROR_OK:ERROR_JTAG_INIT_FAILED;
+                               }
+                       }
+                       debug_level = save_log_level;
+                       if (retval!=ERROR_OK)
+                       {
+                               break;
+                       }
                }
-               usleep(10000);
+               if (retval==ERROR_OK)
+               {
+                       /* Print out result  */
+                       INFO("Succeeded jtag chain test jtag_speed=%d", jtag_speed);
+                       return jtag_test_chain(idcode_buffer);
+               }
+               DEBUG("Failed jtag chain test, dropping clock rate. Trying jtag_speed=%d\n", i+1);
        }
-
-       return ERROR_OK;
+       return retval;
 }
 
 int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
@@ -1678,12 +1857,11 @@ int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char
 
        if (argc > 0)
        {
+               jtag_speed = strtoul(args[0], NULL, 0);
                /* this command can be called during CONFIG, 
                 * in which case jtag isn't initialized */
                if (jtag)
-                       jtag->speed(strtoul(args[0], NULL, 0));
-               else
-                       jtag_speed = strtoul(args[0], NULL, 0);
+                       jtag->speed(jtag_speed);
        }
 
        return ERROR_OK;
@@ -1894,43 +2072,6 @@ int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a
                free(fields[i].out_value);
 
        free(fields);
-
-       return ERROR_OK;
-}
-
-
-
-int MINIDRIVER(interface_jtag_add_shift)(const enum tap_state shift_state, const enum tap_state end_state, int num_bits, u32 value)
-{
-       u8 out_buf[4];
-       buf_set_u32(out_buf, 0, 32, flip_u32(value, 32));
-
-       /* allocate memory for a new list member */
-       jtag_command_t **last_cmd;
-       last_cmd = jtag_get_last_command_p();
-       *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
-       last_comand_pointer = &((*last_cmd)->next);
-       (*last_cmd)->next = NULL;
-       (*last_cmd)->type = JTAG_SCAN;
-
-       /* allocate memory for scan command */
-       (*last_cmd)->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t));
-       (*last_cmd)->cmd.scan->ir_scan = (shift_state==TAP_SI);
-       (*last_cmd)->cmd.scan->num_fields = 1;
-       (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(1 * sizeof(scan_field_t));
-       (*last_cmd)->cmd.scan->end_state = end_state;
-               
-       int num_bytes = CEIL(num_bits, 8);
-       int i=0;
-       (*last_cmd)->cmd.scan->fields[i].device = 0; /* not used by any drivers */
-       (*last_cmd)->cmd.scan->fields[i].num_bits = num_bits;
-       (*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(out_buf, cmd_queue_alloc(num_bytes), num_bits);
-       (*last_cmd)->cmd.scan->fields[i].out_mask = NULL;
-       (*last_cmd)->cmd.scan->fields[i].in_value = NULL;
-       (*last_cmd)->cmd.scan->fields[i].in_check_value = NULL;
-       (*last_cmd)->cmd.scan->fields[i].in_check_mask = NULL;
-       (*last_cmd)->cmd.scan->fields[i].in_handler = NULL;
-       (*last_cmd)->cmd.scan->fields[i].in_handler_priv = NULL;
        
        return ERROR_OK;
 }