nsremote: Add additional check to handle assert disabled
[ipc/ipcdev.git] / packages / ti / sdo / ipc / nsremote / NameServerMessageQ.c
1 /*
2  * Copyright (c) 2012-2015 Texas Instruments Incorporated - http://www.ti.com
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  *  ======== NameServerMessageQ.c ========
34  */
36 #include <xdc/std.h>
37 #include <string.h>
38 #include <stdlib.h>
40 #include <xdc/runtime/Assert.h>
41 #include <xdc/runtime/Error.h>
42 #include <xdc/runtime/Startup.h>
43 #include <xdc/runtime/knl/ISync.h>
45 #include <ti/sysbios/BIOS.h>
46 #include <ti/sysbios/knl/Swi.h>
47 #include <ti/sysbios/knl/Semaphore.h>
48 #include <ti/sysbios/syncs/SyncSwi.h>
49 #include <ti/sysbios/gates/GateMutex.h>
51 #include "package/internal/NameServerMessageQ.xdc.h"
53 #include <ti/sdo/ipc/Ipc.h>
54 #include <ti/sdo/ipc/_MessageQ.h>
55 #include <ti/sdo/utils/_MultiProc.h>
56 #include <ti/sdo/utils/_NameServer.h>
58 /*
59  *  Determine name array size:
60  *    maxNameLen / ((bits per char) / (bits per byte) * (sizeof(Bits32)))
61  */
62 #define MAXNAMEINCHAR   (NameServerMessageQ_maxNameLen / \
63                         (xdc_target__bitsPerChar / 8))
64 #define NAMEARRAYSIZE   (((MAXNAMEINCHAR - 1) / sizeof(Bits32)) + 1)
66 #define MESSAGEQ_INDEX 0
68 /* message sent to remote procId */
69 typedef struct NameServerMsg {
70     MessageQ_MsgHeader header;  /* message header                   */
71     Bits32  value;              /* holds value                      */
72     Bits32  request;            /* whether its a request/response   */
73     Bits32  requestStatus;      /* status of request                */
74     Bits32  reserved;           /* reserved field                   */
75                                 /* name of NameServer instance      */
76     Bits32  instanceName[NAMEARRAYSIZE];
77                                 /* name of NameServer entry         */
78     Bits32  name[NAMEARRAYSIZE];
79 } NameServerMsg;
81 /*
82  *************************************************************************
83  *                       Instance functions
84  *************************************************************************
85  */
86 Void NameServerMessageQ_Instance_init(NameServerMessageQ_Object *obj,
87         UInt16 remoteProcId,
88         const NameServerMessageQ_Params *params)
89 {
90     /* Assert that remoteProcId is valid */
91     Assert_isTrue(remoteProcId != MultiProc_self() &&
92                   remoteProcId != MultiProc_INVALIDID,
93                   Ipc_A_invParam);
95     obj->remoteProcId = remoteProcId;
97     /* register the remote driver with NameServer */
98     ti_sdo_utils_NameServer_registerRemoteDriver(
99             NameServerMessageQ_Handle_upCast(obj), remoteProcId);
102 /*
103  *  ======== NameServerMessageQ_Instance_finalize ========
104  */
105 Void NameServerMessageQ_Instance_finalize(NameServerMessageQ_Object *obj)
107     /* unregister remote driver from NameServer module */
108     ti_sdo_utils_NameServer_unregisterRemoteDriver(obj->remoteProcId);
111 /*
112  *************************************************************************
113  *                       Module functions
114  *************************************************************************
115  */
117 /*
118  *  ======== NameServerMessageQ_Module_startup ========
119  */
120 Int NameServerMessageQ_Module_startup(Int phase)
122     MessageQ_Params2  messageQParams;
123     MessageQ_QueueId queueId;
125     /* Ensure MessageQ and SyncSwi Module_startup() have completed */
126     if ((ti_sdo_ipc_MessageQ_Module_startupDone() == FALSE) ||
127         (ti_sysbios_syncs_SyncSwi_Module_startupDone() == FALSE)) {
128         return (Startup_NOTDONE);
129     }
131     /* Create the message queue for NameServer using SyncSwi */
132     MessageQ_Params2_init(&messageQParams);
133     messageQParams.synchronizer = NameServerMessageQ_module->syncSwiHandle;
134     messageQParams.queueIndex = MESSAGEQ_INDEX;
135     NameServerMessageQ_module->msgHandle =
136         (ti_sdo_ipc_MessageQ_Handle)MessageQ_create2(NULL, &messageQParams);
138     /* assert msgHandle is not null */
139     Assert_isTrue(NameServerMessageQ_module->msgHandle != NULL,
140         Ipc_A_nullPointer);
141     /* Additonal check for case with  assert disabled */
142     if(NameServerMessageQ_module->msgHandle == NULL) {
143         return Startup_NOTDONE;
144     }
146     queueId = MessageQ_getQueueId((MessageQ_Handle)
147                                   NameServerMessageQ_module->msgHandle);
148     /* assert this is the first MessageQ created */
149     Assert_isTrue( (queueId & 0xffff) == MESSAGEQ_INDEX,
150         NameServerMessageQ_A_reservedMsgQueueId);
151     /* Additonal check for case with  assert disabled */
152     if ((queueId & 0xffff) != MESSAGEQ_INDEX) {
153         return Startup_NOTDONE;
154     }
156     return (Startup_DONE);
159 /*
160  *  ======== NameServerMessageQ_attach ========
161  */
162 Int NameServerMessageQ_attach(UInt16 remoteProcId, Ptr sharedAddr)
164     NameServerMessageQ_Params params;
165     NameServerMessageQ_Handle handle;
166     Int status = NameServerMessageQ_E_FAIL;
167     Error_Block eb;
169     Error_init(&eb);
171     /* init params */
172     NameServerMessageQ_Params_init(&params);
174     /* create driver to remote proc */
175     handle = NameServerMessageQ_create(remoteProcId,
176                                        &params,
177                                        &eb);
179     if (handle != NULL) {
180         status = NameServerMessageQ_S_SUCCESS;
181     }
183     return (status);
186 /*
187  *  ======== NameServerMessageQ_detach ========
188  */
189 Int NameServerMessageQ_detach(UInt16 remoteProcId)
191     NameServerMessageQ_Handle handle;
192     Int status = NameServerMessageQ_S_SUCCESS;
194     /* return handle based upon procId */
195     for (handle = NameServerMessageQ_Object_first(); handle != NULL;
196         handle = NameServerMessageQ_Object_next(handle)) {
197         if (handle->remoteProcId == remoteProcId) {
198             break;
199         }
200     }
202     if (handle == NULL) {
203         status = NameServerMessageQ_E_FAIL;
204     }
205     else {
206         NameServerMessageQ_delete(&handle);
207     }
209     return (status);
212 /*
213  *  ======== NameServerMessageQ_get ========
214  */
215 Int NameServerMessageQ_get(NameServerMessageQ_Object *obj,
216                            String instanceName,
217                            String name,
218                            Ptr value,
219                            UInt32 *valueLen,
220                            ISync_Handle syncHandle,
221                            Error_Block *eb)
223     Int status;
224     IArg key;
225     MessageQ_QueueId queueId;
226     NameServerMsg    *msg;
227     Semaphore_Handle semRemoteWait = NameServerMessageQ_module->semRemoteWait;
228     GateMutex_Handle gateMutex = NameServerMessageQ_module->gateMutex;
230     /* enter gate - prevent multiple threads from entering */
231     key = GateMutex_enter(gateMutex);
233     /* alloc a message from specified heap */
234     msg = (NameServerMsg *)MessageQ_alloc(NameServerMessageQ_heapId,
235                                           sizeof(NameServerMsg));
237     /* make sure message is not NULL */
238     if (msg == NULL) {
239         Error_raise(eb, NameServerMessageQ_E_outOfMemory,
240                     NameServerMessageQ_heapId, 0);
241         return (NameServer_E_OSFAILURE);
242     }
244     /* make sure this is a request message */
245     msg->request = NameServerMessageQ_REQUEST;
246     msg->requestStatus = 0;
248     /* assert length is smaller than max (must have room for null character) */
249     Assert_isTrue(strlen(instanceName) < MAXNAMEINCHAR,
250             NameServerMessageQ_A_nameIsTooLong);
252     /* copy the name of instance into putMsg */
253     strncpy((Char *)msg->instanceName, instanceName, MAXNAMEINCHAR - 1);
254     ((Char *)msg->instanceName) [MAXNAMEINCHAR - 1] = '0';
256     /* assert length is smaller than max (must have room for null character) */
257     Assert_isTrue(strlen(name) < MAXNAMEINCHAR,
258             NameServerMessageQ_A_nameIsTooLong);
260     /* copy the name of nameserver entry into putMsg */
261     strncpy((Char *)msg->name, name, MAXNAMEINCHAR - 1);
262     ((Char *)msg->name) [MAXNAMEINCHAR - 1] = '0';
264     /* determine the queueId based upon the processor */
265     queueId = MessageQ_openQueueId(MESSAGEQ_INDEX, obj->remoteProcId);
267     /* set the reply procId */
268     MessageQ_setReplyQueue(
269         (MessageQ_Handle)NameServerMessageQ_module->msgHandle,
270         (MessageQ_Msg)msg);
272     /* send message to remote processor. */
273     status = MessageQ_put(queueId, (MessageQ_Msg)msg);
275     /* make sure message sent successfully */
276     if (status < 0) {
277         /* free the message */
278         MessageQ_free((MessageQ_Msg)msg);
280         return (NameServer_E_FAIL);
281     }
283     /* pend here until we get a response back from remote processor */
284     status = Semaphore_pend(semRemoteWait, NameServerMessageQ_timeout);
286     if (status == FALSE) {
287         /* return timeout failure */
288         return (NameServer_E_OSFAILURE);
289     }
291     /* get the message */
292     msg = NameServerMessageQ_module->msg;
294     if (msg->requestStatus) {
295         /* name is found */
297         /* set length to amount of data that was copied */
298         *valueLen = sizeof(Bits32);
300         /* set the contents of value */
301         memcpy(value, &(msg->value), sizeof(Bits32));
303         /* set the status to success */
304         status = NameServer_S_SUCCESS;
305     }
306     else {
307         /* name is not found */
309         /* set status to not found */
310         status = NameServer_E_NOTFOUND;
311     }
313     /* free the message */
314     MessageQ_free((MessageQ_Msg)msg);
316     /* leave the gate */
317     GateMutex_leave(gateMutex, key);
319     /* return success status */
320     return (status);
323 /*
324  *  ======== NameServerMessageQ_sharedMemReq ========
325  */
326 SizeT NameServerMessageQ_sharedMemReq(Ptr sharedAddr)
328     return (0);
331 /*
332  *  ======== NameServerMessageQ_swiFxn ========
333  */
334 Void NameServerMessageQ_swiFxn(UArg arg0, UArg arg1)
336     NameServerMsg     *msg;
337     NameServer_Handle handle;
338     MessageQ_QueueId  queueId;
339     Int               status = NameServer_E_FAIL;
340     Semaphore_Handle  semRemoteWait = NameServerMessageQ_module->semRemoteWait;
342     /* drain all messages in the messageQ */
343     while (1) {
344         /* get a message, this never waits */
345         status = MessageQ_get(
346                     (MessageQ_Handle)NameServerMessageQ_module->msgHandle,
347                     (MessageQ_Msg *)&msg, 0);
349         /* if no message then return */
350         if (status != MessageQ_S_SUCCESS) {
351             break;
352         }
354         if (msg->request == NameServerMessageQ_REQUEST) {
355             /* reset value of status */
356             status = NameServer_E_FAIL;
358             /*
359              *  Message is a request. Lookup name in NameServer table.
360              *  Send a response message back to source processor.
361              */
362             handle = NameServer_getHandle((String)msg->instanceName);
364             if (handle != NULL) {
365                 /* Search for the NameServer entry */
366                 status = NameServer_getLocalUInt32(handle,
367                          (String)msg->name, &msg->value);
368             }
370             /* set the request status */
371             if (status < 0) {
372                 msg->requestStatus = 0;
373             }
374             else {
375                 msg->requestStatus = 1;
376             }
378             /* specify message as a response */
379             msg->request = NameServerMessageQ_RESPONSE;
381             /* get the remote processor from the msg header */
382             queueId = (UInt32)(msg->header.replyProc) << 16;
384             /* send response message to remote processor */
385             MessageQ_put(queueId, (MessageQ_Msg)msg);
386         }
387         else {
388             /*
389              *  This is a response message. At any given time, there is
390              *  only one of these outstanding because of semMultiBlock.
391              *  This allows us to safely set the Module state's msg pointer
392              *  and post semaphore.
393              */
394             NameServerMessageQ_module->msg = msg;
395             Semaphore_post(semRemoteWait);
396         }
398     }