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 * ======== 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;
101 }
104 /*
105 * ======== Server_create ========
106 */
107 Int Server_create()
108 {
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);
147 }
152 /*
153 * ======== Server_exec ========
154 */
155 Int Server_exec()
156 {
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 /* process the message */
188 //Log_print1(Diags_INFO, "Server_exec: processed cmd=0x%x", msg->cmd);
189 /* send message back */
190 queId = MessageQ_getReplyQueue(msg); /* type-cast not needed */
191 msg->cmd = GATEMPAPP_CMD_SPTR_ADDR_ACK;
192 MessageQ_put(queId, (MessageQ_Msg)msg);
194 Log_print0(Diags_INFO,"Server_exec: Modifying shared variable "
195 "value");
197 /* open host-created GateMP */
198 do {
199 status = GateMP_open(GATEMP_HOST_NAME, &Module.hostGateMPHandle);
200 } while (status == GateMP_E_NOTFOUND);
202 if (status < 0) {
203 Log_error0("Server_exec: Failed to open host-created GateMP");
204 status = GATEMPAPP_E_FAILURE;
205 goto leave;
206 }
208 Log_print0(Diags_INFO,"Server_exec: Opened GateMP successfully");
210 Log_print0(Diags_INFO,"Server_exec: Using host-created gate");
211 for (i = 0;i < LOOP_ITR; i++) {
213 /* modify the shared variable as long as no one else is currently
214 * accessing it
215 */
217 /* enter GateMP */
218 gateKey = GateMP_enter(Module.hostGateMPHandle);
220 /* randomly modify the shared variable */
221 if ( rand() % 2) {
222 *intPtr -= 1;
223 }
224 else {
225 *intPtr += 1;
226 }
228 /* copy shared variable value */
229 num = *intPtr;
231 Log_print2(Diags_INFO, "Server_exec: Current shared variable "
232 "value %d, read value=%d", *intPtr, num);
234 if (*intPtr != num) {
235 Log_print0(Diags_INFO, "Server_exec: mismatch in variable value." \
236 "Test failed.");
237 status = GATEMPAPP_E_FAILURE;
238 goto leave;
239 }
241 /* leave Gate */
242 GateMP_leave(Module.hostGateMPHandle, gateKey);
243 }
245 /* wait for sync message before we switch gates */
246 status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg,
247 MessageQ_FOREVER);
248 if (status < 0) {
249 goto leave;
250 }
252 if (msg->cmd != GATEMPAPP_CMD_SYNC) {
253 status = GATEMPAPP_E_UNEXPECTEDMSG;
254 goto leave;
255 }
257 queId = MessageQ_getReplyQueue(msg);
258 MessageQ_put(queId, (MessageQ_Msg)msg);
260 Log_print0(Diags_INFO,"Server_exec: Using slave-created gate");
262 for (i = 0;i < LOOP_ITR; i++) {
264 /* modify the shared variable as long as no one else is currently
265 * accessing it
266 */
268 /* enter GateMP */
269 gateKey = GateMP_enter(Module.slaveGateMPHandle);
271 /* randomly modify the shared variable */
272 if ( rand() % 2) {
273 *intPtr -= 1;
274 }
275 else {
276 *intPtr += 1;
277 }
279 /* copy shared variable value */
280 num = *intPtr;
282 Log_print2(Diags_INFO, "Server_exec: Current "
283 "value=%d, read value=%d", *intPtr, num);
285 if (*intPtr != num) {
286 Log_print0(Diags_INFO, "Server_exec: mismatch in variable value." \
287 "Test failed.");
288 status = GATEMPAPP_E_FAILURE;
289 goto leave;
290 }
292 /* leave Gate */
293 GateMP_leave(Module.slaveGateMPHandle, gateKey);
294 }
296 leave:
297 if (Module.hostGateMPHandle) {
298 GateMP_close(&Module.hostGateMPHandle);
299 }
301 Log_print1(Diags_EXIT, "<-- Server_exec: %d", (IArg)status);
302 return(status);
303 }
305 /*
306 * ======== Server_delete ========
307 */
308 Int Server_delete()
309 {
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 /* close host GateMP */
330 GateMP_close(&Module.hostGateMPHandle);
331 Log_print0(Diags_ENTRY, "Server_delete: host GateMP closed");
333 /* send message back to say that GateMP has been cleaned up */
334 queId = MessageQ_getReplyQueue(msg); /* type-cast not needed */
335 msg->cmd = GATEMPAPP_CMD_SHUTDOWN_ACK;
336 MessageQ_put(queId, (MessageQ_Msg)msg);
338 /* delete the video message queue */
339 status = MessageQ_delete(&Module.slaveQue);
340 if (status < 0) {
341 Log_print0(Diags_ENTRY, "Server_delete: MessageQ_delete failed");
342 goto leave;
343 }
345 Log_print0(Diags_ENTRY, "Server_delete: MessageQ deleted");
347 /* delete slave GateMP */
348 status = GateMP_delete(&Module.slaveGateMPHandle);
349 if (status < 0) {
350 Log_print0(Diags_ENTRY, "Server_delete: GateMP_delete failed");
351 goto leave;
352 }
354 Log_print0(Diags_ENTRY, "Server_delete: slave GateMP deleted");
356 leave:
357 if (status < 0) {
358 Log_error1("Server_delete: error=0x%x", (IArg)status);
359 }
361 /* disable log events */
362 Log_print1(Diags_EXIT, "<-- Server_delete: %d", (IArg)status);
363 Diags_setMask(MODULE_NAME"-EXF");
365 return(status);
366 }
368 /*
369 * ======== Server_exit ========
370 */
372 Void Server_exit(Void)
373 {
374 /*
375 * Note that there isn't a Registry_removeModule() yet:
376 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=315448
377 *
378 * ... but this is where we'd call it.
379 */
380 }
383 /*
384 * ======== main ========
385 */
386 Int main(Int argc, Char* argv[])
387 {
388 Error_Block eb;
389 Task_Params taskParams;
391 Log_print0(Diags_ENTRY, "--> main:");
393 /* must initialize the error block before using it */
394 Error_init(&eb);
396 /* create main thread (interrupts not enabled in main on BIOS) */
397 Task_Params_init(&taskParams);
398 taskParams.instance->name = "smain";
399 taskParams.stackSize = 0x1000;
400 Task_create(smain, &taskParams, &eb);
402 if (Error_check(&eb)) {
403 System_abort("main: failed to create application startup thread");
404 }
406 /* start scheduler, this never returns */
407 BIOS_start();
409 /* should never get here */
410 Log_print0(Diags_EXIT, "<-- main:");
411 return (0);
412 }
415 /*
416 * ======== smain ========
417 */
418 Void smain(UArg arg0, UArg arg1)
419 {
420 Int status = 0;
422 Log_print0(Diags_ENTRY | Diags_INFO, "--> smain:");
424 /* initialize modules */
425 Server_init();
427 /* turn on Diags_INFO trace */
428 Diags_setMask("Server+F");
430 /* server setup phase */
431 status = Server_create();
433 if (status < 0) {
434 goto leave;
435 }
437 /* server execute phase */
438 status = Server_exec();
440 if (status < 0) {
441 goto leave;
442 }
444 /* server shutdown phase */
445 status = Server_delete();
447 if (status < 0) {
448 goto leave;
449 }
451 /* finalize modules */
452 Server_exit();
454 leave:
455 Log_print1(Diags_EXIT, "<-- smain: %d", (IArg)status);
456 return;
457 }