xref: /utopia/UTPA2-700.0.x/modules/msos/utopia_core/linux_kernel/utopia_adp_bypass.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
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 }