rpmsg_rpc_internal.h 15.4 KB
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
/*
 * Remote Processor Procedure Call Driver
 *
 * Copyright (C) 2012-2016 Texas Instruments Incorporated - http://www.ti.com/
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 * * Neither the name Texas Instruments nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _RPMSG_RPC_INTERNAL_H_
#define _RPMSG_RPC_INTERNAL_H_

#include <linux/cdev.h>
#include <linux/idr.h>
#include <linux/wait.h>
#include <linux/fs.h>
#include <linux/skbuff.h>
#include <linux/rpmsg.h>

typedef u32 virt_addr_t;
typedef u32 dev_addr_t;

/**
 * struct rppc_device - The per-device (server) data
 * @cdev: character device
 * @dev: device
 * @rpdev: rpmsg channel device associated with the remote server
 * @instances: list of currently opened/connected instances
 * @lock: mutex for protection of device variables
 * @comp: completion signal used for unblocking users during a
 *	  remote processor recovery
 * @sig_attr: array of device attributes to use with the publishing of
 *	      function information in sysfs for all the functions
 *	      associated with this remote server device.
 * @signatures: function signatures for the functions published by this
 *		remote server device
 * @minor: minor number for the character device
 * @num_funcs: number of functions published by this remote server device
 * @cur_func: counter used while querying information for each function
 *	      associated with this remote server device
 * @desc: description of the exposed service
 *
 * A rppc_device indicates the base remote server device that supports the
 * execution of a bunch of remote functions. Each such remote server device
 * has an associated character device that is used by the userland apps to
 * connect to it, and request the execution of any of these remote functions.
 */
struct rppc_device {
	struct cdev cdev;
	struct device *dev;
	struct rpmsg_channel *rpdev;
	struct list_head instances;
	struct mutex lock; /* device state variables lock */
	struct completion comp;
	struct device_attribute *sig_attr;
	struct rppc_func_signature *signatures;
	unsigned int minor;
	u32 num_funcs;
	u32 cur_func;
	char desc[RPMSG_NAME_SIZE];
};

/**
 * struct rppc_instance - The per-instance data structure (per user)
 * @list: list node
 * @rppcdev: the rppc device (remote server instance) handle
 * @dev: local device reference pointer of the rppc device
 * @queue: queue of buffers waiting to be read by the user
 * @lock: mutex for protecting instance variables
 * @readq: wait queue of blocked user threads waiting to read data
 * @reply_arrived: signal for unblocking the user thread
 * @ept: rpmsg endpoint associated with the rppc device
 * @in_transition: flag for storing a pending connection request
 * @dst: destination end-point of the remote server instance
 * @state: state of the opened instance, see enum rppc_state
 * @dma_idr: idr structure storing the imported buffers
 * @msg_id: last/current active message id tagged on a message sent
 *	    to the remote processor
 * @fxn_list: list of functions published by the remote server instance
 *
 * This structure is created whenever the user opens the driver. The
 * various elements of the structure are used to store its state and
 * information about the remote server it is connected to.
 */
struct rppc_instance {
	struct list_head list;
	struct rppc_device *rppcdev;
	struct device *dev;
	struct sk_buff_head queue;
	struct mutex lock; /* instance state variables lock */
	wait_queue_head_t readq;
	struct completion reply_arrived;
	struct rpmsg_endpoint *ept;
	int in_transition;
	u32 dst;
	int state;
	struct idr dma_idr;
	u16 msg_id;
	struct list_head fxn_list;
};

/**
 * struct rppc_function_list - outstanding function descriptor
 * @list: list node
 * @function: current remote function descriptor
 * @msg_id: message id for the function invocation
 *
 * This structure is used for storing the information about outstanding
 * functions that the remote side is executing. This provides the host
 * side a means to track every outstanding function, and a means to process
 * the responses received from the remote processor.
 */
struct rppc_function_list {
	struct list_head list;
	struct rppc_function *function;
	u16 msg_id;
};

/**
 * struct rppc_dma_buf - a rppc dma_buf descriptor for buffers imported by rppc
 * @fd: file descriptor of a buffer used to import the dma_buf
 * @id: idr index value for this descriptor
 * @buf: imported dma_buf handle for the buffer
 * @attach: attachment structure returned by exporter upon attaching to
 *	    the buffer by the rppc driver
 * @sgt: the scatter-gather structure associated with @buf
 * @pa: the physical address associated with the imported buffer
 * @autoreg: mode of how the descriptor is created
 *
 * This structure is used for storing the information relevant to the imported
 * buffer. The rpmsg rpc driver acts as a proxy on behalf of the remote core
 * and attaches itself to the driver while the remote processor/accelerators are
 * operating on the buffer.
 */
struct rppc_dma_buf {
	int fd;
	int id;
	struct dma_buf *buf;
	struct dma_buf_attachment *attach;
	struct sg_table *sgt;
	phys_addr_t pa;
	int autoreg;
};

