1 //Compile parameter=================================================================================
2 //1. unit test:
3 #define SPT_UNIT_TEST 0
4 //2. compile options:
5 #define SPT_FORCE_MALLOC 0
6 //3. debug:
7 #define FlagPrint(FLAG) if(FLAG)db_printf
8 #define SPT_DB_SEQMM_MAX_USAGE 0
9 #define SPT_DB_MALLOC_FREE 0
10 #define SPT_DB_MALLOC_FREE_DETAIL 0
11 #define SPT_DB_MEMINFO 0
12 #define SPT_DB_DETAIL 0
13 //==================================================================================================
14 #if SPT_UNIT_TEST == 0
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <linux/slab.h>
18 #include <linux/proc_fs.h>
19 #include <linux/uaccess.h>
20 #include <linux/ioctl.h>
21 #include <linux/seq_file.h>
22 #include <linux/compat.h>
23
24 #define MALLOC(size) kmalloc(size,GFP_KERNEL)
25 #define FREE(ptr) kfree(ptr)
26 #define CPY_FROM_USER copy_from_user
27 #define CPY_to_USER copy_to_user
28 //#define db_printf(argc,...)
29 #define db_printf printk
30
31 typedef unsigned long (*fcpy_t)(void *to, const void *from, unsigned long n);
32
33 #include "utopia.h"
34 #include "utopia_adp.h"
35
36 #else//SPT_UNIT_TEST==0
37 #include "ut_spt_inc.h"
38 #endif//SPT_UNIT_TEST==0
39 #define SPT_MAX_SIZE 100
40
41 //==================================internal tools===============================================
42 #define SRC_MODE_COPY 0x01
43 #define SRC_MODE_CPY_FROM_USR 0x02
44 #define SRC_MODE_MALLOC 0x10
45
SkipCpy(void * to,const void * from,const UADP_STRUCT_POINTER_TABLE * pTable,fcpy_t fcpy)46 static void SkipCpy(void *to, const void *from,const UADP_STRUCT_POINTER_TABLE *pTable,fcpy_t fcpy)
47 {
48 int i;
49 char* pcTo =(char*)to;
50 char* pcFrom =(char*)from;
51 unsigned int uiStart=0, uiEnd=0, uiLen=0, uiSelfSize=0;
52 FlagPrint(SPT_DB_DETAIL)("to=%p, from=%p\n",pcTo, pcFrom);
53 for(i=0;i<SPT_MAX_SIZE;i++)
54 {
55 switch(pTable[i].type)
56 {
57 case UADP_SPT_SELF_SIZE:
58 uiSelfSize = pTable[i].size_or_next;
59 break;
60 case UADP_SPT_POINTER_TO_NEXT:
61 uiEnd = pTable[i].offset - 1;
62 uiLen = uiEnd+1-uiStart; //include uiEnd last byte
63 FlagPrint(SPT_DB_DETAIL)("UADP_SPT_POINTER_TO_NEXT uiStart=%u,uiEnd=%u,uiLen=%u,off=%u,ptr_size=%u\n",uiStart,uiEnd,uiLen,pTable[i].offset,sizeof(pcTo));
64 fcpy(pcTo+uiStart,pcFrom+uiStart,uiLen);
65 uiStart = pTable[i].offset+sizeof(pcTo);
66 break;
67 case UADP_SPT_END:
68 uiEnd = uiSelfSize - 1;
69 uiLen = uiEnd+1-uiStart; //include uiEnd last byte
70 FlagPrint(SPT_DB_DETAIL)("UADP_SPT_END uiStart=%u,uiEnd=%u,uiLen=%u,size=%u\n",uiStart,uiEnd,uiLen,uiSelfSize);
71 fcpy(pcTo+uiStart,pcFrom+uiStart,uiLen);
72 return;
73 case UADP_SDT_AT:
74 case UADP_SDT_ES:
75 break;
76 }
77 }
78 }
79
80 #ifdef CONFIG_COMPAT
81
82 #if 0
83 static void CmpSkipCpy(void *to, const void *from,const UADP_STRUCT_POINTER_TABLE *pTable,fcpy_t fcpy)
84 {
85 int i;
86 char* pcTo =(char*)compat_ptr(to);
87 char* pcFrom =(char*)from;
88 MS_PHY pKStart=0, pKEnd=0, pKLen=0, pKSelfSize=0;
89 MS_PHY pUStart=0, pUEnd=0, pULen=0, pUSelfSize=0;
90 FlagPrint(SPT_DB_DETAIL)("[%s][%d]to=%p, from=%p\n",__FUNCTION__,__LINE__, pcTo, pcFrom);
91 for(i=0;i<SPT_MAX_SIZE;i++)
92 {
93 switch(pTable[i].type)
94 {
95 case UADP_SPT_SELF_SIZE:
96 pKSelfSize = pTable[i].size_or_next;
97 break;
98 case UADP_SDT_P2N:
99 if(pTable[i].offset!=pKStart /* 1. size =0-1 cause error; 2. Over size*/)
100 {
101 pKEnd = pTable[i].offset-1;
102 pKLen = pKEnd+1-pKStart; //include uiEnd last byte
103 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_P2N UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
104 fcpy(pcTo+pUStart,pcFrom+pKStart,pKLen);
105 }
106 pKStart = pTable[i].offset+sizeof(void*);
107 pUStart = pTable[i].offset-(i-1)*4+4;
108
109 break;
110 case UADP_SDT_AT:
111 if(pTable[i].offset!=pKStart /* 1. size =0-1 cause error; 2. Over size*/)
112 {
113 pKEnd = pTable[i].offset-1;
114 pKLen = pKEnd+1-pKStart; //include uiEnd last byte
115 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_AT UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
116 fcpy(pcTo+pUStart,pcFrom+pKStart,pKLen);
117 }
118 pKStart = pTable[i].offset;
119 pUStart = pTable[i].offset-(i-1)*4;
120 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_AT UAdrr=%p KAdrr=%p\n",__FUNCTION__,__LINE__,(pcTo+pUStart), (pcFrom+pKStart));
121 fcpy(pcTo+pUStart,pcFrom+pKStart, 4);
122
123 pKStart = pTable[i].offset+sizeof(void*);
124 pUStart += 4;
125 break;
126 case UADP_SDT_ES:
127 {
128 int k=0;
129 unsigned long StructureOffset=0;
130 UADP_STRUCT_POINTER_TABLE *pTable_ES=NULL;
131 char* to =(pcTo+pUStart);
132 char* from =(pcFrom+pKStart);
133
134 if( pTable[i].offset!=pKStart /* 1. size =0-1 cause error; 2. Over size*/)
135 {
136 pKEnd = pTable[i].offset-1;
137 pKLen = pKEnd +1-pKStart; //include uiEnd last byte
138 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_ES UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
139 fcpy(pcTo+pKStart,pcFrom+pUStart,pKLen);
140 }
141
142 pTable_ES = (UADP_STRUCT_POINTER_TABLE *)(pTable[i].size_or_next);
143 memcpy(&pTable[i].EmbededStr, &pTable_ES, sizeof(void*)); //Record
144 memcpy(&pTable[i].ESfrom, &from, sizeof(void*)); //Record
145 memcpy(&pTable[i].ESto, &to, sizeof(void*)); //Record
146 StructureOffset =pTable_ES[0].size_or_next;
147 for(k=0;k<SPT_MAX_SIZE;k++)
148 {
149 if(pTable_ES[k].type ==UADP_SDT_END)
150 break;
151 }
152 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_ES pTable_ES=%p from=%p to=%p break=%p StructureOffset=0x%x\n",__FUNCTION__,__LINE__,pTable_ES,(pcFrom+pUStart),(pcTo+pKStart),k,StructureOffset);
153 pKStart += StructureOffset;
154 pUStart += StructureOffset-(k-1)*4;
155 break;
156 }
157
158 case UADP_SPT_END:
159 pKEnd = pKSelfSize - 1;
160 pKLen = pKEnd+1-pKStart; //include uiEnd last byte
161 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SPT_END UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
162 fcpy(pcTo+pUStart,pcFrom+pKStart,pKLen);
163 return;
164 }
165 }
166 }
167
168
169 static void CmpCpy(void *to, const void *from,const UADP_STRUCT_POINTER_TABLE *pTable,fcpy_t fcpy)
170 {
171 int i;
172 char* pcTo =(char*)to;
173 char* pcFrom =(char*)compat_ptr(from);
174 MS_PHY pKStart=0, pKEnd=0, pKLen=0, pKSelfSize=0;
175 MS_PHY pUStart=0, pUEnd=0, pULen=0, pUSelfSize=0;
176
177 MS_U64* u64p=NULL;
178 FlagPrint(SPT_DB_DETAIL)("[%s][%d]to=%p, from=%p\n",__FUNCTION__,__LINE__,pcTo, pcFrom);
179
180 for(i=0;i<SPT_MAX_SIZE;i++)
181 {
182 switch(pTable[i].type)
183 {
184 case UADP_SPT_SELF_SIZE:
185 pKSelfSize = pTable[i].size_or_next;
186 FlagPrint(SPT_DB_DETAIL)("[%s][%d]pKSelfSize=%p\n",__FUNCTION__,__LINE__, pKSelfSize);
187 break;
188 case UADP_SDT_P2N:
189 case UADP_SDT_AT:
190 if( pTable[i].offset!=pKStart /* 1. size =0-1 cause error; 2. Over size*/)
191 {
192 pKEnd = pTable[i].offset-1;
193 pKLen = pKEnd +1-pKStart; //include uiEnd last byte
194 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_P2N UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
195 fcpy(pcTo+pKStart,pcFrom+pUStart,pKLen);
196 }
197 u64p = (pcTo+ pTable[i].offset);
198 pUStart = pTable[i].offset-(i-1)*4;
199 fcpy(u64p,pcFrom+pUStart,4);
200 *u64p =(0xFFFFFFFF)& (*u64p);
201 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_AT UAdrr=%p KAdrr=%p NextUaddr=%p\n",__FUNCTION__,__LINE__,(pcTo+pKStart), (pcFrom+pUStart), *u64p);
202
203 pKStart = pTable[i].offset+sizeof(void*);
204 pUStart += 4;
205 break;
206 case UADP_SDT_ES:
207 {
208 int k=0;
209 unsigned long StructureOffset=0;
210 UADP_STRUCT_POINTER_TABLE *pTable_ES=NULL;
211 char* to =(pcTo+pKStart);
212 char* from =(pcFrom+pUStart);
213
214 if( pTable[i].offset!=pKStart /* 1. size =0-1 cause error; 2. Over size*/)
215 {
216 pKEnd = pTable[i].offset-1;
217 pKLen = pKEnd +1-pKStart; //include uiEnd last byte
218 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_ES UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
219 fcpy(pcTo+pKStart,pcFrom+pUStart,pKLen);
220 }
221
222 pTable_ES = (UADP_STRUCT_POINTER_TABLE *)(pTable[i].size_or_next);
223 memcpy(&pTable[i].EmbededStr, &pTable_ES, sizeof(void*)); //Record
224 memcpy(&pTable[i].ESto, &to, sizeof(void*)); //Record
225 memcpy(&pTable[i].ESfrom, &from, sizeof(void*)); //Record
226 StructureOffset =pTable_ES[0].size_or_next;
227 for(k=0;k<SPT_MAX_SIZE;k++)
228 {
229 if(pTable_ES[k].type ==UADP_SDT_END)
230 break;
231 }
232 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_ES pTable_ES=%p from=%p to=%p break=%p StructureOffset=0x%x\n",__FUNCTION__,__LINE__,pTable_ES,(pcFrom+pUStart),(pcTo+pKStart),k,StructureOffset);
233 pKStart += StructureOffset;
234 pUStart += StructureOffset-(k-1)*4;
235 break;
236 }
237 case UADP_SPT_END:
238 pKEnd = pKSelfSize-1;
239 pKLen = pKEnd+1-pKStart; //include uiEnd last byte
240 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SPT_END UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
241 fcpy(pcTo+pKStart,pcFrom+pUStart,pKLen);
242 return;
243 }
244 }
245 }
246 #endif
247
CPY(void * to,const void * from,unsigned int Start,unsigned int Offset,MS_PHY * Len,fcpy_t fcpy,int iMode)248 static void CPY(void *to, const void *from,unsigned int Start,unsigned int Offset, MS_PHY *Len ,fcpy_t fcpy, int iMode)
249 {
250 char* pcTo=NULL;
251 char* pcFrom=NULL;
252 MS_PHY KLen=0,KEnd=0;
253 if(iMode&SRC_MODE_CPY_FROM_USR)
254 {
255 pcTo =(char*)to;
256 pcFrom =(char*)compat_ptr(from);
257 }
258 else
259 {
260 pcTo =(char*)compat_ptr(to);
261 pcFrom =(char*)from;
262 }
263
264 if(Offset!=Start /* 1. size =0-1 cause error; 2. Over size*/)
265 {
266 KEnd = Offset-1;
267 KLen = KEnd+1-Start;
268 fcpy(pcTo,pcFrom,KLen);
269 }
270 else
271 {
272 KLen=0;
273 }
274
275 *Len = KLen;
276 return;
277 }
278
CmpStructRecursiveCpy(void ** ppDest,void * pSrc,const UADP_STRUCT_POINTER_TABLE * pTable,fcpy_t fcpy,int iMode,bool isES,unsigned int * TurnUsrAddrOffset)279 static int CmpStructRecursiveCpy(void** ppDest, void* pSrc,const UADP_STRUCT_POINTER_TABLE *pTable,fcpy_t fcpy, int iMode, bool isES, unsigned int* TurnUsrAddrOffset)
280 {
281 int i=0,ret=0;
282 char* pcBuffer=NULL;
283 void* pCmptr=NULL;
284 FlagPrint(SPT_DB_DETAIL)("ppDest=%p,pTable=%p,pSrc=%p isES=%d TurnUsrAddrOffset=%p\n",ppDest,pTable,pSrc,isES, *TurnUsrAddrOffset);
285
286 char* pcTo =NULL;
287 char* pcFrom =NULL;
288 MS_U64* u64p=NULL;
289 unsigned int ReferenceOffset=0;
290 MS_PHY pKStart=0, pKEnd=0, pKLen=0, pKSelfSize=0;
291 MS_PHY pUStart=0, pUEnd=0, pULen=0, pUSelfSize=0;
292
293 if(pTable==NULL)
294 {
295 db_printf("TABLE is NULL\n");
296 return ret;
297 }
298
299 *TurnUsrAddrOffset=0;
300 for(i=0;i<SPT_MAX_SIZE;i++)
301 {
302 FlagPrint(SPT_DB_DETAIL)("[%s][%d]i=%d type=%d isES=%d \n",__FUNCTION__,__LINE__,i,pTable[i].type,isES);
303 switch(pTable[i].type)
304 {
305 case UADP_SPT_SELF_SIZE:
306 {
307 if(TRUE!=isES)//ES don't need malloc
308 {
309 if(iMode&SRC_MODE_MALLOC && pTable[i].size_or_next!=0)
310 {
311 pcBuffer = MALLOC(pTable[i].size_or_next);
312 *ppDest = pcBuffer;
313 FlagPrint(SPT_DB_MALLOC_FREE)("[%s][%d]<malloc %p, size=%u>\n",__FUNCTION__,__LINE__,*ppDest,pTable[i].size_or_next);
314 }
315 }
316 if(iMode&SRC_MODE_CPY_FROM_USR)
317 {
318 pcFrom =(char*)compat_ptr(pSrc);
319 pcTo =(char*)(*ppDest);
320 }
321 else
322 {
323 pcFrom =(char*)(pSrc);
324 pcTo =(char*)compat_ptr(*ppDest);
325 }
326 pKSelfSize = pTable[i].size_or_next;
327 FlagPrint(SPT_DB_DETAIL)("[%s][%d] UADP_SPT_SELF_SIZE pTable[%d].size_or_next=%d \n",__FUNCTION__,__LINE__, i, pKSelfSize);
328 break;
329 case UADP_SDT_P2N:
330
331 if(iMode&SRC_MODE_CPY_FROM_USR)
332 {
333 //1. Copy before SDT_elements
334 CPY(pcTo+pKStart,pcFrom+pUStart,pKStart,pTable[i].offset,&pKLen,fcpy,iMode);
335 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_P2N pcFrom=%p UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,(pcFrom+pUStart),pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
336
337 //2. Copy SDT_elements
338 u64p = (pcTo+ pTable[i].offset);
339 pUStart += pKLen;
340 fcpy(u64p,pcFrom+pUStart,4);
341 *u64p =(0xFFFFFFFF)& (*u64p);
342 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_P2N UAdrr=%p KAdrr=%p NextUaddr=%p\n",__FUNCTION__,__LINE__, (pcFrom+pUStart),u64p, *u64p);
343
344 //3. P2N CPY
345 pCmptr = compat_ptr(*((void**)(pcFrom+pUStart)));// compat_ptr(*((void**)(pcFrom+pTable[i].offset-(i-1)*4)));
346 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_P2N pTable[%d].offset=%p pCmptr=%p\n",__FUNCTION__,__LINE__,i,(void*)pTable[i].offset,pCmptr);
347 if(pCmptr==NULL)
348 {
349 printk("Next pointer is NULL pointer, ignore it.\n");
350 //Case: maybe pCmptr==NULL, but need to create buffer for Free
351 CmpStructRecursiveCpy((void**)(pcTo+pTable[i].offset),pCmptr,(UADP_STRUCT_POINTER_TABLE *)(pTable[i].size_or_next),CPY_FROM_USER,SRC_MODE_MALLOC|SRC_MODE_CPY_FROM_USR, FALSE, (unsigned int*)&ReferenceOffset);
352 }
353 else
354 {
355 ret += CmpStructRecursiveCpy((void**)(pcTo+pTable[i].offset),pCmptr ,(UADP_STRUCT_POINTER_TABLE *)(pTable[i].size_or_next),fcpy, iMode, FALSE, (unsigned int*)&ReferenceOffset);
356 }
357 }
358 else
359 {
360 //1. Copy before SDT_elements
361 CPY(pcTo+pUStart,pcFrom+pKStart,pKStart,pTable[i].offset,&pKLen,fcpy,iMode);
362 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_P2N pcTo=%p UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,(pcTo+pUStart), pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
363
364 //2. Copy SDT_elements
365 pUStart += pKLen;//pTable[i].offset-(i-1)*4;
366 pCmptr = compat_ptr(*(void**)(pcTo+pUStart));//compat_ptr((void**)(pcTo+pTable[i].offset-(i-1)*4));
367 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_P2N pTable[%d].offset=%p pCmptr=%p\n",__FUNCTION__,__LINE__,i,(void*)pTable[i].offset,pCmptr);
368 if(pCmptr==NULL)
369 {
370 printk("Next pointer is NULL pointer, ignore it.\n");
371 }
372 else
373 {
374 ret += CmpStructRecursiveCpy(&pCmptr,*((void**)(pcFrom+pTable[i].offset)),(UADP_STRUCT_POINTER_TABLE *)(pTable[i].size_or_next),fcpy, iMode, FALSE,(unsigned int*)&ReferenceOffset);
375 }
376 }
377
378 //4. Calculate new start
379 pKStart = pTable[i].offset+sizeof(void*);
380 pUStart +=4;
381
382 //5. if ES, record for return
383 if(TRUE==isES)
384 {
385 *TurnUsrAddrOffset += 4;
386 }
387 break;
388 case UADP_SDT_AT:
389 if (!(iMode&SRC_MODE_COPY))
390 break;
391
392 if(iMode&SRC_MODE_CPY_FROM_USR)
393 {
394 //1. Copy before SDT_elements
395 CPY(pcTo+pKStart,pcFrom+pUStart,pKStart,pTable[i].offset,&pKLen,fcpy,iMode);
396 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_AT pcFrom=%p UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,(pcFrom+pUStart),pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
397
398 //2. Copy SDT_elements
399 u64p = (pcTo+ pTable[i].offset);
400 pUStart += pKLen;//pTable[i].offset-(i-1)*4;
401 fcpy(u64p,pcFrom+pUStart,4);
402 *u64p =(0xFFFFFFFF)& (*u64p);
403 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_AT UAdrr=%p KAdrr=%p NextUaddr=%p\n",__FUNCTION__,__LINE__,(pcFrom+pUStart),u64p,*u64p);
404 }
405 else
406 {
407 //1. Copy before SDT_elements
408 CPY(pcTo+pUStart,pcFrom+pKStart,pKStart,pTable[i].offset,&pKLen,fcpy,iMode);
409 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_AT pcTo=%p UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,(pcTo+pUStart), pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
410
411 //2. Copy SDT_elements
412 pKStart = pTable[i].offset;
413 pUStart += pKLen;//pTable[i].offset-(i-1)*4;
414 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_AT UAdrr=%p KAdrr=%p\n",__FUNCTION__,__LINE__,(pcTo+pUStart), (pcFrom+pKStart));
415 fcpy(pcTo+pUStart,pcFrom+pKStart, 4);
416 }
417
418 //3. Calculate new start
419 pKStart = pTable[i].offset+sizeof(void*);
420 pUStart += 4;
421
422 //4. if ES, record for return
423 if(TRUE==isES)
424 {
425 *TurnUsrAddrOffset += 4;
426 }
427 break;
428 case UADP_SDT_ES:
429 {
430 if (!(iMode&SRC_MODE_COPY))
431 break;
432
433 unsigned long StructureOffset=0;
434 UADP_STRUCT_POINTER_TABLE *pTable_ES=NULL;
435 char* pVal=NULL;
436 if(iMode&SRC_MODE_CPY_FROM_USR)
437 {
438 //1. Copy before SDT_elements
439 CPY(pcTo+pKStart,pcFrom+pUStart,pKStart,pTable[i].offset,&pKLen,fcpy,iMode);
440 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_ES pcFrom=%p UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,(pcFrom+pUStart),pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
441
442 //2. Copy SDT_elements
443 pKStart += pKLen;
444 pUStart += pKLen;//pTable[i].offset-(i-1)*4;
445 pCmptr = compat_ptr(pcFrom+pUStart);//compat_ptr(pcFrom+pTable[i].offset-(i-1)*4);
446 pVal = pcTo+pTable[i].offset;
447 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_ES pCmptr=%p \n",__FUNCTION__,__LINE__,pCmptr);
448 ret += CmpStructRecursiveCpy((void**)&pVal,(void*)pCmptr ,(UADP_STRUCT_POINTER_TABLE *)(pTable[i].size_or_next),fcpy, iMode, TRUE, (unsigned int*)&ReferenceOffset);
449 }
450 else
451 {
452 //1. Copy before SDT_elements
453 CPY(pcTo+pUStart,pcFrom+pKStart,pKStart,pTable[i].offset,&pKLen,fcpy,iMode);
454 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_ES pcTo=%p UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,(pcTo+pUStart), pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
455
456 //2. Copy SDT_elements
457 pKStart += pKLen;
458 pUStart += pKLen;
459 pCmptr = compat_ptr(pcTo+pUStart);//compat_ptr(pcTo+pTable[i].offset-(i-1)*4);
460 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_ES pCmptr=%p \n",__FUNCTION__,__LINE__,pCmptr);
461 ret += CmpStructRecursiveCpy((void**)&pCmptr,(void*)(pcFrom+pTable[i].offset),(UADP_STRUCT_POINTER_TABLE *)(pTable[i].size_or_next),fcpy, iMode, TRUE, (unsigned int*)&ReferenceOffset);
462 }
463
464 //3. Calculate ES offset
465 pTable_ES = (UADP_STRUCT_POINTER_TABLE *)(pTable[i].size_or_next);
466 StructureOffset =pTable_ES[0].size_or_next;
467 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SDT_ES pTable_ES=%p from=%p to=%p StructureOffset=%d\n",__FUNCTION__,__LINE__,pTable_ES,(pcFrom+pUStart),(pcTo+pKStart),StructureOffset);
468 pKStart += StructureOffset;
469 pUStart = pUStart+StructureOffset-ReferenceOffset;
470
471 //4. if ES, record for return
472 if(TRUE==isES)
473 {
474 *TurnUsrAddrOffset += ReferenceOffset;
475 }
476 }
477 break;
478 case UADP_SPT_END:
479 if (!(iMode&SRC_MODE_COPY))
480 return ret;
481
482 //Copy elements
483 if(iMode&SRC_MODE_CPY_FROM_USR)
484 {
485 CPY(pcTo+pKStart,pcFrom+pUStart,pKStart,pKSelfSize,&pKLen,fcpy,iMode);
486 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SPT_END pcFrom=%p UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,(pcFrom+pUStart),pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
487 }
488 else
489 {
490 CPY(pcTo+pUStart,pcFrom+pKStart,pKStart,pKSelfSize,&pKLen,fcpy,iMode);
491 FlagPrint(SPT_DB_DETAIL)("[%s][%d]UADP_SPT_END pcTo=%p UStart=%p KStart=%p,KEnd=%p,KLen=%p,off=%p,ptr_size=%p\n",__FUNCTION__,__LINE__,(pcTo+pUStart), pUStart, pKStart,pKEnd,pKLen,pTable[i].offset,sizeof(pcTo));
492 }
493 return ret;
494 }
495 }
496 }
497
498 db_printf("SPT table size over flow > %d\n",SPT_MAX_SIZE);
499 ret += 1;
500 return ret;
501 }
502 #endif
503
StructRecursiveCpy(void ** ppDest,void * pSrc,const UADP_STRUCT_POINTER_TABLE * pTable,fcpy_t fcpy,int iMode)504 static int StructRecursiveCpy(void** ppDest, void* pSrc,const UADP_STRUCT_POINTER_TABLE *pTable,fcpy_t fcpy, int iMode)
505 {
506 int ret=0;
507 int i;
508 char* pcBuffer=NULL;
509 char* pcSrc=(char*)pSrc;
510
511 FlagPrint(SPT_DB_DETAIL)("ppDest=%p,pTable=%p,pSrc=%p,",ppDest,pTable,pSrc);
512
513 if(pTable==NULL)
514 {
515 db_printf("TABLE is NULL\n");
516 return ret;
517 }
518
519 for(i=0;i<SPT_MAX_SIZE;i++)
520 {
521 switch(pTable[i].type)
522 {
523 case UADP_SPT_SELF_SIZE:
524 if(iMode&SRC_MODE_MALLOC)
525 {
526 pcBuffer = MALLOC(pTable[i].size_or_next);
527 *ppDest = pcBuffer;
528 FlagPrint(SPT_DB_MALLOC_FREE)("<malloc %p, size=%u>\n",*ppDest,pTable[i].size_or_next);
529 if(iMode&SRC_MODE_COPY)fcpy(pcBuffer,pSrc,pTable[i].size_or_next);
530 }
531 else
532 {
533 pcBuffer = *ppDest;
534 FlagPrint(SPT_DB_MALLOC_FREE)("<use buf %p>\n",*ppDest);
535 if(iMode&SRC_MODE_COPY)SkipCpy(pcBuffer,pSrc,pTable,fcpy);
536 }
537 FlagPrint(SPT_DB_DETAIL)("pTable[%d].size_or_next=%d\n",i,pTable[i].size_or_next);
538 break;
539 case UADP_SPT_POINTER_TO_NEXT:
540 FlagPrint(SPT_DB_DETAIL)("pTable[%d].offset=%p\n",i,(void*)pTable[i].offset);
541 FlagPrint(SPT_DB_DETAIL)("pcSrc+pTable[i].offset=%p\n",pcSrc+pTable[i].offset);
542 if((*((void**)(pcSrc+pTable[i].offset)))==NULL)
543 {
544 FlagPrint(SPT_DB_DETAIL)("Next pointer is NULL pointer, ignore it.\n");
545 break;
546 }
547 ret += StructRecursiveCpy((void**)(pcBuffer+pTable[i].offset),*((void**)(pcSrc+pTable[i].offset)),(UADP_STRUCT_POINTER_TABLE *)(pTable[i].size_or_next),fcpy, iMode);
548 break;
549 case UADP_SDT_AT:
550 case UADP_SDT_ES:
551 break;
552 case UADP_SPT_END:
553 return ret;
554 }
555 }
556
557 db_printf("SPT table size over flow > %d\n",SPT_MAX_SIZE);
558 ret += 1;
559 return ret;
560 }
561
StructRecursiveFree(void ** ppDest,const UADP_STRUCT_POINTER_TABLE * pTable)562 static int StructRecursiveFree(void** ppDest,const UADP_STRUCT_POINTER_TABLE *pTable)
563 {
564 int ret=0;
565 int i;
566
567 FlagPrint(SPT_DB_DETAIL)("ppDest=%p,pTable=%p,\n",ppDest,pTable);
568 if(pTable==NULL)return ret;
569
570 for(i=0;i<SPT_MAX_SIZE;i++)
571 {
572 switch(pTable[i].type)
573 {
574 case UADP_SPT_SELF_SIZE:
575 case UADP_SDT_AT:
576 case UADP_SDT_ES:
577 break;
578 case UADP_SPT_POINTER_TO_NEXT:
579 FlagPrint(SPT_DB_DETAIL)("pTable[%d].offset=%p\n",i,(void*)pTable[i].offset);
580 ret += StructRecursiveFree((void**)(*ppDest+pTable[i].offset),(UADP_STRUCT_POINTER_TABLE *)(pTable[i].size_or_next));
581 break;
582 case UADP_SPT_END:
583 FlagPrint(SPT_DB_DETAIL)("<free *ppDest=%p>\n",*ppDest);
584 FREE(*ppDest);
585 *ppDest=NULL;
586 return ret;
587 }
588 }
589
590 db_printf("SPT table size over flow > %d\n",SPT_MAX_SIZE);
591 ret += 1;
592 return ret;
593 }
594
595 #if SPT_DB_MEMINFO
ShowMemInfo(char * str)596 static void ShowMemInfo(char* str)
597 {
598 char buff[100];
599 db_printf("%s\n",str);
600 sprintf(buff,"pmap -x %d | grep total",getpid());
601 system(buff);
602 db_printf("\n");
603 }
604 #else//SPT_DB_MEMINFO
605 #define ShowMemInfo(a)
606 #endif//SPT_DB_MEMINFO
607
608 #if SPT_DB_SEQMM_MAX_USAGE
OverFlowAssert(void * pInstance,unsigned int u32Cmd,void * pMemorySpace)609 static void OverFlowAssert(void* pInstance,unsigned int u32Cmd,void* pMemorySpace)
610 {
611
612 unsigned int u32ModuleID;
613 if(SequenceMMCheckFlag(pMemorySpace,SEQMM_FLAG_OVERFLOW))
614 {
615 UtopiaInstanceGetModuleID(pInstance,&u32ModuleID);
616 db_printf("UADPBypassIoctl overflow: MODULE=%x, CMD=%x, usage/space=%u/%u\n",u32ModuleID,u32Cmd,SequenceMMGetUsage(pMemorySpace),SequenceMMGetSpace(pMemorySpace));
617 while(1);
618 }
619 }
620 #else //SPT_DB_SEQMM_MAX_USAGE
621 #define SeqMMAssert(a)
622 #endif//SPT_DB_SEQMM_MAX_USAGE
623 //==================================public functions===============================================
UADPBypassSetSPT(UADP_STRUCT_POINTER_TABLE * pSpt,unsigned int uiType,unsigned int uiOffset,unsigned long uiSizeOrNext)624 int UADPBypassSetSPT(UADP_STRUCT_POINTER_TABLE* pSpt, unsigned int uiType, unsigned int uiOffset, unsigned long uiSizeOrNext)
625 {
626 FlagPrint(SPT_DB_DETAIL)("pSpt=%p, uiType=%x,uiOffset=%x,uiSizeOrNext_x=%p,uiSizeOrNext_u=%lx\n",pSpt, uiType,uiOffset,uiSizeOrNext,uiSizeOrNext);
627 pSpt->type = uiType;
628 pSpt->offset = uiOffset;
629 pSpt->size_or_next = uiSizeOrNext;
630
631 return 0; //FIXME: It didn't define return value.
632 }
633
UADPBypassIoctl(void * pInstance,unsigned int u32Cmd,void * pArgs,const UADP_STRUCT_POINTER_TABLE * pInTable,const UADP_STRUCT_POINTER_TABLE * pOutTable,void * pWorkBuffer,int iWorkBufferSize)634 int UADPBypassIoctl(void* pInstance, unsigned int u32Cmd, void* pArgs,const UADP_STRUCT_POINTER_TABLE *pInTable,const UADP_STRUCT_POINTER_TABLE *pOutTable, void* pWorkBuffer, int iWorkBufferSize)
635 {
636 void* karg=NULL;
637 const UADP_STRUCT_POINTER_TABLE *FreeTable=NULL;
638 void* data=NULL;
639 unsigned int TurnUsrAddrOffset=0;
640 MS_U32 ret=0;
641
642 //1. generate (in_table_id,kernel_argc) space, and copy user_argc to (in_table_id,kernel_argc)
643 if(SPT_DB_MEMINFO)ShowMemInfo("before malloc:\n");
644 if(pInTable) //malloc(for in/out) and copy
645 {
646 FreeTable=pInTable;
647 if(is_compat_task()==0)
648 {
649 StructRecursiveCpy(&karg,pArgs,pInTable,CPY_FROM_USER,SRC_MODE_COPY|SRC_MODE_MALLOC|SRC_MODE_CPY_FROM_USR);
650 }
651 #ifdef CONFIG_COMPAT
652 else if(is_compat_task()==1)
653 {
654 data = (void*)compat_ptr(pArgs);
655 CmpStructRecursiveCpy(&karg,data,pInTable,CPY_FROM_USER,SRC_MODE_COPY|SRC_MODE_MALLOC|SRC_MODE_CPY_FROM_USR, FALSE, (unsigned int*)&TurnUsrAddrOffset);
656 }
657 #endif
658 }
659 else if(pOutTable) //malloc(for out) only
660 {
661 //need malloc space for karg for output space
662 FreeTable=pOutTable;
663 if(is_compat_task()==0)
664 {
665 StructRecursiveCpy(&karg,pArgs,pOutTable,CPY_FROM_USER,SRC_MODE_MALLOC|SRC_MODE_CPY_FROM_USR);
666 }
667 #ifdef CONFIG_COMPAT
668 else if(is_compat_task()==1)
669 {
670 data = (void*)compat_ptr(pArgs);
671 CmpStructRecursiveCpy(&karg,data,pOutTable,CPY_FROM_USER,SRC_MODE_MALLOC|SRC_MODE_CPY_FROM_USR, FALSE, (unsigned int*)&TurnUsrAddrOffset);
672 }
673 #endif
674 }
675 if(SPT_DB_MEMINFO)ShowMemInfo("after malloc:\n");
676 //2. call fd->CMD_ID(fd, CMD_ID, kernel_argc)
677 ret = UtopiaIoctl(pInstance,u32Cmd,karg);
678 //3. copy (out_table_id,kernel_argc) to user_argc
679 if(pOutTable)
680 {
681 if(is_compat_task()==0)
682 {
683 StructRecursiveCpy(&pArgs,karg,pOutTable,CPY_to_USER,SRC_MODE_COPY);
684 }
685 #ifdef CONFIG_COMPAT
686 else if(is_compat_task()==1)
687 {
688 data = (void*)compat_ptr(pArgs);
689 CmpStructRecursiveCpy(&data,karg,pOutTable,CPY_to_USER,SRC_MODE_COPY,FALSE, (unsigned int*)&TurnUsrAddrOffset);
690 }
691 #endif
692 }
693 //4. free(in_table_id,kernel_argc);
694 if(FreeTable)
695 {
696 StructRecursiveFree(&karg,FreeTable);
697 }
698 if(SPT_DB_MEMINFO)ShowMemInfo("after free:\n");
699
700 return ret; //FIXME: It didn't define return value.
701 }