Generalise FIFO to more integer types
cover Generalise FIFO to more integer types
There is a utility helper for dealing with 8 bit fifos. This should be applicable to other integer widths as well. These two patches generalise this FIFO to work for 16, 32 and 64 bit ints.
Peter Crosthwaite (2):
util/fifo: s/fifo8/fifo globally
util/fifo: Generalise for common integer widths
hw/char/serial.c | 30 +++++----- hw/ssi/xilinx_spi.c | 42 ++++++------- hw/ssi/xilinx_spips.c | 66 ++++++++++---------- include/hw/char/serial.h | 6 +- include/qemu/fifo.h | 104 ++++++++++++++++++++++++++++++++ include/qemu/fifo8.h | 99 ------------------------------ util/Makefile.objs | 2 +- util/fifo.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++ util/fifo8.c | 79 ------------------------ 9 files changed, 329 insertions(+), 251 deletions(-) create mode 100644 include/qemu/fifo.h delete mode 100644 include/qemu/fifo8.h create mode 100644 util/fifo.c delete mode 100644 util/fifo8.c
Signature · 1 line
1.8.5.2
RFC 1/2 util/fifo: s/fifo8/fifo globally
This prepares support for generalising FIFO support to more integer widths.
---
hw/char/serial.c | 30 +++++++++---------
hw/ssi/xilinx_spi.c | 42 ++++++++++++-------------
hw/ssi/xilinx_spips.c | 66 ++++++++++++++++++++--------------------
include/hw/char/serial.h | 6 ++--
include/qemu/{fifo8.h => fifo.h} | 58 +++++++++++++++++------------------
util/Makefile.objs | 2 +-
util/{fifo8.c => fifo.c} | 24 +++++++--------
7 files changed, 114 insertions(+), 114 deletions(-)
rename include/qemu/{fifo8.h => fifo.h} (50%)
rename util/{fifo8.c => fifo.c} (73%)hw/char/serial.c +15 -15
@@ -108,8 +108,8 @@ static void serial_receive1(void *opaque, const uint8_t *buf, int size);static inline void recv_fifo_put (SerialState *s,uint8_t chr) {/* Receive overruns do not overwrite FIFO contents. */ -if (!fifo8_is_full (&s->recv_fifo)) { -fifo8_push (&s->recv_fifo, chr); +if (!fifo_is_full (&s->recv_fifo)) { +fifo_push (&s->recv_fifo, chr); }else { s->lsr |=UART_LSR_OE ; }
@@ -225,8 +225,8 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)if (s->tsr_retry <=0 ) {if (s->fcr &UART_FCR_FE ) { - s->tsr =fifo8_is_full (&s->xmit_fifo) ? -0 :fifo8_pop (&s->xmit_fifo); + s->tsr =fifo_is_full (&s->xmit_fifo) ? +0 :fifo_pop (&s->xmit_fifo);if (!s->xmit_fifo.num) { s->lsr |=UART_LSR_THRE ; }
@@ -282,10 +282,10 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, s->thr = (uint8_t ) val;if (s->fcr &UART_FCR_FE ) {/* xmit overruns overwrite data, so make space if needed */ -if (fifo8_is_full (&s->xmit_fifo)) { -fifo8_pop (&s->xmit_fifo); +if (fifo_is_full (&s->xmit_fifo)) { +fifo_pop (&s->xmit_fifo); } -fifo8_push (&s->xmit_fifo, s->thr); +fifo_push (&s->xmit_fifo, s->thr); s->lsr &= ~UART_LSR_TEMT ; } s->thr_ipending =0 ;
@@ -332,11 +332,11 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,if (val &UART_FCR_RFR ) {timer_del (s->fifo_timeout_timer); s->timeout_ipending=0 ; -fifo8_reset (&s->recv_fifo); +fifo_reset (&s->recv_fifo); }if (val &UART_FCR_XFR ) { -fifo8_reset (&s->xmit_fifo); +fifo_reset (&s->xmit_fifo); }if (val &UART_FCR_FE ) {
@@ -425,8 +425,8 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size) ret = s->divider &0xff ; }else {if (s->fcr &UART_FCR_FE ) { - ret =fifo8_is_empty (&s->recv_fifo) ? -0 :fifo8_pop (&s->recv_fifo); + ret =fifo_is_empty (&s->recv_fifo) ? +0 :fifo_pop (&s->recv_fifo);if (s->recv_fifo.num ==0 ) { s->lsr &= ~(UART_LSR_DR |UART_LSR_BI ); }else {
@@ -633,8 +633,8 @@ static void serial_reset(void *opaque) s->char_transmit_time = (get_ticks_per_sec () /9600 ) *10 ; s->poll_msl =0 ; -fifo8_reset (&s->recv_fifo); -fifo8_reset (&s->xmit_fifo); +fifo_reset (&s->recv_fifo); +fifo_reset (&s->xmit_fifo); s->last_xmit_ts =qemu_clock_get_ns (QEMU_CLOCK_VIRTUAL );
@@ -657,8 +657,8 @@ void serial_realize_core(SerialState *s, Error **errp)qemu_chr_add_handlers (s->chr, serial_can_receive1, serial_receive1, serial_event, s); -fifo8_create (&s->recv_fifo,UART_FIFO_LENGTH ); -fifo8_create (&s->xmit_fifo,UART_FIFO_LENGTH ); +fifo_create (&s->recv_fifo,UART_FIFO_LENGTH ); +fifo_create (&s->xmit_fifo,UART_FIFO_LENGTH ); }void serial_exit_core (SerialState *s)
hw/ssi/xilinx_spi.c +21 -21
112 lines not on this page · raw message
hw/ssi/xilinx_spips.c +33 -33
182 lines not on this page · raw message
include/hw/char/serial.h +3 -3
@@ -28,7 +28,7 @@#include "hw/hw.h" #include "sysemu/sysemu.h" #include "exec/memory.h" -#include "qemu/fifo8.h" +#include "qemu/fifo.h" #define UART_FIFO_LENGTH 16/* 16550A Fifo Length */
@@ -60,8 +60,8 @@ struct SerialState {/* Time when the last byte was successfully sent out of the tsr */ uint64_t last_xmit_ts; -Fifo8 recv_fifo; -Fifo8 xmit_fifo; +Fifo recv_fifo; +Fifo xmit_fifo;/* Interrupt trigger level for recv_fifo */ uint8_t recv_fifo_itl;
include/qemu/fifo.h renamed from include/qemu/fifo8.h +29 -29
118 lines not on this page · raw message
util/Makefile.objs +1 -1
@@ -3,7 +3,7 @@ util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o event_notifier-win util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o event_notifier-posix.o qemu-openpty.o util-obj-y += envlist.o path.o host-utils.o cache-utils.o module.o util-obj-y += bitmap.o bitops.o hbitmap.o -util-obj-y += fifo8.o +util-obj-y += fifo.o util-obj-y += acl.o util-obj-y += error.o qemu-error.o util-obj-$(CONFIG_POSIX) += compatfd.o
util/fifo.c renamed from util/fifo8.c +12 -12
@@ -13,9 +13,9 @@*/ #include "qemu-common.h" -#include "qemu/fifo8.h" +#include "qemu/fifo.h" -void fifo8_create (Fifo8 *fifo,uint32_t capacity) +void fifo_create (Fifo *fifo,uint32_t capacity) { fifo->data =g_new (uint8_t, capacity); fifo->capacity = capacity;
@@ -23,12 +23,12 @@ void fifo8_create(Fifo8 *fifo, uint32_t capacity) fifo->num =0 ; } -void fifo8_destroy (Fifo8 *fifo) +void fifo_destroy (Fifo *fifo) {g_free (fifo->data); } -void fifo8_push (Fifo8 *fifo,uint8_t data) +void fifo_push (Fifo *fifo,uint8_t data) {if (fifo->num == fifo->capacity) {abort ();
@@ -37,7 +37,7 @@ void fifo8_push(Fifo8 *fifo, uint8_t data) fifo->num++; } -uint8_t fifo8_pop (Fifo8 *fifo) +uint8_t fifo_pop (Fifo *fifo) {uint8_t ret;
@@ -50,30 +50,30 @@ uint8_t fifo8_pop(Fifo8 *fifo)return ret; } -void fifo8_reset (Fifo8 *fifo) +void fifo_reset (Fifo *fifo) { fifo->num =0 ; } -bool fifo8_is_empty (Fifo8 *fifo) +bool fifo_is_empty (Fifo *fifo) {return (fifo->num ==0 ); } -bool fifo8_is_full (Fifo8 *fifo) +bool fifo_is_full (Fifo *fifo) {return (fifo->num == fifo->capacity); } -const VMStateDescription vmstate_fifo8 = { +const VMStateDescription vmstate_fifo = { .name ="Fifo8" , .version_id =1 , .minimum_version_id =1 , .minimum_version_id_old =1 , .fields = (VMStateField []) { -VMSTATE_VBUFFER_UINT32 (data, Fifo8,1 ,NULL ,0 , capacity), -VMSTATE_UINT32 (head, Fifo8), -VMSTATE_UINT32 (num, Fifo8), +VMSTATE_VBUFFER_UINT32 (data, Fifo,1 ,NULL ,0 , capacity), +VMSTATE_UINT32 (head, Fifo), +VMSTATE_UINT32 (num, Fifo),VMSTATE_END_OF_LIST () } };
Signature · 1 line
1.8.5.2
RFC 2/2 util/fifo: Generalise for common integer widths
In reply to Peter CrosthwaiteAdd support for 16, 32 and 64 bit width FIFOs. The push and pop functions are patched to accept uint64_t always to support up to 64bit integer elements. The element width is set at creation time.
The backing storage for all element types is still uint8_t regardless of element width so some save-load logic is needed to handle endianess issue WRT VMSD.
---
hw/char/serial.c | 4 +-- hw/ssi/xilinx_spi.c | 4 +-- hw/ssi/xilinx_spips.c | 4 +-- include/qemu/fifo.h | 15 ++++++--- util/fifo.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 98 insertions(+), 20 deletions(-)
hw/char/serial.c +2 -2
@@ -657,8 +657,8 @@ void serial_realize_core(SerialState *s, Error **errp)qemu_chr_add_handlers (s->chr, serial_can_receive1, serial_receive1, serial_event, s); -fifo_create (&s->recv_fifo,UART_FIFO_LENGTH ); -fifo_create (&s->xmit_fifo,UART_FIFO_LENGTH ); +fifo_create (&s->recv_fifo,UART_FIFO_LENGTH ,8 ); +fifo_create (&s->xmit_fifo,UART_FIFO_LENGTH ,8 ); }void serial_exit_core (SerialState *s)
hw/ssi/xilinx_spi.c +2 -2
@@ -341,8 +341,8 @@ static int xilinx_spi_init(SysBusDevice *sbd) s->irqline =-1 ; -fifo_create (&s->tx_fifo,FIFO_CAPACITY ); -fifo_create (&s->rx_fifo,FIFO_CAPACITY ); +fifo_create (&s->tx_fifo,FIFO_CAPACITY ,8 ); +fifo_create (&s->rx_fifo,FIFO_CAPACITY ,8 );return 0 ; }
hw/ssi/xilinx_spips.c +2 -2
@@ -669,8 +669,8 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp) s->irqline =-1 ; -fifo_create (&s->rx_fifo, xsc->rx_fifo_size); -fifo_create (&s->tx_fifo, xsc->tx_fifo_size); +fifo_create (&s->rx_fifo, xsc->rx_fifo_size,8 ); +fifo_create (&s->tx_fifo, xsc->tx_fifo_size,8 ); }static void xilinx_qspips_realize (DeviceState *dev,Error **errp)
include/qemu/fifo.h +10 -5
@@ -5,8 +5,12 @@typedef struct {/* All fields are private */ +int width;/* byte width each each element */ +uint32_t capacity;/* number of elements */ +uint8_t *data; -uint32_t capacity; +uint32_t buffer_size; +uint32_t head;uint32_t num; }Fifo ;
@@ -14,13 +18,14 @@ typedef struct {/** * fifo_create: * @fifo: struct Fifo to initialise with new FIFO -* @capacity: capacity of the newly created FIFO +* @capacity: capacity (number of elements) of the newly created FIFO +* @width: integer width of each element. Must be 8, 16, 32 or 64. * * Create a FIFO of the specified size. Clients should call fifo_destroy() * when finished using the fifo. The FIFO is initially empty. */ -void fifo_create (Fifo *fifo,uint32_t capacity); +void fifo_create (Fifo *fifo,uint32_t capacity,int width);/** * fifo_destroy:
@@ -41,7 +46,7 @@ void fifo_destroy(Fifo *fifo);* Clients are responsible for checking for fullness using fifo_is_full(). */ -void fifo_push (Fifo *fifo,uint8_t data); +void fifo_push (Fifo *fifo,uint64_t data);/** * fifo_pop:
@@ -53,7 +58,7 @@ void fifo_push(Fifo *fifo, uint8_t data);* Returns: The popped data value. */ -uint8_t fifo_pop (Fifo *fifo); +uint64_t fifo_pop (Fifo *fifo);/** * fifo_reset:
util/fifo.c +82 -9
130 lines not on this page · raw message
Signature · 1 line
1.8.5.2