All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC v1 0/2]  Generalise FIFO to more integer types
@ 2014-01-03  1:41 Peter Crosthwaite
  2014-01-03  1:42 ` [Qemu-devel] [RFC v1 1/2] util/fifo: s/fifo8/fifo globally Peter Crosthwaite
  2014-01-03  1:43 ` [Qemu-devel] [RFC v1 2/2] util/fifo: Generalise for common integer widths Peter Crosthwaite
  0 siblings, 2 replies; 3+ messages in thread
From: Peter Crosthwaite @ 2014-01-03  1:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: b.galvani, edgar.iglesias, pbonzini, peter.maydell


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

-- 
1.8.5.2

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Qemu-devel] [RFC v1 1/2] util/fifo: s/fifo8/fifo globally
  2014-01-03  1:41 [Qemu-devel] [RFC v1 0/2] Generalise FIFO to more integer types Peter Crosthwaite
@ 2014-01-03  1:42 ` Peter Crosthwaite
  2014-01-03  1:43 ` [Qemu-devel] [RFC v1 2/2] util/fifo: Generalise for common integer widths Peter Crosthwaite
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Crosthwaite @ 2014-01-03  1:42 UTC (permalink / raw)
  To: qemu-devel; +Cc: b.galvani, edgar.iglesias, pbonzini, peter.maydell

This prepares support for generalising FIFO support to more integer
widths.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---

 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%)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index 27dab7d..9b43e36 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -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)
diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c
index d44caae..8fe3072 100644
--- a/hw/ssi/xilinx_spi.c
+++ b/hw/ssi/xilinx_spi.c
@@ -27,7 +27,7 @@
 #include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
 #include "qemu/log.h"
-#include "qemu/fifo8.h"
+#include "qemu/fifo.h"
 
 #include "hw/ssi.h"
 
