hw: Added generic FIFO API.

Added a FIFO API that can be used to create and operate byte FIFOs.

Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
This commit is contained in:
Peter A. G. Crosthwaite 2012-08-01 20:26:12 +10:00 committed by Peter Crosthwaite
parent 8120e7144b
commit a3578d4a51
3 changed files with 178 additions and 0 deletions

View file

@ -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

78
hw/fifo.c Normal file
View file

@ -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
hw/fifo.h Normal file
View file

@ -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 */