Skip to content

Commit

Permalink
hw: Added generic FIFO API.
Browse files Browse the repository at this point in the history
Added a FIFO API that can be used to create and operate byte FIFOs.

Signed-off-by: Peter A. G. Crosthwaite <[email protected]>
  • Loading branch information
pete128 committed Oct 10, 2012
1 parent 8120e71 commit a3578d4
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 0 deletions.
1 change: 1 addition & 0 deletions hw/Makefile.objs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ common-obj-$(CONFIG_APPLESMC) += applesmc.o
common-obj-$(CONFIG_SMARTCARD) += ccid-card-passthru.o
common-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
common-obj-$(CONFIG_I8259) += i8259_common.o i8259.o
common-obj-y += fifo.o

# PPC devices
common-obj-$(CONFIG_PREP_PCI) += prep_pci.o
Expand Down
78 changes: 78 additions & 0 deletions hw/fifo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Generic FIFO component, implemented as a circular buffer.
*
* Copyright (c) 2012 Peter A. G. Crosthwaite
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/

#include "fifo.h"

void fifo8_create(Fifo8 *fifo, uint32_t capacity)
{
fifo->data = g_new(uint8_t, capacity);
fifo->capacity = capacity;
fifo->head = 0;
fifo->num = 0;
}

void fifo8_destroy(Fifo8 *fifo)
{
g_free(fifo->data);
}

void fifo8_push(Fifo8 *fifo, uint8_t data)
{
if (fifo->num == fifo->capacity) {
abort();
}
fifo->data[(fifo->head + fifo->num) % fifo->capacity] = data;
fifo->num++;
}

uint8_t fifo8_pop(Fifo8 *fifo)
{
uint8_t ret;

if (fifo->num == 0) {
abort();
}
ret = fifo->data[fifo->head++];
fifo->head %= fifo->capacity;
fifo->num--;
return ret;
}

void fifo8_reset(Fifo8 *fifo)
{
fifo->num = 0;
}

bool fifo8_is_empty(Fifo8 *fifo)
{
return (fifo->num == 0);
}

bool fifo8_is_full(Fifo8 *fifo)
{
return (fifo->num == fifo->capacity);
}

const VMStateDescription vmstate_fifo8 = {
.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_END_OF_LIST()
}
};
99 changes: 99 additions & 0 deletions hw/fifo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#ifndef FIFO_H
#define FIFO_H

#include "hw.h"

typedef struct {
/* All fields are private */
uint8_t *data;
uint32_t capacity;
uint32_t head;
uint32_t num;
} Fifo8;

/**
* fifo8_create:
* @fifo: struct Fifo8 to initialise with new FIFO
* @capacity: capacity of the newly created FIFO
*
* Create a FIFO of the specified size. Clients should call fifo8_destroy()
* when finished using the fifo. The FIFO is initially empty.
*/

void fifo8_create(Fifo8 *fifo, uint32_t capacity);

/**
* fifo8_destroy:
* @fifo: FIFO to cleanup
*
* Cleanup a FIFO created with fifo8_create(). Frees memory created for FIFO
*storage. The FIFO is no longer usable after this has been called.
*/

void fifo8_destroy(Fifo8 *fifo);

/**
* fifo8_push:
* @fifo: FIFO to push to
* @data: data byte 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().
*/

void fifo8_push(Fifo8 *fifo, uint8_t data);

/**
* fifo8_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().
*
* Returns: The popped data byte.
*/

uint8_t fifo8_pop(Fifo8 *fifo);

/**
* fifo8_reset:
* @fifo: FIFO to reset
*
* Reset a FIFO. All data is discarded and the FIFO is emptied.
*/

void fifo8_reset(Fifo8 *fifo);

/**
* fifo8_is_empty:
* @fifo: FIFO to check
*
* Check if a FIFO is empty.
*
* Returns: True if the fifo is empty, false otherwise.
*/

bool fifo8_is_empty(Fifo8 *fifo);

/**
* fifo8_is_full:
* @fifo: FIFO to check
*
* Check if a FIFO is full.
*
* Returns: True if the fifo is full, false otherwise.
*/

bool fifo8_is_full(Fifo8 *fifo);

extern const VMStateDescription vmstate_fifo8;

#define VMSTATE_FIFO8(_field, _state) { \
.name = (stringify(_field)), \
.size = sizeof(Fifo8), \
.vmsd = &vmstate_fifo8, \
.flags = VMS_STRUCT, \
.offset = vmstate_offset_value(_state, _field, Fifo8), \
}

#endif /* FIFO_H */

0 comments on commit a3578d4

Please sign in to comment.