1 | /* |
2 | Copyright (c) 2012-2014, Broadcom Europe Ltd |
3 | All rights reserved. |
4 | |
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the following conditions are met: |
7 | * Redistributions of source code must retain the above copyright |
8 | notice, this list of conditions and the following disclaimer. |
9 | * Redistributions in binary form must reproduce the above copyright |
10 | notice, this list of conditions and the following disclaimer in the |
11 | documentation and/or other materials provided with the distribution. |
12 | * Neither the name of the copyright holder nor the |
13 | names of its contributors may be used to endorse or promote products |
14 | derived from this software without specific prior written permission. |
15 | |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | // Contains the protypes for the vchi functions. |
29 | |
30 | #ifndef VCHI_H_ |
31 | #define VCHI_H_ |
32 | |
33 | #include "interface/vcos/vcos.h" |
34 | #include "interface/vchi/vchi_cfg.h" |
35 | #include "interface/vchi/vchi_common.h" |
36 | #include "interface/vchi/connections/connection.h" |
37 | #include "vchi_mh.h" |
38 | |
39 | |
40 | /****************************************************************************** |
41 | Global defs |
42 | *****************************************************************************/ |
43 | |
44 | #define VCHI_SERVICE_HANDLE_INVALID 0 |
45 | |
46 | #define VCHI_BULK_ROUND_UP(x) ((((unsigned long)(x))+VCHI_BULK_ALIGN-1) & ~(VCHI_BULK_ALIGN-1)) |
47 | #define VCHI_BULK_ROUND_DOWN(x) (((unsigned long)(x)) & ~(VCHI_BULK_ALIGN-1)) |
48 | #define VCHI_BULK_ALIGN_NBYTES(x) (VCHI_BULK_ALIGNED(x) ? 0 : (VCHI_BULK_ALIGN - ((unsigned long)(x) & (VCHI_BULK_ALIGN-1)))) |
49 | |
50 | #ifdef USE_VCHIQ_ARM |
51 | #define VCHI_BULK_ALIGNED(x) 1 |
52 | #else |
53 | #define VCHI_BULK_ALIGNED(x) (((unsigned long)(x) & (VCHI_BULK_ALIGN-1)) == 0) |
54 | #endif |
55 | |
56 | typedef struct |
57 | { |
58 | uint32_t version; |
59 | uint32_t version_min; |
60 | } VCHI_VERSION_T; |
61 | #define VCHI_VERSION(v_) { v_, v_ } |
62 | #define VCHI_VERSION_EX(v_,m_) { v_, m_ } |
63 | |
64 | typedef enum |
65 | { |
66 | VCHI_VEC_POINTER, |
67 | VCHI_VEC_HANDLE, |
68 | VCHI_VEC_LIST |
69 | } VCHI_MSG_VECTOR_TYPE_T; |
70 | |
71 | typedef struct vchi_msg_vector_ex { |
72 | |
73 | VCHI_MSG_VECTOR_TYPE_T type; |
74 | union |
75 | { |
76 | // a memory handle |
77 | struct |
78 | { |
79 | VCHI_MEM_HANDLE_T handle; |
80 | uint32_t offset; |
81 | int32_t vec_len; |
82 | } handle; |
83 | |
84 | // an ordinary data pointer |
85 | struct |
86 | { |
87 | const void *vec_base; |
88 | int32_t vec_len; |
89 | } ptr; |
90 | |
91 | // a nested vector list |
92 | struct |
93 | { |
94 | struct vchi_msg_vector_ex *vec; |
95 | uint32_t vec_len; |
96 | } list; |
97 | } u; |
98 | } VCHI_MSG_VECTOR_EX_T; |
99 | |
100 | |
101 | // Construct an entry in a msg vector for a pointer (p) of length (l) |
102 | #define VCHI_VEC_POINTER(p,l) VCHI_VEC_POINTER, { { (VCHI_MEM_HANDLE_T)(p), (l) } } |
103 | |
104 | // Construct an entry in a msg vector for a message handle (h), starting at offset (o) of length (l) |
105 | #define VCHI_VEC_HANDLE(h,o,l) VCHI_VEC_HANDLE, { { (h), (o), (l) } } |
106 | |
107 | // Macros to manipulate fourcc_t values |
108 | #define MAKE_FOURCC(x) ((fourcc_t)( (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3] )) |
109 | #define FOURCC_TO_CHAR(x) (x >> 24) & 0xFF,(x >> 16) & 0xFF,(x >> 8) & 0xFF, x & 0xFF |
110 | |
111 | |
112 | // Opaque service information |
113 | struct opaque_vchi_service_t; |
114 | |
115 | // Descriptor for a held message. Allocated by client, initialised by vchi_msg_hold, |
116 | // vchi_msg_iter_hold or vchi_msg_iter_hold_next. Fields are for internal VCHI use only. |
117 | typedef struct |
118 | { |
119 | struct opaque_vchi_service_t *service; |
120 | void *message; |
121 | } VCHI_HELD_MSG_T; |
122 | |
123 | |
124 | |
125 | // structure used to provide the information needed to open a server or a client |
126 | typedef struct { |
127 | VCHI_VERSION_T version; |
128 | vcos_fourcc_t service_id; |
129 | VCHI_CONNECTION_T *connection; |
130 | uint32_t rx_fifo_size; |
131 | uint32_t tx_fifo_size; |
132 | VCHI_CALLBACK_T callback; |
133 | void *callback_param; |
134 | vcos_bool_t want_unaligned_bulk_rx; // client intends to receive bulk transfers of odd lengths or into unaligned buffers |
135 | vcos_bool_t want_unaligned_bulk_tx; // client intends to transmit bulk transfers of odd lengths or out of unaligned buffers |
136 | vcos_bool_t want_crc; // client wants to check CRCs on (bulk) transfers. Only needs to be set at 1 end - will do both directions. |
137 | } SERVICE_CREATION_T; |
138 | |
139 | // Opaque handle for a VCHI instance |
140 | typedef struct opaque_vchi_instance_handle_t *VCHI_INSTANCE_T; |
141 | |
142 | // Opaque handle for a server or client |
143 | typedef unsigned int VCHI_SERVICE_HANDLE_T; |
144 | |
145 | // Service registration & startup |
146 | typedef void (*VCHI_SERVICE_INIT)(VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections); |
147 | |
148 | typedef struct service_info_tag { |
149 | const char * const vll_filename; /* VLL to load to start this service. This is an empty string if VLL is "static" */ |
150 | VCHI_SERVICE_INIT init; /* Service initialisation function */ |
151 | void *vll_handle; /* VLL handle; NULL when unloaded or a "static VLL" in build */ |
152 | } SERVICE_INFO_T; |
153 | |
154 | // Pagelist structure for copy callback |
155 | struct pagelist_struct; |
156 | |
157 | /****************************************************************************** |
158 | Global funcs - implementation is specific to which side you are on (local / remote) |
159 | *****************************************************************************/ |
160 | |
161 | #ifdef __cplusplus |
162 | extern "C" { |
163 | #endif |
164 | |
165 | extern /*@observer@*/ VCHI_CONNECTION_T * vchi_create_connection( const VCHI_CONNECTION_API_T * function_table, |
166 | const VCHI_MESSAGE_DRIVER_T * low_level); |
167 | |
168 | |
169 | // Routine used to initialise the vchi on both local + remote connections |
170 | extern int32_t vchi_initialise( VCHI_INSTANCE_T *instance_handle ); |
171 | |
172 | extern int32_t vchi_connect( VCHI_CONNECTION_T **connections, |
173 | const uint32_t num_connections, |
174 | VCHI_INSTANCE_T instance_handle ); |
175 | |
176 | //When this is called, ensure that all services have no data pending. |
177 | //Bulk transfers can remain 'queued' |
178 | extern int32_t vchi_disconnect( VCHI_INSTANCE_T instance_handle ); |
179 | |
180 | // Global control over bulk CRC checking |
181 | extern int32_t vchi_crc_control( VCHI_CONNECTION_T *connection, |
182 | VCHI_CRC_CONTROL_T control ); |
183 | |
184 | // helper functions |
185 | extern void * vchi_allocate_buffer(VCHI_SERVICE_HANDLE_T handle, uint32_t *length); |
186 | extern void vchi_free_buffer(VCHI_SERVICE_HANDLE_T handle, void *address); |
187 | extern uint32_t vchi_current_time(VCHI_INSTANCE_T instance_handle); |
188 | |
189 | |
190 | /****************************************************************************** |
191 | Global service API |
192 | *****************************************************************************/ |
193 | // Routine to create a named service |
194 | extern int32_t vchi_service_create( VCHI_INSTANCE_T instance_handle, |
195 | SERVICE_CREATION_T *setup, |
196 | VCHI_SERVICE_HANDLE_T *handle ); |
197 | |
198 | // Routine to destroy a service |
199 | extern int32_t vchi_service_destroy( const VCHI_SERVICE_HANDLE_T handle ); |
200 | |
201 | // Routine to open a named service |
202 | extern int32_t vchi_service_open( VCHI_INSTANCE_T instance_handle, |
203 | SERVICE_CREATION_T *setup, |
204 | VCHI_SERVICE_HANDLE_T *handle); |
205 | |
206 | extern int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle, |
207 | short *peer_version ); |
208 | |
209 | // Routine to close a named service |
210 | extern int32_t vchi_service_close( const VCHI_SERVICE_HANDLE_T handle ); |
211 | |
212 | // Routine to increment ref count on a named service |
213 | extern int32_t vchi_service_use( const VCHI_SERVICE_HANDLE_T handle ); |
214 | |
215 | // Routine to decrement ref count on a named service |
216 | extern int32_t vchi_service_release( const VCHI_SERVICE_HANDLE_T handle ); |
217 | |
218 | // Routine to set a control option for a named service |
219 | extern int32_t vchi_service_set_option( const VCHI_SERVICE_HANDLE_T handle, |
220 | VCHI_SERVICE_OPTION_T option, |
221 | int value); |
222 | |
223 | // Routine to send a message across a service |
224 | extern int32_t vchi_msg_queue( VCHI_SERVICE_HANDLE_T handle, |
225 | const void *data, |
226 | uint32_t data_size, |
227 | VCHI_FLAGS_T flags, |
228 | void *msg_handle ); |
229 | |
230 | // scatter-gather (vector) and send message |
231 | int32_t vchi_msg_queuev_ex( VCHI_SERVICE_HANDLE_T handle, |
232 | VCHI_MSG_VECTOR_EX_T *vector, |
233 | uint32_t count, |
234 | VCHI_FLAGS_T flags, |
235 | void *msg_handle ); |
236 | |
237 | // legacy scatter-gather (vector) and send message, only handles pointers |
238 | int32_t vchi_msg_queuev( VCHI_SERVICE_HANDLE_T handle, |
239 | VCHI_MSG_VECTOR_T *vector, |
240 | uint32_t count, |
241 | VCHI_FLAGS_T flags, |
242 | void *msg_handle ); |
243 | |
244 | // Routine to receive a msg from a service |
245 | // Dequeue is equivalent to hold, copy into client buffer, release |
246 | extern int32_t vchi_msg_dequeue( VCHI_SERVICE_HANDLE_T handle, |
247 | void *data, |
248 | uint32_t max_data_size_to_read, |
249 | uint32_t *actual_msg_size, |
250 | VCHI_FLAGS_T flags ); |
251 | |
252 | // Routine to look at a message in place. |
253 | // The message is not dequeued, so a subsequent call to peek or dequeue |
254 | // will return the same message. |
255 | extern int32_t vchi_msg_peek( VCHI_SERVICE_HANDLE_T handle, |
256 | void **data, |
257 | uint32_t *msg_size, |
258 | VCHI_FLAGS_T flags ); |
259 | |
260 | // Routine to remove a message after it has been read in place with peek |
261 | // The first message on the queue is dequeued. |
262 | extern int32_t vchi_msg_remove( VCHI_SERVICE_HANDLE_T handle ); |
263 | |
264 | // Routine to look at a message in place. |
265 | // The message is dequeued, so the caller is left holding it; the descriptor is |
266 | // filled in and must be released when the user has finished with the message. |
267 | extern int32_t vchi_msg_hold( VCHI_SERVICE_HANDLE_T handle, |
268 | void **data, // } may be NULL, as info can be |
269 | uint32_t *msg_size, // } obtained from HELD_MSG_T |
270 | VCHI_FLAGS_T flags, |
271 | VCHI_HELD_MSG_T *message_descriptor ); |
272 | |
273 | // Initialise an iterator to look through messages in place |
274 | extern int32_t vchi_msg_look_ahead( VCHI_SERVICE_HANDLE_T handle, |
275 | VCHI_MSG_ITER_T *iter, |
276 | VCHI_FLAGS_T flags ); |
277 | |
278 | /****************************************************************************** |
279 | Global service support API - operations on held messages and message iterators |
280 | *****************************************************************************/ |
281 | |
282 | // Routine to get the address of a held message |
283 | extern void *vchi_held_msg_ptr( const VCHI_HELD_MSG_T *message ); |
284 | |
285 | // Routine to get the size of a held message |
286 | extern int32_t vchi_held_msg_size( const VCHI_HELD_MSG_T *message ); |
287 | |
288 | // Routine to get the transmit timestamp as written into the header by the peer |
289 | extern uint32_t vchi_held_msg_tx_timestamp( const VCHI_HELD_MSG_T *message ); |
290 | |
291 | // Routine to get the reception timestamp, written as we parsed the header |
292 | extern uint32_t vchi_held_msg_rx_timestamp( const VCHI_HELD_MSG_T *message ); |
293 | |
294 | // Routine to release a held message after it has been processed |
295 | extern int32_t vchi_held_msg_release( VCHI_HELD_MSG_T *message ); |
296 | |
297 | // Indicates whether the iterator has a next message. |
298 | extern vcos_bool_t vchi_msg_iter_has_next( const VCHI_MSG_ITER_T *iter ); |
299 | |
300 | // Return the pointer and length for the next message and advance the iterator. |
301 | extern int32_t vchi_msg_iter_next( VCHI_MSG_ITER_T *iter, |
302 | void **data, |
303 | uint32_t *msg_size ); |
304 | |
305 | // Remove the last message returned by vchi_msg_iter_next. |
306 | // Can only be called once after each call to vchi_msg_iter_next. |
307 | extern int32_t vchi_msg_iter_remove( VCHI_MSG_ITER_T *iter ); |
308 | |
309 | // Hold the last message returned by vchi_msg_iter_next. |
310 | // Can only be called once after each call to vchi_msg_iter_next. |
311 | extern int32_t vchi_msg_iter_hold( VCHI_MSG_ITER_T *iter, |
312 | VCHI_HELD_MSG_T *message ); |
313 | |
314 | // Return information for the next message, and hold it, advancing the iterator. |
315 | extern int32_t vchi_msg_iter_hold_next( VCHI_MSG_ITER_T *iter, |
316 | void **data, // } may be NULL |
317 | uint32_t *msg_size, // } |
318 | VCHI_HELD_MSG_T *message ); |
319 | |
320 | |
321 | /****************************************************************************** |
322 | Global bulk API |
323 | *****************************************************************************/ |
324 | |
325 | // Routine to prepare interface for a transfer from the other side |
326 | extern int32_t vchi_bulk_queue_receive( VCHI_SERVICE_HANDLE_T handle, |
327 | void *data_dst, |
328 | uint32_t data_size, |
329 | VCHI_FLAGS_T flags, |
330 | void *transfer_handle ); |
331 | |
332 | |
333 | // Prepare interface for a transfer from the other side into relocatable memory. |
334 | int32_t vchi_bulk_queue_receive_reloc( const VCHI_SERVICE_HANDLE_T handle, |
335 | VCHI_MEM_HANDLE_T h_dst, |
336 | uint32_t offset, |
337 | uint32_t data_size, |
338 | const VCHI_FLAGS_T flags, |
339 | void * const bulk_handle ); |
340 | |
341 | // Prepare interface for a transfer from the other side into relocatable memory. |
342 | int32_t vchi_bulk_queue_receive_reloc_func( const VCHI_SERVICE_HANDLE_T handle, |
343 | VCHI_MEM_HANDLE_T h_dst, |
344 | uint32_t offset, |
345 | uint32_t data_size, |
346 | const VCHI_FLAGS_T flags, |
347 | void * const bulk_handle, |
348 | int copy_pagelist(char *vcptr, const struct pagelist_struct *pagelist)); |
349 | |
350 | // Routine to queue up data ready for transfer to the other (once they have signalled they are ready) |
351 | extern int32_t vchi_bulk_queue_transmit( VCHI_SERVICE_HANDLE_T handle, |
352 | const void *data_src, |
353 | uint32_t data_size, |
354 | VCHI_FLAGS_T flags, |
355 | void *transfer_handle ); |
356 | |
357 | |
358 | /****************************************************************************** |
359 | Configuration plumbing |
360 | *****************************************************************************/ |
361 | |
362 | // function prototypes for the different mid layers (the state info gives the different physical connections) |
363 | extern const VCHI_CONNECTION_API_T *single_get_func_table( void ); |
364 | //extern const VCHI_CONNECTION_API_T *local_server_get_func_table( void ); |
365 | //extern const VCHI_CONNECTION_API_T *local_client_get_func_table( void ); |
366 | |
367 | // declare all message drivers here |
368 | const VCHI_MESSAGE_DRIVER_T *vchi_mphi_message_driver_func_table( void ); |
369 | |
370 | #ifdef __cplusplus |
371 | } |
372 | #endif |
373 | |
374 | extern int32_t vchi_bulk_queue_transmit_reloc( VCHI_SERVICE_HANDLE_T handle, |
375 | VCHI_MEM_HANDLE_T h_src, |
376 | uint32_t offset, |
377 | uint32_t data_size, |
378 | VCHI_FLAGS_T flags, |
379 | void *transfer_handle ); |
380 | #endif /* VCHI_H_ */ |
381 | |
382 | /****************************** End of file **********************************/ |
383 | |