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