/**
 * enum rppc_msg_type - message types exchanged between host and remote server
 * @RPPC_MSGTYPE_DEVINFO_REQ: request remote server for channel information
 * @RPPC_MSGTYPE_DEVINFO_RESP: response message from remote server for a
 *			       request of type RPPC_MSGTYPE_DEVINFO_REQ
 * @RPPC_MSGTYPE_FUNCTION_QUERY: request remote server for information about a
 *				 specific function
 * @RPPC_MSGTYPE_FUNCTION_INFO: response message from remote server for a prior
 *				request of type RPPC_MSGTYPE_FUNCTION_QUERY
 * @RPPC_MSGTYPE_CREATE_REQ: request the remote server manager to create a new
 *			     remote server instance. No secondary data is
 *			     needed
 * @RPPC_MSGTYPE_CREATE_RESP: response message from remote server manager for a
 *			      request of type RPPC_MSGTYPE_CREATE_REQ. The
 *			      message contains the new endpoint address in the
 *			      rppc_instance_handle
 * @RPPC_MSGTYPE_DELETE_REQ: request the remote server manager to delete a
 *			     remote server instance
 * @RPPC_MSGTYPE_DELETE_RESP: response message from remote server manager to a
 *			      request of type RPPC_MSGTYPE_DELETE_REQ. The
 *			      message contains the old endpoint address in the
 *			      rppc_instance_handle
 * @RPPC_MSGTYPE_FUNCTION_CALL: request remote server to execute a specific
 *				function
 * @RPPC_MSGTYPE_FUNCTION_RET: response message carrying the return status of a
 *			       specific function execution
 * @RPPC_MSGTYPE_ERROR: an error response message sent by either the remote
 *			server manager or remote server instance while
 *			processing any request messages
 * @RPPC_MSGTYPE_MAX: limit value to define the maximum message type value
 *
 * Every message exchanged between the host-side and the remote-side is
 * identified through a message type defined in this enum. The message type
 * is specified through the msg_type field of the struct rppc_msg_header,
 * which is the common header for rppc messages.
 */
enum rppc_msg_type {
	RPPC_MSGTYPE_DEVINFO_REQ	= 0,
	RPPC_MSGTYPE_DEVINFO_RESP	= 1,
	RPPC_MSGTYPE_FUNCTION_QUERY	= 2,
	RPPC_MSGTYPE_FUNCTION_INFO	= 3,
	RPPC_MSGTYPE_CREATE_REQ		= 6,
	RPPC_MSGTYPE_CREATE_RESP	= 8,
	RPPC_MSGTYPE_DELETE_REQ		= 4,
	RPPC_MSGTYPE_DELETE_RESP	= 7,
	RPPC_MSGTYPE_FUNCTION_CALL	= 5,
	RPPC_MSGTYPE_FUNCTION_RET	= 9,
	RPPC_MSGTYPE_ERROR = 10,
	RPPC_MSGTYPE_MAX
};

/**
 * enum rppc_infotype - function information query type
 * @RPPC_INFOTYPE_FUNC_SIGNATURE: function signature
 * @RPPC_INFOTYPE_NUM_CALLS: the number of times a function has been invoked
 * @RPPC_INFOTYPE_MAX: limit value to define the maximum info type
 *
 * This enum is used for identifying the type of information queried
 * from the remote processor. Only RPPC_INFOTYPE_FUNC_SIGNATURE is
 * currently used.
 */
enum rppc_infotype {
	RPPC_INFOTYPE_FUNC_SIGNATURE = 1,
	RPPC_INFOTYPE_NUM_CALLS,
	RPPC_INFOTYPE_MAX
};

/**
 * struct rppc_instance_handle - rppc instance information
 * @endpoint_address: end-point address of the remote server instance
 * @status: status of the request
 *
 * This structure indicates the format of the message payload exchanged
 * between the host and the remote sides for messages pertaining to
 * creation and deletion of the remote server instances. This payload
 * is associated with messages of type RPPC_MSGTYPE_CREATE_RESP and
 * RPPC_MSGTYPE_DELETE_RESP.
 */
struct rppc_instance_handle {
	u32 endpoint_address;
	u32 status;
} __packed;

/**
 * struct rppc_param_signature - parameter descriptor
 * @direction: input or output classifier, see enum rppc_param_direction
 * @type: parameter data type, see enum rppc_param_type
 * @count: used to do some basic sanity checking on array bounds
 */
struct rppc_param_signature {
	u32 direction;
	u32 type;
	u32 count;
};

/**
 * struct rppc_func_signature - remote function signature descriptor
 * @name: name of the function
 * @num_param: number of parameters to the function
 * @params: parameter descriptors for each of the parameters
 *
 * This structure contains the indicates the format of the message payload
 * exchanged between the host and the remote sides for messages pertaining
 * to creation and deletion of the remote server instances. This payload
 * is associated with messages of type RPPC_MSGTYPE_CREATE_RESP and
 * RPPC_MSGTYPE_FUNCTION_INFO.
 */
struct rppc_func_signature {
	char name[RPPC_MAX_CHANNEL_NAMELEN];
	u32 num_param;
	struct rppc_param_signature params[RPPC_MAX_NUM_PARAMS + 1];
};

