From c4e57af85272f98c28ccaaace040d2abb0ec85c4 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 30 Jan 2014 23:02:04 +0100 Subject: util/fifo8: implement push/pop of multiple bytes The patch adds functions fifo8_push_all() and fifo8_pop_buf() which can be used respectively to push the content of a memory buffer to the fifo and to pop multiple bytes obtaining a pointer to the fifo backing buffer. In addition, it implements fifo8_num_free() and fifo8_num_used() which allow to check if a multi-byte operation can be performed. Signed-off-by: Beniamino Galvani Reviewed-by: Peter Crosthwaite Signed-off-by: Peter Maydell --- util/fifo8.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'util') diff --git a/util/fifo8.c b/util/fifo8.c index 013e903c6e..a7503c2293 100644 --- a/util/fifo8.c +++ b/util/fifo8.c @@ -37,6 +37,27 @@ void fifo8_push(Fifo8 *fifo, uint8_t data) fifo->num++; } +void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num) +{ + uint32_t start, avail; + + if (fifo->num + num > fifo->capacity) { + abort(); + } + + start = (fifo->head + fifo->num) % fifo->capacity; + + if (start + num <= fifo->capacity) { + memcpy(&fifo->data[start], data, num); + } else { + avail = fifo->capacity - start; + memcpy(&fifo->data[start], data, avail); + memcpy(&fifo->data[0], &data[avail], num - avail); + } + + fifo->num += num; +} + uint8_t fifo8_pop(Fifo8 *fifo) { uint8_t ret; @@ -50,6 +71,21 @@ uint8_t fifo8_pop(Fifo8 *fifo) return ret; } +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num) +{ + uint8_t *ret; + + if (max == 0 || max > fifo->num) { + abort(); + } + *num = MIN(fifo->capacity - fifo->head, max); + ret = &fifo->data[fifo->head]; + fifo->head += *num; + fifo->head %= fifo->capacity; + fifo->num -= *num; + return ret; +} + void fifo8_reset(Fifo8 *fifo) { fifo->num = 0; @@ -65,6 +101,16 @@ bool fifo8_is_full(Fifo8 *fifo) return (fifo->num == fifo->capacity); } +uint32_t fifo8_num_free(Fifo8 *fifo) +{ + return fifo->capacity - fifo->num; +} + +uint32_t fifo8_num_used(Fifo8 *fifo) +{ + return fifo->num; +} + const VMStateDescription vmstate_fifo8 = { .name = "Fifo8", .version_id = 1, -- cgit v1.2.3