- the jtag chain is examined and validated after GDB & telnet servers
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Mon, 10 Mar 2008 14:07:28 +0000 (14:07 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Mon, 10 Mar 2008 14:07:28 +0000 (14:07 +0000)
 are up and running. The examination and validation is actually
 "optional" from the point of view of GDB + telnet servers.
 Multiple targets should work fine with this.
- jtag_speed is dropped(divisor is increased), if jtag examination and
 validation fails.
- the chain is validated 10x to catch the worst jtag_speed offences
- added LOG_SILENT that can be used to shut up log. Feeble
 ersatz for try+catch.
- GDB register packets are now always replied in order to make sure
 that GDB connect works. If the target is not halted, then these
 packets contain dummy values.

git-svn-id: svn://svn.berlios.de/openocd/trunk@483 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/jtag/Makefile.am
src/jtag/jtag.c
src/target/arm11.c
src/target/armv4_5.c
src/target/armv7m.c
src/target/target.h

index a35e3f3f17b0e0b645acda77aac034fc76e8a0aa..04e50ffd23fa1e6175ffddcce951255107d3c310 100644 (file)
@@ -9,7 +9,7 @@ else
 FTD2XXINC =
 endif
 
-INCLUDES = -I$(top_srcdir)/src/helper $(FTD2XXINC) $(all_includes)
+INCLUDES = -I$(top_srcdir)/src/helper $(FTD2XXINC) $(all_includes) -I$(top_srcdir)/src/target 
 METASOURCES = AUTO
 noinst_LIBRARIES = libjtag.a
 
index 430a6ff87b2071ba154f9326a628824bd698f475..48cd0595646eafdebcb545da92105388f7079464 100644 (file)
@@ -28,6 +28,7 @@
 #include "command.h"
 #include "log.h"
 #include "interpreter.h"
+#include "target.h"
 
 #include "stdlib.h"
 #include "string.h"
@@ -1327,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;
@@ -1533,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("-");
@@ -1556,24 +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++)
+               {
+               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++)
                {
-                       ERROR("Could not validate JTAG chain, exit");
-                       return ERROR_JTAG_INVALID_INTERFACE;
+                       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)
@@ -1778,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;
index a197945fa913c9725d767cda47871fa83e2a3b41..890b836bb29015916feff62da9db80d676b029f1 100644 (file)
@@ -1040,12 +1040,6 @@ int arm11_get_gdb_reg_list(struct target_s *target, struct reg_s **reg_list[], i
 
     arm11_common_t * arm11 = target->arch_info;
 
-    if (target->state != TARGET_HALTED)
-    {
-       WARNING("target was not halted");
-       return ERROR_TARGET_NOT_HALTED;
-    }
-       
     *reg_list_size  = ARM11_GDB_REGISTER_COUNT;
     *reg_list      = malloc(sizeof(reg_t*) * ARM11_GDB_REGISTER_COUNT);
 
index 82e65c78906d4a781e06242fb60d5b54e0bed6ac..ff5f4735c9adec9fc22c2fcf7acea40a78326620 100644 (file)
@@ -474,12 +474,6 @@ int armv4_5_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list
        armv4_5_common_t *armv4_5 = target->arch_info;
        int i;
        
-       if (target->state != TARGET_HALTED)
-       {
-               ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-       
        *reg_list_size = 26;
        *reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
        
index 6ee5903ac8074628374163226e802032f5d88fa0..f1f0ac967a0d91f90f3c8cd0dbddd4e2a2f7428a 100644 (file)
@@ -321,12 +321,6 @@ int armv7m_get_gdb_reg_list(target_t *target, reg_t **reg_list[], int *reg_list_
        armv7m_common_t *armv7m = target->arch_info;
        int i;
        
-       if (target->state != TARGET_HALTED)
-       {
-               ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-       
        *reg_list_size = 26;
        *reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
        
index 8d70e77ebc9f3ac1cb2263dd742676804e74bfca..e028665043909984b886197ca093693b8d0b80b3 100644 (file)
@@ -127,7 +127,15 @@ typedef struct target_type_s
        int (*soft_reset_halt)(struct target_s *target);
        int (*prepare_reset_halt)(struct target_s *target);
        
-       /* target register access for gdb */
+       /* target register access for gdb.
+        * 
+        * Danger! this function will succeed even if the target is running
+        * and return a register list with dummy values.
+        * 
+        * The reason is that GDB connection will fail without a valid register
+        * list, however it is after GDB is connected that monitor commands can
+        * be run to properly initialize the target
+        */
        int (*get_gdb_reg_list)(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size);
        
        /* target memory access 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)