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;
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 Int prevNum = 0;
164 UInt i = 0;
165 IArg gateKey = 0;
167 Log_print0(Diags_ENTRY | Diags_INFO, "--> Server_exec:");
169 /* wait for inbound message */
170 status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg,
171 MessageQ_FOREVER);
173 if (status < 0) {
174 goto leave;
175 }
177 if (msg->cmd != GATEMPAPP_CMD_SPTR_ADDR) {
178 status = GATEMPAPP_E_UNEXPECTEDMSG;
179 goto leave;
180 }
182 /* Get physical address of shared memory */
183 physAddr = msg->payload;
185 /* translate the physical address to slave virtual addr */
186 intPtr = (volatile UInt32 *)(physAddr - PHYSICAL_OFFSET + VIRTUAL_OFFSET);
188 /* send message back */
189 queId = MessageQ_getReplyQueue(msg); /* type-cast not needed */
190 msg->cmd = GATEMPAPP_CMD_SPTR_ADDR_ACK;
191 MessageQ_put(queId, (MessageQ_Msg)msg);
193 Log_print0(Diags_INFO,"Server_exec: Modifying shared variable "
194 "value");
196 /* open host-created GateMP */
197 do {
198 status = GateMP_open(GATEMP_HOST_NAME, &Module.hostGateMPHandle);
199 } while (status == GateMP_E_NOTFOUND);
201 if (status < 0) {
202 Log_error0("Server_exec: Failed to open host-created GateMP");
203 status = GATEMPAPP_E_FAILURE;
204 goto leave;
205 }
207 Log_print0(Diags_INFO,"Server_exec: Opened GateMP successfully");
209 Log_print0(Diags_INFO,"Server_exec: Using host-created gate");
210 for (i = 0;i < LOOP_ITR; i++) {
212 /* modify the shared variable as long as no one else is currently
213 * accessing it
214 */
216 /* enter GateMP */
217 gateKey = GateMP_enter(Module.hostGateMPHandle);
219 /* read shared variable value */
220 prevNum = *intPtr;
222 /* randomly modify the shared variable */
223 if ( rand() % 2) {
224 *intPtr -= 1;
225 }
226 else {
227 *intPtr += 1;
228 }
230 /* read shared variable value again */
231 num = *intPtr;
233 if ((prevNum != num + 1) && (prevNum != num - 1)) {
234 Log_print0(Diags_INFO, "Server_exec: unexpected variable value." \
235 "Test failed.");
236 Log_print2(Diags_INFO, "Server_exec: Previous shared variable "
237 "value %d, current value=%d", prevNum, num);
239 status = GATEMPAPP_E_FAILURE;
240 goto leave;
241 }
243 /* leave Gate */
244 GateMP_leave(Module.hostGateMPHandle, gateKey);
245 }
247 /* wait for sync message before we switch gates */
248 status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg,
249 MessageQ_FOREVER);
250 if (status < 0) {
251 goto leave;
252 }
254 if (msg->cmd != GATEMPAPP_CMD_SYNC) {
255 status = GATEMPAPP_E_UNEXPECTEDMSG;
256 goto leave;
257 }
259 queId = MessageQ_getReplyQueue(msg);
260 MessageQ_put(queId, (MessageQ_Msg)msg);
262 Log_print0(Diags_INFO,"Server_exec: Using slave-created gate");
264 for (i = 0;i < LOOP_ITR; i++) {
266 /* modify the shared variable as long as no one else is currently
267 * accessing it
268 */
270 /* enter GateMP */
271 gateKey = GateMP_enter(Module.slaveGateMPHandle);
273 /* read shared variable value */
274 prevNum = *intPtr;
276 /* randomly modify the shared variable */
277 if ( rand() % 2) {
278 *intPtr -= 1;
279 }
280 else {
281 *intPtr += 1;
282 }
284 /* read shared variable value again */
285 num = *intPtr;
287 if ((prevNum != num - 1) && (prevNum != num + 1)) {
288 Log_print0(Diags_INFO, "Server_exec: unexpected variable value." \
289 "Test failed.");
290 Log_print2(Diags_INFO, "Server_exec: Previous "
291 "value=%d, current value=%d", prevNum, num);
293 status = GATEMPAPP_E_FAILURE;
294 goto leave;
295 }
297 /* leave Gate */
298 GateMP_leave(Module.slaveGateMPHandle, gateKey);
299 }
301 leave:
302 /* close host GateMP */
303 if (Module.hostGateMPHandle) {
304 GateMP_close(&Module.hostGateMPHandle);
305 }
306 Log_print0(Diags_ENTRY, "Server_exec: host GateMP closed");
308 Log_print1(Diags_EXIT, "<-- Server_exec: %d", (IArg)status);
309 return(status);
310 }
312 /*
313 * ======== Server_delete ========
314 */
315 Int Server_delete()
316 {
317 Int status;
318 GateMPApp_Msg * msg;
319 MessageQ_QueueId queId;
321 Log_print0(Diags_ENTRY, "--> Server_delete:");
323 /* wait for inbound message */
324 status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg,
325 MessageQ_FOREVER);
327 if (status < 0) {
328 goto leave;
329 }
330 Log_print0(Diags_ENTRY, "--> Server_delete: got msg");
331 if (msg->cmd != GATEMPAPP_CMD_SHUTDOWN) {
332 status = GATEMPAPP_E_UNEXPECTEDMSG;
333 goto leave;
334 }
336 /* send message back to say that GateMP has been cleaned up */
337 queId = MessageQ_getReplyQueue(msg); /* type-cast not needed */
338 msg->cmd = GATEMPAPP_CMD_SHUTDOWN_ACK;
339 MessageQ_put(queId, (MessageQ_Msg)msg);
341 /* delete the video message queue */
342 status = MessageQ_delete(&Module.slaveQue);
343 if (status < 0) {
344 Log_print0(Diags_ENTRY, "Server_delete: MessageQ_delete failed");
345 goto leave;
346 }
348 Log_print0(Diags_ENTRY, "Server_delete: MessageQ deleted");
350 /* delete slave GateMP */
351 status = GateMP_delete(&Module.slaveGateMPHandle);
352 if (status < 0) {
353 Log_print0(Diags_ENTRY, "Server_delete: GateMP_delete failed");
354 goto leave;
355 }
357 Log_print0(Diags_ENTRY, "Server_delete: slave GateMP deleted");
359 leave:
360 if (status < 0) {
361 Log_error1("Server_delete: error=0x%x", (IArg)status);
362 }
364 /* disable log events */
365 Log_print1(Diags_EXIT, "<-- Server_delete: %d", (IArg)status);
366 Diags_setMask(MODULE_NAME"-EXF");
368 return(status);
369 }
371 /*
372 * ======== Server_exit ========
373 */
375 Void Server_exit(Void)
376 {
377 /*
378 * Note that there isn't a Registry_removeModule() yet:
379 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=315448
380 *
381 * ... but this is where we'd call it.
382 */
383 }
386 /*
387 * ======== main ========
388 */
389 Int main(Int argc, Char* argv[])
390 {
391 Error_Block eb;
392 Task_Params taskParams;
394 Log_print0(Diags_ENTRY, "--> main:");
396 /* must initialize the error block before using it */
397 Error_init(&eb);
399 /* create main thread (interrupts not enabled in main on BIOS) */
400 Task_Params_init(&taskParams);
401 taskParams.instance->name = "smain";
402 taskParams.stackSize = 0x1000;
403 Task_create(smain, &taskParams, &eb);
405 if (Error_check(&eb)) {
406 System_abort("main: failed to create application startup thread");
407 }
409 /* start scheduler, this never returns */
410 BIOS_start();
412 /* should never get here */
413 Log_print0(Diags_EXIT, "<-- main:");
414 return (0);
415 }
418 /*
419 * ======== smain ========
420 */
421 Void smain(UArg arg0, UArg arg1)
422 {
423 Int status = 0;
425 Log_print0(Diags_ENTRY | Diags_INFO, "--> smain:");
427 /* initialize modules */
428 Server_init();
430 /* turn on Diags_INFO trace */
431 Diags_setMask("Server+F");
433 /* server setup phase */
434 status = Server_create();
436 if (status < 0) {
437 goto leave;
438 }
440 /* server execute phase */
441 status = Server_exec();
443 if (status < 0) {
444 goto leave;
445 }
447 /* server shutdown phase */
448 status = Server_delete();
450 if (status < 0) {
451 goto leave;
452 }
454 /* finalize modules */
455 Server_exit();
457 leave:
458 Log_print1(Diags_EXIT, "<-- smain: %d", (IArg)status);
459 return;
460 }