c920f9ce66b8929e051e9dfa8a41011202780dd9
[ipc/ipcdev.git] / packages / ti / ipc / 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 /* this define must precede inclusion of any xdc header file */
39 #define Registry_CURDESC Test__Desc
40 #define MODULE_NAME "Server"
42 /* xdctools header files */
43 #include <xdc/std.h>
44 #include <xdc/runtime/Diags.h>
45 #include <xdc/runtime/Error.h>
46 #include <xdc/runtime/Log.h>
47 #include <xdc/runtime/System.h>
48 #include <xdc/runtime/Assert.h>
49 #include <xdc/runtime/Registry.h>
51 /* package header files */
52 #include <ti/ipc/Ipc.h>
53 #include <ti/sysbios/BIOS.h>
54 #include <ti/sysbios/knl/Task.h>
55 #include <ti/ipc/MessageQ.h>
56 #include <ti/ipc/MultiProc.h>
57 #include <ti/ipc/GateMP.h>
59 /* sytem header files */
60 #include <stdlib.h>
62 /* local header files */
63 #include "gatempapp_rsc_table_vayu_dsp.h"
64 #include "GateMPAppCommon.h"
66 #define PHYSICAL_OFFSET  0xBA300000  /* base physical address of shared mem */
67 #define VIRTUAL_OFFSET   0x80000000  /* base virtual address of shared mem */
69 /* module structure */
70 typedef struct {
71     UInt16              hostProcId;         /* host processor id */
72     MessageQ_Handle     slaveQue;           /* created locally */
73     GateMP_Handle       hostGateMPHandle;   /* host created gate */
74     GateMP_Handle       slaveGateMPHandle;  /* slave created gate */
75 } Server_Module;
77 /* private data */
78 Registry_Desc               Registry_CURDESC;
79 static Server_Module        Module;
81 /* private functions */
82 static Void smain(UArg arg0, UArg arg1);
85 /*
86  *  ======== Server_init ========
87  */
88 Void Server_init(Void)
89 {
90     Registry_Result result;
92     /* register with xdc.runtime to get a diags mask */
93     result = Registry_addModule(&Registry_CURDESC, MODULE_NAME);
94     Assert_isTrue(result == Registry_SUCCESS, (Assert_Id)NULL);
96     /* initialize module object state */
97     Module.hostProcId = MultiProc_getId("HOST");
98     Module.slaveQue = NULL;
99     Module.hostGateMPHandle = NULL;
100     Module.slaveGateMPHandle = NULL;
104 /*
105  *  ======== Server_create ========
106  */
107 Int Server_create()
109     Int                 status = 0;
110     MessageQ_Params     msgqParams;
111     GateMP_Params       gateParams;
113     /* enable some log events */
114     Diags_setMask(MODULE_NAME"+EXF");
116     /* create GateMP */
117     GateMP_Params_init(&gateParams);
119     gateParams.name             = GATEMP_SLAVE_NAME;
120     gateParams.localProtect     = GateMP_LocalProtect_PROCESS;
121     gateParams.remoteProtect    = GateMP_RemoteProtect_SYSTEM;
123     Module.slaveGateMPHandle = GateMP_create (&gateParams);
125     if (Module.slaveGateMPHandle == NULL) {
126         status = GATEMPAPP_E_FAILURE;
127         Log_print0(Diags_INFO, "Server_create: Failed to create GateMP");
128         goto leave;
129     }
131     /* create local message queue (inbound messages) */
132     MessageQ_Params_init(&msgqParams);
133     Module.slaveQue = MessageQ_create(GateMPApp_SlaveMsgQueName, &msgqParams);
135     if (Module.slaveQue == NULL) {
136         status = -1;
137         Log_print0(Diags_INFO, "Server_create: Failed to create MessageQ");
138         GateMP_delete(&Module.slaveGateMPHandle);
139         goto leave;
140     }
142     Log_print0(Diags_INFO,"Server_create: Slave is ready");
144 leave:
145     Log_print1(Diags_EXIT, "<-- Server_create: %d", (IArg)status);
146     return (status);
152 /*
153  *  ======== Server_exec ========
154  */
155 Int Server_exec()
157     Int                 status;
158     GateMPApp_Msg *           msg;
159     MessageQ_QueueId    queId;
160     UInt32              physAddr;
161     volatile UInt32 *   intPtr              = 0;
162     Int                 num                 = 0;
163     UInt                i                   = 0;
164     IArg                gateKey             = 0;
166     Log_print0(Diags_ENTRY | Diags_INFO, "--> Server_exec:");
168     /* wait for inbound message */
169     status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg,
170         MessageQ_FOREVER);
172     if (status < 0) {
173         goto leave;
174     }
176     if (msg->cmd != GATEMPAPP_CMD_SPTR_ADDR) {
177         status = GATEMPAPP_E_UNEXPECTEDMSG;
178         goto leave;
179     }
181     /* Get physical address of shared memory */
182     physAddr = msg->payload;
184     /* translate the physical address to slave virtual addr */
185     intPtr = (volatile UInt32 *)(physAddr - PHYSICAL_OFFSET + VIRTUAL_OFFSET);
187     /* send message back */
188     queId = MessageQ_getReplyQueue(msg); /* type-cast not needed */
189     msg->cmd = GATEMPAPP_CMD_SPTR_ADDR_ACK;
190     MessageQ_put(queId, (MessageQ_Msg)msg);
192     Log_print0(Diags_INFO,"Server_exec: Modifying shared variable "
193             "value");
195     /* open host-created GateMP */
196     do {
197         status = GateMP_open(GATEMP_HOST_NAME, &Module.hostGateMPHandle);
198     } while (status == GateMP_E_NOTFOUND);
200     if (status < 0) {
201         Log_error0("Server_exec: Failed to open host-created GateMP");
202         status = GATEMPAPP_E_FAILURE;
203         goto leave;
204     }
206     Log_print0(Diags_INFO,"Server_exec: Opened GateMP successfully");
208     Log_print0(Diags_INFO,"Server_exec: Using host-created gate");
209     for (i = 0;i < LOOP_ITR; i++) {
211         /* modify the shared variable as long as no one else is currently
212          * accessing it
213          */
215         /* enter GateMP */
216         gateKey = GateMP_enter(Module.hostGateMPHandle);
218         /* randomly modify the shared variable */
219         if ( rand() % 2) {
220             *intPtr -= 1;
221         }
222         else {
223             *intPtr += 1;
224         }
226         /* copy shared variable value */
227         num = *intPtr;
229         Log_print2(Diags_INFO, "Server_exec: Current shared variable "
230                 "value %d, read value=%d", *intPtr, num);
232         if (*intPtr != num) {
233             Log_print0(Diags_INFO, "Server_exec: mismatch in variable value." \
234                 "Test failed.");
235             status = GATEMPAPP_E_FAILURE;
236             goto leave;
237         }
239         /* leave Gate */
240         GateMP_leave(Module.hostGateMPHandle, gateKey);
241     }
243     /* wait for sync message before we switch gates */
244     status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg,
245         MessageQ_FOREVER);
246     if (status < 0) {
247         goto leave;
248     }
250     if (msg->cmd != GATEMPAPP_CMD_SYNC) {
251         status = GATEMPAPP_E_UNEXPECTEDMSG;
252         goto leave;
253     }
255     queId = MessageQ_getReplyQueue(msg);
256     MessageQ_put(queId, (MessageQ_Msg)msg);
258     Log_print0(Diags_INFO,"Server_exec: Using slave-created gate");
260     for (i = 0;i < LOOP_ITR; i++) {
262         /* modify the shared variable as long as no one else is currently
263          * accessing it
264          */
266         /* enter GateMP */
267         gateKey = GateMP_enter(Module.slaveGateMPHandle);
269         /* randomly modify the shared variable */
270         if ( rand() % 2) {
271             *intPtr -= 1;
272         }
273         else {
274             *intPtr += 1;
275         }
277         /* copy shared variable value */
278         num = *intPtr;
280         Log_print2(Diags_INFO, "Server_exec: Current "
281                 "value=%d, read value=%d", *intPtr, num);
283         if (*intPtr != num) {
284             Log_print0(Diags_INFO, "Server_exec: mismatch in variable value." \
285                 "Test failed.");
286             status = GATEMPAPP_E_FAILURE;
287             goto leave;
288         }
290         /* leave Gate */
291         GateMP_leave(Module.slaveGateMPHandle, gateKey);
292     }
294 leave:
295     /* close host GateMP */
296     if (Module.hostGateMPHandle) {
297         GateMP_close(&Module.hostGateMPHandle);
298     }
299     Log_print0(Diags_ENTRY, "Server_exec: host GateMP closed");
301     Log_print1(Diags_EXIT, "<-- Server_exec: %d", (IArg)status);
302     return(status);
305 /*
306  *  ======== Server_delete ========
307  */
308 Int Server_delete()
310     Int         status;
311     GateMPApp_Msg *           msg;
312     MessageQ_QueueId    queId;
314     Log_print0(Diags_ENTRY, "--> Server_delete:");
316     /* wait for inbound message */
317     status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg,
318         MessageQ_FOREVER);
320     if (status < 0) {
321         goto leave;
322     }
323     Log_print0(Diags_ENTRY, "--> Server_delete: got msg");
324     if (msg->cmd != GATEMPAPP_CMD_SHUTDOWN) {
325         status = GATEMPAPP_E_UNEXPECTEDMSG;
326         goto leave;
327     }
329     /* send message back to say that GateMP has been cleaned up */
330     queId = MessageQ_getReplyQueue(msg); /* type-cast not needed */
331     msg->cmd = GATEMPAPP_CMD_SHUTDOWN_ACK;
332     MessageQ_put(queId, (MessageQ_Msg)msg);
334     /* delete the video message queue */
335     status = MessageQ_delete(&Module.slaveQue);
336     if (status < 0) {
337         Log_print0(Diags_ENTRY, "Server_delete: MessageQ_delete failed");
338         goto leave;
339     }
341     Log_print0(Diags_ENTRY, "Server_delete: MessageQ deleted");
343     /* delete slave GateMP */
344     status = GateMP_delete(&Module.slaveGateMPHandle);
345     if (status < 0) {
346         Log_print0(Diags_ENTRY, "Server_delete: GateMP_delete failed");
347         goto leave;
348     }
350     Log_print0(Diags_ENTRY, "Server_delete: slave GateMP deleted");
352 leave:
353     if (status < 0) {
354         Log_error1("Server_delete: error=0x%x", (IArg)status);
355     }
357     /* disable log events */
358     Log_print1(Diags_EXIT, "<-- Server_delete: %d", (IArg)status);
359     Diags_setMask(MODULE_NAME"-EXF");
361     return(status);
364 /*
365  *  ======== Server_exit ========
366  */
368 Void Server_exit(Void)
370     /*
371      * Note that there isn't a Registry_removeModule() yet:
372      *     https://bugs.eclipse.org/bugs/show_bug.cgi?id=315448
373      *
374      * ... but this is where we'd call it.
375      */
379 /*
380  *  ======== main ========
381  */
382 Int main(Int argc, Char* argv[])
384     Error_Block     eb;
385     Task_Params     taskParams;
387     Log_print0(Diags_ENTRY, "--> main:");
389     /* must initialize the error block before using it */
390     Error_init(&eb);
392     /* create main thread (interrupts not enabled in main on BIOS) */
393     Task_Params_init(&taskParams);
394     taskParams.instance->name = "smain";
395     taskParams.stackSize = 0x1000;
396     Task_create(smain, &taskParams, &eb);
398     if (Error_check(&eb)) {
399         System_abort("main: failed to create application startup thread");
400     }
402     /* start scheduler, this never returns */
403     BIOS_start();
405     /* should never get here */
406     Log_print0(Diags_EXIT, "<-- main:");
407     return (0);
411 /*
412  *  ======== smain ========
413  */
414 Void smain(UArg arg0, UArg arg1)
416     Int                 status = 0;
418     Log_print0(Diags_ENTRY | Diags_INFO, "--> smain:");
420     /* initialize modules */
421     Server_init();
423     /* turn on Diags_INFO trace */
424     Diags_setMask("Server+F");
426     /* server setup phase */
427     status = Server_create();
429     if (status < 0) {
430         goto leave;
431     }
433     /* server execute phase */
434     status = Server_exec();
436     if (status < 0) {
437         goto leave;
438     }
440     /* server shutdown phase */
441     status = Server_delete();
443     if (status < 0) {
444         goto leave;
445     }
447     /* finalize modules */
448     Server_exit();
450 leave:
451     Log_print1(Diags_EXIT, "<-- smain: %d", (IArg)status);
452     return;