1/*
2Copyright (c) 2012-2014, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON 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
25SOFTWARE, 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
56typedef 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
64typedef enum
65{
66 VCHI_VEC_POINTER,
67 VCHI_VEC_HANDLE,
68 VCHI_VEC_LIST
69} VCHI_MSG_VECTOR_TYPE_T;
70
71typedef 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
113struct 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.
117typedef 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
126typedef 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
140typedef struct opaque_vchi_instance_handle_t *VCHI_INSTANCE_T;
141
142// Opaque handle for a server or client
143typedef unsigned int VCHI_SERVICE_HANDLE_T;
144
145// Service registration & startup
146typedef void (*VCHI_SERVICE_INIT)(VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections);
147
148typedef 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
155struct pagelist_struct;
156
157/******************************************************************************
158 Global funcs - implementation is specific to which side you are on (local / remote)
159 *****************************************************************************/
160
161#ifdef __cplusplus
162extern "C" {
163#endif
164
165extern /*@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
170extern int32_t vchi_initialise( VCHI_INSTANCE_T *instance_handle );
171
172extern 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'
178extern int32_t vchi_disconnect( VCHI_INSTANCE_T instance_handle );
179
180// Global control over bulk CRC checking
181extern int32_t vchi_crc_control( VCHI_CONNECTION_T *connection,
182 VCHI_CRC_CONTROL_T control );
183
184// helper functions
185extern void * vchi_allocate_buffer(VCHI_SERVICE_HANDLE_T handle, uint32_t *length);
186extern void vchi_free_buffer(VCHI_SERVICE_HANDLE_T handle, void *address);
187extern 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
194extern 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
199extern int32_t vchi_service_destroy( const VCHI_SERVICE_HANDLE_T handle );
200
201// Routine to open a named service
202extern int32_t vchi_service_open( VCHI_INSTANCE_T instance_handle,
203 SERVICE_CREATION_T *setup,
204 VCHI_SERVICE_HANDLE_T *handle);
205
206extern int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle,
207 short *peer_version );
208
209// Routine to close a named service
210extern int32_t vchi_service_close( const VCHI_SERVICE_HANDLE_T handle );
211
212// Routine to increment ref count on a named service
213extern int32_t vchi_service_use( const VCHI_SERVICE_HANDLE_T handle );
214
215// Routine to decrement ref count on a named service
216extern int32_t vchi_service_release( const VCHI_SERVICE_HANDLE_T handle );
217
218// Routine to set a control option for a named service
219extern 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
224extern 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
231int32_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
238int32_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
246extern 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.
255extern 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.
262extern 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.
267extern 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
274extern 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
283extern void *vchi_held_msg_ptr( const VCHI_HELD_MSG_T *message );
284
285// Routine to get the size of a held message
286extern 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
289extern 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
292extern 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
295extern int32_t vchi_held_msg_release( VCHI_HELD_MSG_T *message );
296
297// Indicates whether the iterator has a next message.
298extern 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.
301extern 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.
307extern 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.
311extern 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.
315extern 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
326extern 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.
334int32_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.
342int32_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)
351extern 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)
363extern 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
368const VCHI_MESSAGE_DRIVER_T *vchi_mphi_message_driver_func_table( void );
369
370#ifdef __cplusplus
371}
372#endif
373
374extern 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