1 /*******************************************************************************
2 * Copyright (C) 2018 Cadence Design Systems, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to use this Software with Cadence processor cores only and
7 * not with any other processors and platforms, subject to
8 * the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 ******************************************************************************/
22
23 /*******************************************************************************
24 * xf-io.h
25 *
26 * Input/output data ports
27 *
28 *******************************************************************************/
29
30 #ifndef __XF_H
31 #error "xf-io.h mustn't be included directly"
32 #endif
33
34 /*******************************************************************************
35 * Types definitions
36 ******************************************************************************/
37
38 /* ...input port with interim buffer */
39 typedef struct xf_input_port
40 {
41 /* ...message queue */
42 xf_msg_queue_t queue;
43
44 /* ...internal contiguous buffer to store incoming data */
45 void *buffer;
46
47 /* ...size of internal buffer */
48 u32 length;
49
50 /* ...current writing position in the buffer */
51 u32 filled;
52
53 /* ...interim pointer to input message buffer */
54 void *access;
55
56 /* ...remaining length of current input message */
57 u32 remaining;
58
59 /* ...execution flags */
60 u32 flags;
61
62 } xf_input_port_t;
63
64 /*******************************************************************************
65 * Input port flags
66 ******************************************************************************/
67
68 /* ...data enabled */
69 #define XF_INPUT_FLAG_CREATED (1 << 0)
70
71 /* ...data enabled */
72 #define XF_INPUT_FLAG_ENABLED (1 << 1)
73
74 /* ...end-of-stream condition */
75 #define XF_INPUT_FLAG_EOS (1 << 2)
76
77 /* ...stream completed */
78 #define XF_INPUT_FLAG_DONE (1 << 3)
79
80 /* ...stream purging sequence */
81 #define XF_INPUT_FLAG_PURGING (1 << 4)
82
83 /* ...base input port flags mask */
84 #define __XF_INPUT_FLAGS(flags) ((flags) & ((1 << 5) - 1))
85
86 /* ...custom input port flag */
87 #define __XF_INPUT_FLAG(f) ((f) << 5)
88
89 /*******************************************************************************
90 * Helpers
91 ******************************************************************************/
92
93 /* ...test if input port is created */
xf_input_port_created(xf_input_port_t * port)94 static inline int xf_input_port_created(xf_input_port_t *port)
95 {
96 return (port->flags & XF_INPUT_FLAG_CREATED);
97 }
98
99 /* ...check if input port is ready (has pending message) */
xf_input_port_ready(xf_input_port_t * port)100 static inline int xf_input_port_ready(xf_input_port_t *port)
101 {
102 return (xf_msg_queue_head(&port->queue) != NULL);
103 }
104
105 /* ...test if input port entered end-of-stream condition */
xf_input_port_done(xf_input_port_t * port)106 static inline int xf_input_port_done(xf_input_port_t *port)
107 {
108 return (port->flags & XF_INPUT_FLAG_DONE);
109 }
110
111 /* ...check if port is in bypass mode */
xf_input_port_bypass(xf_input_port_t * port)112 static inline int xf_input_port_bypass(xf_input_port_t *port)
113 {
114 return port->buffer == NULL;
115 }
116
117 /* ...bypass port only: check if there is a data available */
xf_input_port_data(xf_input_port_t * port)118 static inline void * xf_input_port_data(xf_input_port_t *port)
119 {
120 return port->access;
121 }
122
123 /* ...bypass port only: get remaining length of current message */
xf_input_port_length(xf_input_port_t * port)124 static inline u32 xf_input_port_length(xf_input_port_t *port)
125 {
126 return port->remaining;
127 }
128
129 /* ...non-bypass port only: get current fill level */
xf_input_port_level(xf_input_port_t * port)130 static inline u32 xf_input_port_level(xf_input_port_t *port)
131 {
132 return port->filled;
133 }
134
135 /*******************************************************************************
136 * Output port data
137 ******************************************************************************/
138
139 typedef struct xf_output_port
140 {
141 /* ...pending message queue */
142 xf_msg_queue_t queue;
143
144 /* ...message pool */
145 xf_msg_pool_t pool;
146
147 /* ...saved port unrouting message */
148 xf_message_t *unroute;
149
150 /* ...length of output buffer */
151 u32 length;
152
153 /* ...output port flags */
154 u32 flags;
155
156 } xf_output_port_t;
157
158 /*******************************************************************************
159 * Output port flags
160 ******************************************************************************/
161
162 /* ...port is created */
163 #define XF_OUTPUT_FLAG_CREATED (1 << 0)
164
165 /* ...port is routed */
166 #define XF_OUTPUT_FLAG_ROUTED (1 << 1)
167
168 /* ...data enabled */
169 #define XF_OUTPUT_FLAG_ENABLED (1 << 2)
170
171 /* ...stream completed */
172 #define XF_OUTPUT_FLAG_DONE (1 << 3)
173
174 /* ...flushing sequence is on-going */
175 #define XF_OUTPUT_FLAG_FLUSHING (1 << 4)
176
177 /* ...port is idle - no outstanding messages */
178 #define XF_OUTPUT_FLAG_IDLE (1 << 5)
179
180 /* ...port is being unrouted */
181 #define XF_OUTPUT_FLAG_UNROUTING (1 << 6)
182
183 /* ...base output port flags accessor */
184 #define __XF_OUTPUT_FLAGS(flags) ((flags) & ((1 << 7) - 1))
185
186 /* ...custom output port flag */
187 #define __XF_OUTPUT_FLAG(f) ((f) << 7)
188
189 /*******************************************************************************
190 * Helpers
191 ******************************************************************************/
192
193 /* ...test if input port is created */
xf_output_port_created(xf_output_port_t * port)194 static inline int xf_output_port_created(xf_output_port_t *port)
195 {
196 return (port->flags & XF_OUTPUT_FLAG_CREATED);
197 }
198
199 /* ...check if port is routed */
xf_output_port_routed(xf_output_port_t * port)200 static inline int xf_output_port_routed(xf_output_port_t *port)
201 {
202 return ((port->flags & XF_OUTPUT_FLAG_ROUTED) != 0);
203 }
204
205 /* ...check if port unrouting sequence is ongoing */
xf_output_port_unrouting(xf_output_port_t * port)206 static inline int xf_output_port_unrouting(xf_output_port_t *port)
207 {
208 return ((port->flags & XF_OUTPUT_FLAG_UNROUTING) != 0);
209 }
210
211 /* ...check if port is idle (owns all data buffers) */
xf_output_port_idle(xf_output_port_t * port)212 static inline int xf_output_port_idle(xf_output_port_t *port)
213 {
214 return ((port->flags & XF_OUTPUT_FLAG_IDLE) != 0);
215 }
216
217 /* ...check if port is ready (has output buffers - better use flags - tbd) */
xf_output_port_ready(xf_output_port_t * port)218 static inline int xf_output_port_ready(xf_output_port_t *port)
219 {
220 return (xf_msg_queue_head(&port->queue) != NULL && !xf_output_port_unrouting(port));
221 }
222
223 /* ...output port flow-control message accessor */
xf_output_port_control_msg(xf_output_port_t * port)224 static inline xf_message_t * xf_output_port_control_msg(xf_output_port_t *port)
225 {
226 return xf_msg_pool_item(&port->pool, 0);
227 }
228
229 /*******************************************************************************
230 * Input port API
231 ******************************************************************************/
232
233 /* ...initialize input port structure */
234 extern int xf_input_port_init(xf_input_port_t *port, u32 size, u32 align, u32 core);
235
236 /* ...put message into input port queue */
237 extern int xf_input_port_put(xf_input_port_t *port, xf_message_t *m);
238
239 /* ...fill-in required amount of data into input port buffer */
240 extern int xf_input_port_fill(xf_input_port_t *port);
241
242 /* ...pad input buffer with given value */
243 extern void xf_input_port_pad(xf_input_port_t *port, u8 pad);
244
245 /* ...consume bytes from input buffer */
246 extern void xf_input_port_consume(xf_input_port_t *port, u32 n);
247
248 /* ...purge input port queue */
249 extern void xf_input_port_purge(xf_input_port_t *port);
250
251 /* ...save flow-control message for propagated input port purging sequence */
252 extern void xf_input_port_control_save(xf_input_port_t *port, xf_message_t *m);
253
254 /* ...complete input port purging sequence */
255 extern void xf_input_port_purge_done(xf_input_port_t *port);
256
257 /* ...destroy input port data */
258 extern void xf_input_port_destroy(xf_input_port_t *port, u32 core);
259
260 /*******************************************************************************
261 * Output port API
262 ******************************************************************************/
263
264 /* ...initialize output port structure */
265 extern int xf_output_port_init(xf_output_port_t *port, u32 size);
266
267 /* ...put next message to the output port */
268 extern int xf_output_port_put(xf_output_port_t *port, xf_message_t *m);
269
270 /* ...get data buffer of output message */
271 extern void * xf_output_port_data(xf_output_port_t *port);
272
273 /* ...route output port */
274 extern int xf_output_port_route(xf_output_port_t *port, u32 id, u32 n, u32 length, u32 align);
275
276 /* ...unroute output port */
277 extern void xf_output_port_unroute(xf_output_port_t *port);
278
279 /* ...start output port unrouting sequence */
280 extern void xf_output_port_unroute_start(xf_output_port_t *port, xf_message_t *m);
281
282 /* ...complete port unrouting sequence */
283 extern void xf_output_port_unroute_done(xf_output_port_t *port);
284
285 /* ...produce output message marking amount of bytes produced */
286 extern int xf_output_port_produce(xf_output_port_t *port, u32 n);
287
288 /* ...purge output port */
289 extern void xf_output_port_purge(xf_output_port_t *port);
290
291 /* ...flush output port and return non-zero result if sequence is over */
292 extern int xf_output_port_flush(xf_output_port_t *port, u32 opcode);
293
294 /* ...complete flushing sequence */
295 extern void xf_output_port_flush_done(xf_output_port_t *port);
296
297 /* ...destroy output port data */
298 extern void xf_output_port_destroy(xf_output_port_t *port, u32 core);
299