00001 /* $Id: types.h 22056 2005-09-06 14:16:01Z fm3 $ */ 00002 /*****************************************************************************/ 00003 /** 00004 * \file dsi/include/types.h 00005 * \brief DROPS Stream Interface public types. 00006 * 00007 * \date 07/01/2000 00008 * \author Lars Reuther <reuther@os.inf.tu-dresden.de> 00009 */ 00010 /*****************************************************************************/ 00011 #ifndef _DSI_TYPES_H 00012 #define _DSI_TYPES_H 00013 00014 /* DROPS/L4 includes */ 00015 #include <l4/sys/types.h> 00016 #include <l4/util/setjmp.h> 00017 #include <l4/l4rm/l4rm.h> 00018 #include <l4/thread/thread.h> 00019 00020 /***************************************************************************** 00021 * generic types * 00022 *****************************************************************************/ 00023 00024 /*!\brief jitter constrained periodic stream 00025 * \ingroup general 00026 */ 00027 typedef struct dsi_jcp_stream 00028 { 00029 l4_uint32_t bw; //!< bandwidth, byte/s 00030 l4_uint32_t tau; //!< jitter, microseconds 00031 l4_uint32_t size; //!< packet size 00032 } dsi_jcp_stream_t; 00033 00034 /*!\brief low level stream configuration 00035 * \ingroup general 00036 * 00037 * for now it is specified explicitly, at some stage it should be 00038 * calculated from jitter constrained periodic stream definition 00039 */ 00040 typedef struct dsi_stream_cfg 00041 { 00042 l4_uint32_t num_packets; //!< number of control packets 00043 l4_uint32_t max_sg; //!< max. length of packet scatter gather list 00044 } dsi_stream_cfg_t; 00045 00046 /***************************************************************************** 00047 * component types 00048 *****************************************************************************/ 00049 00050 /***************************************************************************** 00051 * packet 00052 *****************************************************************************/ 00053 00054 /*!\brief packet semaphore type 00055 * \ingroup component 00056 */ 00057 typedef volatile l4_int8_t dsi_semaphore_t; 00058 00059 /*!\brief packet descriptor 00060 * \ingroup component 00061 */ 00062 typedef struct dsi_packet 00063 { 00064 l4_uint32_t no; //!< packet number 00065 volatile l4_uint16_t flags; //!< packet flags 00066 dsi_semaphore_t tx_sem; //!< send semaphore counter (__get_send_packet()) 00067 dsi_semaphore_t rx_sem; /**< receive semaphore counter 00068 (__get_receive_packet()) */ 00069 l4_uint64_t expires; //!< expire time 00070 00071 l4_uint32_t sg_len; //!< length of scatter gather list 00072 l4_uint32_t sg_list; /*!< pointer to scatter gather list, it is an index 00073 to the scatter gather element array */ 00074 l4_uint32_t sg_idx; /*!< index in scatter gather list. Used in 00075 dsi_packet_add_data() to store the index of the 00076 last element in the list, in 00077 dsi_packet_get_data() to store the index of 00078 the next data area to get */ 00079 } dsi_packet_t; 00080 00081 /* packet flags */ 00082 #define DSI_PACKET_RELEASE_CALLBACK 0x0001 /* send notify message if packet 00083 * release by receiver */ 00084 #define DSI_PACKET_MAP 0x0002 /* explicitly map packet data */ 00085 #define DSI_PACKET_COPY 0x0004 /* copy packet data */ 00086 00087 /* internal flags */ 00088 #define DSI_PACKET_TX_WAITING 0x8000 /* sender is waiting for packet */ 00089 #define DSI_PACKET_TX_PENDING 0x4000 /* sender wakeup notification 00090 * pending for this packet */ 00091 #define DSI_PACKET_RX_WAITING 0x2000 /* receiver is waiting for 00092 * packet */ 00093 #define DSI_PACKET_RX_PENDING 0x1000 /* receiver wakeup notification is 00094 * pending for this packet */ 00095 00096 #define DSI_PACKETS_USER_MASK 0x0FFF /* flags defined by user */ 00097 00098 /***************************************************************************** 00099 * sgatter gather element 00100 *****************************************************************************/ 00101 00102 /*!\brief scatter gather element 00103 * \ingroup component 00104 */ 00105 typedef struct dsi_sg_elem 00106 { 00107 l4_addr_t addr; /*!< data area start address, it is relative to the 00108 start address of the data dataspace */ 00109 l4_size_t size; //!< data area size 00110 l4_uint32_t flags; //!< data area flags 00111 00112 l4_uint32_t next; //!< index of next element, DSI_SG_ELEM_LAST end 00113 } dsi_sg_elem_t; 00114 00115 /* scatter gather list flags */ 00116 #define DSI_SG_ELEM_UNUSED 0x00000000 /* internal, sg element unused */ 00117 #define DSI_SG_ELEM_USED 0x80000000 /* internal, sg element used */ 00118 #define DSI_SG_ELEM_USER_MASK 0x0FFFFFFF /* flags defined by user */ 00119 00120 #define DSI_DATA_AREA_GAP 0x00000001 /* empty data area, it describes a 00121 * gap in the data stream */ 00122 #define DSI_DATA_AREA_MAP 0x00000002 /* map data area before usage */ 00123 #define DSI_DATA_AREA_EOS 0x00000004 /* empty data area, the area marks 00124 * the end of the stream */ 00125 #define DSI_DATA_AREA_PHYS 0x00000008 /* chunk contains physical address */ 00126 00127 #define DSI_SG_ELEM_LAST 0xFFFFFFFF 00128 00129 /***************************************************************************** 00130 * socket 00131 *****************************************************************************/ 00132 00133 /** 00134 * \brief control area header 00135 * \ingroup component 00136 */ 00137 typedef struct dsi_ctrl_header 00138 { 00139 /* control area config */ 00140 l4_uint32_t num_packets; ///< number of packets 00141 l4_uint32_t num_sg_elems; ///< number of scatter/gather list elements 00142 l4_uint32_t max_sg_len; ///< maximum length of sg-list 00143 l4_uint32_t packets_committed; /**< number of packets commited by the 00144 ** sender and not yet released (i.e. 00145 ** commited) by the receiver, 00146 ** => 'fill level' of the packet list 00147 **/ 00148 } dsi_ctrl_header_t; 00149 00150 /*!\brief socket id 00151 * \ingroup app 00152 * 00153 * It is used as a global reference to a socket e.g. in 00154 * synchronisation messages between sender and receiver component 00155 */ 00156 typedef l4_int32_t dsi_socketid_t; 00157 00158 /*!\brief socket reference 00159 * \ingroup app 00160 * 00161 * It is given to the application by the component to 00162 * describe a socket 00163 */ 00164 typedef struct dsi_socket_ref 00165 { 00166 /* socket descriptor */ 00167 dsi_socketid_t socket; //!< reference to socket 00168 00169 /* thread ids */ 00170 l4_threadid_t work_th; //!< work thread 00171 l4_threadid_t sync_th; //!< synchronisation thread 00172 l4_threadid_t event_th; ///< event signalling thread 00173 } dsi_socket_ref_t; 00174 00175 /*!\brief socket type 00176 * \ingroup component 00177 */ 00178 typedef struct dsi_socket dsi_socket_t; 00179 00180 /*!\brief prototype for synchronization callback function 00181 * \ingroup component 00182 */ 00183 typedef void(* dsi_sync_callback_fn_t) (dsi_socket_t * socket, 00184 l4_uint32_t packet_no, 00185 l4_uint32_t flags); 00186 00187 /* flags */ 00188 #define DSI_SYNC_NO_SEND_PACKET 0x00000001 00189 #define DSI_SYNC_NO_RECEIVE_PACKET 0x00000002 00190 00191 /*!\brief prototype for release packet callback function 00192 * 00193 * \ingroup component 00194 */ 00195 typedef void(* dsi_release_callback_fn_t) (dsi_socket_t * socket, 00196 dsi_packet_t * packet); 00197 00198 /** 00199 * Event handling 00200 * max. number of events, events are specified as a bit field, we need 00201 * 2 bits in the IPC to the components signalling thread to encode 00202 * the command, therefore we have 30 bits left to specify the event mask 00203 */ 00204 #define DSI_MAX_EVENTS 30 00205 00206 /** 00207 * Event client descriptor 00208 */ 00209 typedef struct dsi_event_client 00210 { 00211 l4_threadid_t id; ///< L4 thread id of client 00212 l4_uint32_t events; ///< event mask 00213 struct dsi_event_client * next; ///< client list 00214 } dsi_event_client_t; 00215 00216 /*!\brief socket descriptor 00217 * \ingroup component 00218 * 00219 * It is the component-local socket reference. 00220 * 00221 */ 00222 struct dsi_socket 00223 { 00224 dsi_ctrl_header_t * header; //!< header 00225 dsi_packet_t * packets; //!< packet array 00226 dsi_sg_elem_t * sg_lists; //!< sg elem array 00227 00228 volatile l4_uint32_t flags; //!< flags 00229 00230 void * data_area; //!< start address of data area 00231 l4_size_t data_size; //!< size of data area 00232 l4_size_t data_map_size; ///< size of data map area (log2) 00233 00234 l4dm_dataspace_t data_ds; //!< dataspace for data 00235 l4dm_dataspace_t ctrl_ds; //!< control dataspace 00236 00237 /* callbacks and abort helpers */ 00238 dsi_sync_callback_fn_t sync_callback; //!< sync event callback 00239 dsi_release_callback_fn_t release_callback; //!< release notification callback 00240 00241 /* thread ids */ 00242 l4_threadid_t work_th; //!< thread id work thread 00243 l4_threadid_t sync_th; //!< synchronisation thread 00244 l4thread_t sync_id; ///< sync thread (thread lib id) 00245 00246 dsi_socketid_t socket_id; //!< my socket id 00247 00248 dsi_socket_ref_t remote_socket; //!< remote socket reference 00249 00250 l4_uint32_t num_sg_elems; //!< number of sg_elems in array 00251 l4_uint32_t num_packets; //!< number of packets in array 00252 00253 /* internal counter */ 00254 l4_uint32_t packet_count; //!< packet counter 00255 l4_uint32_t next_packet; /*!< index of next 00256 send/receive packet */ 00257 l4_uint32_t next_sg_elem; /*!< index of next scatter 00258 gather list element (used 00259 in dsi_packet_add_data() 00260 to find next empty 00261 element) */ 00262 void * next_buf; /**< next receive buffer if 00263 ** copy packet data */ 00264 00265 void * priv; //!< to be used by upper layers 00266 00267 /* events */ 00268 l4_uint32_t events[DSI_MAX_EVENTS]; ///< event counter 00269 l4_uint32_t waiting; /**< bit field indicating for 00270 ** which event a client is 00271 ** waiting */ 00272 dsi_event_client_t * clients; ///< client wait queue 00273 00274 l4_thread_jmp_buf packet_get_abort_env;/*!< used when aborting a 00275 dsi_packet_get() */ 00276 00277 }; 00278 00279 /* socket flags */ 00280 #define DSI_SOCKET_USED 0x00000000 /* internal */ 00281 #define DSI_SOCKET_UNUSED 0x80000000 /* internal */ 00282 00283 #define DSI_SOCKET_FREE_SYNC 0x40000000 /* internal, shutdown sync 00284 * thread on close */ 00285 #define DSI_SOCKET_FREE_CTRL 0x20000000 /* internal, release control 00286 * dataspace on close */ 00287 #define DSI_SOCKET_FREE_DATA 0x10000000 /* internal, release data 00288 * dataspace on close */ 00289 00290 #define DSI_SOCKET_SEND 0x01000000 /* send socket */ 00291 #define DSI_SOCKET_RECEIVE 0x02000000 /* receive socket */ 00292 00293 #define DSI_SOCKET_BLOCKING_IN_GET 0x00010000 /* currently blocking in 00294 packet_get() */ 00295 #define DSI_SOCKET_BLOCK_ABORT 0x00020000 /* Aborting from packet_get() 00296 requested */ 00297 00298 #define DSI_SOCKET_BLOCK 0x00000001 /* block if no packet descriptor 00299 * is available, wait for 00300 * partner to commit packet. 00301 * Specify either NONBLOCK or 00302 * BLOCK. */ 00303 #define DSI_SOCKET_SYNC_CALLBACK 0x00000002 /* call callback function if 00304 * synchronization occurred 00305 * (but only if blocked) */ 00306 #define DSI_SOCKET_RELEASE_CALLBACK 0x00000004 /* notify sender about packet 00307 * release by receiver */ 00308 #define DSI_SOCKET_MAP 0x00000010 /* map packet data */ 00309 #define DSI_SOCKET_COPY 0x00000020 /* copy packet data */ 00310 00311 #define DSI_SOCKET_USER_FLAGS 0x0000FFFF /* flags which can be set at 00312 * runtime */ 00313 00314 /***************************************************************************** 00315 * application types * 00316 *****************************************************************************/ 00317 00318 /*!\brief component descriptor 00319 * \ingroup app 00320 */ 00321 typedef struct dsi_component 00322 { 00323 dsi_socket_ref_t socketref; //!< socket reference 00324 00325 /* component interface functions to connect/start/stop/close sockets */ 00326 void *priv; /*!< Service pointer for component functions. 00327 Can be set by component creator as a 00328 hint for the connect, start, stop 00329 and close callbacks */ 00330 int(*connect)(struct dsi_component*, dsi_socket_ref_t * remote); 00331 //!< interface function for connect action 00332 int(*start)(struct dsi_component*); 00333 //!< interface function for start action 00334 int(*stop)(struct dsi_component*); 00335 //!< interface function for stop action 00336 int(*close)(struct dsi_component*); 00337 //!< interface function for close action 00338 } dsi_component_t; 00339 00340 /*!\brief application stream descriptor 00341 * \ingroup app 00342 * 00343 * Used by in-the-middle-applications to store send- and 00344 * receive-components. Used by dsi_stream_create(), dsi_stream_start(), 00345 * dsi_stream_stop() and dsi_stream_close(). 00346 * 00347 */ 00348 typedef struct dsi_stream 00349 { 00350 /* send/receive component */ 00351 dsi_component_t sender; //!< send component 00352 dsi_component_t receiver; //!< receive component 00353 00354 /* data/control dataspaces */ 00355 l4dm_dataspace_t data; //!< data dataspace 00356 l4dm_dataspace_t ctrl; //!< ctrl dataspace 00357 00358 l4_uint32_t flags; //!< stream flags 00359 00360 void * __private; //!< private data 00361 } dsi_stream_t; 00362 00363 /* stream flags */ 00364 #define DSI_STREAM_USED 0x00000000 /* internal */ 00365 #define DSI_STREAM_UNUSED 0x80000000 /* internal */ 00366 00367 /* component flags */ 00368 #define DSI_SEND_COMPONENT 0x00000001 ///< operation on sender 00369 #define DSI_RECEIVE_COMPONENT 0x00000002 ///< operation on receiver 00370 00371 /** 00372 * dsi_event_select socket list 00373 */ 00374 typedef struct dsi_select_socket 00375 { 00376 dsi_stream_t * stream; ///< stream descriptor 00377 l4_uint32_t component; /**< component (either \c DSI_SEND_COMPONENT 00378 * or \c DSI_RECEIVE_COMPONENT) */ 00379 l4_uint32_t events; ///< event mask 00380 } dsi_select_socket_t; 00381 00382 /* some predefined events */ 00383 #define DSI_EVENT_EOS 0x00000001 ///< end of stream 00384 #define DSI_EVENT_DROPPED 0x00000002 ///< dropped packet 00385 #define DSI_EVENT_ERROR 0x00000004 ///< error in component 00386 00387 #endif /* !_DSI_TYPES_H */