]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - qnx/src/ipc3x_dev/ti/syslink/samples/hlos/deh/usr/tests_omx_errors.c
Merge remote-tracking branch 'ramsey/ready' into 11_eng
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / samples / hlos / deh / usr / tests_omx_errors.c
1 /*
2  * Copyright (c) 2011, 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 "PerfUtils.h"
81 #include <stdbool.h>
84 typedef struct {
85     int a;
86     int b;
87 } fxn_error_args;
89 /* Note: Set bit 31 to indicate static function indicies:
90  * This function order will be hardcoded on BIOS side, hence preconfigured:
91  * See src/examples/srvmgr/test_omx.c.
92  */
93 #define FXN_IDX_FXNERROR             (4 | 0x80000000)
95 unsigned long diff(struct timespec start, struct timespec end)
96 {
97     unsigned long    nsecs;
99     struct timespec temp;
100     if ((end.tv_nsec-start.tv_nsec)<0) {
101         temp.tv_sec = end.tv_sec-start.tv_sec-1;
102         temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
103     } else {
104         temp.tv_sec = end.tv_sec-start.tv_sec;
105         temp.tv_nsec = end.tv_nsec-start.tv_nsec;
106     }
107     nsecs = temp.tv_sec * 1000000 + temp.tv_nsec;
108     return nsecs;
111 int exec_cmd(int fd, char *msg, int len, char *reply_msg, int *reply_len)
113     int ret = 0;
115     ret = write(fd, msg, len);
116     if (ret < 0) {
117          perror("Can't write to OMX instance");
118          return -1;
119     }
121     /* Now, await normal function result from OMX service: */
122     // Note: len should be max length of response expected.
123     ret = read(fd, reply_msg, len);
124     if (ret < 0) {
125          perror("Can't read from OMX instance");
126          return -1;
127     }
128     else {
129           *reply_len = ret;
130     }
131     return(0);
135 void init_omx_packet(omx_packet *packet, uint16_t desc)
137     /* initialize the packet structure */
138     packet->desc  |= desc << OMX_DESC_TYPE_SHIFT;
139     packet->msg_id  = 0;
140     packet->flags  = OMX_POOLID_JOBID_NONE;
141     packet->fxn_idx = OMX_INVALIDFXNIDX;
142     packet->result = 0;
145 void test_exec_call(int fd, int test_id, uint32_t test_arg)
147     uint16_t          server_status;
148     int               packet_len;
149     int               reply_len;
150     char              packet_buf[512] = {0};
151     char              return_buf[512] = {0};
152     omx_packet        *packet = (omx_packet *)packet_buf;
153     omx_packet        *rtn_packet = (omx_packet *)return_buf;
154     fxn_error_args   *fxn_args   = (fxn_error_args *)&packet->data[1];
156     /* Set Packet Header for the RCMServer, synchronous execution: */
157     init_omx_packet(packet, OMX_DESC_MSG);
159     /* Set OMX Function Index to call, with data: */
160     packet->fxn_idx = FXN_IDX_FXNERROR;
162     /* Set data for the OMX function: */
163     packet->data_size = sizeof(fxn_error_args) + sizeof(int);
164     packet->data[0] = 0; // RPC_OMX_MAP_INFO_NONE
165     fxn_args->a = test_id;
166     fxn_args->b = test_arg;
168     /* Exec command: */
169     packet_len = sizeof(omx_packet) + packet->data_size;
170     exec_cmd(fd, (char *)packet, packet_len, (char *)rtn_packet, &reply_len);
172     /* Decode reply: */
173     server_status = (OMX_DESC_TYPE_MASK & rtn_packet->desc) >>
174             OMX_DESC_TYPE_SHIFT;
175     if (server_status == OMXSERVER_STATUS_SUCCESS)  {
177        printf ("omx_errors: called fxnError(%d)), result = %d\n",
178                     fxn_args->a, rtn_packet->result);
179     }
180     else {
181        printf("omx_errors: Failed to execute fxnError: server status: %d\n",
182             server_status);
183     }
186 int main(int argc, char *argv[])
188        int fd;
189        int ret;
190        int test_id = -1;
191        int core_id = 0;
192        uint32_t test_arg = (uint32_t)-1;
193        bool test_arg_set = false;
194        int c;
195        struct omx_conn_req connreq = { .name = "OMX" };
197        while (1)
198        {
199            c = getopt (argc, argv, "t:c:a:");
200            if (c == -1)
201                break;
203            switch (c)
204            {
205            case 't':
206                test_id = atoi(optarg);
207                break;
208            case 'c':
209                core_id = atoi(optarg);
210                break;
211            case 'a':
212                sscanf(optarg, "%x", &test_arg);
213                test_arg_set = true;
214                break;
215            default:
216                printf ("Unrecognized argument\n");
217            }
218        }
220         switch (test_id) {
221             case 1:
222                 printf("DivByZero Test\n");
223                 break;
224             case 2:
225                 printf("WatchDog Test\n");
226                 break;
227             case 3:
228                 printf("MMU Fault Test\n");
229                 if (test_arg == 1) {
230                     test_id = 3;
231                 }
232                 else if (test_arg == 2) {
233                     test_id = 4;
234                 }
235                 else {
236                     printf("Invalid arg\n");
237                     return 1;
238                 }
239                 break;
240             case 4:
241                 printf("AMMU Fault Test\n");
242                 if (test_arg == 1) {
243                     test_id = 5;
244                 }
245                 else if (test_arg == 2) {
246                     test_id = 6;
247                 }
248                 else {
249                     printf("Invalid arg\n");
250                     return 1;
251                 }
252                 break;
253             case 5:
254                 printf("Read Inv. Addr Test\n");
255                 test_id = 7;
256                 if (!test_arg_set) {
257                     printf("Invalid arg\n");
258                     return 1;
259                 }
260                 break;
261             case 6:
262                 printf("Write Inv. Addr Test\n");
263                 test_id = 8;
264                 if (!test_arg_set) {
265                     printf("Invalid arg\n");
266                     return 1;
267                 }
268                 break;
269             default:
270                 printf("Invalid test id\n");
271                 return 1;
272         }
274         if (core_id < 0 || core_id > 1) {
275             printf("Invalid core id\n");
276             return 1;
277         }
279         printf("omx_sample: Connecting to core %d\n", core_id);
281        if (core_id == 0) {
282            /* Connect to the OMX ServiceMgr on Ducati core 0: */
283            fd = open("/dev/rpmsg-omx0", O_RDWR);
284        }
285        else {
286            /* Connect to the OMX ServiceMgr on Ducati core 1: */
287            fd = open("/dev/rpmsg-omx1", O_RDWR);
288        }
289        if (fd < 0) {
290             perror("Can't open OMX device");
291             return 1;
292        }
294        /* Create an OMX server instance, and rebind its address to this
295         * file descriptor.
296         */
297        ret = ioctl(fd, OMX_IOCCONNECT, &connreq);
298        if (ret < 0) {
299             perror("Can't connect to OMX instance");
300             return 1;
301        }
303        printf("omx_sample: Connected to %s\n", connreq.name);
304        test_exec_call(fd, test_id, test_arg);
306        /* Terminate connection and destroy OMX instance */
307        ret = close(fd);
308        if (ret < 0) {
309             perror("Can't close OMX fd ??");
310             return 1;
311        }
313        printf("omx_sample: Closed connection to %s!\n", connreq.name);
314        return 0;