diff options
-rw-r--r-- | packages/ipcdev/ti/ipc/mm/MmRpc.c | 424 | ||||
-rw-r--r-- | packages/ipcdev/ti/ipc/mm/MmRpc.h | 331 | ||||
-rw-r--r-- | packages/kernel-headers/uapi/linux/rpmsg_rpc.h | 183 |
3 files changed, 938 insertions, 0 deletions
diff --git a/packages/ipcdev/ti/ipc/mm/MmRpc.c b/packages/ipcdev/ti/ipc/mm/MmRpc.c new file mode 100644 index 0000000..223262f --- /dev/null +++ b/packages/ipcdev/ti/ipc/mm/MmRpc.c | |||
@@ -0,0 +1,424 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012-2015, Texas Instruments Incorporated | ||
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 | ||
7 | * are met: | ||
8 | * | ||
9 | * * Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * * Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * | ||
16 | * * Neither the name of Texas Instruments Incorporated nor the names of | ||
17 | * its contributors may be used to endorse or promote products derived | ||
18 | * from this software without specific prior written permission. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
22 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||
27 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||
30 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | */ | ||
32 | |||
33 | /* | ||
34 | * ======== MmRpc.c ======== | ||
35 | */ | ||
36 | |||
37 | #include <stdio.h> | ||
38 | #include <stdlib.h> | ||
39 | #include <sys/types.h> | ||
40 | #include <sys/stat.h> | ||
41 | #include <sys/ioctl.h> | ||
42 | #include <fcntl.h> | ||
43 | #include <unistd.h> | ||
44 | #include <string.h> | ||
45 | |||
46 | #include <stdint.h> /* should be in linux/rpmsg_rpc.h */ | ||
47 | #include <stddef.h> /* should be in linux/rpmsg_rpc.h */ | ||
48 | |||
49 | |||
50 | |||
51 | #if defined(KERNEL_INSTALL_DIR) | ||
52 | |||
53 | #ifdef linux | ||
54 | #define _linux_ linux | ||
55 | #undef linux | ||
56 | #endif | ||
57 | |||
58 | #define linux_version_include(kd) <kd/include/generated/uapi/linux/version.h> | ||
59 | #include linux_version_include(KERNEL_INSTALL_DIR) | ||
60 | |||
61 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) | ||
62 | #define linux_include(kd,m) <kd/include/linux/m.h> | ||
63 | #else | ||
64 | #define linux_include(kd,m) <kd/include/uapi/linux/m.h> | ||
65 | #endif | ||
66 | |||
67 | #include linux_include(KERNEL_INSTALL_DIR,rpmsg_rpc) | ||
68 | |||
69 | #ifdef _linux_ | ||
70 | #define linux _linux | ||
71 | #undef _linux_ | ||
72 | #endif | ||
73 | |||
74 | #elif defined(IPC_BUILDOS_QNX) | ||
75 | |||
76 | #include <ti/ipc/rpmsg_rpc.h> | ||
77 | |||
78 | #elif defined(BUILDOS_ANDROID) | ||
79 | #include <uapi/linux/rpmsg_rpc.h> | ||
80 | |||
81 | #else | ||
82 | #error Unsupported Operating System | ||
83 | #endif | ||
84 | |||
85 | #include "MmRpc.h" | ||
86 | |||
87 | #if defined(KERNEL_INSTALL_DIR) || defined(BUILDOS_ANDROID) | ||
88 | static int MmRpc_bufHandle(MmRpc_Handle handle, int cmd, int num, | ||
89 | MmRpc_BufDesc *desc); | ||
90 | #endif | ||
91 | |||
92 | |||
93 | /* | ||
94 | * ======== MmRpc_Object ======== | ||
95 | */ | ||
96 | typedef struct { | ||
97 | int fd; /* device file descriptor */ | ||
98 | struct rppc_create_instance connect; /* connection object */ | ||
99 | } MmRpc_Object; | ||
100 | |||
101 | /* | ||
102 | * ======== MmRpc_Params_init ======== | ||
103 | */ | ||
104 | void MmRpc_Params_init(MmRpc_Params *params) | ||
105 | { | ||
106 | params->reserved = 0; | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * ======== MmRpc_create ======== | ||
111 | */ | ||
112 | int MmRpc_create(const char *service, const MmRpc_Params *params, | ||
113 | MmRpc_Handle *handlePtr) | ||
114 | { | ||
115 | int status = MmRpc_S_SUCCESS; | ||
116 | MmRpc_Object * obj = NULL; | ||
117 | char cbuf[RPPC_MAX_INST_NAMELEN+16]; | ||
118 | (void)params; | ||
119 | |||
120 | if (service == NULL || handlePtr == NULL) { | ||
121 | status = MmRpc_E_INVALIDPARAM; | ||
122 | goto leave; | ||
123 | } | ||
124 | |||
125 | /* allocate the instance object */ | ||
126 | obj = (MmRpc_Object *)calloc(1, sizeof(MmRpc_Object)); | ||
127 | |||
128 | if (obj == NULL) { | ||
129 | status = MmRpc_E_FAIL; | ||
130 | goto leave; | ||
131 | } | ||
132 | |||
133 | /* open the driver */ | ||
134 | sprintf(cbuf, "/dev/%s", service); | ||
135 | obj->fd = open(cbuf, O_RDWR); | ||
136 | |||
137 | if (obj->fd < 0) { | ||
138 | printf("MmRpc_create: Error: open failed, name=%s\n", cbuf); | ||
139 | status = MmRpc_E_FAIL; | ||
140 | goto leave; | ||
141 | } | ||
142 | |||
143 | strncpy(obj->connect.name, service, (RPPC_MAX_INST_NAMELEN - 1)); | ||
144 | obj->connect.name[RPPC_MAX_INST_NAMELEN - 1] = '\0'; | ||
145 | |||
146 | /* create a server instance, rebind its address to this file descriptor */ | ||
147 | status = ioctl(obj->fd, RPPC_IOC_CREATE, &obj->connect); | ||
148 | |||
149 | if (status < 0) { | ||
150 | printf("MmRpc_create: Error: connect failed\n"); | ||
151 | status = MmRpc_E_FAIL; | ||
152 | goto leave; | ||
153 | } | ||
154 | |||
155 | leave: | ||
156 | if (status < 0) { | ||
157 | if ((obj != NULL) && (obj->fd >= 0)) { | ||
158 | close(obj->fd); | ||
159 | } | ||
160 | if (obj != NULL) { | ||
161 | free(obj); | ||
162 | } | ||
163 | if (handlePtr) { | ||
164 | *handlePtr = NULL; | ||
165 | } | ||
166 | } | ||
167 | else { | ||
168 | *handlePtr = (MmRpc_Handle)obj; | ||
169 | } | ||
170 | |||
171 | return(status); | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * ======== MmRpc_delete ======== | ||
176 | */ | ||
177 | int MmRpc_delete(MmRpc_Handle *handlePtr) | ||
178 | { | ||
179 | int status = MmRpc_S_SUCCESS; | ||
180 | MmRpc_Object *obj; | ||
181 | |||
182 | if (handlePtr == NULL) { | ||
183 | return MmRpc_E_INVALIDPARAM; | ||
184 | } | ||
185 | |||
186 | obj = (MmRpc_Object *)(*handlePtr); | ||
187 | |||
188 | /* close the device */ | ||
189 | if ((obj != NULL) && (obj->fd >= 0)) { | ||
190 | close(obj->fd); | ||
191 | } | ||
192 | |||
193 | /* free the instance object */ | ||
194 | free((void *)(*handlePtr)); | ||
195 | *handlePtr = NULL; | ||
196 | |||
197 | return(status); | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * ======== MmRpc_call ======== | ||
202 | */ | ||
203 | int MmRpc_call(MmRpc_Handle handle, MmRpc_FxnCtx *ctx, int32_t *ret) | ||
204 | { | ||
205 | int status = MmRpc_S_SUCCESS; | ||
206 | MmRpc_Object *obj = (MmRpc_Object *)handle; | ||
207 | struct rppc_function *rpfxn; | ||
208 | struct rppc_function_return reply_msg; | ||
209 | MmRpc_Param *param; | ||
210 | void *msg = NULL; | ||
211 | int len; | ||
212 | unsigned int i; | ||
213 | |||
214 | if (handle == NULL || ctx == NULL || ret == NULL) { | ||
215 | status = MmRpc_E_INVALIDPARAM; | ||
216 | goto leave; | ||
217 | } | ||
218 | |||
219 | /* combine params and translation array into one contiguous message */ | ||
220 | len = sizeof(struct rppc_function) + | ||
221 | (ctx->num_xlts * sizeof(struct rppc_param_translation)); | ||
222 | msg = (void *)calloc(len, sizeof(char)); | ||
223 | |||
224 | if (msg == NULL) { | ||
225 | printf("MmRpc_call: Error: msg alloc failed\n"); | ||
226 | status = MmRpc_E_FAIL; | ||
227 | goto leave; | ||
228 | } | ||
229 | |||
230 | /* copy function parameters into message */ | ||
231 | rpfxn = (struct rppc_function *)msg; | ||
232 | rpfxn->fxn_id = ctx->fxn_id; | ||
233 | rpfxn->num_params = ctx->num_params; | ||
234 | |||
235 | for (i = 0; i < ctx->num_params; i++) { | ||
236 | param = &ctx->params[i]; | ||
237 | |||
238 | switch (param->type) { | ||
239 | case MmRpc_ParamType_Scalar: | ||
240 | rpfxn->params[i].type = RPPC_PARAM_TYPE_ATOMIC; | ||
241 | rpfxn->params[i].size = param->param.scalar.size; | ||
242 | rpfxn->params[i].data = param->param.scalar.data; | ||
243 | rpfxn->params[i].base = 0; | ||
244 | rpfxn->params[i].fd = 0; | ||
245 | break; | ||
246 | |||
247 | case MmRpc_ParamType_Ptr: | ||
248 | rpfxn->params[i].type = RPPC_PARAM_TYPE_PTR; | ||
249 | rpfxn->params[i].size = param->param.ptr.size; | ||
250 | rpfxn->params[i].data = param->param.ptr.addr; | ||
251 | rpfxn->params[i].base = param->param.ptr.addr; | ||
252 | rpfxn->params[i].fd = param->param.ptr.handle; | ||
253 | break; | ||
254 | |||
255 | case MmRpc_ParamType_OffPtr: | ||
256 | rpfxn->params[i].type = RPPC_PARAM_TYPE_PTR; | ||
257 | rpfxn->params[i].size = param->param.offPtr.size; | ||
258 | rpfxn->params[i].data = param->param.offPtr.base + | ||
259 | param->param.offPtr.offset; | ||
260 | rpfxn->params[i].base = param->param.offPtr.base; | ||
261 | rpfxn->params[i].fd = param->param.offPtr.handle; | ||
262 | break; | ||
263 | |||
264 | default: | ||
265 | printf("MmRpc_call: Error: invalid parameter type\n"); | ||
266 | status = MmRpc_E_INVALIDPARAM; | ||
267 | goto leave; | ||
268 | break; | ||
269 | } | ||
270 | } | ||
271 | |||
272 | /* copy offset array into message */ | ||
273 | rpfxn->num_translations = ctx->num_xlts; | ||
274 | |||
275 | for (i = 0; i < ctx->num_xlts; i++) { | ||
276 | /* pack the pointer translation entry */ | ||
277 | rpfxn->translations[i].index = ctx->xltAry[i].index; | ||
278 | rpfxn->translations[i].offset = ctx->xltAry[i].offset; | ||
279 | rpfxn->translations[i].base = ctx->xltAry[i].base; | ||
280 | rpfxn->translations[i].fd = (int32_t)ctx->xltAry[i].handle; | ||
281 | } | ||
282 | |||
283 | /* send message for remote execution */ | ||
284 | status = write(obj->fd, msg, len); | ||
285 | |||
286 | if (status < 0) { | ||
287 | printf("MmRpc_call: Error: write failed\n"); | ||
288 | status = MmRpc_E_FAIL; | ||
289 | goto leave; | ||
290 | } | ||
291 | |||
292 | /* wait for return status from remote service */ | ||
293 | status = read(obj->fd, &reply_msg, sizeof(struct rppc_function_return)); | ||
294 | |||
295 | if (status < 0) { | ||
296 | printf("MmRpc_call: Error: read failed\n"); | ||
297 | status = MmRpc_E_FAIL; | ||
298 | goto leave; | ||
299 | } | ||
300 | else if (status != sizeof(struct rppc_function_return)) { | ||
301 | printf("MmRpc_call: Error: reply bytes=%d, expected %d\n", | ||
302 | status, sizeof(struct rppc_function_return)); | ||
303 | status = MmRpc_E_FAIL; | ||
304 | goto leave; | ||
305 | } | ||
306 | else { | ||
307 | status = MmRpc_S_SUCCESS; | ||
308 | } | ||
309 | |||
310 | *ret = (int32_t)reply_msg.status; | ||
311 | |||
312 | leave: | ||
313 | if (msg != NULL) { | ||
314 | free(msg); | ||
315 | } | ||
316 | |||
317 | return(status); | ||
318 | } | ||
319 | |||
320 | /* | ||
321 | * ======== MmRcp_release ======== | ||
322 | */ | ||
323 | int MmRpc_release(MmRpc_Handle handle, MmRpc_BufType type, int num, | ||
324 | MmRpc_BufDesc *desc) | ||
325 | { | ||
326 | int stat = MmRpc_S_SUCCESS; | ||
327 | |||
328 | switch (type) { | ||
329 | |||
330 | #if defined(KERNEL_INSTALL_DIR) || defined(BUILDOS_ANDROID) | ||
331 | case MmRpc_BufType_Handle: | ||
332 | stat = MmRpc_bufHandle(handle, RPPC_IOC_BUFUNREGISTER, num, desc); | ||
333 | break; | ||
334 | |||
335 | #elif defined(IPC_BUILDOS_QNX) | ||
336 | case MmRpc_BufType_Ptr: | ||
337 | break; | ||
338 | #endif | ||
339 | default: | ||
340 | printf("MmRpc_release: Error: unsupported type value: %d\n", type); | ||
341 | stat = MmRpc_E_INVALIDPARAM; | ||
342 | break; | ||
343 | } | ||
344 | |||
345 | if (stat < 0) { | ||
346 | printf("MmRpc_release: Error: unable to release buffer\n"); | ||
347 | } | ||
348 | |||
349 | return(stat); | ||
350 | } | ||
351 | |||
352 | /* | ||
353 | * ======== MmRcp_use ======== | ||
354 | */ | ||
355 | int MmRpc_use(MmRpc_Handle handle, MmRpc_BufType type, int num, | ||
356 | MmRpc_BufDesc *desc) | ||
357 | { | ||
358 | int stat = MmRpc_S_SUCCESS; | ||
359 | |||
360 | switch (type) { | ||
361 | |||
362 | #if defined(KERNEL_INSTALL_DIR) || defined(BUILDOS_ANDROID) | ||
363 | case MmRpc_BufType_Handle: | ||
364 | stat = MmRpc_bufHandle(handle, RPPC_IOC_BUFREGISTER, num, desc); | ||
365 | break; | ||
366 | |||
367 | #elif defined(IPC_BUILDOS_QNX) | ||
368 | case MmRpc_BufType_Ptr: | ||
369 | break; | ||
370 | #endif | ||
371 | default: | ||
372 | printf("MmRpc_use: Error: unsupported type value: %d\n", type); | ||
373 | stat = MmRpc_E_INVALIDPARAM; | ||
374 | break; | ||
375 | } | ||
376 | |||
377 | if (stat < 0) { | ||
378 | printf("MmRpc_use: Error: unable to declare buffer use\n"); | ||
379 | } | ||
380 | |||
381 | return(stat); | ||
382 | } | ||
383 | |||
384 | #if defined(KERNEL_INSTALL_DIR) || defined(BUILDOS_ANDROID) | ||
385 | /* | ||
386 | * ======== MmRpc_bufHandle ======== | ||
387 | */ | ||
388 | int MmRpc_bufHandle(MmRpc_Handle handle, int cmd, int num, MmRpc_BufDesc *desc) | ||
389 | { | ||
390 | int stat = MmRpc_S_SUCCESS; | ||
391 | MmRpc_Object *obj = (MmRpc_Object *)handle; | ||
392 | int i; | ||
393 | struct rppc_buf_fds reg = { num, NULL }; | ||
394 | |||
395 | if (handle == NULL || desc == NULL) { | ||
396 | stat = MmRpc_E_INVALIDPARAM; | ||
397 | goto leave; | ||
398 | } | ||
399 | |||
400 | reg.fds = (int32_t *)malloc(num * sizeof(int32_t)); | ||
401 | |||
402 | if (reg.fds == NULL) { | ||
403 | stat = MmRpc_E_NOMEM; | ||
404 | goto leave; | ||
405 | } | ||
406 | |||
407 | for (i = 0; i < num; i++) { | ||
408 | reg.fds[i] = desc[i].handle; | ||
409 | } | ||
410 | |||
411 | stat = ioctl(obj->fd, cmd, ®); | ||
412 | |||
413 | if (stat < 0) { | ||
414 | stat = MmRpc_E_SYS; | ||
415 | } | ||
416 | |||
417 | leave: | ||
418 | if (reg.fds != NULL) { | ||
419 | free(reg.fds); | ||
420 | } | ||
421 | |||
422 | return(stat); | ||
423 | } | ||
424 | #endif | ||
diff --git a/packages/ipcdev/ti/ipc/mm/MmRpc.h b/packages/ipcdev/ti/ipc/mm/MmRpc.h new file mode 100644 index 0000000..feee339 --- /dev/null +++ b/packages/ipcdev/ti/ipc/mm/MmRpc.h | |||
@@ -0,0 +1,331 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012-2014, Texas Instruments Incorporated | ||
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 | ||
7 | * are met: | ||
8 | * | ||
9 | * * Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * * Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * | ||
16 | * * Neither the name of Texas Instruments Incorporated nor the names of | ||
17 | * its contributors may be used to endorse or promote products derived | ||
18 | * from this software without specific prior written permission. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
22 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||
27 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||
30 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | */ | ||
32 | |||
33 | /** | ||
34 | * @file ti/ipc/mm/MmRpc.h | ||
35 | * | ||
36 | * @brief Multi-Media derived Remote Procedure Call | ||
37 | * | ||
38 | * @note MmRpc is currently only available for HLOS (Linux, QNX, Android). | ||
39 | */ | ||
40 | |||
41 | #ifndef ti_ipc_mm_MmRpc__include | ||
42 | #define ti_ipc_mm_MmRpc__include | ||
43 | |||
44 | /* add includes here */ | ||
45 | #include <stddef.h> | ||
46 | #include <stdint.h> | ||
47 | |||
48 | #if defined(__cplusplus) | ||
49 | extern "C" { | ||
50 | #endif | ||
51 | |||
52 | /*! | ||
53 | * @brief Operation is successful | ||
54 | */ | ||
55 | #define MmRpc_S_SUCCESS (0) | ||
56 | |||
57 | /*! | ||
58 | * @brief Operation failed | ||
59 | */ | ||
60 | #define MmRpc_E_FAIL (-1) | ||
61 | |||
62 | /*! | ||
63 | * @brief Invalid parameter type | ||
64 | */ | ||
65 | #define MmRpc_E_INVALIDPARAM (-2) | ||
66 | |||
67 | /*! | ||
68 | * @brief Memory allocation failed | ||
69 | */ | ||
70 | #define MmRpc_E_NOMEM (-3) | ||
71 | |||
72 | /*! | ||
73 | * @brief A system call failed | ||
74 | */ | ||
75 | #define MmRpc_E_SYS (-4) | ||
76 | |||
77 | /*! | ||
78 | * @brief Size of parameter array in function context structure | ||
79 | */ | ||
80 | #define MmRpc_MAX_PARAMS (10) | ||
81 | |||
82 | /*! | ||
83 | * @brief Maximum size of translation array in function context structure | ||
84 | */ | ||
85 | #define MmRpc_MAX_TRANSLATIONS (1024) | ||
86 | |||
87 | /*! | ||
88 | * @brief Macro for computing offset to a field of a structure. | ||
89 | * | ||
90 | * @code | ||
91 | * struct foobar { | ||
92 | * int a; | ||
93 | * int *p; | ||
94 | * }; | ||
95 | * | ||
96 | * struct foobar *sp = ...; | ||
97 | * offset = MmRpc_OFFSET(sp, &sp->p); | ||
98 | * struct foobar st = ...; | ||
99 | * offset = MmRpc_OFFSET(&st, &st.p); | ||
100 | * @endcode | ||
101 | */ | ||
102 | #define MmRpc_OFFSET(base, field) ((unsigned int)(field)-(unsigned int)(base)) | ||
103 | |||
104 | /*! | ||
105 | * @brief MmRpc_Handle type | ||
106 | */ | ||
107 | typedef struct MmRpc_Object *MmRpc_Handle; | ||
108 | |||
109 | /*! | ||
110 | * @brief MmRpc_ParamType enum | ||
111 | */ | ||
112 | typedef enum { | ||
113 | MmRpc_ParamType_Scalar = 1, /*!< pass by value */ | ||
114 | MmRpc_ParamType_Ptr, /*!< data pointer */ | ||
115 | MmRpc_ParamType_OffPtr, /*!< buffer at offset in memory block */ | ||
116 | MmRpc_ParamType_Elem /*!< array element */ | ||
117 | } MmRpc_ParamType; | ||
118 | |||
119 | /*! | ||
120 | * @brief MmRpc_Param type | ||
121 | */ | ||
122 | typedef struct { | ||
123 | MmRpc_ParamType type; /*!< parameter type */ | ||
124 | |||
125 | union { | ||
126 | struct { | ||
127 | size_t size; /*!< size of the data */ | ||
128 | size_t data; /*!< data (pass by value)*/ | ||
129 | } scalar; | ||
130 | |||
131 | struct { | ||
132 | size_t size; /*!< size of the data referenced */ | ||
133 | size_t addr; /*!< pointer value */ | ||
134 | size_t handle; /*!< memory allocator handle */ | ||
135 | } ptr; | ||
136 | |||
137 | struct { | ||
138 | size_t size; /*!< size (bytes) of param structure */ | ||
139 | size_t base; /*!< param address */ | ||
140 | size_t offset; /*!< offset within param */ | ||
141 | size_t handle; /*!< memory allocator handle */ | ||
142 | } offPtr; | ||
143 | |||
144 | } param; | ||
145 | } MmRpc_Param; | ||
146 | |||
147 | typedef struct { | ||
148 | uint32_t index; /*!< parameter index to base pointer */ | ||
149 | ptrdiff_t offset; /*!< offset to embedded pointer | ||
150 | * | ||
151 | * If param type is MmRpc_ParamType_Ptr, offset | ||
152 | * to embedded pointer from addr. If param type | ||
153 | * is MmRpc_ParamType_OffPtr, offset to embedded | ||
154 | * pointer from base+offset. | ||
155 | */ | ||
156 | size_t base; /*!< addr or file descriptor [+ data offset] | ||
157 | * | ||
158 | * If param type is MmRpc_ParamType_Ptr, the | ||
159 | * value of the embedded pointer. If param type | ||
160 | * is MmRpc_ParamType_OffPtr, the file descriptor | ||
161 | * of the block referenced by the embedded pointer | ||
162 | * plus an optional data offset. | ||
163 | */ | ||
164 | size_t handle; /*!< memory allocator handle */ | ||
165 | } MmRpc_Xlt; | ||
166 | |||
167 | /*! | ||
168 | * @brief Function call context structure | ||
169 | */ | ||
170 | typedef struct { | ||
171 | uint32_t fxn_id; /*!< function id to call */ | ||
172 | uint32_t num_params; /*!< number of parameters in params array */ | ||
173 | MmRpc_Param params[MmRpc_MAX_PARAMS]; | ||
174 | /*!< the array of parameters */ | ||
175 | uint32_t num_xlts; /*!< number of translations in xltAry */ | ||
176 | MmRpc_Xlt * xltAry; /*!< array of translations */ | ||
177 | } MmRpc_FxnCtx; | ||
178 | |||
179 | /*! | ||
180 | * @brief Memory buffer types | ||
181 | * | ||
182 | * @remark Not all operating systems support all buffer types. | ||
183 | */ | ||
184 | typedef enum { | ||
185 | MmRpc_BufType_Handle, /*!< memory allocator handle */ | ||
186 | MmRpc_BufType_Ptr /*!< buffer address */ | ||
187 | } MmRpc_BufType; | ||
188 | |||
189 | /*! | ||
190 | * @brief Memory buffer descriptor | ||
191 | */ | ||
192 | typedef union { | ||
193 | size_t handle; /*!< file descriptor or handle */ | ||
194 | |||
195 | struct { | ||
196 | size_t addr; /*!< address of memory buffer */ | ||
197 | size_t size; /*!< size (bytes) of memory buffer */ | ||
198 | } ptr; | ||
199 | |||
200 | } MmRpc_BufDesc; | ||
201 | |||
202 | /*! | ||
203 | * @brief Instance create parameters | ||
204 | */ | ||
205 | typedef struct { | ||
206 | int reserved; | ||
207 | } MmRpc_Params; | ||
208 | |||
209 | /*! | ||
210 | * @brief Invoke a remote procedure call | ||
211 | * | ||
212 | * @param[in] handle MmRpc handle, obtained from MmRpc_create() | ||
213 | * @param[in] ctx Context with which to invoke the remote service | ||
214 | * @param[in, out] ret Return value from the remotely invoked service | ||
215 | * | ||
216 | * @pre @c handle must be a valid handle for the service instance | ||
217 | * returned by an earlier call to MmRpc_create(). | ||
218 | * | ||
219 | * @sa MmRpc_create() | ||
220 | * @sa MmRpc_delete() | ||
221 | */ | ||
222 | int MmRpc_call(MmRpc_Handle handle, MmRpc_FxnCtx *ctx, int32_t *ret); | ||
223 | |||
224 | /*! | ||
225 | * @brief Create an MmRpc instance | ||
226 | * | ||
227 | * @param[in] service Name of the service to create | ||
228 | * @param[in] params Initialized MmRpc parameters | ||
229 | * @param[in,out] handlePtr Space to hold the MmRpc handle | ||
230 | * | ||
231 | * @retval MmRpc_S_SUCCESS @copydoc MmRpc_S_SUCCESS | ||
232 | * @retval MmRpc_E_FAIL @copydoc MmRpc_E_FAIL | ||
233 | * | ||
234 | * @remark This instantiates an instance of the service on a remote | ||
235 | * core. Each remote instance consists of a unique thread | ||
236 | * listening for requests made via a call to MmRpc_call(). | ||
237 | */ | ||
238 | int MmRpc_create(const char *service, const MmRpc_Params *params, | ||
239 | MmRpc_Handle *handlePtr); | ||
240 | |||
241 | /*! | ||
242 | * @brief Delete an MmRpc instance | ||
243 | * | ||
244 | * @param[in] handlePtr MmRpc handle, obtained from MmRpc_create() | ||
245 | * | ||
246 | * @pre @c handlePtr must be a valid handle for the service instance | ||
247 | * returned by an earlier call to MmRpc_create() | ||
248 | * | ||
249 | * @sa MmRpc_create() | ||
250 | */ | ||
251 | int MmRpc_delete(MmRpc_Handle *handlePtr); | ||
252 | |||
253 | /*! | ||
254 | * @brief Release buffers which were declared in use | ||
255 | * | ||
256 | * @param[in] handle Service handle returned by MmRpc_create() | ||
257 | * @param[in] type Buffer descriptor type | ||
258 | * @param[in] num Number of elements in @c desc array | ||
259 | * @param[in] desc Pointer to array of buffer descriptors | ||
260 | * | ||
261 | * @pre @c handle must be a valid handle for the service instance | ||
262 | * returned by an earlier call to MmRpc_create(). | ||
263 | * | ||
264 | * @remark When the remote processor no longer needs a reference | ||
265 | * to a buffer, calling MmRpc_release() will release the | ||
266 | * buffer and any associated resources. | ||
267 | * | ||
268 | * @retval MmRpc_S_SUCCESS @copydoc MmRpc_S_SUCCESS | ||
269 | * @retval MmRpc_E_INVALIDPARAM @copydoc MmRpc_E_INVALIDPARAM | ||
270 | * @retval MmRpc_E_NOMEM @copydoc MmRpc_E_NOMEM | ||
271 | * @retval MmRpc_E_SYS @copydoc MmRpc_E_SYS | ||
272 | * | ||
273 | * @sa MmRpc_use() | ||
274 | */ | ||
275 | int MmRpc_release(MmRpc_Handle handle, MmRpc_BufType type, int num, | ||
276 | MmRpc_BufDesc *desc); | ||
277 | |||
278 | /*! | ||
279 | * @brief Declare the use of the given buffers | ||
280 | * | ||
281 | * @param[in] handle Service handle returned by MmRpc_create() | ||
282 | * @param[in] type Buffer descriptor type | ||
283 | * @param[in] num Number of elements in @c desc array | ||
284 | * @param[in] desc Pointer to array of buffer descriptors | ||
285 | * | ||
286 | * @pre @c handle must be a valid handle for the service instance | ||
287 | * returned by an earlier call to MmRpc_create(). | ||
288 | * | ||
289 | * @remark When using MmRpc_call() to invoke remote function calls, | ||
290 | * any referenced buffers will be made available to the | ||
291 | * remote processor only for the duration of the remote | ||
292 | * function call. If the remote processor maintains a | ||
293 | * reference to the buffer across multiple invocations of | ||
294 | * MmRpc_call(), then the application must declare the buffer | ||
295 | * "in use". This will make the buffer persistent. | ||
296 | * | ||
297 | * @remark The application must release the buffer when it is no | ||
298 | * longer needed. | ||
299 | * | ||
300 | * @code | ||
301 | * #include <ti/ipc/mm/MmRpc.h> | ||
302 | * | ||
303 | * MmRpc_BufDesc desc[2]; | ||
304 | * | ||
305 | * desc[0].handle = fd1; | ||
306 | * desc[1].handle = fd2; | ||
307 | * | ||
308 | * MmRpc_use(h, MmRpc_BufType_Handle, 2, desc); | ||
309 | * @endcode | ||
310 | * | ||
311 | * @retval MmRpc_S_SUCCESS @copydoc MmRpc_S_SUCCESS | ||
312 | * @retval MmRpc_E_INVALIDPARAM @copydoc MmRpc_E_INVALIDPARAM | ||
313 | * @retval MmRpc_E_NOMEM @copydoc MmRpc_E_NOMEM | ||
314 | * @retval MmRpc_E_SYS @copydoc MmRpc_E_SYS | ||
315 | * | ||
316 | * @sa MmRpc_release() | ||
317 | */ | ||
318 | int MmRpc_use(MmRpc_Handle handle, MmRpc_BufType type, int num, | ||
319 | MmRpc_BufDesc *desc); | ||
320 | |||
321 | /*! | ||
322 | * @brief Initialize the instance create parameter structure | ||
323 | * | ||
324 | */ | ||
325 | void MmRpc_Params_init(MmRpc_Params *params); | ||
326 | |||
327 | |||
328 | #if defined(__cplusplus) | ||
329 | } | ||
330 | #endif | ||
331 | #endif /* ti_ipc_mm_MmRpc__include */ | ||
diff --git a/packages/kernel-headers/uapi/linux/rpmsg_rpc.h b/packages/kernel-headers/uapi/linux/rpmsg_rpc.h new file mode 100644 index 0000000..88b7126 --- /dev/null +++ b/packages/kernel-headers/uapi/linux/rpmsg_rpc.h | |||
@@ -0,0 +1,183 @@ | |||
1 | /* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ | ||
2 | /* | ||
3 | * Remote Processor Procedure Call Driver | ||
4 | * | ||
5 | * Copyright (C) 2012-2019 Texas Instruments Incorporated - http://www.ti.com/ | ||
6 | */ | ||
7 | |||
8 | #ifndef _UAPI_LINUX_RPMSG_RPC_H_ | ||
9 | #define _UAPI_LINUX_RPMSG_RPC_H_ | ||
10 | |||
11 | #include <linux/ioctl.h> | ||
12 | |||
13 | /** | ||
14 | * struct rppc_buf_fds - rppc buffer registration/deregistration | ||
15 | * @num: number of file descriptors | ||
16 | * @fds: pointer to the array holding the file descriptors | ||
17 | */ | ||
18 | struct rppc_buf_fds { | ||
19 | uint32_t num; | ||
20 | int32_t *fds; | ||
21 | }; | ||
22 | |||
23 | /* | ||
24 | * ioctl definitions | ||
25 | */ | ||
26 | #define RPPC_IOC_MAGIC 'r' | ||
27 | #define RPPC_IOC_CREATE _IOW(RPPC_IOC_MAGIC, 1, char *) | ||
28 | #define RPPC_IOC_BUFREGISTER _IOW(RPPC_IOC_MAGIC, 2, struct rppc_buf_fds) | ||
29 | #define RPPC_IOC_BUFUNREGISTER _IOW(RPPC_IOC_MAGIC, 3, struct rppc_buf_fds) | ||
30 | #define RPPC_IOC_MAXNR (4) | ||
31 | |||
32 | #define RPPC_MAX_PARAMETERS (10) | ||
33 | #define RPPC_MAX_TRANSLATIONS (1024) | ||
34 | #define RPPC_MAX_INST_NAMELEN (48) | ||
35 | |||
36 | /** | ||
37 | * enum rppc_param_type - RPC function parameter type | ||
38 | * @RPPC_PARAM_TYPE_UNKNOWN: unrecognized parameter | ||
39 | * @RPPC_PARAM_TYPE_ATOMIC: an atomic data type, 1 byte to architecture limit | ||
40 | * sized bytes | ||
41 | * @RPPC_PARAM_TYPE_PTR: a pointer to shared memory. The fd field in the | ||
42 | * structures rppc_param and rppc_param_translation must | ||
43 | * contain the file descriptor of the associated dma_buf | ||
44 | * @RPPC_PARAM_TYPE_STRUCT: (unsupported) a structure type. Will be architecture | ||
45 | * width aligned in memory | ||
46 | * | ||
47 | * These enum values are used to identify the parameter type for every | ||
48 | * parameter argument of the remote function. | ||
49 | */ | ||
50 | enum rppc_param_type { | ||
51 | RPPC_PARAM_TYPE_UNKNOWN = 0, | ||
52 | RPPC_PARAM_TYPE_ATOMIC, | ||
53 | RPPC_PARAM_TYPE_PTR, | ||
54 | RPPC_PARAM_TYPE_STRUCT, | ||
55 | }; | ||
56 | |||
57 | /** | ||
58 | * struct rppc_param_translation - pointer translation helper structure | ||
59 | * @index: index of the parameter where the translation needs to be done in. | ||
60 | * used for computing the primary offset and mapping into kernel | ||
61 | * the page from the buffer referred to in the corresponding parameter | ||
62 | * @offset: offset from the primary base pointer to the pointer to translate. | ||
63 | * This is the secondary offset, and used either for mentioning the | ||
64 | * offset from an structure array element base, or within a single | ||
65 | * structure which itself is at an offset in an allocated buffer | ||
66 | * @base: the base user virtual address of the pointer to translate (used to | ||
67 | * calculate translated pointer offset) | ||
68 | * @fd: dma_buf file descriptor of the allocated buffer pointer within which | ||
69 | * the translated pointer is present | ||
70 | */ | ||
71 | struct rppc_param_translation { | ||
72 | uint32_t index; | ||
73 | ptrdiff_t offset; | ||
74 | size_t base; | ||
75 | int32_t fd; | ||
76 | }; | ||
77 | |||
78 | /** | ||
79 | * struct rppc_param - descriptor structure for each parameter | ||
80 | * @type: type of the parameter, as dictated by enum rppc_param_type | ||
81 | * @size: size of the data (for atomic types) or size of the containing | ||
82 | * structure in which translations are performed | ||
83 | * @data: either the parameter value itself (for atomic type) or | ||
84 | * the actual user space pointer address to the data (for pointer type) | ||
85 | * @base: the base user space pointer address of the original allocated buffer, | ||
86 | * providing a reference if data has the pointer that is at an offset | ||
87 | * from the original pointer | ||
88 | * @fd: file descriptor of the exported allocation (will be used to | ||
89 | * import the associated dma_buf within the driver). | ||
90 | */ | ||
91 | struct rppc_param { | ||
92 | uint32_t type; | ||
93 | size_t size; | ||
94 | size_t data; | ||
95 | size_t base; | ||
96 | int32_t fd; | ||
97 | }; | ||
98 | |||
99 | /** | ||
100 | * struct rppc_function - descriptor structure for the remote function | ||
101 | * @fxn_id: index of the function to invoke on the opened rppc device | ||
102 | * @num_params: number of parameters filled in the params field | ||
103 | * @params: array of parameter descriptor structures | ||
104 | * @num_translations: number of in-place translations to be performed within | ||
105 | * the arguments. | ||
106 | * @translations: an open array of the translation descriptor structures, whose | ||
107 | * length is given in @num_translations. Used for translating | ||
108 | * the pointers within the function data. | ||
109 | * | ||
110 | * This is the primary descriptor structure passed down from the userspace, | ||
111 | * describing the function, its parameter arguments and the needed translations. | ||
112 | */ | ||
113 | struct rppc_function { | ||
114 | uint32_t fxn_id; | ||
115 | uint32_t num_params; | ||
116 | struct rppc_param params[RPPC_MAX_PARAMETERS]; | ||
117 | uint32_t num_translations; | ||
118 | struct rppc_param_translation translations[0]; | ||
119 | }; | ||
120 | |||
121 | /** | ||
122 | * struct rppc_function_return - function return status descriptor structure | ||
123 | * @fxn_id: index of the function invoked on the opened rppc device | ||
124 | * @status: return value of the executed function | ||
125 | */ | ||
126 | struct rppc_function_return { | ||
127 | uint32_t fxn_id; | ||
128 | uint32_t status; | ||
129 | }; | ||
130 | |||
131 | /** | ||
132 | * struct rppc_create_instance - rppc channel connector helper | ||
133 | * @name: Name of the rppc server device to establish a connection with | ||
134 | */ | ||
135 | struct rppc_create_instance { | ||
136 | char name[RPPC_MAX_INST_NAMELEN]; | ||
137 | }; | ||
138 | |||
139 | /* | ||
140 | * helper macros for manipulating the function index in the marshalled packet | ||
141 | */ | ||
142 | #define RPPC_DESC_EXEC_SYNC (0x0100) | ||
143 | #define RPPC_DESC_TYPE_MASK (0x0F00) | ||
144 | |||
145 | /* | ||
146 | * helper macros for manipulating the function index in the marshalled packet. | ||
147 | * The remote functions are offset by one relative to the client | ||
148 | * XXX: Remove the relative offset | ||
149 | */ | ||
150 | #define RPPC_SET_FXN_IDX(idx) (((idx) + 1) | 0x80000000) | ||
151 | #define RPPC_FXN_MASK(idx) (((idx) - 1) & 0x7FFFFFFF) | ||
152 | |||
153 | /** | ||
154 | * struct rppc_packet - the actual marshalled packet | ||
155 | * @desc: type of function execution, currently only synchronous function | ||
156 | * invocations are supported | ||
157 | * @msg_id: an incremental message index identifier | ||
158 | * @flags: a combination of job id and pool id of the worker threads | ||
159 | * of the server | ||
160 | * @fxn_id: id of the function to execute | ||
161 | * @result: result of the remotely executed function | ||
162 | * @data_size: size of the payload packet | ||
163 | * @data: variable payload, containing the marshalled function data. | ||
164 | * | ||
165 | * This is actually a condensed structure of the Remote Command Messaging | ||
166 | * (RCM) structure. The initial fields of the structure are used by the | ||
167 | * remote-side server to schedule the execution of the function. The actual | ||
168 | * variable payload data starts from the .data field. This marshalled packet | ||
169 | * is the payload for a rpmsg message. | ||
170 | * | ||
171 | * XXX: remove or mask unneeded fields, some fields can be stripped down | ||
172 | */ | ||
173 | struct rppc_packet { | ||
174 | uint16_t desc; | ||
175 | uint16_t msg_id; | ||
176 | uint32_t flags; | ||
177 | uint32_t fxn_id; | ||
178 | int32_t result; | ||
179 | uint32_t data_size; | ||
180 | uint8_t data[0]; | ||
181 | } __packed; | ||
182 | |||
183 | #endif /* _UAPI_LINUX_RPMSG_RPC_H_ */ | ||