xref: /openbmc/qemu/tests/unit/test-fifo.c (revision 6fdc5bc1)
1 /*
2  * Fifo8 tests
3  *
4  * Copyright 2024 Mark Cave-Ayland
5  *
6  * Authors:
7  *  Mark Cave-Ayland    <mark.cave-ayland@ilande.co.uk>
8  *
9  * This work is licensed under the terms of the GNU LGPL, version 2 or later.
10  * See the COPYING.LIB file in the top-level directory.
11  */
12 
13 #include "qemu/osdep.h"
14 #include "migration/vmstate.h"
15 #include "qemu/fifo8.h"
16 
17 const VMStateInfo vmstate_info_uint32;
18 const VMStateInfo vmstate_info_buffer;
19 
20 
21 static void test_fifo8_pop_bufptr_wrap(void)
22 {
23     Fifo8 fifo;
24     uint8_t data_in1[] = { 0x1, 0x2, 0x3, 0x4 };
25     uint8_t data_in2[] = { 0x5, 0x6, 0x7, 0x8, 0x9, 0xa };
26     const uint8_t *buf;
27     uint32_t count;
28 
29     fifo8_create(&fifo, 8);
30     /*
31      *  head --v-- tail             used = 0
32      * FIFO: [ . . . . . . . . ]
33      */
34 
35     fifo8_push_all(&fifo, data_in1, sizeof(data_in1));
36     /*
37      *  head --v      ]-- tail      used = 4
38      * FIFO: [ 1 2 3 4 . . . . ]
39      */
40     buf = fifo8_pop_bufptr(&fifo, 2, &count);
41     /*
42      *      head --v  ]-- tail      used = 2
43      * FIFO: [ 1 2 3 4 . . . . ]
44      *  buf  --^                    count = 2
45      */
46     g_assert(count == 2);
47     g_assert(buf[0] == 0x1 && buf[1] == 0x2);
48 
49     fifo8_push_all(&fifo, data_in2, sizeof(data_in2));
50     /*
51      *     tail --]v-- head         used = 8
52      * FIFO: [ 9 a 3 4 5 6 7 8 ]
53      */
54     buf = fifo8_pop_bufptr(&fifo, 8, &count);
55     /*
56      *  head --v  ]-- tail          used = 2
57      * FIFO: [ 9 a 3 4 5 6 7 8 ]
58      *  buf      --^                count = 6
59      */
60     g_assert(count == 6);
61     g_assert(buf[0] == 0x3 && buf[1] == 0x4 && buf[2] == 0x5 &&
62              buf[3] == 0x6 && buf[4] == 0x7 && buf[5] == 0x8);
63 
64     g_assert(fifo8_num_used(&fifo) == 2);
65     fifo8_destroy(&fifo);
66 }
67 
68 static void test_fifo8_pop_bufptr(void)
69 {
70     Fifo8 fifo;
71     uint8_t data_in[] = { 0x1, 0x2, 0x3, 0x4 };
72     const uint8_t *buf;
73     uint32_t count;
74 
75     fifo8_create(&fifo, 8);
76     /*
77      *  head --v-- tail             used = 0
78      * FIFO: [ . . . . . . . . ]
79      */
80 
81     fifo8_push_all(&fifo, data_in, sizeof(data_in));
82     /*
83      *  head --v      ]-- tail      used = 4
84      * FIFO: [ 1 2 3 4 . . . . ]
85      */
86     buf = fifo8_pop_bufptr(&fifo, 2, &count);
87     /*
88      *      head --v  ]-- tail      used = 2
89      * FIFO: [ 1 2 3 4 . . . . ]
90      *  buf  --^                    count = 2
91      */
92     g_assert(count == 2);
93     g_assert(buf[0] == 0x1 && buf[1] == 0x2);
94 
95     g_assert(fifo8_num_used(&fifo) == 2);
96     fifo8_destroy(&fifo);
97 }
98 
99 static void test_fifo8_peek_bufptr_wrap(void)
100 {
101     Fifo8 fifo;
102     uint8_t data_in1[] = { 0x1, 0x2, 0x3, 0x4 };
103     uint8_t data_in2[] = { 0x5, 0x6, 0x7, 0x8, 0x9, 0xa };
104     const uint8_t *buf;
105     uint32_t count;
106 
107     fifo8_create(&fifo, 8);
108     /*
109      *  head --v-- tail             used = 0
110      * FIFO: { . . . . . . . . }
111      */
112 
113     fifo8_push_all(&fifo, data_in1, sizeof(data_in1));
114     /*
115      *  head --v      ]-- tail      used = 4
116      * FIFO: { 1 2 3 4 . . . . }
117      */
118     buf = fifo8_peek_bufptr(&fifo, 2, &count);
119     /*
120      *  head --v      ]-- tail      used = 4
121      * FIFO: { 1 2 3 4 . . . . }
122      *  buf: [ 1 2 ]                count = 2
123      */
124     g_assert(count == 2);
125     g_assert(buf[0] == 0x1 && buf[1] == 0x2);
126 
127     buf = fifo8_pop_bufptr(&fifo, 2, &count);
128     /*
129      *     head  --v  ]-- tail      used = 2
130      * FIFO: { 1 2 3 4 . . . . }
131      *  buf: [ 1 2 ]                count = 2
132      */
133     g_assert(count == 2);
134     g_assert(buf[0] == 0x1 && buf[1] == 0x2);
135     fifo8_push_all(&fifo, data_in2, sizeof(data_in2));
136     /*
137      *  tail   ---]v-- head         used = 8
138      * FIFO: { 9 a 3 4 5 6 7 8 }
139      */
140 
141     buf = fifo8_peek_bufptr(&fifo, 8, &count);
142     /*
143      *     tail --]v-- head         used = 8
144      * FIFO: { 9 a 3 4 5 6 7 8 }
145      *  buf:     [ 3 4 5 6 7 8 ]    count = 6
146      */
147     g_assert(count == 6);
148     g_assert(buf[0] == 0x3 && buf[1] == 0x4 && buf[2] == 0x5 &&
149              buf[3] == 0x6 && buf[4] == 0x7 && buf[5] == 0x8);
150 
151     g_assert(fifo8_num_used(&fifo) == 8);
152     fifo8_destroy(&fifo);
153 }
154 
155 static void test_fifo8_peek_bufptr(void)
156 {
157     Fifo8 fifo;
158     uint8_t data_in[] = { 0x1, 0x2, 0x3, 0x4 };
159     const uint8_t *buf;
160     uint32_t count;
161 
162     fifo8_create(&fifo, 8);
163     /*
164      *  head --v-- tail             used = 0
165      * FIFO: { . . . . . . . . }
166      */
167 
168     fifo8_push_all(&fifo, data_in, sizeof(data_in));
169     /*
170      *  head --v      ]-- tail      used = 4
171      * FIFO: { 1 2 3 4 . . . . }
172      */
173     buf = fifo8_peek_bufptr(&fifo, 2, &count);
174     /*
175      *  head --v      ]-- tail      used = 4
176      * FIFO: { 1 2 3 4 . . . . }
177      *  buf: [ 1 2 ]                count = 2
178      */
179     g_assert(count == 2);
180     g_assert(buf[0] == 0x1 && buf[1] == 0x2);
181 
182     g_assert(fifo8_num_used(&fifo) == 4);
183     fifo8_destroy(&fifo);
184 }
185 
186 static void test_fifo8_pop_buf_wrap(void)
187 {
188     Fifo8 fifo;
189     uint8_t data_in1[] = { 0x1, 0x2, 0x3, 0x4 };
190     uint8_t data_in2[] = { 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc };
191     uint8_t data_out[4];
192     int count;
193 
194     fifo8_create(&fifo, 8);
195     /*
196      *  head --v-- tail             used = 0
197      * FIFO: { . . . . . . . . }
198      */
199 
200     fifo8_push_all(&fifo, data_in1, sizeof(data_in1));
201     /*
202      *  head --v      ]-- tail      used = 4
203      * FIFO: { 1 2 3 4 . . . . }
204      */
205     fifo8_pop_buf(&fifo, NULL, 4);
206     /*
207      *         tail --]v-- head     used = 0
208      * FIFO: [ 1 2 3 4 . . . . ]
209      */
210 
211     fifo8_push_all(&fifo, data_in2, sizeof(data_in2));
212     /*
213      *         tail --]v-- head     used = 8
214      * FIFO: { 9 a b c 5 6 7 8 }
215      */
216     count = fifo8_pop_buf(&fifo, NULL, 4);
217     /*
218      * head  --v      ]-- tail      used = 4
219      * FIFO: { 9 a b c 5 6 7 8 }
220      */
221     g_assert(count == 4);
222     count = fifo8_pop_buf(&fifo, data_out, 4);
223     /*
224      *         tail --]v-- head     used = 0
225      * FIFO: { 9 a b c 5 6 7 8 }
226      */
227     g_assert(count == 4);
228     g_assert(data_out[0] == 0x9 && data_out[1] == 0xa &&
229              data_out[2] == 0xb && data_out[3] == 0xc);
230 
231     g_assert(fifo8_num_used(&fifo) == 0);
232     fifo8_destroy(&fifo);
233 }
234 
235 static void test_fifo8_pop_buf(void)
236 {
237     Fifo8 fifo;
238     uint8_t data_in[] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 };
239     uint8_t data_out[] = { 0xff, 0xff, 0xff, 0xff };
240     int count;
241 
242     fifo8_create(&fifo, 8);
243     /*
244      *  head --v-- tail             used = 0
245      * FIFO: { . . . . . . . . }
246      */
247 
248     fifo8_push_all(&fifo, data_in, sizeof(data_in));
249     /*
250      *  head --v      ]-- tail      used = 4
251      * FIFO: { 1 2 3 4 . . . . }
252      */
253     count = fifo8_pop_buf(&fifo, NULL, 4);
254     /*
255      *         tail --]v-- head     used = 0
256      * FIFO: { 1 2 3 4 . . . . }
257      */
258     g_assert(count == 4);
259     count = fifo8_pop_buf(&fifo, data_out, 4);
260     g_assert(data_out[0] == 0x5 && data_out[1] == 0x6 &&
261              data_out[2] == 0x7 && data_out[3] == 0x8);
262 
263     g_assert(fifo8_num_used(&fifo) == 0);
264     fifo8_destroy(&fifo);
265 }
266 
267 static void test_fifo8_peek_buf_wrap(void)
268 {
269     Fifo8 fifo;
270     uint8_t data_in1[] = { 0x1, 0x2, 0x3, 0x4 };
271     uint8_t data_in2[] = { 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc };
272     uint8_t data_out[8];
273     int count;
274 
275     fifo8_create(&fifo, 8);
276     /*
277      *  head --v-- tail             used = 0
278      * FIFO: { . . . . . . . . }
279      */
280 
281     fifo8_push_all(&fifo, data_in1, sizeof(data_in1));
282     /*
283      *  head --v      ]-- tail      used = 4
284      * FIFO: { 1 2 3 4 . . . . }
285      */
286     fifo8_pop_buf(&fifo, NULL, 4);
287     /*
288      *         tail --]v-- head     used = 0
289      * FIFO: { 1 2 3 4 . . . . }
290      */
291 
292     fifo8_push_all(&fifo, data_in2, sizeof(data_in2));
293     /*
294      *         tail --]v-- head     used = 8
295      * FIFO: { 9 a b c 5 6 7 8 }
296      */
297     count = fifo8_peek_buf(&fifo, NULL, 4);
298     g_assert(count == 4);
299     count = fifo8_peek_buf(&fifo, data_out, 4);
300     /*
301      *         tail --]v-- head     used = 8
302      * FIFO: { 9 a b c 5 6 7 8 }
303      *  buf:         [ 5 6 7 8 ]    count = 4
304      */
305     g_assert(count == 4);
306     g_assert(data_out[0] == 0x5 && data_out[1] == 0x6 &&
307              data_out[2] == 0x7 && data_out[3] == 0x8);
308 
309     count = fifo8_peek_buf(&fifo, data_out, 8);
310     /*
311      *         tail --]v-- head     used = 8
312      * FIFO: { 9 a b c 5 6 7 8 }
313      *  buf:         [ 5 6 7 8 9 a b c ] count = 8
314      */
315     g_assert(count == 8);
316     g_assert(data_out[0] == 0x5 && data_out[1] == 0x6 &&
317              data_out[2] == 0x7 && data_out[3] == 0x8);
318     g_assert(data_out[4] == 0x9 && data_out[5] == 0xa &&
319              data_out[6] == 0xb && data_out[7] == 0xc);
320 
321     g_assert(fifo8_num_used(&fifo) == 8);
322     fifo8_destroy(&fifo);
323 }
324 
325 static void test_fifo8_peek_buf(void)
326 {
327     Fifo8 fifo;
328     uint8_t data_in[] = { 0x1, 0x2, 0x3, 0x4 };
329     uint8_t data_out[] = { 0xff, 0xff, 0xff, 0xff };
330     int count;
331 
332     fifo8_create(&fifo, 8);
333     /*
334      *  head --v-- tail             used = 0
335      * FIFO: { . . . . . . . . }
336      */
337 
338     fifo8_push_all(&fifo, data_in, sizeof(data_in));
339     /*
340      *  head --v      ]-- tail      used = 4
341      * FIFO: { 1 2 3 4 . . . . }
342      */
343     count = fifo8_peek_buf(&fifo, NULL, 4);
344     g_assert(count == 4);
345 
346     g_assert(data_out[0] == 0xff && data_out[1] == 0xff &&
347              data_out[2] == 0xff && data_out[3] == 0xff);
348     count = fifo8_peek_buf(&fifo, data_out, 4);
349     /*
350      *  head --v      ]-- tail      used = 4
351      * FIFO: { 1 2 3 4 . . . . }
352      *  buf: [ 1 2 3 4 ]            count = 4
353      */
354     g_assert(count == 4);
355     g_assert(data_out[0] == 0x1 && data_out[1] == 0x2 &&
356              data_out[2] == 0x3 && data_out[3] == 0x4);
357 
358     g_assert(fifo8_num_used(&fifo) == 4);
359     fifo8_destroy(&fifo);
360 }
361 
362 static void test_fifo8_peek(void)
363 {
364     Fifo8 fifo;
365     uint8_t c;
366 
367     fifo8_create(&fifo, 8);
368     /*
369      *  head --v-- tail             used = 0
370      * FIFO: { . . . . . . . . }
371      */
372     fifo8_push(&fifo, 0x1);
373     /*
374      *  head --v]-- tail            used = 1
375      * FIFO: { 1 . . . . . . . }
376      */
377     fifo8_push(&fifo, 0x2);
378     /*
379      *  head --v  ]-- tail          used = 2
380      * FIFO: { 1 2 . . . . . . }
381      */
382 
383     c = fifo8_peek(&fifo);
384     g_assert(c == 0x1);
385     fifo8_pop(&fifo);
386     /*
387      *    head --v]-- tail          used = 1
388      * FIFO: { 1 2 . . . . . . }
389      */
390     c = fifo8_peek(&fifo);
391     g_assert(c == 0x2);
392 
393     g_assert(fifo8_num_used(&fifo) == 1);
394     fifo8_destroy(&fifo);
395 }
396 
397 static void test_fifo8_pushpop(void)
398 {
399     Fifo8 fifo;
400     uint8_t c;
401 
402     fifo8_create(&fifo, 8);
403     /*
404      *  head --v-- tail             used = 0
405      * FIFO: { . . . . . . . . }
406      */
407     fifo8_push(&fifo, 0x1);
408     /*
409      *  head --v]-- tail            used = 1
410      * FIFO: { 1 . . . . . . . }
411      */
412     fifo8_push(&fifo, 0x2);
413     /*
414      *  head --v  ]-- tail          used = 2
415      * FIFO: { 1 2 . . . . . . }
416      */
417 
418     c = fifo8_pop(&fifo);
419     /*
420      *    head --v]-- tail          used = 1
421      * FIFO: { 1 2 . . . . . . }
422      */
423     g_assert(c == 0x1);
424     c = fifo8_pop(&fifo);
425     /*
426      *     tail --]v-- head         used = 0
427      * FIFO: { 1 2 . . . . . . }
428      */
429     g_assert(c == 0x2);
430 
431     g_assert(fifo8_num_used(&fifo) == 0);
432     fifo8_destroy(&fifo);
433 }
434 
435 int main(int argc, char *argv[])
436 {
437     g_test_init(&argc, &argv, NULL);
438     g_test_add_func("/fifo8/pushpop", test_fifo8_pushpop);
439     g_test_add_func("/fifo8/peek", test_fifo8_peek);
440     g_test_add_func("/fifo8/peek_buf", test_fifo8_peek_buf);
441     g_test_add_func("/fifo8/peek_buf_wrap", test_fifo8_peek_buf_wrap);
442     g_test_add_func("/fifo8/pop_buf", test_fifo8_pop_buf);
443     g_test_add_func("/fifo8/pop_buf_wrap", test_fifo8_pop_buf_wrap);
444     g_test_add_func("/fifo8/peek_bufptr", test_fifo8_peek_bufptr);
445     g_test_add_func("/fifo8/peek_bufptr_wrap", test_fifo8_peek_bufptr_wrap);
446     g_test_add_func("/fifo8/pop_bufptr", test_fifo8_pop_bufptr);
447     g_test_add_func("/fifo8/pop_bufptr_wrap", test_fifo8_pop_bufptr_wrap);
448     return g_test_run();
449 }
450