|
Bullet Collision Detection & Physics Library
|
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