/****************************************************************************** * FILE PURPOSE: Functions to OSAL related routines for running NWAL, PA, QMSS,etc ****************************************************************************** * FILE NAME: osal.c * * DESCRIPTION: Functions to initialize framework resources for running NWAL * * REVISION HISTORY: * * Copyright (c) Texas Instruments Incorporated 2010-2011 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef DISABLE_OSAL /* CSL RL includes */ #include #include #include #include "hplib.h" #include #include #include #include #include #include #include #include //#include "netapi_util.h" #include "hplibmod.h" #include #include typedef struct osal_shm_Tag { hplib_spinLock_T qmss_lock; hplib_spinLock_T nwal_lock; hplib_spinLock_T hplib_lock; hplib_spinLock_T cppi_lock; hplib_spinLock_T sa_lock; hplib_spinLock_T pktlib_lock; int init_done; } osal_shm_T; void* pBase = NULL; osal_shm_T* posalShm; uint32_t Osal_qmss_MallocCounter =0; uint32_t Osal_qmss_FreeCounter =0; uint32_t Osal_cppi_MallocCounter =0; uint32_t Osal_cppi_FreeCounter =0; static __thread int our_core = 0; static __thread HPLIB_SPINLOCK_IF_T* p_lock_if; void* Osal_saGetSCPhyAddr(void* vaddr); static unsigned int cache_op_cycles=0; static unsigned int n_cache_op_cycles=0; void Osal_cache_op_measure_reset(void) { cache_op_cycles=0; n_cache_op_cycles=0;} unsigned int Osal_cache_op_measure(unsigned long long * p_n) { *p_n = n_cache_op_cycles; return cache_op_cycles;} HPLIB_SPINLOCK_IF_T lock_if_lol = { hplib_mSpinLockInit, hplib_mSpinLockTryLock, hplib_mSpinLockIsLocked, hplib_mSpinLockLock, hplib_mSpinLockUnlock, hplib_mRWLockInit, hplib_mRWLockWriteLock, hplib_mRWLockWriteUnlock, hplib_mRWLockReadLock, hplib_mRWLockReadUnlock }; HPLIB_SPINLOCK_IF_T lock_if_mp = { hplib_mSpinLockInit, hplib_mSpinLockTryLock, hplib_mSpinLockIsLocked, hplib_mSpinLockLockMP, hplib_mSpinLockUnlockMP, hplib_mRWLockInit, hplib_mRWLockWriteLockMP, hplib_mRWLockWriteUnlockMP, hplib_mRWLockReadLockMP, hplib_mRWLockReadUnlockMP }; /* This is called 1 Time per system boot by the global master process */ hplib_RetValue hplib_utilOsalCreate() { hplib_RetValue retVal = hplib_OK; pBase = hplib_shmOpen(); if ((retVal = hplib_shmAddEntry(pBase, sizeof(osal_shm_T), OSAL_ENTRY)) != hplib_OK) { hplib_Log("hplib_utilOsalCreate: hplib_shmAddEntry failed for OSAL_ENTRY\n"); return retVal; } else { posalShm = (osal_shm_T*)hplib_shmGetEntry(pBase, OSAL_ENTRY); posalShm->init_done = 0; } posalShm = (osal_shm_T*)hplib_shmGetEntry(pBase, OSAL_ENTRY); posalShm->qmss_lock = hplib_spinLock_UNLOCKED_INITIALIZER; posalShm->nwal_lock = hplib_spinLock_UNLOCKED_INITIALIZER; posalShm->hplib_lock = hplib_spinLock_UNLOCKED_INITIALIZER; posalShm->cppi_lock = hplib_spinLock_UNLOCKED_INITIALIZER; posalShm->sa_lock = hplib_spinLock_UNLOCKED_INITIALIZER; posalShm->pktlib_lock = hplib_spinLock_UNLOCKED_INITIALIZER; posalShm->init_done = 1; return retVal; } /* This can be called for every other process which is NOT the global master process */ hplib_RetValue Osal_start(void *pShmBase) { if (!pBase) pBase = pShmBase; posalShm = (osal_shm_T*)hplib_shmGetEntry(pBase, OSAL_ENTRY); if (posalShm) { if(posalShm->init_done) return hplib_OK; } return hplib_FAILURE; } void * Osal_qmssMtCsEnter() { p_lock_if->lock(&posalShm->qmss_lock); return NULL; } void Osal_qmssMtCsExit(void *key) { p_lock_if->unlock(&posalShm->qmss_lock); return; } void* Osal_qmssAccCsEnter (void) { return NULL; } void Osal_qmssAccCsExit (void *CsHandle) { return; } void Osal_nwalCsEnter(uint32_t *key) { p_lock_if->lock(&posalShm->nwal_lock); } void Osal_nwalCsExit(uint32_t key) { p_lock_if->unlock(&posalShm->nwal_lock); } void Osal_qmssLog ( String fmt, ... ) { return; } void Osal_cppiCsEnter (uint32_t *key) { p_lock_if->lock(&posalShm->cppi_lock); } void Osal_cppiCsExit (uint32_t key) { p_lock_if->unlock(&posalShm->cppi_lock); } void Osal_paBeginMemAccess (Ptr addr, uint32_t size) { /*No implementation required for ARM*/ } void Osal_paEndMemAccess (Ptr addr, uint32_t size) { /*No implementation required for ARM*/ } void Osal_paMtCsEnter (uint32_t *key) { /*No implementation required for ARM*/ } void Osal_paMtCsExit (uint32_t key) { /*No implementation required for ARM*/ } void* Osal_qmssCsEnter () { p_lock_if->lock(&posalShm->qmss_lock); return NULL; } void Osal_qmssCsExit (void * key) { p_lock_if->unlock(&posalShm->qmss_lock); } Ptr Osal_qmssMalloc (uint32_t num_bytes) { Ptr ret; Osal_qmss_MallocCounter++; ret = malloc (num_bytes); return ret; } void Osal_qmssFree (Ptr ptr, uint32_t size) { /* Increment the free counter. */ Osal_qmss_FreeCounter++; free(ptr); } Ptr Osal_cppiMalloc (uint32_t num_bytes) { Ptr ret; Osal_cppi_MallocCounter++; //num_bytes += (CACHE_L2_LINESIZE-1); num_bytes += (127); ret = malloc (num_bytes); return ret; } void Osal_cppiFree (Ptr ptr, uint32_t size) { /* Increment the free counter. */ Osal_cppi_FreeCounter++; free(ptr); } void Osal_qmssBeginMemAccess (void *blockPtr, uint32_t size) { return; } void Osal_qmssEndMemAccess (void *blockPtr, uint32_t size) { return; } void Osal_cppiBeginMemAccess (void *blockPtr, uint32_t size) { return; } void Osal_cppiEndMemAccess (void *blockPtr, uint32_t size) { return; } void Osal_nwalInvalidateCache (void *blockPtr, uint32_t size) { return; } void Osal_nwalWriteBackCache (void *blockPtr, uint32_t size) { return; } uint32_t Osal_nwalGetCacheLineSize (void ) { /* By default assumes L2 cache line is enabled. If not return CACHE_L1D_LINESIZE */ return (CACHE_L2_LINESIZE); } /******************************************************************** * FUNCTION PURPOSE: Convert local address to global ******************************************************************** * DESCRIPTION: Returns global address ********************************************************************/ unsigned int Osal_nwalLocToGlobAddr(unsigned int x) { return x; } void Osal_nwalSetProcId (uint16_t core_id ) { our_core = core_id; } void Osal_setHplibSpinLockIfType(hplib_spinLock_Type if_type ) { if (if_type == hplib_spinLock_Type_MP) p_lock_if = &lock_if_mp; else p_lock_if = &lock_if_lol; } uint16_t Osal_nwalGetProcId (void ) { return our_core; } uint64_t Osal_nwalGetTimeStamp(void) { return hplib_mUtilGetTimestamp(); } uint16_t Osal_saGetProcId (void ) { return 0; } void* Osal_saGetSCPhyAddr(void* vaddr) { if(vaddr == NULL) { return NULL; } return (void *)(memPoolAddr[0].memStartPhy + ((uint8_t*) vaddr - memPoolAddr[0].memStart)); } void Osal_saBeginScAccess (void* addr, uint32_t size) { hplib_cacheInv(addr,size); } void Osal_saEndScAccess (void* addr, uint32_t size) { hplib_cacheWb(addr,size); } void Osal_saCsEnter (uint32_t *key) { p_lock_if->lock(&posalShm->sa_lock); } void Osal_saCsExit (uint32_t key) { p_lock_if->unlock(&posalShm->sa_lock); } void Osal_saMtCsEnter (uint32_t *key) { p_lock_if->lock(&posalShm->sa_lock); } void Osal_saMtCsExit (uint32_t key) { p_lock_if->unlock(&posalShm->sa_lock); } void Osal_saBeginMemAccess (void *blockPtr, uint32_t size) { /* not required on ARM */ /*Osal_invalidateCache(blockPtr,size); */ } void Osal_saEndMemAccess (void *blockPtr, uint32_t size) { /* not required on ARM */ /* Osal_writeBackCache(blockPtr,size); */ } int Osal_saGetSysEndianMode(void) { #if defined( _BIG_ENDIAN ) return((int)sa_SYS_ENDIAN_MODE_BIG); #else return((int)sa_SYS_ENDIAN_MODE_LITTLE); #endif } void Osal_pktLibBeginMemAccess(void* ptr, uint32_t size) { //Osal_invalidateCache(ptr,size); } void Osal_pktLibEndMemAccess(void* ptr, uint32_t size) { //Osal_writeBackCache(ptr,size); } void Osal_pktLibBeginPktAccess(Pktlib_HeapHandle heapHandle, Ti_Pkt* ptrPkt, uint32_t size) { /* not required on ARM */ /* Osal_invalidateCache(ptrPkt,size); */ } void Osal_pktLibEndPktAccess(Pktlib_HeapHandle heapHandle, Ti_Pkt* ptrPkt, uint32_t size) { /* Cache Write back for the packet. Currently being disabled as it will be done during * QMSS Push operation Osal_writeBackCache((void *)ptrPkt,size); */ } void* Osal_pktLibEnterCriticalSection(Pktlib_HeapHandle heapHandle) { /* TODO: We should use the 'heapHandle' and compare it with what we got from the * 'create/find' HEAP API & depending upon the comparison take appropriate action. * Implementations here could range from a MULTI-THREAD protection if the packets in * the heap are being accessed across multiple threads or MULTI-CORE if the packets * are being accessed across multiple cores and features: split and clone are used. * For NWAL layer no protection required. * * For testing we are not doing any of this so we are simply setting it to NOOP */ p_lock_if->lock(&posalShm->pktlib_lock); return NULL; } void Osal_pktLibExitCriticalSection(Pktlib_HeapHandle heapHandle, void* csHandle) { /* TODO: We should use the 'heapHandle' and compare it with what we got from the * 'create/find' HEAP API & depending upon the comparison take appropriate action. * Implementations here could range from a MULTI-THREAD protection if the packets in * the heap are being accessed across multiple threads or MULTI-CORE if the packets * are being accessed across multiple cores and features: split and clone are used. * For NWAL layer no protection required.. * * For testing we are not doing any of this so we are simply setting it to NOOP */ p_lock_if->unlock(&posalShm->pktlib_lock); return; } void* Osal_pktLibPhyToVirt(void *ptr) { return(hplib_mVMPhyToVirt(ptr)); } void* Osal_qmssVirtToPhy (void *ptr) { return hplib_mVMVirtToPhy(ptr); } void * Osal_qmssPhyToVirt (void *ptr) { return hplib_mVMPhyToVirt(ptr); } /****************************************************************************** * Function to traverse a CPPI descriptor and convert all address references * from virtual to physical. ******************************************************************************/ //#define ASSUME_ALL_DESCRIPTOR //define this if mono and host descriptors are present, else don't //define and just host will be assumed (more efficient) void* Osal_qmssConvertDescVirtToPhy(uint32_t QID, void *descAddr) { return hplib_mVMConvertDescVirtToPhy(descAddr); } /****************************************************************************** * Function to traverse a CPPI descriptor and convert all address references * from physical to virtual. ******************************************************************************/ void* Osal_qmssConvertDescPhyToVirt(uint32_t QID, void *descAddr) { return hplib_mVMConvertDescPhyToVirt(descAddr); } void* Osal_stubCsEnter (void) { return NULL; } void Osal_stubCsExit (void *CsHandle) { return; } /* Internal Function used by hplib */ void* Osal_hplibCsEnter (void) { p_lock_if->lock(&posalShm->hplib_lock); return NULL; } /* Internal Function used by hplib */ void Osal_hplibCsExit (void *CsHandle) { p_lock_if->unlock(&posalShm->hplib_lock); return; } #endif