aboutsummaryrefslogtreecommitdiff
path: root/include/qemu/fifo32.h
blob: 4e9fd1b5ef88c06060b7406ae453d0c5fd19324a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
 * 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 */