1b13460ba05397a4cddd56c1a852ecef2c569fbf
[ipc/ipcdev.git] / linux / src / tests / GateMPApp.c
1 /*
2  * Copyright (c) 2013-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  */
33 /*
34  *  ======== GateMPApp.c ========
35  *
36  */
38 /* host header files */
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
43 /* package header files */
44 #include <ti/ipc/Std.h>
45 #include <ti/ipc/MessageQ.h>
46 #include <ti/ipc/GateMP.h>
48 /* local header files */
49 #include "GateMPApp.h"
51 /* CMEM */
52 #include <ti/cmem.h>
54 #include <ti/ipc/tests/GateMPAppCommon.h>
56 /* module structure */
57 typedef struct {
58     MessageQ_Handle       hostQue;    /* created locally */
59     MessageQ_QueueId      slaveQue;   /* opened remotely */
60     UInt16                heapId;     /* MessageQ heapId */
61     UInt32                msgSize;    /* Size of messages */
62     volatile UInt32 *     intPtr;     /* Integer pointer */
63     UInt32                physAddr;   /* Physical address of shared memory */
64     GateMP_Handle         hostGateMPHandle;  /* handle to host-created gate */
65     GateMP_Handle         slaveGateMPHandle; /* handle to slave-created gate */
66 } GateMPApp_Module;
68 /* private data */
69 static GateMPApp_Module Module;
71 /* Global CMEM attrs */
72 CMEM_AllocParams          cmemAttrs;
74 /*
75  *  ======== GateMPApp_create ========
76  */
78 Int GateMPApp_create()
79 {
80     Int                 status    =0;
81     MessageQ_Params     msgqParams;
82     GateMP_Params       gateParams;
84     printf("--> GateMPApp_create:\n");
86     /* setting default values */
87     Module.hostQue = NULL;
88     Module.slaveQue = MessageQ_INVALIDMESSAGEQ;
89     Module.heapId = GateMPApp_MsgHeapId;
90     Module.intPtr = NULL;
91     Module.physAddr = 0;
92     Module.hostGateMPHandle = NULL;
93     Module.slaveGateMPHandle = NULL;
94     Module.msgSize = sizeof(GateMPApp_Msg);
96     /* create local message queue (inbound messages) */
97     MessageQ_Params_init(&msgqParams);
99     Module.hostQue = MessageQ_create(GateMPApp_HostMsgQueName, &msgqParams);
101     if (Module.hostQue == NULL) {
102         printf("GateMPApp_create: Failed creating MessageQ\n");
103         status = GATEMPAPP_E_FAILURE;
104         goto leave;
105     }
107     /* open the remote message queue */
108     do {
109         status = MessageQ_open(GateMPApp_SlaveMsgQueName, &Module.slaveQue);
110         sleep(1);
111     } while (status == MessageQ_E_NOTFOUND);
113     if (status < 0) {
114         printf("GateMPApp_create: Failed opening MessageQ\n");
115         status = GATEMPAPP_E_FAILURE;
116         goto leave;
117     }
119     /* allocate space from shared memory for an integer */
120     cmemAttrs.type = CMEM_HEAP;
121     cmemAttrs.flags = CMEM_NONCACHED;
122     cmemAttrs.alignment = 0;
123     Module.intPtr = (UInt32 *)CMEM_alloc(sizeof(UInt32), &cmemAttrs);
124     if (Module.intPtr < 0) {
125         printf("GateMPApp_create: Could not allocate CMEM shared memory\n");
126         status = GATEMPAPP_E_FAILURE;
127         goto leave;
128     }
130     Module.physAddr = (UInt32)CMEM_getPhys((Void *)Module.intPtr);
132     if (Module.physAddr == 0) {
133         printf("GateMPApp_create: Failed to get physical buffer address\n");
134         status = GATEMPAPP_E_FAILURE;
135         goto leave;
136     }
138     /* create GateMP */
139     GateMP_Params_init(&gateParams);
141     gateParams.name             = GATEMP_HOST_NAME;
142     gateParams.localProtect     = GateMP_LocalProtect_PROCESS;
143     gateParams.remoteProtect    = GateMP_RemoteProtect_SYSTEM;
145     Module.hostGateMPHandle = GateMP_create (&gateParams);
147     if (Module.hostGateMPHandle == NULL) {
148         status = GATEMPAPP_E_FAILURE;
149         printf("GateMPApp_create: Failed to create GateMP\n");
150         goto leave;
151     }
152     printf("GateMPApp_create: Host is ready\n");
154 leave:
155     printf("<-- GateMPApp_create:\n");
156     return(status);
160 /*
161  *  ======== GateMPApp_delete ========
162  */
163 Int GateMPApp_delete(Void)
165     Int         status;
166     GateMPApp_Msg *   msg;
168     printf("--> GateMPApp_delete:\n");
170     /* allocate message */
171     msg = (GateMPApp_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
173     if (msg == NULL) {
174         status = GATEMPAPP_E_FAILURE;
175         goto leave;
176     }
178     /* set the return address in the message header */
179     MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
181     /* sending shutdown command */
182     msg->cmd = GATEMPAPP_CMD_SHUTDOWN;
183     MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
185     /* wait for acknowledgement message */
186     status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
187             MessageQ_FOREVER);
189     if (status < 0) {
190         status = GATEMPAPP_E_FAILURE;
191         goto leave;
192     }
194     if (msg->cmd != GATEMPAPP_CMD_SHUTDOWN_ACK) {
195         status = GATEMPAPP_E_UNEXPECTEDMSG;
196         goto leave;
197     }
199     /* free the message */
200     MessageQ_free((MessageQ_Msg)msg);
202     /* delete GateMP */
203     GateMP_delete(&Module.hostGateMPHandle);
205     /* free shared memory buffer */
206     status = CMEM_free((Ptr)Module.intPtr, &cmemAttrs);
207     if(status < 0) {
208         status = GATEMPAPP_E_FAILURE;
209         goto leave;
210     }
212     /* close remote resources */
213     status = MessageQ_close(&Module.slaveQue);
215     if (status < 0) {
216         status = GATEMPAPP_E_FAILURE;
217         goto leave;
218     }
220     /* delete the host message queue */
221     status = MessageQ_delete(&Module.hostQue);
223     if (status < 0) {
224         status = GATEMPAPP_E_FAILURE;
225         goto leave;
226     }
228 leave:
229     printf("<-- GateMPApp_delete:\n");
230     return(status);
234 /*
235  *  ======== GateMPApp_exec ========
236  */
237 Int GateMPApp_exec(Void)
239     Int         status;
240     Int         i;
241     GateMPApp_Msg *   msg;
242     IArg        gateKey         = 0;
243     UInt32      num;
245     printf("--> GateMPApp_exec:\n");
247     /* set shared variable initial value */
248     *Module.intPtr = 500;
250     /* allocate message */
251     msg = (GateMPApp_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
252     if (msg == NULL) {
253         status = GATEMPAPP_E_FAILURE;
254         goto leave;
255     }
257     /* set the return address in the message header */
258     MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
260     /* fill in message payload */
261     msg->cmd = GATEMPAPP_CMD_SPTR_ADDR;
262     msg->payload = Module.physAddr;
264     /* send message */
265     MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
267     /* wait for return message */
268     status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
269         MessageQ_FOREVER);
270     if (status < 0) {
271         goto leave;
272     }
274     if (msg->cmd != GATEMPAPP_CMD_SPTR_ADDR_ACK)
275     {
276         status = GATEMPAPP_E_UNEXPECTEDMSG;
277         goto leave;
278     }
280     /* free the message */
281     MessageQ_free((MessageQ_Msg)msg);
283     /* open slave-created GateMP */
284     do {
285         status = GateMP_open(GATEMP_SLAVE_NAME, &Module.slaveGateMPHandle);
286     } while (status == GateMP_E_NOTFOUND);
288     if (status < 0) {
289         printf("GateMPApp_exec: Failed to open slave-created GateMP");
290         status = GATEMPAPP_E_FAILURE;
291         goto leave;
292     }
294     printf("GateMPApp_exec: Using host-created gate\n");
295     for (i = 0; i < LOOP_ITR; i++) {
296         /* read the shared variable as long as no one is currently modifying
297          * it
298          */
300         /* enter GateMP */
301         gateKey = GateMP_enter(Module.hostGateMPHandle);
303         /* randomly modify the shared variable */
304         if (rand() % 2) {
305             *Module.intPtr -= 1;
306         }
307         else {
308             *Module.intPtr += 1;
309         }
311         /* read shared variable value */
312         num = *Module.intPtr;
313         printf("GateMPApp_exec: Current value: %d, " \
314             "previously read=%d\n", *Module.intPtr, num);
316         if (*Module.intPtr != num) {
317             printf("GateMPApp_exec: mismatch in variable value." \
318                 "Test failed.\n");
319             status = GATEMPAPP_E_FAILURE;
320             goto leave;
321         }
323         /* exit GateMP */
324         GateMP_leave(Module.hostGateMPHandle, gateKey);
325     }
327     /* allocate message */
328     msg = (GateMPApp_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
329     if (msg == NULL) {
330         status = GATEMPAPP_E_FAILURE;
331         goto leave;
332     }
334     /* set the return address in the message header */
335     MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
337     /* fill in message payload */
338     msg->cmd = GATEMPAPP_CMD_SYNC;
340     /* send sync message */
341     MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
343     /* wait for return sync message before we switch gates */
344     status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
345         MessageQ_FOREVER);
346     if (status < 0) {
347         goto leave;
348     }
350     if (msg->cmd != GATEMPAPP_CMD_SYNC)
351     {
352         status = GATEMPAPP_E_UNEXPECTEDMSG;
353         goto leave;
354     }
356     /* free the message */
357     MessageQ_free((MessageQ_Msg)msg);
359     printf("GateMPApp_exec: Using slave-created gate\n");
360     for (i = 0; i < LOOP_ITR; i++) {
361         /* read the shared variable as long as no one is currently modifying
362          * it
363          */
365         /* enter GateMP */
366         gateKey = GateMP_enter(Module.slaveGateMPHandle);
368         /* randomly modify the shared variable */
369         if (rand() % 2) {
370             *Module.intPtr -= 1;
371         }
372         else {
373             *Module.intPtr += 1;
374         }
376         /* read shared variable value */
377         num = *Module.intPtr;
378         printf("GateMPApp_exec: Current value: %d, " \
379             "previously read=%d\n", *Module.intPtr, num);
381         if (*Module.intPtr != num) {
382             printf("GateMPApp_exec: mismatch in variable value." \
383                 "Test failed.\n");
384             status = GATEMPAPP_E_FAILURE;
385             goto leave;
386         }
388         /* exit GateMP */
389         GateMP_leave(Module.slaveGateMPHandle, gateKey);
390     }
392 leave:
393     if (Module.slaveGateMPHandle) {
394         GateMP_close(&Module.slaveGateMPHandle);
395     }
397     printf("<-- GateMPApp_exec: %d\n", status);
398     return(status);