From 495ef923ef6eaced194bf17ce9080b66a7fee4ea Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Harboe?= Date: Sat, 17 Jul 2010 22:22:21 +0200 Subject: [PATCH] debug-feature: jtagtcpip, improve jtag performance MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit postpone callbacks until jtag execute queue time. Signed-off-by: Øyvind Harboe --- src/jtag/zy1000/jtag_minidriver.h | 19 +++++++++--- src/jtag/zy1000/zy1000.c | 61 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/jtag/zy1000/jtag_minidriver.h b/src/jtag/zy1000/jtag_minidriver.h index 0f2b46a0f..7e13f6668 100644 --- a/src/jtag/zy1000/jtag_minidriver.h +++ b/src/jtag/zy1000/jtag_minidriver.h @@ -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 diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index a2b88917f..28c65b6e5 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -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(); -- 2.11.4.GIT