xref: /openbmc/qemu/include/qemu/fifo32.h (revision 6f1d2d1c)
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