]> git.sur5r.net Git - openocd/commitdiff
debug-feature: jtagtcpip, improve jtag performance
authorØyvind Harboe <oyvind.harboe@zylin.com>
Sat, 17 Jul 2010 20:22:21 +0000 (22:22 +0200)
committerØyvind Harboe <oyvind.harboe@zylin.com>
Sun, 18 Jul 2010 14:33:02 +0000 (16:33 +0200)
postpone callbacks until jtag execute queue time.

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
src/jtag/zy1000/jtag_minidriver.h
src/jtag/zy1000/zy1000.c

index 0f2b46a0f41996161a95e6bfe2023179d951fc09..7e13f6668262826e85b011787f6e275a8482d94f 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2007-2009 by Øyvind Harboe                              *
+ *   Copyright (C) 2007-2010 by Øyvind Harboe                              *
  *                                                                         *
  *   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  *
@@ -63,9 +63,16 @@ static __inline__ void zy1000_flush_readqueue(void)
 {
        /* Not used w/hardware fifo */
 }
+static __inline__ void zy1000_flush_callbackqueue(void)
+{
+       /* Not used w/hardware fifo */
+}
 #else
 extern void waitIdle(void);
 void zy1000_flush_readqueue(void);
+void zy1000_flush_callbackqueue(void);
+void zy1000_jtag_add_callback4(jtag_callback_t callback, jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3);
+void zy1000_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0);
 #endif
 
 static __inline__ void waitQueue(void)
@@ -228,6 +235,10 @@ static __inline__ void interface_jtag_add_dr_out(struct jtag_tap *target_tap,
        }
 }
 
-/* Must flush any read queue before we can invoke callback */
-#define interface_jtag_add_callback(callback, in) {zy1000_flush_readqueue(); callback(in);}
-#define interface_jtag_add_callback4(callback, in, data1, data2, data3) {zy1000_flush_readqueue(); jtag_set_error(callback(in, data1, data2, data3));}
+#if BUILD_ECOSBOARD
+#define interface_jtag_add_callback(callback, in) callback(in)
+#define interface_jtag_add_callback4(callback, in, data1, data2, data3) jtag_set_error(callback(in, data1, data2, data3))
+#else
+#define interface_jtag_add_callback(callback, in) zy1000_jtag_add_callback(callback, in)
+#define interface_jtag_add_callback4(callback, in, data1, data2, data3) zy1000_jtag_add_callback4(callback, in, data1, data2, data3)
+#endif
index a2b88917f2e5f41cb996c75bf0c37176c2337e44..28c65b6e56658e9312e1ca3ca642b71a0dcdbc05 100644 (file)
@@ -468,6 +468,9 @@ int interface_jtag_execute_queue(void)
         */
        zy1000_flush_readqueue();
 
+       /* and handle any callbacks... */
+       zy1000_flush_callbackqueue();
+
        if (zy1000_rclk)
        {
                /* Only check for errors when using RCLK to speed up
@@ -1222,6 +1225,64 @@ void zy1000_flush_readqueue(void)
        readqueue_pos = 0;
 }
 
+/* By queuing the callback's we avoid flushing the
+read queue until jtag_execute_queue(). This can
+reduce latency dramatically for cases where
+callbacks are used extensively.
+*/
+#define callbackqueue_size 128
+static struct callbackentry
+{
+       jtag_callback_t callback;
+       jtag_callback_data_t data0;
+       jtag_callback_data_t data1;
+       jtag_callback_data_t data2;
+       jtag_callback_data_t data3;
+} callbackqueue[callbackqueue_size];
+
+static int callbackqueue_pos = 0;
+
+void zy1000_jtag_add_callback4(jtag_callback_t callback, jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
+{
+       if (callbackqueue_pos >= callbackqueue_size)
+       {
+               zy1000_flush_callbackqueue();
+       }
+
+       callbackqueue[callbackqueue_pos].callback = callback;
+       callbackqueue[callbackqueue_pos].data0 = data0;
+       callbackqueue[callbackqueue_pos].data1 = data1;
+       callbackqueue[callbackqueue_pos].data2 = data2;
+       callbackqueue[callbackqueue_pos].data3 = data3;
+       callbackqueue_pos++;
+}
+
+static int zy1000_jtag_convert_to_callback4(jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
+{
+       ((jtag_callback1_t)data1)(data0);
+       return ERROR_OK;
+}
+
+void zy1000_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0)
+{
+       zy1000_jtag_add_callback4(zy1000_jtag_convert_to_callback4, data0, (jtag_callback_data_t)callback, 0, 0);
+}
+
+void zy1000_flush_callbackqueue(void)
+{
+       /* we have to flush the read queue so we have access to
+        the data the callbacks will use 
+       */
+       zy1000_flush_readqueue();
+       int i;
+       for (i = 0; i < callbackqueue_pos; i++)
+       {
+               struct callbackentry *entry = &callbackqueue[i];
+               jtag_set_error(entry->callback(entry->data0, entry->data1, entry->data2, entry->data3));
+       }
+       callbackqueue_pos = 0;
+}
+
 static void writeShiftValue(uint8_t *data, int bits)
 {
        waitIdle();