a1a8c695a6196acc8db68e8d14db007ce091c920
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 =
108 {
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()
123 {
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;
150 }
152 /* This can be called for every other process which is NOT the global master process */
153 hplib_RetValue Osal_start(void *pShmBase)
154 {
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;
165 }
167 void * Osal_qmssMtCsEnter()
168 {
169 p_lock_if->lock(&posalShm->qmss_lock);
170 return NULL;
171 }
174 void Osal_qmssMtCsExit(void *key)
175 {
176 p_lock_if->unlock(&posalShm->qmss_lock);
177 return;
178 }
180 void Osal_nwalCsEnter(uint32_t *key)
181 {
182 p_lock_if->lock(&posalShm->nwal_lock);
183 }
185 void Osal_nwalCsExit(uint32_t key)
186 {
187 p_lock_if->unlock(&posalShm->nwal_lock);
188 }
190 void Osal_qmssLog ( String fmt, ... )
191 {
192 return;
193 }
196 void Osal_cppiCsEnter (uint32_t *key)
197 {
198 p_lock_if->lock(&posalShm->cppi_lock);
199 }
201 void Osal_cppiCsExit (uint32_t key)
202 {
203 p_lock_if->unlock(&posalShm->cppi_lock);
204 }
206 void Osal_paBeginMemAccess (Ptr addr, uint32_t size)
207 {
208 /*No implementation required for ARM*/
209 }
211 void Osal_paEndMemAccess (Ptr addr, uint32_t size)
212 {
213 /*No implementation required for ARM*/
214 }
215 void Osal_paMtCsEnter (uint32_t *key)
216 {
217 /*No implementation required for ARM*/
218 }
219 void Osal_paMtCsExit (uint32_t key)
220 {
221 /*No implementation required for ARM*/
222 }
224 void* Osal_qmssCsEnter ()
225 {
226 p_lock_if->lock(&posalShm->qmss_lock);
227 return NULL;
228 }
230 void Osal_qmssCsExit (void * key)
231 {
232 p_lock_if->unlock(&posalShm->qmss_lock);
233 }
235 Ptr Osal_qmssMalloc (uint32_t num_bytes)
236 {
237 Ptr ret;
239 Osal_qmss_MallocCounter++;
240 ret = malloc (num_bytes);
241 return ret;
242 }
244 void Osal_qmssFree (Ptr ptr, uint32_t size)
245 {
246 /* Increment the free counter. */
247 Osal_qmss_FreeCounter++;
248 free(ptr);
249 }
251 Ptr Osal_cppiMalloc (uint32_t num_bytes)
252 {
253 Ptr ret;
255 Osal_cppi_MallocCounter++;
256 //num_bytes += (CACHE_L2_LINESIZE-1);
257 num_bytes += (127);
258 ret = malloc (num_bytes);
259 return ret;
260 }
262 void Osal_cppiFree (Ptr ptr, uint32_t size)
263 {
264 /* Increment the free counter. */
265 Osal_cppi_FreeCounter++;
266 free(ptr);
267 }
269 void Osal_qmssBeginMemAccess (void *blockPtr, uint32_t size)
270 {
271 return;
272 }
274 void Osal_qmssEndMemAccess (void *blockPtr, uint32_t size)
275 {
276 return;
277 }
279 void Osal_cppiBeginMemAccess (void *blockPtr, uint32_t size)
280 {
281 return;
282 }
284 void Osal_cppiEndMemAccess (void *blockPtr, uint32_t size)
285 {
286 return;
287 }
289 void Osal_nwalInvalidateCache (void *blockPtr, uint32_t size)
290 {
291 return;
292 }
294 void Osal_nwalWriteBackCache (void *blockPtr, uint32_t size)
295 {
296 return;
297 }
299 uint32_t Osal_nwalGetCacheLineSize (void )
300 {
301 /* By default assumes L2 cache line is enabled. If not return CACHE_L1D_LINESIZE */
302 return (CACHE_L2_LINESIZE);
303 }
305 /********************************************************************
306 * FUNCTION PURPOSE: Convert local address to global
307 ********************************************************************
308 * DESCRIPTION: Returns global address
309 ********************************************************************/
311 unsigned int Osal_nwalLocToGlobAddr(unsigned int x)
312 {
313 return x;
314 }
317 void Osal_nwalSetProcId (uint16_t core_id )
318 {
319 our_core = core_id;
320 }
324 void Osal_setHplibSpinLockIfType(hplib_spinLock_Type if_type )
325 {
326 if (if_type == hplib_spinLock_Type_MP)
327 p_lock_if = &lock_if_mp;
328 else
329 p_lock_if = &lock_if_lol;
330 }
331 uint16_t Osal_nwalGetProcId (void )
332 {
333 return our_core;
334 }
336 uint64_t Osal_nwalGetTimeStamp(void)
337 {
338 return hplib_mUtilGetTimestamp();
339 }
341 uint16_t Osal_saGetProcId (void )
342 {
343 return 0;
344 }
346 void* Osal_saGetSCPhyAddr(void* vaddr)
347 {
348 if(vaddr == NULL)
349 {
350 return NULL;
351 }
352 return (void *)(memPoolAddr[0].memStartPhy + ((uint8_t*) vaddr - memPoolAddr[0].memStart));
353 }
355 void Osal_saBeginScAccess (void* addr, uint32_t size)
356 {
357 hplib_cacheInv(addr,size);
358 }
360 void Osal_saEndScAccess (void* addr, uint32_t size)
361 {
362 hplib_cacheWb(addr,size);
363 }
366 void Osal_saCsEnter (uint32_t *key)
367 {
368 p_lock_if->lock(&posalShm->sa_lock);
369 }
371 void Osal_saCsExit (uint32_t key)
372 {
373 p_lock_if->unlock(&posalShm->sa_lock);
374 }
377 void Osal_saMtCsEnter (uint32_t *key)
378 {
379 p_lock_if->lock(&posalShm->sa_lock);
380 }
382 void Osal_saMtCsExit (uint32_t key)
383 {
384 p_lock_if->unlock(&posalShm->sa_lock);
385 }
387 void Osal_saBeginMemAccess (void *blockPtr, uint32_t size)
388 {
389 /* not required on ARM */
390 /*Osal_invalidateCache(blockPtr,size); */
391 }
393 void Osal_saEndMemAccess (void *blockPtr, uint32_t size)
394 {
395 /* not required on ARM */
396 /* Osal_writeBackCache(blockPtr,size); */
397 }
399 int Osal_saGetSysEndianMode(void)
400 {
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
406 }
408 void Osal_pktLibBeginMemAccess(void* ptr, uint32_t size)
409 {
410 //Osal_invalidateCache(ptr,size);
411 }
414 void Osal_pktLibEndMemAccess(void* ptr, uint32_t size)
415 {
416 //Osal_writeBackCache(ptr,size);
417 }
420 void Osal_pktLibBeginPktAccess(Pktlib_HeapHandle heapHandle, Ti_Pkt* ptrPkt, uint32_t size)
421 {
422 /* not required on ARM */
423 /* Osal_invalidateCache(ptrPkt,size); */
424 }
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
433 Osal_writeBackCache((void *)ptrPkt,size);
434 */
435 }
438 void* Osal_pktLibEnterCriticalSection(Pktlib_HeapHandle heapHandle)
439 {
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;
450 }
453 void Osal_pktLibExitCriticalSection(Pktlib_HeapHandle heapHandle, void* csHandle)
454 {
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;
465 }
467 void* Osal_pktLibPhyToVirt(void *ptr)
468 {
469 return(hplib_mVMPhyToVirt(ptr));
470 }
472 void* Osal_qmssVirtToPhy (void *ptr)
473 {
474 return hplib_mVMVirtToPhy(ptr);
475 }
477 void * Osal_qmssPhyToVirt (void *ptr)
478 {
479 return hplib_mVMPhyToVirt(ptr);
480 }
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)
489 {
490 return hplib_mVMConvertDescVirtToPhy(descAddr);
491 }
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)
497 {
498 return hplib_mVMConvertDescPhyToVirt(descAddr);
499 }
500 void* Osal_stubCsEnter (void)
501 {
502 return NULL;
503 }
504 void Osal_stubCsExit (void *CsHandle)
505 {
506 return;
507 }
509 /* Internal Function used by hplib */
510 void* Osal_hplibCsEnter (void)
511 {
512 p_lock_if->lock(&posalShm->hplib_lock);
513 return NULL;
514 }
515 /* Internal Function used by hplib */
517 void Osal_hplibCsExit (void *CsHandle)
518 {
519 p_lock_if->unlock(&posalShm->hplib_lock);
520 return;
521 }
522 #endif