am65xx: Update Resource type to match sciclient API change
[ipc/ipcdev.git] / qnx / src / api / gates / GateHWSpinlock.c
1 /*
2  * Copyright (c) 2013-2015, 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  *  ======== GateHWSpinlock.c ========
35  */
37 /* Standard headers */
38 #include <ti/ipc/Std.h>
40 /* Utilities & OSAL headers */
41 #include <ti/ipc/MultiProc.h>
42 #include <ti/ipc/GateMP.h>
44 #include <ti/syslink/inc/GateHWSpinlock.h>
45 #include <ti/syslink/inc/usr/Qnx/GateHWSpinlockDrv.h>
46 #include <ti/syslink/inc/GateHWSpinlockDrvDefs.h>
47 #include <ti/syslink/inc/_GateHWSpinlock.h>
49 #include <ti/syslink/utils/IGateProvider.h>
51 #include <ti/syslink/utils/GateMutex.h>
53 /* Module level headers */
54 #include <ti/syslink/utils/String.h>
56 #include <_IpcLog.h>
58 #include <assert.h>
59 #include <string.h>
60 #include <stdlib.h>
61 #include <sys/mman.h>
64 /* =============================================================================
65  * Structures & Enums
66  * =============================================================================
67  */
68 /* GateHWSpinlock instance object */
69 struct GateHWSpinlock_Object {
70     IGateProvider_SuperObject; /* For inheritance from IGateProvider */
71     UInt                        lockNum;
72     UInt                        nested;
73     IGateProvider_Handle        localGate;
74     int                         token;  /* HWSpinlock token */
75 };
78 /* =============================================================================
79  * Globals
80  * =============================================================================
81  */
82 GateHWSpinlock_Module_State _GateHWSpinlock_state =
83 {
84     .vAddr                  = NULL,
85     .gmHandle               = NULL,
86     .cfg.numLocks           = 128,
87     .cfg.baseAddr           = 0,
88     .cfg.offset             = 0,
89     .cfg.size               = 0,
90     .numLocks               = 128u
91 };
93 static GateHWSpinlock_Module_State *Mod = &_GateHWSpinlock_state;
95 static GateHWSpinlock_Params GateHWSpinlock_defInstParams =
96 {
97     .resourceId = 0,
98     .openFlag   = FALSE,
99     .regionId   = 0,
100     .sharedAddr = NULL
101 };
103 /* traces in this file are controlled via _GateHWSpinlock_verbose */
104 Bool _GateHWSpinlock_verbose = FALSE;
105 #define verbose _GateHWSpinlock_verbose
107 /* =============================================================================
108  * APIS
109  * =============================================================================
110  */
111 /*
112  *  Function to start the GateHWSpinlock module.
113  */
114 Int32 GateHWSpinlock_start(Void)
116     Int32                 status = GateHWSpinlock_S_SUCCESS;
117     UInt32                dst;
119     GateHWSpinlock_getConfig(&Mod->cfg);
121     /* map the hardware lock registers into the local address space */
122     if (status == GateHWSpinlock_S_SUCCESS) {
123         dst = (UInt32)mmap(NULL, Mod->cfg.size,
124                             (PROT_READ | PROT_WRITE | PROT_NOCACHE),
125                             (MAP_PHYS|MAP_SHARED), NOFD,
126                             (off_t)Mod->cfg.baseAddr);
128         if (dst == (UInt32)MAP_FAILED) {
129             PRINTVERBOSE0("GateHWSpinlock_start: Memory map failed")
130             status = GateHWSpinlock_E_OSFAILURE;
131         }
132         else {
133             Mod->vAddr = (UInt32 *)(dst + Mod->cfg.offset);
134             status = GateHWSpinlock_S_SUCCESS;
135         }
136     }
138     /* create GateMutex for local protection*/
139     if (status == GateHWSpinlock_S_SUCCESS) {
140         Mod->gmHandle = GateMutex_create(NULL, NULL);
142         if (Mod->gmHandle == NULL) {
143             PRINTVERBOSE0("GateHWSpinlock_start: GateMutex create failed")
144             status = GateHWSpinlock_E_FAIL;
145             GateHWSpinlock_stop();
146         }
147     }
149     return (status);
152 /*
153  *  Function to stop the GateHWSpinlock module.
154  */
155 Int GateHWSpinlock_stop(Void)
157     Int32               status = GateHWSpinlock_S_SUCCESS;
159     /* delete GateMutex */
160     if (Mod->gmHandle != NULL) {
161         status = GateMutex_delete(&Mod->gmHandle);
162     }
164     /* release lock register mapping */
165     if (Mod->vAddr != NULL) {
166         munmap((void *)Mod->vAddr, Mod->cfg.size);
167     }
169     return(status);
172 /*
173  *  Initialize parameter structure
174  */
175 Void GateHWSpinlock_Params_init(GateHWSpinlock_Params *params)
177     assert(params != NULL);
179     memcpy(params, &GateHWSpinlock_defInstParams,
180         sizeof(GateHWSpinlock_Params));
183 /*
184  * Create a GateHWSpinlock instance
185  */
186 /* TODO: change the function to accept a local gate. Do this on all platforms */
187 GateHWSpinlock_Handle GateHWSpinlock_create(GateHWSpinlock_LocalProtect
188     localProtect, const GateHWSpinlock_Params * params)
190     GateHWSpinlock_Object * obj = (GateHWSpinlock_Object *)calloc(1,
191         sizeof (GateHWSpinlock_Object));
193     if (!obj) {
194         PRINTVERBOSE0("GateHWSpinlock_create: memory allocation failure")
195         return NULL;
196     }
198     IGateProvider_ObjectInitializer(obj, GateHWSpinlock);
199     /* TODO: handle more local protection types */
200     obj->localGate = (IGateProvider_Handle)Mod->gmHandle;
201     obj->lockNum = params->resourceId;
202     obj->nested = 0;
204     return (GateHWSpinlock_Handle)obj;
207 /*
208  * Delete a GateHWSpinlock instance
209  */
210 Int GateHWSpinlock_delete (GateHWSpinlock_Handle * handle)
212     GateHWSpinlock_Object * obj;
213     Int  status = GateHWSpinlock_S_SUCCESS;
215     if (handle == NULL) {
216         return GateHWSpinlock_E_INVALIDARG;
217     }
218     if (*handle == NULL) {
219         return GateHWSpinlock_E_INVALIDARG;
220     }
222     obj = (GateHWSpinlock_Object *)(*handle);
224     free(obj);
225     *handle = NULL;
227     return (status);
230 /*
231  *  Enter a GateHWSpinlock instance
232  */
233 IArg GateHWSpinlock_enter(GateHWSpinlock_Object *obj)
235     volatile UInt32 *baseAddr = Mod->vAddr;
236     IArg key;
238     key = IGateProvider_enter(obj->localGate);
240     /* if gate already entered, just return with current key */
241     obj->nested++;
242     if (obj->nested > 1) {
243         return(key);
244     }
246     /* enter the spinlock */
247     while (1) {
248         /* read the spinlock, returns non-zero when we get it */
249         if (baseAddr[obj->lockNum] == 0) {
250             break;
251         }
252         obj->nested--;
253         IGateProvider_leave(obj->localGate, key);
254         key = IGateProvider_enter(obj->localGate);
255         obj->nested++; /* re-nest the gate */
256     }
258     return (key);
261 /*
262  *  Leave a GateHWSpinlock instance
263  */
264 Int GateHWSpinlock_leave(GateHWSpinlock_Object *obj, IArg key)
266     volatile UInt32 *baseAddr = Mod->vAddr;
268     obj->nested--;
270     /* release the spinlock if not nested */
271     if (obj->nested == 0) {
272         baseAddr[obj->lockNum] = 0;
273     }
275     IGateProvider_leave(obj->localGate, key);
277     return GateHWSpinlock_S_SUCCESS;