a1a8c695a6196acc8db68e8d14db007ce091c920
[keystone-rtos/netapi.git] / ti / runtime / hplib / src / osal.c
1 /******************************************************************************
2  * FILE PURPOSE:  Functions to OSAL related routines for running NWAL, PA, QMSS,etc
3  ******************************************************************************
4  * FILE NAME:   osal.c
5  *
6  * DESCRIPTION: Functions to initialize framework resources for running NWAL
7  *
8  * REVISION HISTORY:
9  *
10  *  Copyright (c) Texas Instruments Incorporated 2010-2011
11  * 
12  *  Redistribution and use in source and binary forms, with or without 
13  *  modification, are permitted provided that the following conditions 
14  *  are met:
15  *
16  *    Redistributions of source code must retain the above copyright 
17  *    notice, this list of conditions and the following disclaimer.
18  *
19  *    Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the 
21  *    documentation and/or other materials provided with the   
22  *    distribution.
23  *
24  *    Neither the name of Texas Instruments Incorporated nor the names of
25  *    its contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
29  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
30  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
32  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
33  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
34  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
37  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
38  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  */
42 #ifndef DISABLE_OSAL
44 /* CSL RL includes */
45 #include <ti/csl/csl_cache.h>
47 #include <stdlib.h>
48 #include <stdio.h>
50 #include "hplib.h"
51 #include <unistd.h>
52 #include <sys/mman.h>
53 #include <sys/types.h>
54 #include <sys/stat.h>
55 #include <sys/ioctl.h>
56 #include <fcntl.h>
57 #include <errno.h>
58 #include <string.h>
59 //#include "netapi_util.h"
60 #include "hplibmod.h"
61 #include <ti/drv/sa/sa_osal.h>
62 #include <ti/runtime/pktlib/pktlib.h>
64 typedef struct osal_shm_Tag
65 {
66     hplib_spinLock_T qmss_lock;
67     hplib_spinLock_T nwal_lock;
68     hplib_spinLock_T hplib_lock;
69     hplib_spinLock_T cppi_lock;
70     hplib_spinLock_T sa_lock;
71     hplib_spinLock_T pktlib_lock;
72     int init_done;
73 } osal_shm_T;
75 void* pBase = NULL;
76 osal_shm_T* posalShm;
78 uint32_t              Osal_qmss_MallocCounter =0;
79 uint32_t              Osal_qmss_FreeCounter =0;
80 uint32_t              Osal_cppi_MallocCounter =0;
81 uint32_t              Osal_cppi_FreeCounter =0;
83 static __thread int our_core = 0;
84 static __thread HPLIB_SPINLOCK_IF_T* p_lock_if;
86 void* Osal_saGetSCPhyAddr(void* vaddr);
88 static unsigned int cache_op_cycles=0;
89 static unsigned int n_cache_op_cycles=0;
90 void Osal_cache_op_measure_reset(void) { cache_op_cycles=0; n_cache_op_cycles=0;}
91 unsigned int Osal_cache_op_measure(unsigned long long * p_n) { *p_n = n_cache_op_cycles;  return cache_op_cycles;}
93 HPLIB_SPINLOCK_IF_T lock_if_lol =
94 {
95     hplib_mSpinLockInit,
96     hplib_mSpinLockTryLock,
97     hplib_mSpinLockIsLocked,
98     hplib_mSpinLockLock,
99     hplib_mSpinLockUnlock,
100     hplib_mRWLockInit,
101     hplib_mRWLockWriteLock,
102     hplib_mRWLockWriteUnlock,
103     hplib_mRWLockReadLock,
104     hplib_mRWLockReadUnlock
105 };
107 HPLIB_SPINLOCK_IF_T lock_if_mp =
109     hplib_mSpinLockInit,
110     hplib_mSpinLockTryLock,
111     hplib_mSpinLockIsLocked,
112     hplib_mSpinLockLockMP,
113     hplib_mSpinLockUnlockMP,
114     hplib_mRWLockInit,
115     hplib_mRWLockWriteLockMP,
116     hplib_mRWLockWriteUnlockMP,
117     hplib_mRWLockReadLockMP,
118     hplib_mRWLockReadUnlockMP
119 };
121 /* This is called 1 Time per system boot by the global master process */
122 hplib_RetValue hplib_utilOsalCreate()
124     hplib_RetValue retVal = hplib_OK;
125     pBase = hplib_shmOpen();
127     if ((retVal = hplib_shmAddEntry(pBase, sizeof(osal_shm_T), OSAL_ENTRY)) !=
128         hplib_OK)
129     {
130         hplib_Log("hplib_utilOsalCreate: hplib_shmAddEntry failed for OSAL_ENTRY\n");
131         return retVal;
132     }
133     else
134     {
135         posalShm = (osal_shm_T*)hplib_shmGetEntry(pBase, OSAL_ENTRY);
136         posalShm->init_done = 0;
137     }
139     posalShm = (osal_shm_T*)hplib_shmGetEntry(pBase, OSAL_ENTRY);
141     posalShm->qmss_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
142     posalShm->nwal_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
143     posalShm->hplib_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
144     posalShm->cppi_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
145     posalShm->sa_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
146     posalShm->pktlib_lock = hplib_spinLock_UNLOCKED_INITIALIZER;
148     posalShm->init_done = 1;
149     return retVal;
152 /* This can be called for every other process which is NOT the global master process */
153 hplib_RetValue Osal_start(void *pShmBase)
155     if (!pBase)
156         pBase = pShmBase;
158     posalShm = (osal_shm_T*)hplib_shmGetEntry(pBase, OSAL_ENTRY);
159     if (posalShm)
160     {
161         if(posalShm->init_done)
162             return hplib_OK;
163     }
164     return hplib_FAILURE;
167 void *  Osal_qmssMtCsEnter()
169     p_lock_if->lock(&posalShm->qmss_lock);
170     return NULL;
174 void Osal_qmssMtCsExit(void *key)
176     p_lock_if->unlock(&posalShm->qmss_lock);
177     return;
180 void Osal_nwalCsEnter(uint32_t *key)
182     p_lock_if->lock(&posalShm->nwal_lock);
185 void Osal_nwalCsExit(uint32_t key)
187     p_lock_if->unlock(&posalShm->nwal_lock);
190 void Osal_qmssLog ( String fmt, ... )
192     return;
196 void Osal_cppiCsEnter (uint32_t *key)
198     p_lock_if->lock(&posalShm->cppi_lock);
201 void Osal_cppiCsExit (uint32_t key)
203     p_lock_if->unlock(&posalShm->cppi_lock);
206 void Osal_paBeginMemAccess (Ptr addr, uint32_t size)
208     /*No implementation required for ARM*/
211 void Osal_paEndMemAccess (Ptr addr, uint32_t size)
212 {      
213     /*No implementation required for ARM*/
215 void Osal_paMtCsEnter (uint32_t *key)
217     /*No implementation required for ARM*/
219 void Osal_paMtCsExit (uint32_t key)
221     /*No implementation required for ARM*/
224 void*  Osal_qmssCsEnter ()
226     p_lock_if->lock(&posalShm->qmss_lock);
227     return NULL;
230 void Osal_qmssCsExit (void *  key)
232     p_lock_if->unlock(&posalShm->qmss_lock);
235 Ptr Osal_qmssMalloc (uint32_t num_bytes)
237     Ptr ret;
239     Osal_qmss_MallocCounter++;
240     ret = malloc (num_bytes);
241     return ret;
244 void Osal_qmssFree (Ptr ptr, uint32_t size)
246     /* Increment the free counter. */
247     Osal_qmss_FreeCounter++;    
248     free(ptr);
251 Ptr Osal_cppiMalloc (uint32_t num_bytes)
253     Ptr ret;
254     
255     Osal_cppi_MallocCounter++;
256     //num_bytes += (CACHE_L2_LINESIZE-1);
257         num_bytes += (127);
258     ret = malloc (num_bytes);
259     return ret;
262 void Osal_cppiFree (Ptr ptr, uint32_t size)
264     /* Increment the free counter. */
265     Osal_cppi_FreeCounter++;    
266     free(ptr);    
269 void Osal_qmssBeginMemAccess (void *blockPtr, uint32_t size)
271     return;
274 void  Osal_qmssEndMemAccess (void *blockPtr, uint32_t size)
276     return;
279 void Osal_cppiBeginMemAccess (void *blockPtr, uint32_t size)
281     return;
284 void Osal_cppiEndMemAccess (void *blockPtr, uint32_t size)
286     return;
289 void Osal_nwalInvalidateCache (void *blockPtr, uint32_t size)
291     return;
294 void Osal_nwalWriteBackCache (void *blockPtr, uint32_t size)
296     return;
299 uint32_t Osal_nwalGetCacheLineSize (void )
301     /* By default assumes L2 cache line is enabled. If not return CACHE_L1D_LINESIZE */
302     return (CACHE_L2_LINESIZE);
305 /********************************************************************
306  * FUNCTION PURPOSE: Convert local address to global
307  ********************************************************************
308  * DESCRIPTION: Returns global address
309  ********************************************************************/
311 unsigned int Osal_nwalLocToGlobAddr(unsigned int x)
313     return x;
317 void Osal_nwalSetProcId (uint16_t core_id )
319     our_core = core_id;
324 void Osal_setHplibSpinLockIfType(hplib_spinLock_Type if_type )
326     if (if_type == hplib_spinLock_Type_MP)
327         p_lock_if = &lock_if_mp;
328     else
329         p_lock_if = &lock_if_lol;
331 uint16_t Osal_nwalGetProcId (void )
333     return our_core;
336 uint64_t Osal_nwalGetTimeStamp(void)
338     return hplib_mUtilGetTimestamp();
341 uint16_t Osal_saGetProcId (void )
343     return 0;
346 void* Osal_saGetSCPhyAddr(void* vaddr)
348     if(vaddr == NULL)
349     {
350         return NULL;
351     }
352     return (void *)(memPoolAddr[0].memStartPhy + ((uint8_t*) vaddr - memPoolAddr[0].memStart));
355 void Osal_saBeginScAccess (void* addr, uint32_t size)
357     hplib_cacheInv(addr,size);
360 void Osal_saEndScAccess   (void* addr, uint32_t size)
362     hplib_cacheWb(addr,size);
366 void Osal_saCsEnter (uint32_t *key)
368     p_lock_if->lock(&posalShm->sa_lock);
371 void Osal_saCsExit (uint32_t key)
373     p_lock_if->unlock(&posalShm->sa_lock);
377 void Osal_saMtCsEnter (uint32_t *key)
379     p_lock_if->lock(&posalShm->sa_lock);
382 void Osal_saMtCsExit (uint32_t key)
384     p_lock_if->unlock(&posalShm->sa_lock);
387 void Osal_saBeginMemAccess (void *blockPtr, uint32_t size)
389     /*  not required on ARM */
390     /*Osal_invalidateCache(blockPtr,size); */
393 void Osal_saEndMemAccess (void *blockPtr, uint32_t size)
395     /*  not required on ARM */
396     /*  Osal_writeBackCache(blockPtr,size); */
399 int   Osal_saGetSysEndianMode(void)
401 #if defined( _BIG_ENDIAN ) 
402     return((int)sa_SYS_ENDIAN_MODE_BIG);
403 #else
404     return((int)sa_SYS_ENDIAN_MODE_LITTLE);
405 #endif
408 void Osal_pktLibBeginMemAccess(void* ptr, uint32_t size)
410     //Osal_invalidateCache(ptr,size);
414 void Osal_pktLibEndMemAccess(void* ptr, uint32_t size)
416     //Osal_writeBackCache(ptr,size);
420 void Osal_pktLibBeginPktAccess(Pktlib_HeapHandle heapHandle, Ti_Pkt* ptrPkt, uint32_t size)
422     /*  not required on ARM */
423     /* Osal_invalidateCache(ptrPkt,size); */
427 void Osal_pktLibEndPktAccess(Pktlib_HeapHandle heapHandle, Ti_Pkt* ptrPkt, uint32_t size)
428 {    
430     /* Cache Write back for the packet. Currently being disabled as it will be done during
431      * QMSS Push operation
432      
433     Osal_writeBackCache((void *)ptrPkt,size);
434     */
438 void* Osal_pktLibEnterCriticalSection(Pktlib_HeapHandle heapHandle)
440     /* TODO: We should use the 'heapHandle' and compare it with what we got from the
441      * 'create/find' HEAP API & depending upon the comparison take appropriate action. 
442      * Implementations here could range from a MULTI-THREAD protection if the packets in 
443      * the heap are being accessed across multiple threads or MULTI-CORE if the packets
444      * are being accessed across multiple cores and features: split and clone are used.
445      * For NWAL layer no protection required.
446      *
447      * For testing we are not doing any of this so we are simply setting it to NOOP */
448     p_lock_if->lock(&posalShm->pktlib_lock);
449     return NULL;
453 void  Osal_pktLibExitCriticalSection(Pktlib_HeapHandle heapHandle, void* csHandle)
455     /* TODO: We should use the 'heapHandle' and compare it with what we got from the
456      * 'create/find' HEAP API & depending upon the comparison take appropriate action. 
457      * Implementations here could range from a MULTI-THREAD protection if the packets in 
458      * the heap are being accessed across multiple threads or MULTI-CORE if the packets
459      * are being accessed across multiple cores and features: split and clone are used.
460      * For NWAL layer no protection required.. 
461      *
462      * For testing we are not doing any of this so we are simply setting it to NOOP */
463     p_lock_if->unlock(&posalShm->pktlib_lock);
464     return;
467 void* Osal_pktLibPhyToVirt(void *ptr)
469     return(hplib_mVMPhyToVirt(ptr));
472 void* Osal_qmssVirtToPhy (void *ptr)
474     return hplib_mVMVirtToPhy(ptr);
477 void * Osal_qmssPhyToVirt (void *ptr)
479     return hplib_mVMPhyToVirt(ptr);
482 /******************************************************************************
483 * Function to traverse a CPPI descriptor and convert all address references
484 * from virtual to physical.
485 ******************************************************************************/
486 //#define ASSUME_ALL_DESCRIPTOR   //define this if mono and host descriptors are present, else don't
487                                   //define and just host will be assumed (more efficient)
488 void* Osal_qmssConvertDescVirtToPhy(uint32_t QID, void *descAddr)
490     return hplib_mVMConvertDescVirtToPhy(descAddr);
492 /******************************************************************************
493 * Function to traverse a CPPI descriptor and convert all address references
494 * from physical to virtual.
495 ******************************************************************************/
496 void* Osal_qmssConvertDescPhyToVirt(uint32_t QID, void *descAddr)
498     return hplib_mVMConvertDescPhyToVirt(descAddr);
500 void* Osal_stubCsEnter (void)
502     return NULL;
504 void Osal_stubCsExit (void *CsHandle)
506     return;
509 /* Internal Function used by hplib */
510 void* Osal_hplibCsEnter (void)
512     p_lock_if->lock(&posalShm->hplib_lock);
513     return NULL;
515 /* Internal Function used by hplib */
517 void Osal_hplibCsExit (void *CsHandle)
519     p_lock_if->unlock(&posalShm->hplib_lock);
520     return;
522 #endif