| /* |
| * Generic FIFO32 component, based on FIFO8. |
| * |
| * Copyright (c) 2016 Jean-Christophe Dubois |
| * |
| * 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/>. |
| */ |
| |
| #ifndef FIFO32_H |
| #define FIFO32_H |
| |
| #include "qemu/fifo8.h" |
| |
| typedef struct { |
| Fifo8 fifo; |
| } Fifo32; |
| |
| /** |
| * fifo32_create: |
| * @fifo: struct Fifo32 to initialise with new FIFO |
| * @capacity: capacity of the newly created FIFO expressed in 32 bit words |
| * |
| * Create a FIFO of the specified size. Clients should call fifo32_destroy() |
| * when finished using the fifo. The FIFO is initially empty. |
| */ |
| |
| static inline void fifo32_create(Fifo32 *fifo, uint32_t capacity) |
| { |
| fifo8_create(&fifo->fifo, capacity * sizeof(uint32_t)); |
| } |
| |
| /** |
| * fifo32_destroy: |
| * @fifo: FIFO to cleanup |
| * |
| * Cleanup a FIFO created with fifo32_create(). Frees memory created for FIFO |
| * storage. The FIFO is no longer usable after this has been called. |
| */ |
| |
| static inline void fifo32_destroy(Fifo32 *fifo) |
| { |
| fifo8_destroy(&fifo->fifo); |
| } |
| |
| /** |
| * fifo32_num_free: |
| * @fifo: FIFO to check |
| * |
| * Return the number of free uint32_t slots in the FIFO. |
| * |
| * Returns: Number of free 32 bit words. |
| */ |
| |
| static inline uint32_t fifo32_num_free(Fifo32 *fifo) |
| { |
| return DIV_ROUND_UP(fifo8_num_free(&fifo->fifo), sizeof(uint32_t)); |
| } |
| |
| /** |
| * fifo32_num_used: |
| * @fifo: FIFO to check |
| * |
| * Return the number of used uint32_t slots in the FIFO. |
| * |
| * Returns: Number of used 32 bit words. |
| */ |
| |
| static inline uint32_t fifo32_num_used(Fifo32 *fifo) |
| { |
| return DIV_ROUND_UP(fifo8_num_used(&fifo->fifo), sizeof(uint32_t)); |
| } |
| |
| /** |
| * fifo32_push: |
| * @fifo: FIFO to push to |
| * @data: 32 bits data word to push |
| * |
| * Push a 32 bits data word to the FIFO. Behaviour is undefined if the FIFO |
| * is full. Clients are responsible for checking for fullness using |
| * fifo32_is_full(). |
| */ |
| |
| static inline void fifo32_push(Fifo32 *fifo, uint32_t data) |
| { |
| int i; |
| |
| for (i = 0; i < sizeof(data); i++) { |
| fifo8_push(&fifo->fifo, data & 0xff); |
| data >>= 8; |
| } |
| } |
| |
| /** |
| * fifo32_push_all: |
| * @fifo: FIFO to push to |
| * @data: data to push |
| * @size: number of 32 bit words to push |
| * |
| * Push a 32 bit word array to the FIFO. Behaviour is undefined if the FIFO |
| * is full. Clients are responsible for checking the space left in the FIFO |
| * using fifo32_num_free(). |
| */ |
| |
| static inline void fifo32_push_all(Fifo32 *fifo, const uint32_t *data, |
| uint32_t num) |
| { |
| int i; |
| |
| for (i = 0; i < num; i++) { |
| fifo32_push(fifo, data[i]); |
| } |
| } |
| |
| /** |
| * fifo32_pop: |
| * @fifo: fifo to pop from |
| * |
| * Pop a 32 bits data word from the FIFO. Behaviour is undefined if the FIFO |
| * is empty. Clients are responsible for checking for emptiness using |
| * fifo32_is_empty(). |
| * |
| * Returns: The popped 32 bits data word. |
| */ |
| |
| static inline uint32_t fifo32_pop(Fifo32 *fifo) |
| { |
| uint32_t ret = 0; |
| int i; |
| |
| for (i = 0; i < sizeof(uint32_t); i++) { |
| ret |= (fifo8_pop(&fifo->fifo) << (i * 8)); |
| } |
| |
| return ret; |
| } |
| |
| /** |
| * There is no fifo32_pop_buf() because the data is not stored in the buffer |
| * as a set of native-order words. |
| */ |
| |
| /** |
| * fifo32_reset: |
| * @fifo: FIFO to reset |
| * |
| * Reset a FIFO. All data is discarded and the FIFO is emptied. |
| */ |
| |
| static inline void fifo32_reset(Fifo32 *fifo) |
| { |
| fifo8_reset(&fifo->fifo); |
| } |
| |
| /** |
| * fifo32_is_empty: |
| * @fifo: FIFO to check |
| * |
| * Check if a FIFO is empty. |
| * |
| * Returns: True if the fifo is empty, false otherwise. |
| */ |
| |
| static inline bool fifo32_is_empty(Fifo32 *fifo) |
| { |
| return fifo8_is_empty(&fifo->fifo); |
| } |
| |
| /** |
| * fifo32_is_full: |
| * @fifo: FIFO to check |
| * |
| * Check if a FIFO is full. |
| * |
| * Returns: True if the fifo is full, false otherwise. |
| */ |
| |
| static inline bool fifo32_is_full(Fifo32 *fifo) |
| { |
| return fifo8_num_free(&fifo->fifo) < sizeof(uint32_t); |
| } |
| |
| #define VMSTATE_FIFO32(_field, _state) VMSTATE_FIFO8(_field.fifo, _state) |
| |
| #endif /* FIFO32_H */ |