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 * ======== mmrpc_test.c ========
35 */
36 #include <stdio.h>
37 #include <stdlib.h>
39 /* IPC Headers */
40 #include <ti/ipc/Std.h>
42 #if defined(SYSLINK_BUILDOS_QNX)
43 #include <ti/ipc/Ipc.h>
44 #include <ti/shmemallocator/SharedMemoryAllocatorUsr.h>
45 #else /* Linux HLOS */
46 #include <omap/omap_drm.h>
47 #include <libdrm/omap_drmif.h>
48 #include <errno.h>
49 #include <string.h>
50 #endif
52 #include "Mx.h"
54 #define PROC_ID_DFLT 1
56 /*
57 * These callCompute() functions separated per HLOS due to very different
58 * HLOS specific shared memory buffer allocation methods.
59 */
61 #if defined(SYSLINK_BUILDOS_QNX)
63 static int callCompute_QnX()
64 {
65 Mx_Compute *compute;
66 shm_buf shmCompute, shmInBuf, shmOutBuf;
67 int status = 0;
68 int size;
69 int32_t ret;
70 uint32_t val;
71 int i;
73 /* allocate a compute structure in shared memory */
74 SHM_alloc(sizeof(Mx_Compute), &shmCompute);
75 compute = (Mx_Compute *)(shmCompute.vir_addr);
77 if (compute == NULL) {
78 /* temporary: memory alloc not implemented on Linux */
79 fprintf(stderr, "failed to map omap_bo to user space\n");
80 goto leave;
81 }
83 /* initialize compute structure */
84 compute->coef = 0x80400000;
85 compute->key = 0xABA0;
86 compute->size = 0x1000;
87 compute->inBuf = NULL;
88 compute->outBuf = NULL;
90 /* allocate an input buffer in shared memory */
91 size = compute->size * sizeof(uint32_t);
92 SHM_alloc(size, &shmInBuf);
93 compute->inBuf = (uint32_t *)(shmInBuf.vir_addr);
95 if (compute->inBuf == NULL) {
96 printf("mmrpc_test: Error: compute->inBuf == NULL\n");
97 status = -1;
98 goto leave;
99 }
101 /* fill input buffer with seed value */
102 for (i = 0; i < compute->size; i++) {
103 compute->inBuf[i] = 0x2010;
104 }
106 /* allocate an output buffer in shared memory */
107 SHM_alloc(size, &shmOutBuf);
108 compute->outBuf = (uint32_t *)(shmOutBuf.vir_addr);
110 if (compute->outBuf == NULL) {
111 printf("mmrpc_test: Error: compute->outBuf == NULL\n");
112 status = -1;
113 goto leave;
114 }
116 /* clear output buffer */
117 for (i = 0; i < compute->size; i++) {
118 compute->outBuf[i] = 0;
119 }
121 /* print some debug info */
122 printf("mmrpc_test: calling Mx_compute(0x%x)\n", (unsigned int)compute);
123 printf("mmrpc_test: compute->coef=0x%x\n", compute->coef);
124 printf("mmrpc_test: compute->key=0x%x\n", compute->key);
125 printf("mmrpc_test: compute->size=0x%x\n", compute->size);
126 printf("mmrpc_test: compute->inBuf=0x%x\n", (unsigned int)compute->inBuf);
127 printf("mmrpc_test: compute->outBuf=0x%x\n", (unsigned int)compute->outBuf);
129 /* process the buffer */
130 ret = Mx_compute_QnX(compute);
132 if (ret < 0) {
133 status = -1;
134 printf("mmrpc_test: Error: Mx_Compute() failed\n");
135 goto leave;
136 }
138 printf("mmrpc_test: after Mx_compute(0x%x)\n", (unsigned int)compute);
139 printf("mmrpc_test: compute->coef=0x%x\n", compute->coef);
140 printf("mmrpc_test: compute->key=0x%x\n", compute->key);
141 printf("mmrpc_test: compute->size=0x%x\n", compute->size);
142 printf("mmrpc_test: compute->inBuf=0x%x\n", (unsigned int)compute->inBuf);
143 printf("mmrpc_test: compute->outBuf=0x%x\n", (unsigned int)compute->outBuf);
144 printf("mmrpc_test: compute->inBuf[0]=0x%x\n",
145 (unsigned int)compute->inBuf[0]);
146 printf("mmrpc_test: compute->outBuf[0]=0x%x\n",
147 (unsigned int)compute->outBuf[0]);
149 /* check the output buffer */
150 for (i = 0; i < compute->size; i++) {
151 val = compute->outBuf[i] | compute->coef;
152 if (compute->outBuf[i] != val) {
153 status = -1;
154 printf("mmrpc_test: Error: incorrect outBuf\n");
155 break;
156 }
157 }
159 leave:
160 SHM_release(&shmOutBuf);
161 SHM_release(&shmInBuf);
162 SHM_release(&shmCompute);
164 return (status);
165 }
167 #else /* Linux */
169 static int callCompute_Linux()
170 {
171 Mx_Compute *compute = NULL;
172 int drmFd = 0;
173 struct omap_device *dev = NULL;
174 struct omap_bo *compute_bo = NULL;
175 struct omap_bo *inBuf_bo = NULL;
176 struct omap_bo *outBuf_bo = NULL;
177 uint32_t * inBufPtr = NULL;
178 uint32_t * outBufPtr = NULL;
179 int status = 0;
180 int size;
181 uint32_t val;
182 int i;
183 int32_t ret;
185 /* On Linux, use omapdrm driver to get a Tiler buffer for shared memory */
186 drmFd = drmOpen("omapdrm", NULL);
188 if (drmFd < 0) {
189 fprintf(stderr, "could not open omapdrm device: %d: %s\n",
190 errno, strerror(errno));
191 return 1;
192 }
194 dev = omap_device_new(drmFd);
195 if (!dev) {
196 fprintf(stderr, "could not get device from fd\n");
197 goto leave;
198 }
200 /* allocate a compute structure in shared memory and get a pointer */
201 compute_bo = omap_bo_new(dev, sizeof(Mx_Compute), OMAP_BO_CACHED);
202 if (compute_bo) {
203 compute = (Mx_Compute *)omap_bo_map(compute_bo);
204 }
205 else {
206 fprintf(stderr, "failed to allocate omap_bo\n");
207 }
209 if (compute == NULL) {
210 fprintf(stderr, "failed to map omap_bo to user space\n");
211 goto leave;
212 }
214 /* initialize compute structure */
215 compute->coef = 0x80400000;
216 compute->key = 0xABA0;
217 compute->size = 0x1000;
218 compute->inBuf = NULL;
219 compute->outBuf = NULL;
221 /* allocate an input buffer in shared memory */
222 size = compute->size * sizeof(uint32_t);
223 inBuf_bo = omap_bo_new(dev, size, OMAP_BO_CACHED);
224 if (inBuf_bo) {
225 inBufPtr = (uint32_t *)omap_bo_map(inBuf_bo);
226 }
227 else {
228 fprintf(stderr, "failed to allocate inBuf_bo\n");
229 }
231 if (inBufPtr == NULL) {
232 printf("mmrpc_test: Error: inBufPtr == NULL\n");
233 status = -1;
234 goto leave;
235 }
237 /* fill input buffer with seed value */
238 for (i = 0; i < compute->size; i++) {
239 inBufPtr[i] = 0x2010;
240 }
242 /* allocate an output buffer in shared memory */
243 outBuf_bo = omap_bo_new(dev, size, OMAP_BO_CACHED);
244 if (outBuf_bo) {
245 outBufPtr = (uint32_t *)omap_bo_map(outBuf_bo);
246 }
247 else {
248 fprintf(stderr, "failed to allocate outBuf_bo handle\n");
249 }
251 if (outBufPtr == NULL) {
252 printf("mmrpc_test: Error: outBufPtr == NULL\n");
253 status = -1;
254 goto leave;
255 }
257 /* clear output buffer */
258 for (i = 0; i < compute->size; i++) {
259 outBufPtr[i] = 0;
260 }
262 compute->inBuf = (uint32_t *)inBufPtr;
263 compute->outBuf = (uint32_t *)outBufPtr;
265 /* print some debug info */
266 printf("mmrpc_test: calling Mx_compute(0x%x)\n", (unsigned int)compute);
267 printf("mmrpc_test: compute->coef=0x%x\n", compute->coef);
268 printf("mmrpc_test: compute->key=0x%x\n", compute->key);
269 printf("mmrpc_test: compute->size=0x%x\n", compute->size);
270 printf("mmrpc_test: compute->inBuf=0x%x\n", (unsigned int)compute->inBuf);
271 printf("mmrpc_test: compute->outBuf=0x%x\n", (unsigned int)compute->outBuf);
273 /* process the buffer */
274 ret = Mx_compute_Linux(compute, omap_bo_dmabuf(compute_bo),
275 omap_bo_dmabuf(inBuf_bo),
276 omap_bo_dmabuf(outBuf_bo));
278 if (ret < 0) {
279 status = -1;
280 printf("mmrpc_test: Error: Mx_Compute() failed\n");
281 goto leave;
282 }
284 printf("mmrpc_test: after Mx_compute(0x%x)\n", (unsigned int)compute);
285 printf("mmrpc_test: compute->coef=0x%x\n", compute->coef);
286 printf("mmrpc_test: compute->key=0x%x\n", compute->key);
287 printf("mmrpc_test: compute->size=0x%x\n", compute->size);
288 printf("mmrpc_test: compute->inBuf=0x%x\n", (unsigned int)compute->inBuf);
289 printf("mmrpc_test: compute->outBuf=0x%x\n", (unsigned int)compute->outBuf);
290 printf("mmrpc_test: compute->inBuf[0]=0x%x\n",
291 (unsigned int)compute->inBuf[0]);
292 printf("mmrpc_test: compute->outBuf[0]=0x%x\n",
293 (unsigned int)compute->outBuf[0]);
295 /* check the output buffer */
296 for (i = 0; i < compute->size; i++) {
297 val = outBufPtr[i] | compute->coef;
298 if (outBufPtr[i] != val) {
299 status = -1;
300 printf("mmrpc_test: Error: incorrect outBuf\n");
301 break;
302 }
303 }
305 leave:
306 if (outBuf_bo) {
307 omap_bo_del(outBuf_bo);
308 }
309 if (inBuf_bo) {
310 omap_bo_del(inBuf_bo);
311 }
312 if (compute_bo) {
313 omap_bo_del(compute_bo);
314 }
315 if (dev) {
316 omap_device_del(dev);
317 }
318 if (drmFd) {
319 close(drmFd);
320 }
322 return (status);
323 }
324 #endif
327 /*
328 * ======== main ========
329 */
330 int main(int argc, char **argv)
331 {
332 int status;
333 int32_t ret;
334 UInt16 procId = PROC_ID_DFLT;
336 printf("mmrpc_test: --> main\n");
338 /* Parse Args: */
339 switch (argc) {
340 case 1:
341 /* use defaults */
342 break;
343 case 2:
344 procId = atoi(argv[1]);
345 break;
346 default:
347 printf("Usage: %s [<ProcId>]\n", argv[0]);
348 printf("\tDefaults: ProcId: %d\n", PROC_ID_DFLT);
349 exit(0);
350 }
352 #if defined(SYSLINK_BUILDOS_QNX)
353 /* Need to start IPC for MultiProc */
354 status = Ipc_start();
355 if (status < 0) {
356 printf("Ipc_start failed: status = %d\n", status);
357 return (0);
358 }
359 #endif
361 /* initialize Mx module (setup rpc connection) */
362 status = Mx_initialize(procId);
364 if (status < 0) {
365 goto leave;
366 }
368 /* invoke Mx functions */
369 ret = Mx_triple(11);
370 printf("mmrpc_test: Mx_triple(11), ret=%d\n", ret);
372 if (ret < 0) {
373 status = -1;
374 goto leave;
375 }
377 ret = Mx_triple(111);
378 printf("mmrpc_test: Mx_triple(111), ret=%d\n", ret);
380 if (ret < 0) {
381 status = -1;
382 goto leave;
383 }
385 ret = Mx_add(44, 66);
386 printf("mmrpc_test: Mx_add(44, 66), ret=%d\n", ret);
388 if (ret < 0) {
389 status = -1;
390 goto leave;
391 }
393 #if defined(SYSLINK_BUILDOS_QNX)
394 ret = callCompute_QnX();
395 #else
396 ret = callCompute_Linux();
397 #endif
398 if (ret < 0) {
399 status = -1;
400 }
402 leave:
404 /* finalize Mx module (destroy rpc connection) */
405 Mx_finalize();
407 #if defined(SYSLINK_BUILDOS_QNX)
408 Ipc_stop();
409 #endif
411 if (status < 0) {
412 printf("mmrpc_test: FAILED\n");
413 }
414 else {
415 printf("mmrpc_test: PASSED\n");
416 }
417 return(0);
418 }