nsremote: Add additional check to handle assert disabled
[ipc/ipcdev.git] / packages / ti / sdo / ipc / nsremote / NameServerRemoteNotify.c
1 /*
2  * Copyright (c) 2012-2019, 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  */
32 /*
33  *  ======== NameServerRemoteNotify.c ========
34  */
36 /* Remove Windows strncpy warning */
37 #define _CRT_SECURE_NO_DEPRECATE 1
39 #include <xdc/std.h>
40 #include <string.h>
41 #include <stdlib.h>
43 #include <xdc/runtime/Assert.h>
44 #include <xdc/runtime/Error.h>
45 #include <xdc/runtime/knl/ISync.h>
47 #include <ti/sysbios/BIOS.h>
48 #include <ti/sysbios/hal/Cache.h>
49 #include <ti/sysbios/knl/Swi.h>
50 #include <ti/sysbios/knl/Semaphore.h>
52 #include "package/internal/NameServerRemoteNotify.xdc.h"
54 #include <ti/sdo/ipc/Ipc.h>
55 #include <ti/sdo/ipc/_Notify.h>
56 #include <ti/sdo/ipc/_GateMP.h>
57 #include <ti/sdo/ipc/_SharedRegion.h>
58 #include <ti/sdo/utils/_MultiProc.h>
59 #include <ti/sdo/utils/_NameServer.h>
61 /* Need to use reserved notify events */
62 #undef NameServerRemoteNotify_notifyEventId
63 #define NameServerRemoteNotify_notifyEventId \
64         ti_sdo_ipc_nsremote_NameServerRemoteNotify_notifyEventId + \
65                     (UInt32)((UInt32)Notify_SYSTEMKEY << 16)
67 /* private constant values */
68 #define NameServerRemoteNotify_RequestMsg       1
69 #define NameServerRemoteNotify_ResponseMsg      2
71 /*
72  *************************************************************************
73  *                       Instance functions
74  *************************************************************************
75  */
76 Int NameServerRemoteNotify_Instance_init(NameServerRemoteNotify_Object *obj,
77         UInt16 remoteProcId, const NameServerRemoteNotify_Params *params,
78         Error_Block *eb)
79 {
80     Int               offset = 0;
81     Int               status;
82     Semaphore_Params  semParams;
83     Semaphore_Handle  semHandle;
84     Swi_Params        swiParams;
85     Swi_Handle        swiHandle;
86     SizeT          cacheLineSize;
88     /* Assert that a NameServerRemoteNotify_Params has been supplied */
89     Assert_isTrue(params != NULL, Ipc_A_nullArgument);
91     /* Assert that remoteProcId is valid */
92     Assert_isTrue(remoteProcId != MultiProc_self() &&
93                   remoteProcId != MultiProc_INVALIDID,
94                   Ipc_A_invParam);
96     /* determine the offset based upon own id and remote's id */
97     if (MultiProc_self() > remoteProcId) {
98         offset = 1;
99     }
101     obj->regionId = SharedRegion_getId(params->sharedAddr);
102     obj->localState = NameServerRemoteNotify_IDLE;
103     obj->remoteState = NameServerRemoteNotify_IDLE;
105     cacheLineSize = SharedRegion_getCacheLineSize(obj->regionId);
106     if (cacheLineSize !=  0) {
107         /* assert that sharedAddr is cache aligned */
108         Assert_isTrue((((UArg)params->sharedAddr) %
109             cacheLineSize == 0),
110             Ipc_A_addrNotCacheAligned);
112         /* asset message structure size is cache aligned */
113         Assert_isTrue((sizeof(NameServerRemoteNotify_Message) %
114             cacheLineSize) == 0,
115             NameServerRemoteNotify_A_messageSize);
116     }
118     obj->msg[0] = (NameServerRemoteNotify_Message *)(params->sharedAddr);
119     obj->msg[1] = (NameServerRemoteNotify_Message *)((UArg)obj->msg[0] +
120                           sizeof(NameServerRemoteNotify_Message));
121     obj->gate = params->gate;
122     obj->remoteProcId = remoteProcId;
124     /* construct the remoteWait semaphore */
125     semHandle = NameServerRemoteNotify_Instance_State_semRemoteWait(obj);
126     Semaphore_Params_init(&semParams);
127     Semaphore_construct(Semaphore_struct(semHandle), 0, &semParams);
129     /* construct the multiBlock semaphore */
130     semHandle = NameServerRemoteNotify_Instance_State_semMultiBlock(obj);
131     Semaphore_Params_init(&semParams);
132     Semaphore_construct(Semaphore_struct(semHandle), 1, &semParams);
134     /* construct swi which handles the request message */
135     swiHandle = NameServerRemoteNotify_Instance_State_swiRequest(obj);
136     Swi_Params_init(&swiParams);
137     swiParams.arg0 = (UArg)obj;
138     swiParams.priority = 0; /* lowest priority */
139     Swi_construct(Swi_struct(swiHandle),
140              (ti_sysbios_knl_Swi_FuncPtr)NameServerRemoteNotify_swiFxnRequest,
141              &swiParams, eb);
143     /* construct swi which handles the response message */
144     swiHandle = NameServerRemoteNotify_Instance_State_swiResponse(obj);
145     Swi_Params_init(&swiParams);
146     swiParams.arg0 = (UArg)obj;
147     swiParams.priority = 0; /* lowest priority */
148     Swi_construct(Swi_struct(swiHandle),
149              (ti_sysbios_knl_Swi_FuncPtr)NameServerRemoteNotify_swiFxnResponse,
150              &swiParams, eb);
152     /* initialize own side of message struct only */
153     obj->msg[offset]->requestStatus = 0;
154     obj->msg[offset]->value = 0;
155     obj->msg[offset]->valueLen = 0;
157     memset(obj->msg[offset]->instanceName, 0,
158                sizeof(obj->msg[offset]->instanceName));
159     memset(obj->msg[offset]->name, 0,
160                sizeof(obj->msg[offset]->name));
162     /* determine cacheability of the object from the regionId */
163     obj->cacheEnable = SharedRegion_isCacheEnabled(obj->regionId);
164     if (obj->cacheEnable) {
165         /* write back shared memory that was modified */
166         Cache_wbInv(obj->msg[offset], sizeof(NameServerRemoteNotify_Message),
167                     Cache_Type_ALL, TRUE);
168     }
170     /* register notify callback function to handle message notifications */
171     status = Notify_registerEventSingle(remoteProcId, 0,
172             NameServerRemoteNotify_notifyEventId,
173             (Notify_FnNotifyCbck)NameServerRemoteNotify_cbFxn, (UArg)obj);
175     /* if not successful return */
176     if (status < 0) {
177         Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0);
178         return (1);
179     }
181     /* register the remote driver with NameServer */
182     ti_sdo_utils_NameServer_registerRemoteDriver(
183             NameServerRemoteNotify_Handle_upCast(obj), remoteProcId);
185     return (0);
188 /*
189  *  ======== NameServerRemoteNotify_Instance_finalize ========
190  */
191 Void NameServerRemoteNotify_Instance_finalize(
192         NameServerRemoteNotify_Object *obj, Int status)
194     Semaphore_Handle  semHandle;
195     Swi_Handle        swiHandle;
197     if (status == 0) {
198         /* unregister remote driver from NameServer module */
199         ti_sdo_utils_NameServer_unregisterRemoteDriver(obj->remoteProcId);
201         /* unregister event from Notify module */
202         Notify_unregisterEventSingle(obj->remoteProcId, 0,
203                 NameServerRemoteNotify_notifyEventId);
204     }
206     semHandle = NameServerRemoteNotify_Instance_State_semRemoteWait(obj);
207     if (semHandle != NULL) {
208         Semaphore_destruct(Semaphore_struct(semHandle));
209     }
211     semHandle = NameServerRemoteNotify_Instance_State_semMultiBlock(obj);
212     if (semHandle != NULL) {
213         Semaphore_destruct(Semaphore_struct(semHandle));
214     }
216     swiHandle = NameServerRemoteNotify_Instance_State_swiRequest(obj);
217     if (swiHandle != NULL) {
218         Swi_destruct(Swi_struct(swiHandle));
219     }
221     swiHandle = NameServerRemoteNotify_Instance_State_swiResponse(obj);
222     if (swiHandle != NULL) {
223         Swi_destruct(Swi_struct(swiHandle));
224     }
227 /*
228  *************************************************************************
229  *                       Module functions
230  *************************************************************************
231  */
233 /*
234  *  ======== NameServerRemoteNotify_attach ========
235  */
236 Int NameServerRemoteNotify_attach(UInt16 remoteProcId, Ptr sharedAddr)
238     NameServerRemoteNotify_Params nsrParams;
239     NameServerRemoteNotify_Handle handle;
240     Int status = NameServerRemoteNotify_E_FAIL;
241     Error_Block eb;
243     /* Assert that the default GateMP is not NULL */
244     Assert_isTrue(GateMP_getDefaultRemote() != NULL, Ipc_A_internal);
246     Error_init(&eb);
248     /* Use default GateMP */
249     NameServerRemoteNotify_Params_init(&nsrParams);
250     nsrParams.gate = (ti_sdo_ipc_GateMP_Handle)GateMP_getDefaultRemote();
252     /* determine the address */
253     nsrParams.sharedAddr = sharedAddr;
255     /* create only if notify driver has been created to remote proc */
256     if (Notify_intLineRegistered(remoteProcId, 0)) {
257         handle = NameServerRemoteNotify_create(remoteProcId,
258                                                &nsrParams,
259                                                &eb);
260         if (handle != NULL) {
261             status = NameServerRemoteNotify_S_SUCCESS;
262         }
263     }
265     return (status);
268 /*
269  *  ======== NameServerRemoteNotify_cbFxn ========
270  */
271 Void NameServerRemoteNotify_cbFxn(UInt16 procId, UInt16 lineId, UInt32 eventId,
272         UArg arg, UInt32 payload)
274     NameServerRemoteNotify_Object *obj;
275     Swi_Handle swiHandle = NULL;
277     obj = (NameServerRemoteNotify_Object *)arg;
280     switch (payload)
281     {
282         case NameServerRemoteNotify_RequestMsg:
283             swiHandle = NameServerRemoteNotify_Instance_State_swiRequest(obj);
285             /* set object state (used by ROV) */
286             obj->remoteState = NameServerRemoteNotify_RECEIVE_REQUEST;
287             break;
289         case NameServerRemoteNotify_ResponseMsg:
290             swiHandle = NameServerRemoteNotify_Instance_State_swiResponse(obj);
292             /* set object state (used by ROV) */
293             obj->localState = NameServerRemoteNotify_RECEIVE_RESPONSE;
294             break;
296         default:
297             /* We should never get here but assert if we do */
298             Assert_isTrue(swiHandle != NULL, Ipc_A_internal);
299     }
300     if (swiHandle == NULL) {
301         return;
302     }
304     Swi_post(swiHandle);
307 /*
308  *  ======== NameServerRemoteNotify_detach ========
309  */
310 Int NameServerRemoteNotify_detach(UInt16 remoteProcId)
312     NameServerRemoteNotify_Handle handle;
313     Int status = NameServerRemoteNotify_S_SUCCESS;
315     for (handle = NameServerRemoteNotify_Object_first(); handle != NULL;
316         handle = NameServerRemoteNotify_Object_next(handle)) {
317         if (handle->remoteProcId == remoteProcId) {
318             break;
319         }
320     }
322     if (handle == NULL) {
323         status = NameServerRemoteNotify_E_FAIL;
324     }
325     else {
326         NameServerRemoteNotify_delete(&handle);
327     }
329     return (status);
332 /*
333  *  ======== NameServerRemoteNotify_get ========
334  */
335 Int NameServerRemoteNotify_get(NameServerRemoteNotify_Object *obj,
336         String instanceName, String name, Ptr value, UInt32 *valueLen,
337         ISync_Handle syncHandle, Error_Block *eb)
339     Int len;
340     Int retval = NameServer_E_NOTFOUND;
341     Int offset = 0;
342     Int status;
343     Int notifyStatus;
344     Semaphore_Handle semRemoteWait;
345     Semaphore_Handle semMultiBlock;
347     Assert_isTrue(*valueLen <= 300, NameServerRemoteNotify_A_invalidValueLen);
349     semRemoteWait = NameServerRemoteNotify_Instance_State_semRemoteWait(obj);
350     semMultiBlock = NameServerRemoteNotify_Instance_State_semMultiBlock(obj);
352     /* prevent multiple threads from entering */
353     Semaphore_pend(semMultiBlock, BIOS_WAIT_FOREVER);
355     if (MultiProc_self() > obj->remoteProcId) {
356         offset = 1;
357     }
359     if (obj->cacheEnable) {
360         /* Make sure there's no outstanding message */
361         Cache_inv(obj->msg[offset], sizeof(NameServerRemoteNotify_Message),
362                   Cache_Type_ALL, TRUE);
363     }
365     /* this is a request message */
366     obj->msg[offset]->requestStatus = 0;
367     obj->msg[offset]->valueLen = *valueLen;
369     /* copy the name of instance into shared memory */
370     len = strlen(instanceName);
371     strncpy((Char *)obj->msg[offset]->instanceName, instanceName, len + 1);
373     /* copy the name of nameserver entry into shared memory */
374     len = strlen(name);
375     strncpy((Char *)obj->msg[offset]->name, name, len + 1);
377     /* set object state (used by ROV) */
378     obj->localState = NameServerRemoteNotify_SEND_REQUEST;
380     if (obj->cacheEnable) {
381         Cache_wbInv(obj->msg[offset], sizeof(NameServerRemoteNotify_Message),
382                     Cache_Type_ALL, TRUE);
383     }
385     /*
386      *  Send the notification to remote processor. Do not wait here since
387      *  we hold the GateMP.
388      */
389     notifyStatus = Notify_sendEvent(obj->remoteProcId, 0,
390             NameServerRemoteNotify_notifyEventId,
391             NameServerRemoteNotify_RequestMsg, TRUE);
393     if (notifyStatus < 0) {
394         /* undo previous options */
395         obj->msg[offset]->valueLen = 0;
397         /* post the semaphore to make sure it doesn't block */
398         Semaphore_post(semMultiBlock);
400         return (retval);
401     }
403     /* pend here until we get a notification back from remote processor */
404     status = Semaphore_pend(semRemoteWait, NameServerRemoteNotify_timeout);
406     if (status == FALSE) {
407         retval = NameServer_E_TIMEOUT;
408     }
409     else {
410         /* getting here means we got the notification back */
412         if (obj->cacheEnable) {
413             Cache_inv(obj->msg[offset], sizeof(NameServerRemoteNotify_Message),
414                     Cache_Type_ALL, TRUE);
415         }
417         /* if successful request then copy to value */
418         if (obj->msg[offset]->requestStatus == TRUE) {
420             /* copy to value */
421             if (obj->msg[offset]->valueLen == sizeof(UInt32)) {
422                 memcpy(value, &(obj->msg[offset]->value), sizeof(UInt32));
423             }
424             else {
425                 memcpy(value, &(obj->msg[offset]->valueBuf),
426                        obj->msg[offset]->valueLen);
427             }
429             /* set length to amount of data that was copied */
430             *valueLen = obj->msg[offset]->valueLen;
432             /* set the status */
433             retval = NameServer_S_SUCCESS;
434         }
436         /* set object state (used by ROV) */
437         obj->localState = NameServerRemoteNotify_IDLE;
438     }
440     Semaphore_post(semMultiBlock);
442     return (retval);
445 /*
446  *  ======== NameServerRemoteNotify_sharedMemReq ========
447  */
448 SizeT NameServerRemoteNotify_sharedMemReq(Ptr sharedAddr)
450     /*
451      *  Two Message structs are required.
452      *  One for sending request and one for sending response.
453      */
454     if (ti_sdo_utils_MultiProc_numProcessors > 1) {
455         return (2 * sizeof(NameServerRemoteNotify_Message));
456     }
458     return (0);
461 /*
462  *  ======== NameServerRemoteNotify_swiFxnRequest ========
463  */
464 Void NameServerRemoteNotify_swiFxnRequest(UArg arg)
466     Int count = NameServer_E_FAIL;
467     Int remoteId;
468     UInt32 valueLen;
469     NameServer_Handle handle;
470     NameServerRemoteNotify_Object *obj;
471 #ifndef xdc_runtime_Assert_DISABLE_ALL
472     Int status;
473 #endif
475     obj = (NameServerRemoteNotify_Object *)arg;
477     /* compute index to remote message */
478     remoteId = (MultiProc_self() > obj->remoteProcId) ? 0 : 1;
480     if (obj->cacheEnable) {
481         Cache_inv(obj->msg[remoteId], sizeof(NameServerRemoteNotify_Message),
482                 Cache_Type_ALL, TRUE);
483     }
485     /* get the NameServer handle */
486     handle = NameServer_getHandle((String)obj->msg[remoteId]->instanceName);
487     valueLen = obj->msg[remoteId]->valueLen;
489     if (handle != NULL) {
490         /* Search for the NameServer entry */
491         if (valueLen == sizeof(UInt32)) {
492             count = NameServer_getLocalUInt32(handle,
493                 (String)obj->msg[remoteId]->name, &obj->msg[remoteId]->value);
494         }
495         else {
496             count = NameServer_getLocal(handle,
497                 (String)obj->msg[remoteId]->name,
498                 &obj->msg[remoteId]->valueBuf, &valueLen);
499         }
500     }
502     /*
503      *  If an entry was found, set requestStatus to TRUE
504      *  and valueLen to the size of data that was copied.
505      */
506     if (count == NameServer_S_SUCCESS) {
507         obj->msg[remoteId]->requestStatus = TRUE;
508         obj->msg[remoteId]->valueLen = valueLen;
509     }
511     /* set object state (used by ROV) */
512     obj->remoteState = NameServerRemoteNotify_SEND_RESPONSE;
514     if (obj->cacheEnable) {
515         Cache_wbInv(obj->msg[remoteId], sizeof(NameServerRemoteNotify_Message),
516                 Cache_Type_ALL, TRUE);
517     }
519     /* must wait to prevent dropped events, even though this is a swi */
520 #ifndef xdc_runtime_Assert_DISABLE_ALL
521     status =
522 #endif
523     Notify_sendEvent(obj->remoteProcId, 0,
524             NameServerRemoteNotify_notifyEventId,
525             NameServerRemoteNotify_ResponseMsg, TRUE);
527     /* The NS query could fail, but the reply should never fail */
528     Assert_isTrue(status >= 0, Ipc_A_internal);
530     /* set object state (used by ROV) */
531     obj->remoteState = NameServerRemoteNotify_IDLE;
534 /*
535  *  ======== NameServerRemoteNotify_swiFxnResponse ========
536  */
537 Void NameServerRemoteNotify_swiFxnResponse(UArg arg)
539     NameServerRemoteNotify_Object *obj;
540     Semaphore_Handle  sem;
542     obj = (NameServerRemoteNotify_Object *)arg;
544     /* post the semaphore to unblock waiting task */
545     sem = NameServerRemoteNotify_Instance_State_semRemoteWait(obj);
546     Semaphore_post(sem);
549 /*
550  *  ======== NameServerRemoteNotify_getHandle ========
551  */
552 NameServerRemoteNotify_Handle NameServerRemoteNotify_getHandle(
553     UInt16 remoteProcId)
555     NameServerRemoteNotify_Handle obj;
557     for (obj = NameServerRemoteNotify_Object_first(); obj != NULL;
558         obj = NameServerRemoteNotify_Object_next(obj)) {
559         if (obj->remoteProcId == remoteProcId) {
560             break;
561         }
562     }
564     return (obj);