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 <b.galvani@gmail.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Beniamino Galvani 2014-01-30 23:02:04 +01:00 committed by Peter Maydell
parent 999b53ec87
commit c4e57af852
2 changed files with 107 additions and 0 deletions

View file

@ -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,