Cleanup: removed directory qnx/src/ipc3x_dev/perfutils
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / samples / hlos / deh / usr / tests_omx_errors.c
1 /*
2  * Copyright (c) 2011-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  */
32 /*
33  * omx_benchmark.c
34  *
35  * Benchmark average round trip time for equivalent of SysLink 2 RcmClient_exec.
36  *
37  * This calls the fxnDouble RcmServer function, similar to the SysLink 2 ducati
38  * rcm/singletest.
39  *
40  * Requires:
41  * --------
42  * test_omx.c sample, with fxnDouble registered in RcmServer table.
43  *
44  * To Configure Ducati code for Benchmarking:
45  * ------------------------------------------
46  * In package.bld:
47  *   - Set profile=release in package.bld
48  * In bencmark test code:
49  *   - Disable printf's, trace.
50  * In benchmark .cfg file:
51  *   - Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF
52  *   - Defaults.common$.logger = null;
53  *
54  * Expected Result:  (Linux, Panda Board ES 2.1, rpmsg13 branch)
55  * ---------------
56  * avg time: 110 usecs
57  *
58  * Expected Result:  (Qnx, Playbook ES 2.1, no branch yet - local development)
59  * ---------------
60  * avg time: 140 usecs
61  */
63 #include <sys/select.h>
64 #include <sys/types.h>
65 #include <sys/stat.h>
66 #include <fcntl.h>
67 #include <errno.h>
68 #include <stdio.h>
69 #include <string.h>
70 #include <stdlib.h>
71 #include <unistd.h>
72 #include <pthread.h>
73 #include <time.h>
74 //#include <sys/eventfd.h>
76 #include "ti/ipc/rpmsg_omx.h"
78 #include "omx_packet.h"
80 #include <stdbool.h>
83 typedef struct {
84     int a;
85     int b;
86 } fxn_error_args;
88 /* Note: Set bit 31 to indicate static function indicies:
89  * This function order will be hardcoded on BIOS side, hence preconfigured:
90  * See src/examples/srvmgr/test_omx.c.
91  */
92 #define FXN_IDX_FXNERROR             (4 | 0x80000000)
94 unsigned long diff(struct timespec start, struct timespec end)
95 {
96     unsigned long    nsecs;
98     struct timespec temp;
99     if ((end.tv_nsec-start.tv_nsec)<0) {
100         temp.tv_sec = end.tv_sec-start.tv_sec-1;
101         temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
102     } else {
103         temp.tv_sec = end.tv_sec-start.tv_sec;
104         temp.tv_nsec = end.tv_nsec-start.tv_nsec;
105     }
106     nsecs = temp.tv_sec * 1000000 + temp.tv_nsec;
107     return nsecs;
110 int exec_cmd(int fd, char *msg, int len, char *reply_msg, int *reply_len)
112     int ret = 0;
114     ret = write(fd, msg, len);
115     if (ret < 0) {
116          perror("Can't write to OMX instance");
117          return -1;
118     }
120     /* Now, await normal function result from OMX service: */
121     // Note: len should be max length of response expected.
122     ret = read(fd, reply_msg, len);
123     if (ret < 0) {
124          perror("Can't read from OMX instance");
125          return -1;
126     }
127     else {
128           *reply_len = ret;
129     }
130     return(0);
134 void init_omx_packet(omx_packet *packet, uint16_t desc)
136     /* initialize the packet structure */
137     packet->desc  |= desc << OMX_DESC_TYPE_SHIFT;
138     packet->msg_id  = 0;
139     packet->flags  = OMX_POOLID_JOBID_NONE;
140     packet->fxn_idx = OMX_INVALIDFXNIDX;
141     packet->result = 0;
144 void test_exec_call(int fd, int test_id, uint32_t test_arg)
146     uint16_t          server_status;
147     int               packet_len;
148     int               reply_len;
149     char              packet_buf[512] = {0};
150     char              return_buf[512] = {0};
151     omx_packet        *packet = (omx_packet *)packet_buf;
152     omx_packet        *rtn_packet = (omx_packet *)return_buf;
153     fxn_error_args   *fxn_args   = (fxn_error_args *)&packet->data[1];
155     /* Set Packet Header for the RCMServer, synchronous execution: */
156     init_omx_packet(packet, OMX_DESC_MSG);
158     /* Set OMX Function Index to call, with data: */
159     packet->fxn_idx = FXN_IDX_FXNERROR;
161     /* Set data for the OMX function: */
162     packet->data_size = sizeof(fxn_error_args) + sizeof(int);
163     packet->data[0] = 0; // RPC_OMX_MAP_INFO_NONE
164     fxn_args->a = test_id;
165     fxn_args->b = test_arg;
167     /* Exec command: */
168     packet_len = sizeof(omx_packet) + packet->data_size;
169     exec_cmd(fd, (char *)packet, packet_len, (char *)rtn_packet, &reply_len);
171     /* Decode reply: */
172     server_status = (OMX_DESC_TYPE_MASK & rtn_packet->desc) >>
173             OMX_DESC_TYPE_SHIFT;
174     if (server_status == OMXSERVER_STATUS_SUCCESS)  {
176        printf ("omx_errors: called fxnError(%d)), result = %d\n",
177                     fxn_args->a, rtn_packet->result);
178     }
179     else {
180        printf("omx_errors: Failed to execute fxnError: server status: %d\n",
181             server_status);
182     }
185 int main(int argc, char *argv[])
187        int fd;
188        int ret;
189        int test_id = -1;
190        int core_id = 0;
191        uint32_t test_arg = (uint32_t)-1;
192        bool test_arg_set = false;
193        int c;
194        struct omx_conn_req connreq = { .name = "OMX" };
196        while (1)
197        {
198            c = getopt (argc, argv, "t:c:a:");
199            if (c == -1)
200                break;
202            switch (c)
203            {
204            case 't':
205                test_id = atoi(optarg);
206                break;
207            case 'c':
208                core_id = atoi(optarg);
209                break;
210            case 'a':
211                sscanf(optarg, "%x", &test_arg);
212                test_arg_set = true;
213                break;
214            default:
215                printf ("Unrecognized argument\n");
216            }
217        }
219         switch (test_id) {
220             case 1:
221                 printf("DivByZero Test\n");
222                 break;
223             case 2:
224                 printf("WatchDog Test\n");
225                 break;
226             case 3:
227                 printf("MMU Fault Test\n");
228                 if (test_arg == 1) {
229                     test_id = 3;
230                 }
231                 else if (test_arg == 2) {
232                     test_id = 4;
233                 }
234                 else {
235                     printf("Invalid arg\n");
236                     return 1;
237                 }
238                 break;
239             case 4:
240                 printf("AMMU Fault Test\n");
241                 if (test_arg == 1) {
242                     test_id = 5;
243                 }
244                 else if (test_arg == 2) {
245                     test_id = 6;
246                 }
247                 else {
248                     printf("Invalid arg\n");
249                     return 1;
250                 }
251                 break;
252             case 5:
253                 printf("Read Inv. Addr Test\n");
254                 test_id = 7;
255                 if (!test_arg_set) {
256                     printf("Invalid arg\n");
257                     return 1;
258                 }
259                 break;
260             case 6:
261                 printf("Write Inv. Addr Test\n");
262                 test_id = 8;
263                 if (!test_arg_set) {
264                     printf("Invalid arg\n");
265                     return 1;
266                 }
267                 break;
268             default:
269                 printf("Invalid test id\n");
270                 return 1;
271         }
273         if (core_id < 0 || core_id > 1) {
274             printf("Invalid core id\n");
275             return 1;
276         }
278         printf("omx_sample: Connecting to core %d\n", core_id);
280        if (core_id == 0) {
281            /* Connect to the OMX ServiceMgr on Ducati core 0: */
282            fd = open("/dev/rpmsg-omx0", O_RDWR);
283        }
284        else {
285            /* Connect to the OMX ServiceMgr on Ducati core 1: */
286            fd = open("/dev/rpmsg-omx1", O_RDWR);
287        }
288        if (fd < 0) {
289             perror("Can't open OMX device");
290             return 1;
291        }
293        /* Create an OMX server instance, and rebind its address to this
294         * file descriptor.
295         */
296        ret = ioctl(fd, OMX_IOCCONNECT, &connreq);
297        if (ret < 0) {
298             perror("Can't connect to OMX instance");
299             return 1;
300        }
302        printf("omx_sample: Connected to %s\n", connreq.name);
303        test_exec_call(fd, test_id, test_arg);
305        /* Terminate connection and destroy OMX instance */
306        ret = close(fd);
307        if (ret < 0) {
308             perror("Can't close OMX fd ??");
309             return 1;
310        }
312        printf("omx_sample: Closed connection to %s!\n", connreq.name);
313        return 0;