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#ifndef REMOTE_PORT_PROTO_H__
26#define REMOTE_PORT_PROTO_H__
27
28#include <stdbool.h>
29#include <string.h>
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53#define RP_VERSION_MAJOR 4
54#define RP_VERSION_MINOR 2
55
56#if defined(_WIN32) && defined(__MINGW32__)
57
58#define PACKED __attribute__ ((gcc_struct, packed))
59#else
60#define PACKED __attribute__ ((packed))
61#endif
62
63
64enum rp_cmd {
65 RP_CMD_nop = 0,
66 RP_CMD_hello = 1,
67 RP_CMD_cfg = 2,
68 RP_CMD_read = 3,
69 RP_CMD_write = 4,
70 RP_CMD_interrupt = 5,
71 RP_CMD_sync = 6,
72 RP_CMD_max = 6
73};
74
75enum {
76 RP_OPT_quantum = 0,
77};
78
79struct rp_cfg_state {
80 uint64_t quantum;
81};
82
83enum {
84 RP_PKT_FLAGS_optional = 1 << 0,
85 RP_PKT_FLAGS_response = 1 << 1,
86};
87
88struct rp_pkt_hdr {
89 uint32_t cmd;
90 uint32_t len;
91 uint32_t id;
92 uint32_t flags;
93 uint32_t dev;
94} PACKED;
95
96struct rp_pkt_cfg {
97 struct rp_pkt_hdr hdr;
98 uint32_t opt;
99 uint8_t set;
100} PACKED;
101
102struct rp_version {
103 uint16_t major;
104 uint16_t minor;
105} PACKED;
106
107struct rp_capabilities {
108
109 uint32_t offset;
110 uint16_t len;
111 uint16_t reserved0;
112} PACKED;
113
114enum {
115 CAP_BUSACCESS_EXT_BASE = 1,
116 CAP_BUSACCESS_EXT_BYTE_EN = 2,
117};
118
119struct rp_pkt_hello {
120 struct rp_pkt_hdr hdr;
121 struct rp_version version;
122 struct rp_capabilities caps;
123} PACKED;
124
125
126enum {
127 RP_BUS_ATTR_EOP = (1 << 0),
128 RP_BUS_ATTR_SECURE = (1 << 1),
129 RP_BUS_ATTR_EXT_BASE = (1 << 2),
130};
131
132struct rp_pkt_busaccess {
133 struct rp_pkt_hdr hdr;
134 uint64_t timestamp;
135 uint64_t attributes;
136 uint64_t addr;
137
138
139 uint32_t len;
140
141
142
143 uint32_t width;
144
145
146
147
148 uint32_t stream_width;
149
150
151 uint16_t master_id;
152} PACKED;
153
154
155
156struct rp_pkt_busaccess_ext_base {
157 struct rp_pkt_hdr hdr;
158 uint64_t timestamp;
159 uint64_t attributes;
160 uint64_t addr;
161
162
163 uint32_t len;
164
165
166
167 uint32_t width;
168
169
170
171
172 uint32_t stream_width;
173
174
175 uint16_t master_id;
176
177
178 uint16_t master_id_31_16;
179 uint32_t master_id_63_32;
180
181
182
183 uint32_t data_offset;
184 uint32_t next_offset;
185
186 uint32_t byte_enable_offset;
187 uint32_t byte_enable_len;
188
189
190
191
192
193
194
195
196
197} PACKED;
198
199struct rp_pkt_interrupt {
200 struct rp_pkt_hdr hdr;
201 uint64_t timestamp;
202 uint64_t vector;
203 uint32_t line;
204 uint8_t val;
205} PACKED;
206
207struct rp_pkt_sync {
208 struct rp_pkt_hdr hdr;
209 uint64_t timestamp;
210} PACKED;
211
212struct rp_pkt {
213 union {
214 struct rp_pkt_hdr hdr;
215 struct rp_pkt_hello hello;
216 struct rp_pkt_busaccess busaccess;
217 struct rp_pkt_busaccess_ext_base busaccess_ext_base;
218 struct rp_pkt_interrupt interrupt;
219 struct rp_pkt_sync sync;
220 };
221};
222
223struct rp_peer_state {
224 void *opaque;
225
226 struct rp_pkt pkt;
227 bool hdr_used;
228
229 struct rp_version version;
230
231 struct {
232 bool busaccess_ext_base;
233 bool busaccess_ext_byte_en;
234 } caps;
235
236
237 int64_t clk_base;
238
239 struct rp_cfg_state local_cfg;
240 struct rp_cfg_state peer_cfg;
241};
242
243const char *rp_cmd_to_string(enum rp_cmd cmd);
244int rp_decode_hdr(struct rp_pkt *pkt);
245int rp_decode_payload(struct rp_pkt *pkt);
246
247void rp_encode_hdr(struct rp_pkt_hdr *hdr,
248 uint32_t cmd, uint32_t id, uint32_t dev, uint32_t len,
249 uint32_t flags);
250
251
252
253
254
255
256size_t rp_encode_hello_caps(uint32_t id, uint32_t dev, struct rp_pkt_hello *pkt,
257 uint16_t version_major, uint16_t version_minor,
258 uint32_t *caps, uint32_t *features_out,
259 uint32_t features_len);
260
261
262static inline size_t __attribute__ ((deprecated))
263rp_encode_hello(uint32_t id, uint32_t dev, struct rp_pkt_hello *pkt,
264 uint16_t version_major, uint16_t version_minor) {
265 return rp_encode_hello_caps(id, dev, pkt, version_major, version_minor,
266 NULL, NULL, 0);
267}
268
269static inline void *__attribute__ ((deprecated))
270rp_busaccess_dataptr(struct rp_pkt_busaccess *pkt)
271{
272
273 return pkt + 1;
274}
275
276
277
278
279
280
281
282
283static inline unsigned char *
284rp_busaccess_tx_dataptr(struct rp_peer_state *peer,
285 struct rp_pkt_busaccess_ext_base *pkt)
286{
287 unsigned char *p = (unsigned char *) pkt;
288
289 if (peer->caps.busaccess_ext_base) {
290
291 return p + sizeof *pkt;
292 } else {
293
294 return p + sizeof(struct rp_pkt_busaccess);
295 }
296}
297
298
299
300
301
302
303static inline unsigned char *
304rp_busaccess_rx_dataptr(struct rp_peer_state *peer,
305 struct rp_pkt_busaccess_ext_base *pkt)
306{
307 unsigned char *p = (unsigned char *) pkt;
308
309 if (pkt->attributes & RP_BUS_ATTR_EXT_BASE) {
310 return p + pkt->data_offset;
311 } else {
312
313 return p + sizeof(struct rp_pkt_busaccess);
314 }
315}
316
317static inline unsigned char *
318rp_busaccess_byte_en_ptr(struct rp_peer_state *peer,
319 struct rp_pkt_busaccess_ext_base *pkt)
320{
321 unsigned char *p = (unsigned char *) pkt;
322
323 if ((pkt->attributes & RP_BUS_ATTR_EXT_BASE)
324 && pkt->byte_enable_len) {
325 assert(pkt->byte_enable_offset >= sizeof *pkt);
326 assert(pkt->byte_enable_offset + pkt->byte_enable_len
327 <= pkt->hdr.len + sizeof pkt->hdr);
328 return p + pkt->byte_enable_offset;
329 }
330 return NULL;
331}
332
333size_t __attribute__ ((deprecated))
334rp_encode_read(uint32_t id, uint32_t dev,
335 struct rp_pkt_busaccess *pkt,
336 int64_t clk, uint16_t master_id,
337 uint64_t addr, uint64_t attr, uint32_t size,
338 uint32_t width, uint32_t stream_width);
339
340size_t __attribute__ ((deprecated))
341rp_encode_read_resp(uint32_t id, uint32_t dev,
342 struct rp_pkt_busaccess *pkt,
343 int64_t clk, uint16_t master_id,
344 uint64_t addr, uint64_t attr, uint32_t size,
345 uint32_t width, uint32_t stream_width);
346
347size_t __attribute__ ((deprecated))
348rp_encode_write(uint32_t id, uint32_t dev,
349 struct rp_pkt_busaccess *pkt,
350 int64_t clk, uint16_t master_id,
351 uint64_t addr, uint64_t attr, uint32_t size,
352 uint32_t width, uint32_t stream_width);
353
354size_t __attribute__ ((deprecated))
355rp_encode_write_resp(uint32_t id, uint32_t dev,
356 struct rp_pkt_busaccess *pkt,
357 int64_t clk, uint16_t master_id,
358 uint64_t addr, uint64_t attr, uint32_t size,
359 uint32_t width, uint32_t stream_width);
360
361struct rp_encode_busaccess_in {
362 uint32_t cmd;
363 uint32_t id;
364 uint32_t flags;
365 uint32_t dev;
366 int64_t clk;
367 uint64_t master_id;
368 uint64_t addr;
369 uint64_t attr;
370 uint32_t size;
371 uint32_t width;
372 uint32_t stream_width;
373 uint32_t byte_enable_len;
374};
375
376
377static inline void
378rp_encode_busaccess_in_rsp_init(struct rp_encode_busaccess_in *in,
379 struct rp_pkt *pkt) {
380 memset(in, 0, sizeof *in);
381 in->cmd = pkt->hdr.cmd;
382 in->id = pkt->hdr.id;
383 in->flags = pkt->hdr.flags | RP_PKT_FLAGS_response;
384 in->dev = pkt->hdr.dev;
385
386 in->master_id = pkt->busaccess.master_id;
387 in->addr = pkt->busaccess.addr;
388 in->size = pkt->busaccess.len;
389 in->width = pkt->busaccess.width;
390 in->stream_width = pkt->busaccess.stream_width;
391 in->byte_enable_len = 0;
392}
393size_t rp_encode_busaccess(struct rp_peer_state *peer,
394 struct rp_pkt_busaccess_ext_base *pkt,
395 struct rp_encode_busaccess_in *in);
396
397size_t rp_encode_interrupt(uint32_t id, uint32_t dev,
398 struct rp_pkt_interrupt *pkt,
399 int64_t clk,
400 uint32_t line, uint64_t vector, uint8_t val);
401
402size_t rp_encode_sync(uint32_t id, uint32_t dev,
403 struct rp_pkt_sync *pkt,
404 int64_t clk);
405
406size_t rp_encode_sync_resp(uint32_t id, uint32_t dev,
407 struct rp_pkt_sync *pkt,
408 int64_t clk);
409
410void rp_process_caps(struct rp_peer_state *peer,
411 void *caps, size_t caps_len);
412
413
414
415typedef struct RemotePortDynPkt {
416 struct rp_pkt *pkt;
417 size_t size;
418} RemotePortDynPkt;
419
420
421
422
423
424void rp_dpkt_alloc(RemotePortDynPkt *dpkt, size_t size);
425
426void rp_dpkt_swap(RemotePortDynPkt *a, RemotePortDynPkt *b);
427
428
429
430
431
432bool rp_dpkt_is_valid(RemotePortDynPkt *dpkt);
433
434
435
436
437
438void rp_dpkt_invalidate(RemotePortDynPkt *dpkt);
439
440void rp_dpkt_free(RemotePortDynPkt *dpkt);
441
442#endif
443