]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - qnx/src/ipc3x_dev/ti/syslink/ipc/hlos/knl/GateMP_daemon.c
Merge remote-tracking branch 'origin/3.00' into ipc-3.10-next
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / ipc / hlos / knl / GateMP_daemon.c
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  *  ======== GateMP_daemon.c ========
35  */
38 /* Standard headers */
39 #include <ti/ipc/Std.h>
41 /* Qnx specific header files */
42 #include <pthread.h>
44 /* System headers */
45 #include <sys/mman.h>
46 #include <stdlib.h>
47 #include <assert.h>
49 /* Module level headers */
50 #include <ti/ipc/GateMP.h>
51 #include <ti/ipc/NameServer.h>
52 #include <ti/ipc/MultiProc.h>
53 #include <_MultiProc.h>
54 #include <GateMP_config.h>
55 #include <_GateMP.h>
57 #include <ti/syslink/utils/IGateProvider.h>
58 #include <ti/syslink/inc/_GateMP_daemon.h>
59 #include <_IpcLog.h>
61 #if defined (__cplusplus)
62 extern "C" {
63 #endif
65 #define NUM_INFO_FIELDS       6    /* Number of fields in info entry */
67 /* Values used to populate the resource 'inUse' arrays */
68 #define UNUSED          ((UInt8)0)
69 #define USED            ((UInt8)1)
70 #define RESERVED        ((UInt8)-1)
72 /* Name of GateMP's nameserver */
73 #define GateMP_NAMESERVER  "GateMP"
75 /* =============================================================================
76  * Structures & Enums
77  * =============================================================================
78  */
80 /* structure for GateMP module state */
81 typedef struct {
82     Int               numRemoteSystem;
83     Int               numRemoteCustom1;
84     Int               numRemoteCustom2;
85     UInt8 *           remoteSystemInUse;
86     UInt8 *           remoteCustom1InUse;
87     UInt8 *           remoteCustom2InUse;
88     GateMP_Handle     defaultGate;
89     NameServer_Handle nameServer;
90     Bool              isSetup;
91 } GateMP_ModuleObject;
93 /* Internal functions */
94 static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr);
95 static Int GateMP_closeDefaultGate(GateMP_Handle *handlePtr);
97 /* =============================================================================
98  *  Globals
99  * =============================================================================
100  */
101 /*
102  * GateMP_state
103  */
104 static GateMP_ModuleObject GateMP_state = {
105     .numRemoteSystem                 = 0,
106     .numRemoteCustom1                = 0,
107     .numRemoteCustom2                = 0,
108     .remoteSystemInUse               = NULL,
109     .remoteCustom1InUse              = NULL,
110     .remoteCustom2InUse              = NULL,
111     .defaultGate                     = NULL,
112     .nameServer                      = NULL,
113     .isSetup                         = FALSE
114 };
116 static GateMP_ModuleObject * GateMP_module = &GateMP_state;
118 /* =============================================================================
119  * APIS
120  * =============================================================================
121  */
123 /* Function to setup the gatemp module. */
124 Int GateMP_setup(Void)
126     Int               status = GateMP_S_SUCCESS;
127     NameServer_Params params;
128     UInt32            nsValue[NUM_INFO_FIELDS];
129     UInt32            len;
131     NameServer_Params_init(&params);
132     params.maxRuntimeEntries = MAX_RUNTIME_ENTRIES;
133     params.maxNameLen = MAX_NAME_LEN;
135     /* Assume info entry has more fields than other entries */
136     params.maxValueLen = NUM_INFO_FIELDS * sizeof(UInt32);
138     GateMP_module->nameServer =
139                 NameServer_create(GateMP_NAMESERVER, &params);
141     if (GateMP_module->nameServer == NULL) {
142         status = GateMP_E_FAIL;
143         LOG0("GateMP_setup: NameServer_create failed\n");
144     }
146     if (status == GateMP_S_SUCCESS) {
147         do {
148             sleep(1);   /* Give the slaves some time to get NameServer ready */
149             status = GateMP_openDefaultGate(&GateMP_module->defaultGate);
150         } while (status == GateMP_E_NOTFOUND);
153         if (status < 0) {
154             LOG0("GateMP_setup: failed to open default gate\n");
155             status = GateMP_E_FAIL;
156         }
157     }
159     if (status == GateMP_S_SUCCESS) {
160         /* Process global info NameServer entry */
161         len = sizeof(nsValue);
163         status = NameServer_get(GateMP_module->nameServer, "_GateMP_TI_info",
164             &nsValue, &len, NULL);
166         if (status < 0) {
167             LOG0("GateMP_setup: failed to find info entry\n");
168             status = GateMP_E_NOTFOUND;
169         }
170         else {
171             GateMP_module->numRemoteSystem = nsValue[3];
172             GateMP_module->numRemoteCustom1 = nsValue[4];
173             GateMP_module->numRemoteCustom2 = nsValue[5];
175             /* Map InUse arrays to daemon's address space */
176             GateMP_module->remoteSystemInUse = mmap(NULL,
177                 GateMP_module->numRemoteSystem * sizeof (UInt8),
178                 (PROT_READ|PROT_WRITE|PROT_NOCACHE),
179                 (MAP_PHYS|MAP_SHARED), NOFD, (off_t)nsValue[0]);
180             if (GateMP_module->remoteSystemInUse == MAP_FAILED) {
181                  GateMP_module->remoteSystemInUse = NULL;
182                  status = GateMP_E_MEMORY;
183                  LOG0("Failed to map remoteSystemInUse to host address space!");
184             }
186             if (status == GateMP_S_SUCCESS) {
187                 GateMP_module->remoteCustom1InUse = mmap(NULL,
188                     GateMP_module->numRemoteCustom1 * sizeof (UInt8),
189                     (PROT_READ|PROT_WRITE|PROT_NOCACHE),
190                     (MAP_PHYS|MAP_SHARED), NOFD, (off_t)nsValue[1]);
191                 if (GateMP_module->remoteCustom1InUse == MAP_FAILED) {
192                     GateMP_module->remoteCustom1InUse = NULL;
193                     status = GateMP_E_MEMORY;
194                     LOG0("Failed to map remoteSystemInUse to host address" \
195                         " space!");
196                 }
197             }
199             if (status == GateMP_S_SUCCESS) {
200                 GateMP_module->remoteCustom2InUse = mmap(NULL,
201                     GateMP_module->numRemoteCustom2 * sizeof (UInt8),
202                     (PROT_READ|PROT_WRITE|PROT_NOCACHE),
203                     (MAP_PHYS|MAP_SHARED), NOFD, (off_t)nsValue[2]);
204                 if (GateMP_module->remoteCustom2InUse == MAP_FAILED) {
205                     GateMP_module->remoteCustom2InUse = NULL;
206                     status = GateMP_E_MEMORY;
207                     LOG0("Failed to map remoteSystemInUse to host address" \
208                         " space!");
209                 }
210             }
211         }
212     }
214     /* TODO: setup the proxy map */
216     /* clean up if error */
217     if (status < 0) {
218         GateMP_destroy();
219     }
221     GateMP_module->isSetup = TRUE;
223     return (status);
226 Void GateMP_destroy(Void)
228     if (GateMP_module->remoteSystemInUse) {
229         munmap((unsigned int *)GateMP_module->remoteSystemInUse,
230             GateMP_module->numRemoteSystem * sizeof (UInt8));
231         GateMP_module->remoteSystemInUse = NULL;
232     }
234     if (GateMP_module->remoteCustom1InUse) {
235         munmap((unsigned int *)GateMP_module->remoteCustom1InUse,
236             GateMP_module->numRemoteCustom1 * sizeof (UInt8));
237         GateMP_module->remoteCustom1InUse = NULL;
238     }
240     if (GateMP_module->remoteCustom2InUse) {
241         munmap((unsigned int *)GateMP_module->remoteCustom2InUse,
242             GateMP_module->numRemoteCustom2 * sizeof (UInt8));
243         GateMP_module->remoteCustom2InUse = NULL;
244     }
246     if (GateMP_module->defaultGate) {
247         GateMP_closeDefaultGate(&GateMP_module->defaultGate);
248     }
250     if (GateMP_module->nameServer) {
251         NameServer_delete(&GateMP_module->nameServer);
252         GateMP_module->nameServer = NULL;
253     }
255     GateMP_module->isSetup = FALSE;
257     return;
260 /* Open default gate during GateMP_setup. Should only be called once */
261 static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr)
263     Int             status = GateMP_S_SUCCESS;
264     UInt32          len;
265     UInt32          nsValue[4];
266     GateMP_Object * obj = NULL;
267     UInt32          arg;
268     UInt32          mask;
269     UInt32          creatorProcId;
271     GateMP_RemoteSystemProxy_Params     systemParams;
273     /* assert that a valid pointer has been supplied */
274     if (handlePtr == NULL) {
275         LOG0("GateMP_open: argument cannot be null\n");
276         status = GateMP_E_INVALIDARG;
277     }
279     if (status == GateMP_S_SUCCESS) {
280         len = sizeof(nsValue);
282         status = NameServer_get(GateMP_module->nameServer, "_GateMP_TI_dGate",
283             &nsValue, &len, NULL);
285         if (status < 0) {
286             *handlePtr = NULL;
287             status = GateMP_E_NOTFOUND;
288         }
289         else {
290             arg = nsValue[2];
291             mask = nsValue[3];
292             creatorProcId = nsValue[1] >> 16;
293         }
294     }
296     if (status == GateMP_S_SUCCESS) {
297         /* allocate the instance object */
298         obj = (GateMP_Object *)calloc(1, sizeof (GateMP_Object));
299         if (obj != NULL) {
300             obj->localGate  = NULL;  /* TODO: create the local gate instance */
301             obj->localProtect  = GETLOCAL(mask);
302             obj->remoteProtect = GETREMOTE(mask);
303             obj->nsKey         = 0;
304             obj->numOpens      = 1;
305             obj->objType       = Ipc_ObjType_OPENDYNAMIC;
306             obj->resourceId    = arg;
308             assert(obj->remoteProtect == GateMP_RemoteProtect_SYSTEM);
310             /* create the proxy object */
311             GateMP_RemoteSystemProxy_Params_init(&systemParams);
312             systemParams.resourceId = obj->resourceId;
313             systemParams.openFlag = TRUE;
315             /*
316              * TODO: Currently passing in localProtect instead of localGate,
317              * since GateHWSpinlock owns the local gate
318              */
319             obj->gateHandle = (IGateProvider_Handle)
320                 GateMP_RemoteSystemProxy_create(obj->localProtect,
321                     &systemParams);
323             if (obj->gateHandle == NULL) {
324                 LOG0("GateMP_openDefaultGate: failed to create proxy\n");
325                 free(obj);
326                 obj = NULL;
327             }
328         }
329         else {
330             LOG0("GateMP_openDefaultGate: Memory allocation failed")
331         }
333         if (obj == NULL) {
334             status = GateMP_E_FAIL;
335         }
336     }
338     /* Return the "opened" GateMP instance  */
339     *handlePtr = (GateMP_Handle)obj;
341     return status;
344 static Int GateMP_closeDefaultGate(GateMP_Handle *handlePtr)
346     Int status = GateMP_S_SUCCESS;
347     GateMP_Object * obj = *(GateMP_Object **)handlePtr;
349     if (obj->gateHandle != NULL) {
350         /* Default gate is always of type System when more than 1 processor */
351         GateMP_RemoteSystemProxy_delete(
352             (GateMP_RemoteSystemProxy_Handle *)&obj->gateHandle);
353     }
355     free(*handlePtr);
356     *handlePtr = NULL;
358     return(status);
361 Int GateMP_getFreeResource(GateMP_RemoteProtect type)
363     IArg   key;
364     Bool   flag = FALSE;
365     Int    resourceId = -1;
366     UInt8* inUse = NULL;
367     Int    num = 0;
369     /* Remote case */
370     switch (type) {
371         /* TODO: currently only support System proxy */
372         case GateMP_RemoteProtect_SYSTEM:
373         case GateMP_RemoteProtect_CUSTOM1:
374         case GateMP_RemoteProtect_CUSTOM2:
375             inUse = GateMP_module->remoteSystemInUse;
376             num = GateMP_module->numRemoteSystem;
377             break;
379         default:
380             LOG0("GateMP_getFreeResource: Invalid remote protection type\n");
381             break;
382     }
384     if (inUse != NULL) {
385         assert(GateMP_module->defaultGate != NULL);
386         key = GateMP_enter(GateMP_module->defaultGate);
388         /*
389          *  Find a free resource id. Note: zero is reserved on the
390          *  system proxy for the default gate.
391          */
392         for (resourceId = 0; resourceId < num; resourceId++) {
393             /*
394              *  If not in-use, set the inUse to TRUE to prevent other
395              *  creates from getting this one.
396              */
397             if (inUse[resourceId] == UNUSED) {
398                 flag = TRUE;
400                 /* Denote in shared memory that the resource is used */
401                 inUse[resourceId] = USED;
402                 break;
403             }
404         }
406         GateMP_leave(GateMP_module->defaultGate, key);
407     }
409     if (flag == FALSE) {
410         resourceId = -1;
411     }
413     return (resourceId);
416 Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
418     Int    status = GateMP_S_SUCCESS;
419     IArg   key;
420     UInt8* inUse = NULL;
421     Int    num = 0;
423     /* Remote case */
424     switch (type) {
425         /* TODO: currently only support System proxy */
426         case GateMP_RemoteProtect_SYSTEM:
427         case GateMP_RemoteProtect_CUSTOM1:
428         case GateMP_RemoteProtect_CUSTOM2:
429             inUse = GateMP_module->remoteSystemInUse;
430             num = GateMP_module->numRemoteSystem;
431             break;
433         default:
434             LOG0("GateMP_releaseResource: Invalid remote protection type\n");
435             status = GateMP_E_FAIL;
436             break;
437     }
439     if ((inUse != NULL) && (id < num)) {
440         assert(GateMP_module->defaultGate != NULL);
441         key = GateMP_enter(GateMP_module->defaultGate);
442         inUse[id] = UNUSED;
443         GateMP_leave(GateMP_module->defaultGate, key);
444     }
445     else {
446         /* Should not happen if module is properly setup */
447         status = GateMP_E_FAIL;
448     }
450     return (status);
453 Int GateMP_getNumResources(GateMP_RemoteProtect type)
455     Int   num = -1;
457     /* Remote case */
458     switch (type) {
459         /* TODO: currently only support System proxy */
460         case GateMP_RemoteProtect_SYSTEM:
461         case GateMP_RemoteProtect_CUSTOM1:
462         case GateMP_RemoteProtect_CUSTOM2:
463             num = GateMP_module->numRemoteSystem;
464             break;
466         default:
467             LOG0("GateMP_getNumResources: Invalid remote protection type\n");
468             break;
469     }
471     return (num);
474 NameServer_Handle GateMP_getNameServer(Void)
476     return (GateMP_module->nameServer);
479 Bool GateMP_isSetup(Void)
481     return (GateMP_module->isSetup);
484 IArg GateMP_enter(GateMP_Handle handle)
486     GateMP_Object * obj;
487     IArg            key;
489     obj = (GateMP_Object *)handle;
490     key = IGateProvider_enter(obj->gateHandle);
492     return(key);
495 Void GateMP_leave(GateMP_Handle handle, IArg key)
497     GateMP_Object *obj;
499     obj = (GateMP_Object *)handle;
500     IGateProvider_leave(obj->gateHandle, key);