Skip to contentSkip to conversation

Generalise FIFO to more integer types

RFC Superseded Peter Crosthwaite 1 participant 3 messages Jan 3, 2014 Arm/Zynq architecture

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 27dab7d..9b43e36 100644
@@ -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
index f431764..021499b 100644
@@ -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
index af3e5cb..6719142 100644
@@ -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
similarity index 73%
rename from util/fifo8.c
rename to util/fifo.c
index 013e903..1adaa11 100644
@@ -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
#2 lore raw

RFC 2/2 util/fifo: Generalise for common integer widths

In reply to Peter Crosthwaite

Add 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
index 9b43e36..cc71249 100644
@@ -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
index 8fe3072..cac666b 100644
@@ -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
index c3d9c05..aeff06c 100644
@@ -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
index e488387..a1737c3 100644
@@ -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