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 */ 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) */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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) */ 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) */ 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 */ 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