1 /*
2 * Copyright (c) 2013, 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 */
33 /*
34 * ======== Mx.c ========
35 */
36 #include <stdio.h>
37 #include <ti/ipc/Std.h>
39 #include <ti/ipc/mm/MmRpc.h>
40 #include <ti/ipc/MultiProc.h>
42 #if defined(SYSLINK_BUILDOS_QNX)
43 #include <ti/shmemallocator/SharedMemoryAllocatorUsr.h>
44 #endif
46 #include "Mx.h"
48 /* hande used for remote communication */
49 static MmRpc_Handle Mx_rpcIpu = NULL;
51 /* static function indicies */
52 #define Mx_Fxn_triple (0x80000000 | 1)
53 #define Mx_Fxn_add (0x80000000 | 2)
54 #define Mx_Fxn_compute (0x80000000 | 5)
56 #define Mx_OFFSET(base, member) ((uint_t)(member) - (uint_t)(base))
58 #define SERVICE_NAME "rpc_example"
60 /*
61 * ======== Mx_initialize ========
62 */
63 int Mx_initialize(UInt16 procId)
64 {
65 int status;
66 MmRpc_Params args;
67 Char mmServerName[20];
69 /* create remote server instance */
70 MmRpc_Params_init(&args);
72 /* Construct an MmRpc server name adorned with core name: */
73 sprintf(mmServerName, "%s_%d", SERVICE_NAME, procId);
75 status = MmRpc_create(mmServerName, &args, &Mx_rpcIpu);
77 if (status < 0) {
78 printf("mmrpc_test: Error: MmRpc_create of %s failed\n", mmServerName);
79 status = -1;
80 }
81 else {
82 status = 0;
83 }
85 return(status);
86 }
88 /*
89 * ======== Mx_finalize ========
90 */
91 void Mx_finalize(void)
92 {
93 /* delete remote server instance */
94 if (Mx_rpcIpu != NULL) {
95 MmRpc_delete(&Mx_rpcIpu);
96 }
97 }
99 /*
100 * ======== Mx_triple ========
101 */
102 int32_t Mx_triple(uint32_t a)
103 {
104 MmRpc_FxnCtx *fxnCtx;
105 int32_t fxnRet;
106 char send_buf[512] = {0};
107 int status;
109 /* marshall function arguments into the send buffer */
110 fxnCtx = (MmRpc_FxnCtx *)send_buf;
112 fxnCtx->fxn_id = Mx_Fxn_triple;
113 fxnCtx->num_params = 1;
114 fxnCtx->params[0].type = MmRpc_ParamType_Scalar;
115 fxnCtx->params[0].param.scalar.size = sizeof(int);
116 fxnCtx->params[0].param.scalar.data = a;
117 fxnCtx->num_xlts = 0;
118 fxnCtx->xltAry = NULL;
120 /* invoke the remote function call */
121 status = MmRpc_call(Mx_rpcIpu, fxnCtx, &fxnRet);
123 if (status < 0) {
124 printf("mmrpc_test: Error: MmRpc_call failed\n");
125 fxnRet = -1;
126 }
128 return(fxnRet);
129 }
131 /*
132 * ======== Mx_add ========
133 */
134 int32_t Mx_add(int32_t a, int32_t b)
135 {
136 MmRpc_FxnCtx *fxnCtx;
137 int32_t fxnRet;
138 char send_buf[512] = {0};
139 int status;
141 /* marshall function arguments into the send buffer */
142 fxnCtx = (MmRpc_FxnCtx *)send_buf;
144 fxnCtx->fxn_id = Mx_Fxn_add;
145 fxnCtx->num_params = 2;
146 fxnCtx->params[0].type = MmRpc_ParamType_Scalar;
147 fxnCtx->params[0].param.scalar.size = sizeof(int);
148 fxnCtx->params[0].param.scalar.data = a;
149 fxnCtx->params[1].type = MmRpc_ParamType_Scalar;
150 fxnCtx->params[1].param.scalar.size = sizeof(int);
151 fxnCtx->params[1].param.scalar.data = b;
152 fxnCtx->num_xlts = 0;
154 /* invoke the remote function call */
155 status = MmRpc_call(Mx_rpcIpu, fxnCtx, &fxnRet);
157 if (status < 0) {
158 printf("mmrpc_test: Error: MmRpc_call failed\n");
159 fxnRet = -1;
160 }
162 return(fxnRet);
163 }
165 /*
166 * ======== Mx_compute ========
167 */
168 #if defined(SYSLINK_BUILDOS_QNX)
169 int32_t Mx_compute_QnX(Mx_Compute *compute)
170 #else
171 int32_t Mx_compute_Linux(Mx_Compute *compute, int fd, int fdIn, int fdOut)
172 #endif
173 {
174 MmRpc_FxnCtx *fxnCtx;
175 MmRpc_Xlt xltAry[2];
176 int32_t fxnRet;
177 char send_buf[512] = {0};
178 int status;
179 MmRpc_BufDesc desc[1];
180 int num = 0;
182 /* make the output buffer persistent */
183 #if defined(SYSLINK_BUILDOS_QNX)
184 desc[0].ptr.addr = (size_t)compute->outBuf;
185 desc[0].ptr.size = compute->size * sizeof(uint32_t);
186 num = 1;
188 status = MmRpc_use(Mx_rpcIpu, MmRpc_BufType_Ptr, num, desc);
189 #else
190 desc[0].handle = fdOut;
191 num = 1;
193 status = MmRpc_use(Mx_rpcIpu, MmRpc_BufType_Handle, num, desc);
194 #endif
196 if (status < 0) {
197 printf("mmrpc_test: Error: MmRpc_use failed\n");
198 num = 0;
199 fxnRet = -1;
200 goto leave;
201 }
203 /* marshall function arguments into the send buffer */
204 fxnCtx = (MmRpc_FxnCtx *)send_buf;
206 fxnCtx->fxn_id = Mx_Fxn_compute;
207 fxnCtx->num_params = 1;
208 fxnCtx->params[0].type = MmRpc_ParamType_Ptr;
209 fxnCtx->params[0].param.ptr.size = sizeof(Mx_Compute);
210 fxnCtx->params[0].param.ptr.addr = (size_t)compute;
211 #if defined(SYSLINK_BUILDOS_QNX)
212 fxnCtx->params[0].param.ptr.handle = NULL;
213 #else
214 fxnCtx->params[0].param.ptr.handle = fd;
215 #endif
217 fxnCtx->num_xlts = 2;
218 fxnCtx->xltAry = xltAry;
220 fxnCtx->xltAry[0].index = 0;
221 fxnCtx->xltAry[0].offset = MmRpc_OFFSET(compute, &compute->inBuf);
222 fxnCtx->xltAry[0].base = (size_t)compute->inBuf;
223 #if defined(SYSLINK_BUILDOS_QNX)
224 fxnCtx->xltAry[0].handle = NULL;
225 #else
226 fxnCtx->xltAry[0].handle = fdIn;
227 #endif
229 fxnCtx->xltAry[1].index = 0;
230 fxnCtx->xltAry[1].offset = MmRpc_OFFSET(compute, &compute->outBuf);
231 fxnCtx->xltAry[1].base = (size_t)compute->outBuf;
232 #if defined(SYSLINK_BUILDOS_QNX)
233 fxnCtx->xltAry[1].handle = NULL;
234 #else
235 fxnCtx->xltAry[1].handle = fdOut;
236 #endif
238 /* invoke the remote function call */
239 status = MmRpc_call(Mx_rpcIpu, fxnCtx, &fxnRet);
241 if (status < 0) {
242 printf("mmrpc_test: Error: MmRpc_call failed\n");
243 fxnRet = -1;
244 goto leave;
245 }
247 leave:
248 /* release the output buffer */
249 if (num > 0) {
250 #if defined(SYSLINK_BUILDOS_QNX)
251 status = MmRpc_release(Mx_rpcIpu, MmRpc_BufType_Ptr, num, desc);
252 #else
253 status = MmRpc_release(Mx_rpcIpu, MmRpc_BufType_Handle, num, desc);
254 #endif
256 if (status < 0) {
257 printf("mmrpc_test: Error: MmRpc_release failed\n");
258 fxnRet = -1;
259 }
260 }
262 return(fxnRet);
263 }