@@ -89,15 +89,15 @@ typedef struct XilinxSPI {
 
     SSIBus *spi;
 
-    Fifo8 rx_fifo;
-    Fifo8 tx_fifo;
+    Fifo rx_fifo;
+    Fifo tx_fifo;
 
     uint32_t regs[R_MAX];
 } XilinxSPI;
 
 static void txfifo_reset(XilinxSPI *s)
 {
-    fifo8_reset(&s->tx_fifo);
+    fifo_reset(&s->tx_fifo);
 
     s->regs[R_SPISR] &= ~SR_TX_FULL;
     s->regs[R_SPISR] |= SR_TX_EMPTY;
@@ -105,7 +105,7 @@ static void txfifo_reset(XilinxSPI *s)
 
 static void rxfifo_reset(XilinxSPI *s)
 {
-    fifo8_reset(&s->rx_fifo);
+    fifo_reset(&s->rx_fifo);
 
     s->regs[R_SPISR] |= SR_RX_EMPTY;
     s->regs[R_SPISR] &= ~SR_RX_FULL;
@@ -125,8 +125,8 @@ static void xlx_spi_update_irq(XilinxSPI *s)
     uint32_t pending;
 
     s->regs[R_IPISR] |=
-            (!fifo8_is_empty(&s->rx_fifo) ? IRQ_DRR_NOT_EMPTY : 0) |
-            (fifo8_is_full(&s->rx_fifo) ? IRQ_DRR_FULL : 0);
+            (!fifo_is_empty(&s->rx_fifo) ? IRQ_DRR_NOT_EMPTY : 0) |
+            (fifo_is_full(&s->rx_fifo) ? IRQ_DRR_FULL : 0);
 
     pending = s->regs[R_IPISR] & s->regs[R_IPIER];
 
@@ -171,16 +171,16 @@ static void spi_flush_txfifo(XilinxSPI *s)
     uint32_t tx;
     uint32_t rx;
 
-    while (!fifo8_is_empty(&s->tx_fifo)) {
-        tx = (uint32_t)fifo8_pop(&s->tx_fifo);
+    while (!fifo_is_empty(&s->tx_fifo)) {
+        tx = (uint32_t)fifo_pop(&s->tx_fifo);
         DB_PRINT("data tx:%x\n", tx);
         rx = ssi_transfer(s->spi, tx);
         DB_PRINT("data rx:%x\n", rx);
-        if (fifo8_is_full(&s->rx_fifo)) {
+        if (fifo_is_full(&s->rx_fifo)) {
             s->regs[R_IPISR] |= IRQ_DRR_OVERRUN;
         } else {
-            fifo8_push(&s->rx_fifo, (uint8_t)rx);
-            if (fifo8_is_full(&s->rx_fifo)) {
+            fifo_push(&s->rx_fifo, (uint8_t)rx);
+            if (fifo_is_full(&s->rx_fifo)) {
                 s->regs[R_SPISR] |= SR_RX_FULL;
                 s->regs[R_IPISR] |= IRQ_DRR_FULL;
             }
@@ -205,14 +205,14 @@ spi_read(void *opaque, hwaddr addr, unsigned int size)
     addr >>= 2;
     switch (addr) {
     case R_SPIDRR:
-        if (fifo8_is_empty(&s->rx_fifo)) {
+        if (fifo_is_empty(&s->rx_fifo)) {
             DB_PRINT("Read from empty FIFO!\n");
             return 0xdeadbeef;
         }
 
         s->regs[R_SPISR] &= ~SR_RX_FULL;
-        r = fifo8_pop(&s->rx_fifo);
-        if (fifo8_is_empty(&s->rx_fifo)) {
+        r = fifo_pop(&s->rx_fifo);
+        if (fifo_is_empty(&s->rx_fifo)) {
             s->regs[R_SPISR] |= SR_RX_EMPTY;
         }
         break;
@@ -253,8 +253,8 @@ spi_write(void *opaque, hwaddr addr,
 
     case R_SPIDTR:
         s->regs[R_SPISR] &= ~SR_TX_EMPTY;
-        fifo8_push(&s->tx_fifo, (uint8_t)value);
-        if (fifo8_is_full(&s->tx_fifo)) {
+        fifo_push(&s->tx_fifo, (uint8_t)value);
+        if (fifo_is_full(&s->tx_fifo)) {
             s->regs[R_SPISR] |= SR_TX_FULL;
         }
         if (!spi_master_enabled(s)) {
@@ -341,8 +341,8 @@ static int xilinx_spi_init(SysBusDevice *sbd)
 
     s->irqline = -1;
 
-    fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
-    fifo8_create(&s->rx_fifo, FIFO_CAPACITY);
+    fifo_create(&s->tx_fifo, FIFO_CAPACITY);
+    fifo_create(&s->rx_fifo, FIFO_CAPACITY);
 
     return 0;
 }
@@ -353,8 +353,8 @@ static const VMStateDescription vmstate_xilinx_spi = {
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_FIFO8(tx_fifo, XilinxSPI),
-        VMSTATE_FIFO8(rx_fifo, XilinxSPI),
+        VMSTATE_FIFO(tx_fifo, XilinxSPI),
+        VMSTATE_FIFO(rx_fifo, XilinxSPI),
         VMSTATE_UINT32_ARRAY(regs, XilinxSPI, R_MAX),
         VMSTATE_END_OF_LIST()
     }
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 6a28746..c3d9c05 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -26,7 +26,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/ptimer.h"
 #include "qemu/log.h"
-#include "qemu/fifo8.h"
+#include "qemu/fifo.h"
 #include "hw/ssi.h"
 #include "qemu/bitops.h"
 
@@ -150,8 +150,8 @@ typedef struct {
     qemu_irq *cs_lines;
     SSIBus **spi;
 
-    Fifo8 rx_fifo;
-    Fifo8 tx_fifo;
+    Fifo rx_fifo;
+    Fifo tx_fifo;
 
     uint8_t num_txrx_bytes;
 
@@ -196,7 +196,7 @@ static inline int num_effective_busses(XilinxSPIPS *s)
 static inline bool xilinx_spips_cs_is_set(XilinxSPIPS *s, int i, int field)
 {
     return ~field & (1 << i) && (s->regs[R_CONFIG] & MANUAL_CS
-                    || !fifo8_is_empty(&s->tx_fifo));
+                    || !fifo_is_empty(&s->tx_fifo));
 }
 
 static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
@@ -239,9 +239,9 @@ static void xilinx_spips_update_ixr(XilinxSPIPS *s)
                                 IXR_TX_FIFO_MODE_FAIL);
     /* these are pure functions of fifo state, set them here */
     s->regs[R_INTR_STATUS] |=
-        (fifo8_is_full(&s->rx_fifo) ? IXR_RX_FIFO_FULL : 0) |
+        (fifo_is_full(&s->rx_fifo) ? IXR_RX_FIFO_FULL : 0) |
         (s->rx_fifo.num >= s->regs[R_RX_THRES] ? IXR_RX_FIFO_NOT_EMPTY : 0) |
-        (fifo8_is_full(&s->tx_fifo) ? IXR_TX_FIFO_FULL : 0) |
+        (fifo_is_full(&s->tx_fifo) ? IXR_TX_FIFO_FULL : 0) |
         (s->tx_fifo.num < s->regs[R_TX_THRES] ? IXR_TX_FIFO_NOT_FULL : 0);
     /* drive external interrupt pin */
     int new_irqline = !!(s->regs[R_INTR_MASK] & s->regs[R_INTR_STATUS] &
@@ -261,8 +261,8 @@ static void xilinx_spips_reset(DeviceState *d)
         s->regs[i] = 0;
     }
 
-    fifo8_reset(&s->rx_fifo);
-    fifo8_reset(&s->rx_fifo);
+    fifo_reset(&s->rx_fifo);
+    fifo_reset(&s->rx_fifo);
     /* non zero resets */
     s->regs[R_CONFIG] |= MODEFAIL_GEN_EN;
     s->regs[R_SLAVE_IDLE_COUNT] = 0xFF;
@@ -315,7 +315,7 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
         uint8_t tx = 0;
         uint8_t tx_rx[num_effective_busses(s)];
 
-        if (fifo8_is_empty(&s->tx_fifo)) {
+        if (fifo_is_empty(&s->tx_fifo)) {
             if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) {
                 s->regs[R_INTR_STATUS] |= IXR_TX_FIFO_UNDERFLOW;
             }
@@ -323,11 +323,11 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
             return;
         } else if (s->snoop_state == SNOOP_STRIPING) {
             for (i = 0; i < num_effective_busses(s); ++i) {
-                tx_rx[i] = fifo8_pop(&s->tx_fifo);
+                tx_rx[i] = fifo_pop(&s->tx_fifo);
             }
             stripe8(tx_rx, num_effective_busses(s), false);
         } else {
-            tx = fifo8_pop(&s->tx_fifo);
+            tx = fifo_pop(&s->tx_fifo);
             for (i = 0; i < num_effective_busses(s); ++i) {
                 tx_rx[i] = tx;
             }
@@ -339,16 +339,16 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
             DB_PRINT_L(debug_level, "rx = %02x\n", tx_rx[i]);
         }
 
-        if (fifo8_is_full(&s->rx_fifo)) {
+        if (fifo_is_full(&s->rx_fifo)) {
             s->regs[R_INTR_STATUS] |= IXR_RX_FIFO_OVERFLOW;
             DB_PRINT_L(0, "rx FIFO overflow");
         } else if (s->snoop_state == SNOOP_STRIPING) {
             stripe8(tx_rx, num_effective_busses(s), true);
             for (i = 0; i < num_effective_busses(s); ++i) {
-                fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[i]);
+                fifo_push(&s->rx_fifo, (uint8_t)tx_rx[i]);
             }
         } else {
-           fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[0]);
+           fifo_push(&s->rx_fifo, (uint8_t)tx_rx[0]);
         }
 
         DB_PRINT_L(debug_level, "initial snoop state: %x\n",
@@ -395,8 +395,8 @@ static inline void rx_data_bytes(XilinxSPIPS *s, uint8_t *value, int max)
 {
     int i;
 
-    for (i = 0; i < max && !fifo8_is_empty(&s->rx_fifo); ++i) {
-        value[i] = fifo8_pop(&s->rx_fifo);
+    for (i = 0; i < max && !fifo_is_empty(&s->rx_fifo); ++i) {
+        value[i] = fifo_pop(&s->rx_fifo);
     }
 }
 
@@ -453,12 +453,12 @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
 static inline void tx_data_bytes(XilinxSPIPS *s, uint32_t value, int num)
 {
     int i;
-    for (i = 0; i < num && !fifo8_is_full(&s->tx_fifo); ++i) {
+    for (i = 0; i < num && !fifo_is_full(&s->tx_fifo); ++i) {
         if (s->regs[R_CONFIG] & ENDIAN) {
-            fifo8_push(&s->tx_fifo, (uint8_t)(value >> 24));
+            fifo_push(&s->tx_fifo, (uint8_t)(value >> 24));
             value <<= 8;
         } else {
-            fifo8_push(&s->tx_fifo, (uint8_t)value);
+            fifo_push(&s->tx_fifo, (uint8_t)value);
             value >>= 8;
         }
     }
@@ -520,7 +520,7 @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
 no_reg_update:
     xilinx_spips_update_cs_lines(s);
     if ((man_start_com && s->regs[R_CONFIG] & MAN_START_EN) ||
-            (fifo8_is_empty(&s->tx_fifo) && s->regs[R_CONFIG] & MAN_START_EN)) {
+            (fifo_is_empty(&s->tx_fifo) && s->regs[R_CONFIG] & MAN_START_EN)) {
         xilinx_spips_flush_txfifo(s);
     }
     xilinx_spips_update_cs_lines(s);
@@ -580,22 +580,22 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
 
         DB_PRINT_L(0, "config reg status: %08x\n", s->regs[R_LQSPI_CFG]);
 
-        fifo8_reset(&s->tx_fifo);
-        fifo8_reset(&s->rx_fifo);
+        fifo_reset(&s->tx_fifo);
+        fifo_reset(&s->rx_fifo);
 
         /* instruction */
         DB_PRINT_L(0, "pushing read instruction: %02x\n",
                    (unsigned)(uint8_t)(s->regs[R_LQSPI_CFG] &
                                        LQSPI_CFG_INST_CODE));
-        fifo8_push(&s->tx_fifo, s->regs[R_LQSPI_CFG] & LQSPI_CFG_INST_CODE);
+        fifo_push(&s->tx_fifo, s->regs[R_LQSPI_CFG] & LQSPI_CFG_INST_CODE);
         /* read address */
         DB_PRINT_L(0, "pushing read address %06x\n", flash_addr);
-        fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 16));
-        fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 8));
-        fifo8_push(&s->tx_fifo, (uint8_t)flash_addr);
+        fifo_push(&s->tx_fifo, (uint8_t)(flash_addr >> 16));
+        fifo_push(&s->tx_fifo, (uint8_t)(flash_addr >> 8));
+        fifo_push(&s->tx_fifo, (uint8_t)flash_addr);
         /* mode bits */
         if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_MODE_EN) {
-            fifo8_push(&s->tx_fifo, extract32(s->regs[R_LQSPI_CFG],
+            fifo_push(&s->tx_fifo, extract32(s->regs[R_LQSPI_CFG],
                                               LQSPI_CFG_MODE_SHIFT,
                                               LQSPI_CFG_MODE_WIDTH));
         }
@@ -603,11 +603,11 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
         for (i = 0; i < (extract32(s->regs[R_LQSPI_CFG], LQSPI_CFG_DUMMY_SHIFT,
                                    LQSPI_CFG_DUMMY_WIDTH)); ++i) {
             DB_PRINT_L(0, "pushing dummy byte\n");
-            fifo8_push(&s->tx_fifo, 0);
+            fifo_push(&s->tx_fifo, 0);
         }
         xilinx_spips_update_cs_lines(s);
         xilinx_spips_flush_txfifo(s);
-        fifo8_reset(&s->rx_fifo);
+        fifo_reset(&s->rx_fifo);
 
         DB_PRINT_L(0, "starting QSPI data read\n");
 
@@ -669,8 +669,8 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
 
     s->irqline = -1;
 
-    fifo8_create(&s->rx_fifo, xsc->rx_fifo_size);
-    fifo8_create(&s->tx_fifo, xsc->tx_fifo_size);
+    fifo_create(&s->rx_fifo, xsc->rx_fifo_size);
+    fifo_create(&s->tx_fifo, xsc->tx_fifo_size);
 }
 
 static void xilinx_qspips_realize(DeviceState *dev, Error **errp)
@@ -707,8 +707,8 @@ static const VMStateDescription vmstate_xilinx_spips = {
     .minimum_version_id_old = 2,
     .post_load = xilinx_spips_post_load,
     .fields = (VMStateField[]) {
-        VMSTATE_FIFO8(tx_fifo, XilinxSPIPS),
-        VMSTATE_FIFO8(rx_fifo, XilinxSPIPS),
+        VMSTATE_FIFO(tx_fifo, XilinxSPIPS),
+        VMSTATE_FIFO(rx_fifo, XilinxSPIPS),
         VMSTATE_UINT32_ARRAY(regs, XilinxSPIPS, R_MAX),
         VMSTATE_UINT8(snoop_state, XilinxSPIPS),
         VMSTATE_END_OF_LIST()
diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index f431764..021499b 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -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;
 
diff --git a/include/qemu/fifo8.h b/include/qemu/fifo.h
similarity index 50%
rename from include/qemu/fifo8.h
rename to include/qemu/fifo.h
index d318f71..e488387 100644
--- a/include/qemu/fifo8.h
+++ b/include/qemu/fifo.h
@@ -9,63 +9,63 @@ typedef struct {
     uint32_t capacity;
     uint32_t head;
     uint32_t num;
-} Fifo8;
+} Fifo;
 
 /**
- * fifo8_create:
- * @fifo: struct Fifo8 to initialise with new FIFO
+ * fifo_create:
+ * @fifo: struct Fifo to initialise with new FIFO
  * @capacity: capacity of the newly created FIFO
  *
- * Create a FIFO of the specified size. Clients should call fifo8_destroy()
+ * Create a FIFO of the specified size. Clients should call fifo_destroy()
  * when finished using the fifo. The FIFO is initially empty.
  */
 
-void fifo8_create(Fifo8 *fifo, uint32_t capacity);
+void fifo_create(Fifo *fifo, uint32_t capacity);
 
 /**
- * fifo8_destroy:
+ * fifo_destroy:
  * @fifo: FIFO to cleanup
  *
- * Cleanup a FIFO created with fifo8_create(). Frees memory created for FIFO
+ * Cleanup a FIFO created with fifo_create(). Frees memory created for FIFO
   *storage. The FIFO is no longer usable after this has been called.
  */
 
-void fifo8_destroy(Fifo8 *fifo);
+void fifo_destroy(Fifo *fifo);
 
 /**
- * fifo8_push:
+ * fifo_push:
  * @fifo: FIFO to push to
- * @data: data byte to push
+ * @data: data value to push
  *
- * Push a data byte to the FIFO. Behaviour is undefined if the FIFO is full.
- * Clients are responsible for checking for fullness using fifo8_is_full().
+ * Push a data value to the FIFO. Behaviour is undefined if the FIFO is full.
+ * Clients are responsible for checking for fullness using fifo_is_full().
  */
 
-void fifo8_push(Fifo8 *fifo, uint8_t data);
+void fifo_push(Fifo *fifo, uint8_t data);
 
 /**
- * fifo8_pop:
+ * fifo_pop:
  * @fifo: fifo to pop from
  *
- * Pop a data byte from the FIFO. Behaviour is undefined if the FIFO is empty.
- * Clients are responsible for checking for emptyness using fifo8_is_empty().
+ * Pop a data value from the FIFO. Behaviour is undefined if the FIFO is empty.
+ * Clients are responsible for checking for emptyness using fifo_is_empty().
  *
- * Returns: The popped data byte.
+ * Returns: The popped data value.
  */
 
-uint8_t fifo8_pop(Fifo8 *fifo);
+uint8_t fifo_pop(Fifo *fifo);
 
 /**
- * fifo8_reset:
+ * fifo_reset:
  * @fifo: FIFO to reset
  *
  * Reset a FIFO. All data is discarded and the FIFO is emptied.
  */
 
-void fifo8_reset(Fifo8 *fifo);
+void fifo_reset(Fifo *fifo);
 
 /**
- * fifo8_is_empty:
+ * fifo_is_empty:
  * @fifo: FIFO to check
  *
  * Check if a FIFO is empty.
@@ -73,10 +73,10 @@ void fifo8_reset(Fifo8 *fifo);
  * Returns: True if the fifo is empty, false otherwise.
  */
 
-bool fifo8_is_empty(Fifo8 *fifo);
+bool fifo_is_empty(Fifo *fifo);
 
 /**
- * fifo8_is_full:
+ * fifo_is_full:
  * @fifo: FIFO to check
  *
  * Check if a FIFO is full.
@@ -84,16 +84,16 @@ bool fifo8_is_empty(Fifo8 *fifo);
  * Returns: True if the fifo is full, false otherwise.
  */
 
-bool fifo8_is_full(Fifo8 *fifo);
+bool fifo_is_full(Fifo *fifo);
 
-extern const VMStateDescription vmstate_fifo8;
+extern const VMStateDescription vmstate_fifo;
 
-#define VMSTATE_FIFO8(_field, _state) {                              \
+#define VMSTATE_FIFO(_field, _state) {                               \
     .name       = (stringify(_field)),                               \
-    .size       = sizeof(Fifo8),                                     \
-    .vmsd       = &vmstate_fifo8,                                    \
+    .size       = sizeof(Fifo),                                      \
+    .vmsd       = &vmstate_fifo,                                     \
     .flags      = VMS_STRUCT,                                        \
-    .offset     = vmstate_offset_value(_state, _field, Fifo8),       \
+    .offset     = vmstate_offset_value(_state, _field, Fifo),        \
 }
 
 #endif /* FIFO_H */
diff --git a/util/Makefile.objs b/util/Makefile.objs
index af3e5cb..6719142 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -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
diff --git a/util/fifo8.c b/util/fifo.c
similarity index 73%
rename from util/fifo8.c
rename to util/fifo.c
index 013e903..1adaa11 100644
--- a/util/fifo8.c
+++ b/util/fifo.c
@@ -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()
     }
 };
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [Qemu-devel] [RFC v1 2/2] util/fifo: Generalise for common integer widths
  2014-01-03  1:41 [Qemu-devel] [RFC v1 0/2] Generalise FIFO to more integer types Peter Crosthwaite
  2014-01-03  1:42 ` [Qemu-devel] [RFC v1 1/2] util/fifo: s/fifo8/fifo globally Peter Crosthwaite
@ 2014-01-03  1:43 ` Peter Crosthwaite
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Crosthwaite @ 2014-01-03  1:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: b.galvani, edgar.iglesias, pbonzini, peter.maydell

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.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---

 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(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index 9b43e36..cc71249 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -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)
diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c
index 8fe3072..cac666b 100644
--- a/hw/ssi/xilinx_spi.c
+++ b/hw/ssi/xilinx_spi.c
@@ -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;
 }
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index c3d9c05..aeff06c 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -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)
diff --git a/include/qemu/fifo.h b/include/qemu/fifo.h
index e488387..a1737c3 100644
--- a/include/qemu/fifo.h
+++ b/include/qemu/fifo.h
@@ -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:
diff --git a/util/fifo.c b/util/fifo.c
index 1adaa11..33356ee 100644
--- a/util/fifo.c
+++ b/util/fifo.c
@@ -15,9 +15,11 @@
 #include "qemu-common.h"
 #include "qemu/fifo.h"
 
-void fifo_create(Fifo *fifo, uint32_t capacity)
+void fifo_create(Fifo *fifo, uint32_t capacity, int width)
 {
-    fifo->data = g_new(uint8_t, capacity);
+    assert(width == 8 || width == 16 || width == 32 || width == 64);
+    fifo->width = width / 8;
+    fifo->data = g_new(uint8_t, capacity * fifo->width);
     fifo->capacity = capacity;
     fifo->head = 0;
     fifo->num = 0;
@@ -28,26 +30,55 @@ void fifo_destroy(Fifo *fifo)
     g_free(fifo->data);
 }
 
-void fifo_push(Fifo *fifo, uint8_t data)
+void fifo_push(Fifo *fifo, uint64_t data)
 {
+    uint32_t next_idx = (fifo->head + fifo->num) % fifo->capacity;
+
     if (fifo->num == fifo->capacity) {
         abort();
     }
-    fifo->data[(fifo->head + fifo->num) % fifo->capacity] = data;
+    switch (fifo->width) {
+    case(1):
+        ((uint8_t *)fifo->data)[next_idx] = data;
+        break;
+    case(2):
+        ((uint16_t *)fifo->data)[next_idx] = data;
+        break;
+    case(4):
+        ((uint32_t *)fifo->data)[next_idx] = data;
+        break;
+    case(8):
+        ((uint64_t *)fifo->data)[next_idx] = data;
+        break;
+    default:
+        abort();
+    }
     fifo->num++;
 }
 
-uint8_t fifo_pop(Fifo *fifo)
+uint64_t fifo_pop(Fifo *fifo)
 {
-    uint8_t ret;
+    uint32_t next_idx;
 
     if (fifo->num == 0) {
         abort();
     }
-    ret = fifo->data[fifo->head++];
+    next_idx = fifo->head++;
     fifo->head %= fifo->capacity;
     fifo->num--;
-    return ret;
+    switch (fifo->width) {
+    case(1):
+        return ((uint8_t *)fifo->data)[next_idx];
+    case(2):
+        return ((uint16_t *)fifo->data)[next_idx];
+    case(4):
+        return ((uint32_t *)fifo->data)[next_idx];
+    case(8):
+        return ((uint64_t *)fifo->data)[next_idx];
+    default:
+        abort();
+        return 0; /* unreachable */
+    }
 }
 
 void fifo_reset(Fifo *fifo)
@@ -65,13 +96,55 @@ bool fifo_is_full(Fifo *fifo)
     return (fifo->num == fifo->capacity);
 }
 
+/* Always store buffer data in little (arbitrarily chosen) endian format to
+ * allow for migration to/from BE <-> LE hosts.
+ */
+
+static inline void fifo_save_load_swap(Fifo *fifo) {
+#ifdef HOST_WORDS_BIGENDIAN
+    int i;
+    uint16_t *d16 = (uint16_t *)fifo->data;
+    uint32_t *d32 = (uint32_t *)fifo->data;
+    uint64_t *d64 = (uint64_t *)fifo->data;
+
+    for (i = 0; i < fifo->capacity; ++i) {
+        switch (fifo->width) {
+        case(1):
+            return;
+        case(2):
+            d16[i] = bswap16(d16[i]);
+            break;
+        case(4):
+            d32[i] = bswap32(d32[i]);
+            break;
+        case(8):
+            d64[i] = bswap64(d64[i]);
+            break;
+        default:
+            abort();
+        }
+    }
+#endif
+}
+
+static void fifo_pre_save(void * opaque) {
+    fifo_save_load_swap((Fifo *)opaque);
+}
+
+static int fifo_post_load(void *opaque, int version_id) {
+    fifo_save_load_swap((Fifo *)opaque);
+    return 0;
+}
+
 const VMStateDescription vmstate_fifo = {
     .name = "Fifo8",
     .version_id = 1,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
+    .pre_save = fifo_pre_save,
+    .post_load = fifo_post_load,
     .fields      = (VMStateField[]) {
-        VMSTATE_VBUFFER_UINT32(data, Fifo, 1, NULL, 0, capacity),
+        VMSTATE_VBUFFER_UINT32(data, Fifo, 1, NULL, 0, buffer_size),
         VMSTATE_UINT32(head, Fifo),
         VMSTATE_UINT32(num, Fifo),
         VMSTATE_END_OF_LIST()
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2014-01-03  1:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-03  1:41 [Qemu-devel] [RFC v1 0/2] Generalise FIFO to more integer types Peter Crosthwaite
2014-01-03  1:42 ` [Qemu-devel] [RFC v1 1/2] util/fifo: s/fifo8/fifo globally Peter Crosthwaite
2014-01-03  1:43 ` [Qemu-devel] [RFC v1 2/2] util/fifo: Generalise for common integer widths Peter Crosthwaite

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.