SpuFakeDma.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #include "SpuFakeDma.h"
00017 #include <LinearMath/btScalar.h> //for btAssert
00018 //Disabling memcpy sometimes helps debugging DMA
00019 
00020 #define USE_MEMCPY 1
00021 #ifdef USE_MEMCPY
00022 
00023 #endif
00024 
00025 
00026 void*   cellDmaLargeGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
00027 {
00028 
00029 #if defined (__SPU__) || defined (USE_LIBSPE2)
00030         cellDmaLargeGet(ls,ea,size,tag,tid,rid);
00031         return ls;
00032 #else
00033         return (void*)(ppu_address_t)ea;
00034 #endif
00035 }
00036 
00037 void*   cellDmaSmallGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
00038 {
00039 #if defined (__SPU__) || defined (USE_LIBSPE2)
00040         mfc_get(ls,ea,size,tag,0,0);
00041         return ls;
00042 #else
00043         return (void*)(ppu_address_t)ea;
00044 #endif
00045 }
00046 
00047 
00048 
00049 
00050 void*   cellDmaGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
00051 {
00052 #if defined (__SPU__) || defined (USE_LIBSPE2)
00053         cellDmaGet(ls,ea,size,tag,tid,rid);
00054         return ls;
00055 #else
00056         return (void*)(ppu_address_t)ea;
00057 #endif
00058 }
00059 
00060 
00062 int stallingUnalignedDmaSmallGet(void *ls, uint64_t ea, uint32_t size)
00063 {
00064         
00065         btAssert(size<32);
00066         
00067         ATTRIBUTE_ALIGNED16(char        tmpBuffer[32]);
00068 
00069 
00070         char* localStore = (char*)ls;
00071         uint32_t i;
00072         
00073 
00075         uint32_t last4BitsOffset = ea & 0x0f;
00076         char* tmpTarget = tmpBuffer + last4BitsOffset;
00077         
00078 #if defined (__SPU__) || defined (USE_LIBSPE2)
00079         
00080         int remainingSize = size;
00081 
00082 //#define FORCE_cellDmaUnalignedGet 1
00083 #ifdef FORCE_cellDmaUnalignedGet
00084         cellDmaUnalignedGet(tmpTarget,ea,size,DMA_TAG(1),0,0);
00085 #else
00086         char* remainingTmpTarget = tmpTarget;
00087         uint64_t remainingEa = ea;
00088 
00089         while (remainingSize)
00090         {
00091                 switch (remainingSize)
00092                 {
00093                 case 1:
00094                 case 2:
00095                 case 4:
00096                 case 8:
00097                 case 16:
00098                         {
00099                                 mfc_get(remainingTmpTarget,remainingEa,remainingSize,DMA_TAG(1),0,0);
00100                                 remainingSize=0;
00101                                 break;
00102                         }
00103                 default:
00104                         {
00105                                 //spu_printf("unaligned DMA with non-natural size:%d\n",remainingSize);
00106                                 int actualSize = 0;
00107 
00108                                 if (remainingSize > 16)
00109                                         actualSize = 16;
00110                                 else
00111                                         if (remainingSize >8)
00112                                                 actualSize=8;
00113                                         else
00114                                                 if (remainingSize >4)
00115                                                         actualSize=4;
00116                                                 else
00117                                                         if (remainingSize >2)
00118                                                                 actualSize=2;
00119                                 mfc_get(remainingTmpTarget,remainingEa,actualSize,DMA_TAG(1),0,0);
00120                                 remainingSize-=actualSize;
00121                                 remainingTmpTarget+=actualSize;
00122                                 remainingEa += actualSize;
00123                         }
00124                 }
00125         }
00126 #endif//FORCE_cellDmaUnalignedGet
00127 
00128 #else
00129         char* mainMem = (char*)ea;
00130         //copy into final destination
00131 #ifdef USE_MEMCPY
00132                 
00133                 memcpy(tmpTarget,mainMem,size);
00134 #else
00135                 for ( i=0;i<size;i++)
00136                 {
00137                         tmpTarget[i] = mainMem[i];
00138                 }
00139 #endif //USE_MEMCPY
00140 
00141 #endif
00142 
00143         cellDmaWaitTagStatusAll(DMA_MASK(1));
00144 
00145         //this is slowish, perhaps memcpy on SPU is smarter?
00146         for (i=0; btLikely( i<size );i++)
00147         {
00148                 localStore[i] = tmpTarget[i];
00149         }
00150 
00151         return 0;
00152 }
00153 
00154 #if defined (__SPU__) || defined (USE_LIBSPE2)
00155 #else
00156 
00157 int     cellDmaLargeGet(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
00158 {
00159         char* mainMem = (char*)ea;
00160         char* localStore = (char*)ls;
00161 
00162 #ifdef USE_MEMCPY
00163         memcpy(localStore,mainMem,size);
00164 #else
00165         for (uint32_t i=0;i<size;i++)
00166         {
00167                 localStore[i] = mainMem[i];
00168         }
00169 #endif
00170         return 0;
00171 }
00172 
00173 int     cellDmaGet(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
00174 {
00175         char* mainMem = (char*)ea;
00176         char* localStore = (char*)ls;
00177 
00178 //      printf("mainMem=%x, localStore=%x",mainMem,localStore);
00179 
00180 #ifdef USE_MEMCPY
00181         memcpy(localStore,mainMem,size);
00182 #else
00183         for (uint32_t i=0;i<size;i++)
00184         {
00185                 localStore[i] = mainMem[i];
00186         }       
00187 #endif //#ifdef USE_MEMCPY
00188 //      printf(" finished\n");
00189         return 0;
00190 }
00191 
00192 int cellDmaLargePut(const void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid)
00193 {
00194         char* mainMem = (char*)ea;
00195         const char* localStore = (const char*)ls;
00196 #ifdef USE_MEMCPY
00197         memcpy(mainMem,localStore,size);
00198 #else
00199         for (uint32_t i=0;i<size;i++)
00200         {
00201                 mainMem[i] = localStore[i];
00202         }       
00203 #endif //#ifdef USE_MEMCPY
00204 
00205         return 0;
00206 }
00207 
00208 
00209 
00210 void    cellDmaWaitTagStatusAll(int ignore)
00211 {
00212 
00213 }
00214 
00215 #endif