OpenMP Runtime
tomp_util.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
00003  *   All rights reserved.
00004  *
00005  *  Redistribution and use in source and binary forms, with or without
00006  *  modification, are permitted provided that the following conditions are met:
00007  *      * Redistributions of source code must retain the above copyright
00008  *        notice, this list of conditions and the following disclaimer.
00009  *      * Redistributions in binary form must reproduce the above copyright
00010  *        notice, this list of conditions and the following disclaimer in the
00011  *        documentation and/or other materials provided with the distribution.
00012  *      * Neither the name of Texas Instruments Incorporated nor the
00013  *        names of its contributors may be used to endorse or promote products
00014  *        derived from this software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
00020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
00026  * POSSIBILITY OF SUCH DAMAGE.
00027  */
00035 #ifndef _tomp_util_h_
00036 #define _tomp_util_h_
00037 
00038 #include "tomp_defs.h"
00039 #include "tomp_config.h"
00040 #include "tomp_log.h"
00041 
00042 #include <stdint.h>
00043 #include <stdbool.h>
00044 
00045 #include <ti/csl/csl_chip.h>
00046 #include <ti/csl/csl_cache.h>
00047 #include <ti/csl/csl_cacheAux.h>
00048 #include <ti/csl/csl_xmc.h>
00049 #include <ti/csl/csl_xmcAux.h>
00050 #include <ti/csl/csl_semAux.h>
00051 
00056 typedef struct _tomp_Barrier
00057 {
00060     volatile unsigned int count;
00061 
00063     volatile unsigned int size;
00064 
00066     volatile unsigned int sense;
00067 
00068 } tomp_Barrier;
00069 
00070 extern void tomp_completePendingTasks();
00071 
00072 // Convert local address to global address.
00073 static inline uint32_t tomp_makeAddressGlobal(uint32_t core_idx, 
00074                                               uint32_t address)
00075 {
00076     if (address < 0x01000000)
00077     {
00078         // Mask: 0x00****** => 0x1"core_idx"******
00079         address = (0x10 + core_idx) << 24 | address;
00080     }
00081 
00082     return address;
00083 }
00084 
00085 // Wait until data written to memory
00086 static inline void tomp_mfence(void)
00087 {
00088     // In order to accurately trace mfence instructions, a nop and mark 
00089     // instruction must follow each mfence instruction 
00090     asm (" mfence ");
00091     asm(" nop ");
00092     asm(" mark 0");
00093     asm (" mfence ");  // 2nd MFENCE as per Keystone I FAE Alert
00094     asm(" nop ");
00095     asm(" mark 0");
00096 
00097     // sprz332b.pdf, Advisory 24 - Require 16 NOPs after MFENCE after certain
00098     // cache coherency operations
00099     asm(" nop 9");  
00100     asm(" nop 7");
00101 }
00102 
00103 
00104 // Write back and invalidate all L1 cache
00105 static inline void tomp_cacheWbInvAllL1d (void)
00106 {
00107     uint32_t lvInt = _disable_interrupts();
00108     CACHE_wbInvAllL1d(CACHE_NOWAIT);
00109     tomp_mfence();
00110     CSL_XMC_invalidatePrefetchBuffer();
00111     tomp_mfence();
00112     _restore_interrupts(lvInt);
00113     return;
00114 }
00115 
00116 
00117 // Write back and invalidate all L2 cache
00118 static inline void tomp_cacheWbInvAll (void)
00119 {
00120     uint32_t lvInt = _disable_interrupts();
00121     CACHE_wbInvAllL1d(CACHE_NOWAIT);
00122     tomp_mfence();
00123     if (CACHE_getL2Size() > 0)
00124         CACHE_invAllL2(CACHE_NOWAIT);
00125     CSL_XMC_invalidatePrefetchBuffer();
00126     tomp_mfence();
00127     _restore_interrupts(lvInt);
00128     return;
00129 }
00130 
00131 // Write back and invalidate L1D specific block
00132 static inline void tomp_cacheWbInv 
00133 (
00134     void*       blockPtr,
00135     Uint32      byteCnt)
00136 {
00137     uint32_t lvInt = _disable_interrupts();
00138     if (((uint32_t)blockPtr) & 0x80000000)
00139         CACHE_wbInvL2(blockPtr,byteCnt,CACHE_NOWAIT);
00140     else
00141         CACHE_wbInvL1d(blockPtr,byteCnt,CACHE_NOWAIT);
00142     CSL_XMC_invalidatePrefetchBuffer();
00143     tomp_mfence();
00144     _restore_interrupts(lvInt);
00145     return;
00146 }
00147 
00148 static inline void tomp_cacheInv (void* blockPtr, Uint32 byteCnt)
00149 {
00150     uint32_t lvInt = _disable_interrupts();
00151     if (((uint32_t)blockPtr) & 0x80000000)
00152         CACHE_invL2(blockPtr,byteCnt,CACHE_NOWAIT);
00153     else
00154         CACHE_invL1d(blockPtr,byteCnt,CACHE_NOWAIT);
00155     CSL_XMC_invalidatePrefetchBuffer();
00156     tomp_mfence();
00157     _restore_interrupts(lvInt);
00158     return;
00159 }
00160 
00161 
00166 static inline unsigned int tomp_decrementAtomic(volatile unsigned int *ptr)
00167 {
00168         while ((CSL_semAcquireDirect (TOMP_ATOMIC_HW_SEM_IDX)) == 0);
00169         unsigned int oldval = *ptr;
00170         *ptr -= 1;
00171         tomp_mfence();
00172         CSL_semReleaseSemaphore (TOMP_ATOMIC_HW_SEM_IDX);
00173         return oldval;
00174 }
00175 
00180 static inline unsigned int tomp_incrementAtomic(volatile unsigned int *ptr)
00181 {
00182     while ((CSL_semAcquireDirect (TOMP_ATOMIC_HW_SEM_IDX)) == 0);
00183     unsigned int newval;
00184     *ptr += 1;
00185     newval = *ptr;
00186     tomp_mfence();
00187     CSL_semReleaseSemaphore (TOMP_ATOMIC_HW_SEM_IDX);
00188     return newval;
00189 }
00190 
00191 
00197 static inline void tomp_initBarrier(tomp_Barrier *barrier, unsigned int nthreads)
00198 {
00199         barrier->count = nthreads;
00200         barrier->size = nthreads;
00201         barrier->sense = 0;
00202 }
00203 
00208 static inline void tomp_waitAtBarrier(tomp_Barrier *barrier)
00209 {
00210     // Complete any pending tasks. Implicit and explicit barriers are task
00211     // synchronization points.
00212     tomp_completePendingTasks();
00213  
00214     // For re-use reason, the barrier contains a sense variation
00215     unsigned int mysense = !(barrier->sense);
00216 
00217     // Pass only if it's the last thread
00218     if (tomp_decrementAtomic(&barrier->count) == 1)
00219     {
00220         // Reset of the barrier
00221         barrier->count = barrier->size;
00222         barrier->sense = !(barrier->sense);
00223     }
00224     else
00225     {
00226         // A modification of the sense represents the end of the barrier
00227         // Check for pending tasks and execute them when waiting
00228         while (mysense != barrier->sense)
00229             tomp_completePendingTasks();
00230     }
00231 }
00232 
00233 void tomp_waitAtCoreBarrier(void);
00234 void *tomp_allocInitTLSBlock(void);
00235 
00240 static inline void tomp_mutex_lock(unsigned int lock)
00241 {
00242     while ((CSL_semAcquireDirect (lock)) == 0);
00243 }
00244 
00250 static inline void tomp_mutex_unlock(unsigned int lock)
00251 {
00252     tomp_mfence(); /* To ensure writes have landed in memory */
00253     CSL_semReleaseSemaphore (lock);
00254 }
00255 
00256 
00260 static inline bool tomp_isPtrCached(void *ptr)
00261 {
00262     volatile uint32_t *MAR = (volatile uint32_t *)MAR_ADDRESS_BASE;
00263 
00264     // Compute the MAR index for the pointer
00265     int idx = (uint32_t)ptr >> 24;
00266 
00267     // Need to special case L2SRAM as this space could be mapped to a 
00268     // global address space by ORing with (DNUM + 16) << 24. 
00269     // The MAR indices corresponding to this global space are invalid.
00270     // Assumption: any variable in L2SRAM scratch is cached in L1
00271     if ((idx & (~(DNUM + 16))) == 0)
00272         return true;
00273 
00274     // if bit 0 (PC) of the MAR is 1, the address has caching enabled
00275     if (MAR[idx] & 0x1) 
00276         return true;
00277 
00278     return false;
00279 }
00280 
00281 static inline void acquire_dsp_heap_lock()
00282 {
00283     while ((CSL_semAcquireDirect (TOMP_MALLOC_HW_SEM_IDX)) == 0);
00284 }
00285 
00286 static inline void release_dsp_heap_lock()
00287 {
00288     tomp_mfence();
00289     CSL_semReleaseSemaphore (TOMP_MALLOC_HW_SEM_IDX);
00290 }
00291 
00292 extern unsigned int __TI_get_DP(void);
00293 extern void         __TI_set_DP(unsigned int new_DP);
00294 
00295 #endif /* _tomp_util_h_ */
 All Classes Files Functions Variables Typedefs Enumerations Defines