/**
 * struct rppc_query_function - function info packet structure
 * @info_type: type of the function information requested, see
 *	       enum rppc_infotype
 * @fxn_id: function identifier on this specific remote server instance
 * @num_calls: number of types function is invoked, filled in during a response
 *	       (only valid for rppc_infotype RPPC_INFOTYPE_NUM_CALLS)
 * @signature: the signature of the function including its return type,
 *	       parameters and their description
 *	       (only valid for rppc_infotype RPPC_INFOTYPE_FUNC_SIGNATURE)
 *
 * This structure indicates the format of the message payload exchanged
 * between the host and the remote sides for messages pertaining to
 * information about each function supported by the remote server instance.
 * This payload is associated with messages of type RPPC_MSGTYPE_FUNCTION_QUERY
 * and RPPC_MSGTYPE_FUNCTION_INFO.
 */
struct rppc_query_function {
	u32 info_type;
	u32 fxn_id;
	union {
		u32 num_calls;
		struct rppc_func_signature signature;
	} info;
};

/**
 * enum rppc_translate_direction - pointer translation direction
 * @RPPC_UVA_TO_RPA: user virtual address to remote device address translation
 * @RPPC_RPA_TO_UVA: remote device address to user virtual address translation
 *
 * An enum used for identifying the rppc function message direction, whether
 * it is going to the remote side, or is a response from the remote side. This
 * is used in translating the pointers from the host-side to the remote-side
 * and vice versa depending on the packet direction.
 */
enum rppc_translate_direction {
	RPPC_UVA_TO_RPA,
	RPPC_RPA_TO_UVA,
};

/**
 * enum rppc_state - rppc instance state
 * @RPPC_STATE_DISCONNECTED: uninitialized state
 * @RPPC_STATE_CONNECTED: initialized state
 * @RPPC_STATE_STALE: invalid or stale state
 * @RPPC_STATE_MAX: limit value for the different state values
 *
 * This enum value is used to define the status values of a
 * rppc_instance object.
 */
enum rppc_state {
	RPPC_STATE_DISCONNECTED,
	RPPC_STATE_CONNECTED,
	RPPC_STATE_STALE,
	RPPC_STATE_MAX
};

/**
 * struct rppc_device_info - rppc remote server device info
 * @num_funcs: number of functions supported by a remote server instance
 *
 * This structure indicates the format of the message payload responded by
 * the remote side upon a request for message type RPPC_MSGTYPE_DEVINFO_REQ.
 * This payload is associated with messages of type RPPC_MSGTYPE_DEVINFO_RESP.
 */
struct rppc_device_info {
	u32 num_funcs;
};

/**
 * struct rppc_error - rppc error information
 * @endpoint_address: end-point address of the remote server instance
 * @status: status of the request
 *
 * This structure indicates the format of the message payload exchanged
 * between the host and the remote sides for error messages. This payload
 * is associated with messages of type RPPC_MSGTYPE_ERROR
 * XXX: check if this is needed still, not used anywhere at present
 */
struct rppc_error {
	u32 endpoint_address;
	u32 status;
} __packed;

/**
 * struct rppc_param_data - marshalled parameter data structure
 * @size: size of the parameter data type
 * @data: actual parameter data
 *
 * Each function parameter is marshalled in this form between the host
 * and remote sides. The @data field would contain the actual value of
 * of the parameter if it is a scalar argument type, or the remote-side
 * device address (virtual address) of the pointer if the argument is
 * of pointer type.
 */
struct rppc_param_data {
	size_t size;
	size_t data;
} __packed;

/**
 * struct rppc_msg_header - generic rpmsg rpc message header
 * @msg_type: message type, see enum rppc_msg_type
 * @msg_len: length of the message payload in bytes
 * @msg_data: the actual message payload (depends on message type)
 *
 * All RPPC messages will start with this common header (which will begin
 * right after the standard rpmsg header ends).
 */
struct rppc_msg_header {
	u32 msg_type;
	u32 msg_len;
	u8  msg_data[0];
} __packed;

#define RPPC_PAYLOAD(ptr, type)	\
		((struct type *)&(ptr)[sizeof(struct rppc_msg_header)])

/* from rpmsg_rpc.c */
dev_addr_t rppc_local_to_remote_da(struct rppc_instance *rpc, phys_addr_t pa);

/* from rpmsg_rpc_dmabuf.c */
struct rppc_dma_buf *rppc_alloc_dmabuf(struct rppc_instance *rpc,
				       int fd, bool autoreg);
struct rppc_dma_buf *rppc_find_dmabuf(struct rppc_instance *rpc, int fd);
int rppc_free_dmabuf(int id, void *p, void *data);
dev_addr_t rppc_buffer_lookup(struct rppc_instance *rpc, virt_addr_t uva,
			      virt_addr_t buva, int fd);
int rppc_xlate_buffers(struct rppc_instance *rpc, struct rppc_function *func,
		       int direction);

/* from rpmsg_rpc_sysfs.c */
int rppc_create_sysfs(struct rppc_device *rppcdev);
int rppc_remove_sysfs(struct rppc_device *rppcdev);

#endif