1 /*
2 * Generic FIFO32 component, based on FIFO8.
3 *
4 * Copyright (c) 2016 Jean-Christophe Dubois
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * You should have received a copy of the GNU General Public License along
12 * with this program; if not, see <http://www.gnu.org/licenses/>.
13 */
14
15 #ifndef FIFO32_H
16 #define FIFO32_H
17
18 #include "qemu/fifo8.h"
19
20 typedef struct {
21 Fifo8 fifo;
22 } Fifo32;
23
24 /**
25 * fifo32_create:
26 * @fifo: struct Fifo32 to initialise with new FIFO
27 * @capacity: capacity of the newly created FIFO expressed in 32 bit words
28 *
29 * Create a FIFO of the specified size. Clients should call fifo32_destroy()
30 * when finished using the fifo. The FIFO is initially empty.
31 */
32
fifo32_create(Fifo32 * fifo,uint32_t capacity)33 static inline void fifo32_create(Fifo32 *fifo, uint32_t capacity)
34 {
35 fifo8_create(&fifo->fifo, capacity * sizeof(uint32_t));
36 }
37
38 /**
39 * fifo32_destroy:
40 * @fifo: FIFO to cleanup
41 *
42 * Cleanup a FIFO created with fifo32_create(). Frees memory created for FIFO
43 * storage. The FIFO is no longer usable after this has been called.
44 */
45
fifo32_destroy(Fifo32 * fifo)46 static inline void fifo32_destroy(Fifo32 *fifo)
47 {
48 fifo8_destroy(&fifo->fifo);
49 }
50
51 /**
52 * fifo32_num_free:
53 * @fifo: FIFO to check
54 *
55 * Return the number of free uint32_t slots in the FIFO.
56 *
57 * Returns: Number of free 32 bit words.
58 */
59
fifo32_num_free(Fifo32 * fifo)60 static inline uint32_t fifo32_num_free(Fifo32 *fifo)
61 {
62 return DIV_ROUND_UP(fifo8_num_free(&fifo->fifo), sizeof(uint32_t));
63 }
64
65 /**
66 * fifo32_num_used:
67 * @fifo: FIFO to check
68 *
69 * Return the number of used uint32_t slots in the FIFO.
70 *
71 * Returns: Number of used 32 bit words.
72 */
73
fifo32_num_used(Fifo32 * fifo)74 static inline uint32_t fifo32_num_used(Fifo32 *fifo)
75 {
76 return DIV_ROUND_UP(fifo8_num_used(&fifo->fifo), sizeof(uint32_t));
77 }
78
79 /**
80 * fifo32_push:
81 * @fifo: FIFO to push to
82 * @data: 32 bits data word to push
83 *
84 * Push a 32 bits data word to the FIFO. Behaviour is undefined if the FIFO
85 * is full. Clients are responsible for checking for fullness using
86 * fifo32_is_full().
87 */
88
fifo32_push(Fifo32 * fifo,uint32_t data)89 static inline void fifo32_push(Fifo32 *fifo, uint32_t data)
90 {
91 int i;
92
93 for (i = 0; i < sizeof(data); i++) {
94 fifo8_push(&fifo->fifo, data & 0xff);
95 data >>= 8;
96 }
97 }
98
99 /**
100 * fifo32_push_all:
101 * @fifo: FIFO to push to
102 * @data: data to push
103 * @size: number of 32 bit words to push
104 *
105 * Push a 32 bit word array to the FIFO. Behaviour is undefined if the FIFO
106 * is full. Clients are responsible for checking the space left in the FIFO
107 * using fifo32_num_free().
108 */
109
fifo32_push_all(Fifo32 * fifo,const uint32_t * data,uint32_t num)110 static inline void fifo32_push_all(Fifo32 *fifo, const uint32_t *data,
111 uint32_t num)
112 {
113 int i;
114
115 for (i = 0; i < num; i++) {
116 fifo32_push(fifo, data[i]);
117 }
118 }
119
120 /**
121 * fifo32_pop:
122 * @fifo: fifo to pop from
123 *
124 * Pop a 32 bits data word from the FIFO. Behaviour is undefined if the FIFO
125 * is empty. Clients are responsible for checking for emptiness using
126 * fifo32_is_empty().
127 *
128 * Returns: The popped 32 bits data word.
129 */
130
fifo32_pop(Fifo32 * fifo)131 static inline uint32_t fifo32_pop(Fifo32 *fifo)
132 {
133 uint32_t ret = 0;
134 int i;
135
136 for (i = 0; i < sizeof(uint32_t); i++) {
137 ret |= (fifo8_pop(&fifo->fifo) << (i * 8));
138 }
139
140 return ret;
141 }
142
143 /**
144 * There is no fifo32_pop_buf() because the data is not stored in the buffer
145 * as a set of native-order words.
146 */
147
148 /**
149 * fifo32_reset:
150 * @fifo: FIFO to reset
151 *
152 * Reset a FIFO. All data is discarded and the FIFO is emptied.
153 */
154
fifo32_reset(Fifo32 * fifo)155 static inline void fifo32_reset(Fifo32 *fifo)
156 {
157 fifo8_reset(&fifo->fifo);
158 }
159
160 /**
161 * fifo32_is_empty:
162 * @fifo: FIFO to check
163 *
164 * Check if a FIFO is empty.
165 *
166 * Returns: True if the fifo is empty, false otherwise.
167 */
168
fifo32_is_empty(Fifo32 * fifo)169 static inline bool fifo32_is_empty(Fifo32 *fifo)
170 {
171 return fifo8_is_empty(&fifo->fifo);
172 }
173
174 /**
175 * fifo32_is_full:
176 * @fifo: FIFO to check
177 *
178 * Check if a FIFO is full.
179 *
180 * Returns: True if the fifo is full, false otherwise.
181 */
182
fifo32_is_full(Fifo32 * fifo)183 static inline bool fifo32_is_full(Fifo32 *fifo)
184 {
185 return fifo8_num_free(&fifo->fifo) < sizeof(uint32_t);
186 }
187
188 #define VMSTATE_FIFO32(_field, _state) VMSTATE_FIFO8(_field.fifo, _state)
189
190 #endif /* FIFO32_H */
191