* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).