aboutsummaryrefslogtreecommitdiff
path: root/src/helper/binarybuffer.c
diff options
context:
space:
mode:
authorAndreas Fritiofson <andreas.fritiofson@gmail.com>2012-02-12 22:29:50 +0100
committerPeter Stuge <peter@stuge.se>2012-07-06 14:58:25 +0000
commit6d639b09f0e3ef0c1cc38606a851e6ae9a4f4e30 (patch)
treeaa7993fc4fdd0a470721138883654606fa83ab47 /src/helper/binarybuffer.c
parentedf0c3376d5394bc05b1028c5a17c19e17657dcb (diff)
downloadriscv-openocd-6d639b09f0e3ef0c1cc38606a851e6ae9a4f4e30.zip
riscv-openocd-6d639b09f0e3ef0c1cc38606a851e6ae9a4f4e30.tar.gz
riscv-openocd-6d639b09f0e3ef0c1cc38606a851e6ae9a4f4e30.tar.bz2
Add a bit-level transfer queue
Interface drivers regularly need to keep track of where each part of a long read buffer should be copied, once that data arrives. Both source and destination are often at an arbitrary bit offset. This queued bit-level copy can help with that, by allowing the driver to perform postponed reads from the receive buffer already when building the transmit buffer, and have those reads executed at a later time when data is available. For simplicity, it uses the linked list implementation list.h imported from the Linux kernel. Change-Id: I06862a0a6f057cbbcacfb021f17a795195faded2 Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Reviewed-on: http://openocd.zylin.com/450 Tested-by: jenkins Reviewed-by: Xiaofan <xiaofanc@gmail.com> Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com> Reviewed-by: Peter Stuge <peter@stuge.se>
Diffstat (limited to 'src/helper/binarybuffer.c')
-rw-r--r--src/helper/binarybuffer.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c
index 74af53a..d98fa16 100644
--- a/src/helper/binarybuffer.c
+++ b/src/helper/binarybuffer.c
@@ -327,3 +327,46 @@ int str_to_buf(const char *str, unsigned str_len,
return i;
}
+
+void bit_copy_queue_init(struct bit_copy_queue *q)
+{
+ INIT_LIST_HEAD(&q->list);
+}
+
+int bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset, const uint8_t *src,
+ unsigned src_offset, unsigned bit_count)
+{
+ struct bit_copy_queue_entry *qe = malloc(sizeof(*qe));
+ if (!qe)
+ return ERROR_FAIL;
+
+ qe->dst = dst;
+ qe->dst_offset = dst_offset;
+ qe->src = src;
+ qe->src_offset = src_offset;
+ qe->bit_count = bit_count;
+ list_add_tail(&qe->list, &q->list);
+
+ return ERROR_OK;
+}
+
+void bit_copy_execute(struct bit_copy_queue *q)
+{
+ struct bit_copy_queue_entry *qe;
+ struct bit_copy_queue_entry *tmp;
+ list_for_each_entry_safe(qe, tmp, &q->list, list) {
+ bit_copy(qe->dst, qe->dst_offset, qe->src, qe->src_offset, qe->bit_count);
+ list_del(&qe->list);
+ free(qe);
+ }
+}
+
+void bit_copy_discard(struct bit_copy_queue *q)
+{
+ struct bit_copy_queue_entry *qe;
+ struct bit_copy_queue_entry *tmp;
+ list_for_each_entry_safe(qe, tmp, &q->list, list) {
+ list_del(&qe->list);
+ free(qe);
+ }
+}