blob: 51e2f3c396b162066379bd60d19412891885e026 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
2 *
3 * (C)Copyright 2005 - 2011 Marvell. All Rights Reserved.
4 *
5 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
6 * The copyright notice above does not evidence any actual or intended
7 * publication of such source code.
8 * This Module contains Proprietary Information of Marvell and should be
9 * treated as Confidential.
10 * The information in this file is provided for the exclusive use of the
11 * licensees of Marvell.
12 * Such users have the right to use, modify, and incorporate this code into
13 * products for purposes authorized by the license agreement provided they
14 * include this notice and the associated copyright notice with any such
15 * product.
16 * The information in this file is provided "AS IS" without warranty.
17 *
18 *
19 * FILENAME: Misc.c
20 *
21 * PURPOSE: Contain helpful misc. functions
22 *
23******************************************************************************/
24
25#include "misc.h"
26
27
28static unsigned char* StrPtr8;
29static unsigned int DataWidth;
30
31// Very simple routine to reverse bytes on up to a 512 byte buffer.
32UINT_T ReverseBytes (UINT8_T* Address, UINT_T Size)
33{
34 UINT8_T Buffer[512];
35 UINT_T i;
36
37 if (Size > 512)
38 return InvalidSizeError;
39
40 // First copy to a Buffer
41 for (i=0; (i < Size); i++)
42 Buffer[i] = Address[i];
43
44 // Next copy to Address in reverse order
45 for (i=0; (i < Size); i++)
46 Address[Size - 1 - i] = Buffer[i];
47
48 return NoError;
49}
50
51//endian conversion function: self explanatory
52unsigned int Endian_Convert (unsigned int in)
53{
54 unsigned int out;
55 out = in << 24;
56 out |= (in & 0xFF00) << 8;
57 out |= (in & 0xFF0000) >> 8;
58 out |= (in & 0xFF000000) >> 24;
59 return out;
60}
61
62// return 1 if majority of right-most numBits in Word are 1
63// return 0 if majority of right-most numBits in Word are 0
64// return 0 if 1s are equal to 0s (this means numBits is even)
65unsigned int MajorityVote (unsigned int Word, unsigned int numBits)
66{
67 int i;
68 int numOnes = 0;
69 int numZeros = 0;
70 for (i=1; i<=numBits; i++)
71 {
72 if ( (Word & 1) == 1 ) numOnes++;
73 else numZeros++;
74
75 Word = Word>>1;
76 }
77 if (numOnes > numZeros) return 1;
78 else return 0; // If majority voting is requested for even number of bits and numOnes == numZeros, zero wins
79}
80
81/**
82 * Memory set function
83 **/
84void memset(void *Addr, unsigned char Val, unsigned long Size)
85{
86
87 unsigned long i;
88 for(i=0; i < Size; i++ )
89 {
90 ((unsigned char*)Addr)[i] = Val;
91 }
92}
93
94void *memcpy(void *dest, const void *src, unsigned int n)
95{
96 const unsigned char *s = (const unsigned char*)src;
97 unsigned char *d = (unsigned char *)dest;
98
99 //don't copy if we don't need to
100 if(dest == src)
101 return dest;
102
103 //smart copy, in case of overlap:
104 while(n-- > 0)
105 if(s > d) //copy 'forwards'
106 *d++ = *s++;
107 else //copy 'in reverse'
108 d[n] = s[n];
109
110 return dest;
111}
112
113void *memmove(void *dest, const void *src, unsigned int n)
114{
115 return memcpy(dest, src, n);
116}
117
118int memcmp( const void *buffer1, const void *buffer2, int count)
119{
120 UINT8_T* buf1 = (UINT8_T*)buffer1;
121 UINT8_T* buf2 = (UINT8_T*)buffer2;
122
123 while(count)
124 {
125 if( *(buf1) != *(buf2) )
126 return( (*buf1 < *buf2) ? -1 : 1 );
127
128 buf1 += sizeof(UINT8_T);
129 buf2 += sizeof(UINT8_T);
130 count--;
131 }
132
133 return 0;
134}
135
136int ConvertStringToInteger8(const unsigned char* StringPtr, unsigned int Count)
137{
138 int Output = 0;
139 unsigned char c;
140 while (*StringPtr)
141 {
142 Output *= Count;
143 c = *StringPtr++;
144 if (c >= '0' && c <= '9')
145 Output += (c-'0');
146 else
147 Output += ((c|' ')-'a'+10);
148 }
149 return (Output);
150}
151
152int DivideTwoNumbers(int Numerator,int Denominator)
153{
154 int Tmp = 0;
155 int Output = 0;
156 int Count;
157 if(!Denominator)
158 return Numerator;
159
160 for (Count = 28; Count >= 0; Count -= 4)
161 {
162 Tmp <<= 4;
163 Output <<= 4;
164 Tmp |= (Numerator >> Count)&0xf;
165 while(Tmp >= 0)
166 {
167 Tmp -= Denominator;
168 Output++;
169 }
170 Tmp += Denominator;
171 Output--;
172 }
173 return(Output);
174}
175
176int ModOfTwoNumbers(int Numerator, int Denominator)
177{
178 //return(Numerator - (Denominator * DivideTwoNumbers(Numerator, Denominator)));
179 int Tmp;
180 Tmp = DivideTwoNumbers(Numerator, Denominator);
181 Tmp = Tmp * Denominator;
182 Tmp = Numerator - Tmp;
183#if LINUX_BUILD
184 // The GCC compiler assigns the value in R1(Quotient) to variable on the left side of the "="
185 // in the calling code. So we need to move the Remainder (in Tmp) to R1 so we get the Remainder
186 // returned and not the quotient.
187 // Syntax below informs the compiler we modified R1 intentionally and don't mess with it.
188 asm("mov r1, %[value]" :: [value] "r" (Tmp): "r1"); // this move the contents of temp into r1
189#endif
190 return Tmp;
191}
192
193
194void ConvertLongIntToBuf8(int DataValue, int Count)
195{
196 if (DataValue >= Count)
197 {
198 ConvertLongIntToBuf8(DivideTwoNumbers(DataValue, Count), Count);
199 StrPtr8++;
200 DataWidth--;
201 DataValue = ModOfTwoNumbers(DataValue, Count);
202 }
203 if (DataWidth > 0)
204 *StrPtr8 = (unsigned char)(DataValue + (DataValue < 10 ? '0' : ('a'-10)));
205}
206
207
208void ConvertIntToBuf8(unsigned char* StringPtr,unsigned int Value, int Width,unsigned int Count)
209{
210 int i;
211 StrPtr8 = StringPtr;
212 DataWidth = Width;
213 if (Value >= Count)
214 {
215 ConvertLongIntToBuf8(DivideTwoNumbers(Value,Count),Count);
216 StrPtr8++;
217 DataWidth--;
218 Value=ModOfTwoNumbers(Value,Count);
219 }
220 if (DataWidth-->0)
221 *StrPtr8=(unsigned char)(Value + (Value < 10 ? '0' : ('a'-10)));
222
223 // If DataWidth=0, the following will do nothing, so just return here
224 if (DataWidth == 0) return;
225
226 // Shift the contents of the buffer to right by DataWidth to achieve right alignment
227 for (i=Width; i > DataWidth; i--)
228 {
229 *(StrPtr8+DataWidth) = *(StrPtr8);
230 StrPtr8--;
231 }
232 // Prepend leading zeros if necessary
233 while (DataWidth-- > 0)
234 *++StrPtr8 = '0';
235}
236
237void __aeabi_idiv0( void ){
238
239 //dummy function for the compiler
240 // need to investigate the in32t_divide.o and x0_a000.o libraries from XDB
241 return;
242}
243
244//The below functions are pulled in from a library when built by RVCT or SDT compiler (NDT flag)
245//When built by the linux compiler, we need to define the calls ourselves
246#if LINUX_BUILD
247
248void __aeabi_idiv(void){
249//void __divsi3(void){
250 asm("b DivideTwoNumbers");
251 return;
252}
253
254void __aeabi_uidiv(void){
255//void __udivsi3(void){
256 asm("b DivideTwoNumbers");
257 return;
258}
259
260void __aeabi_uidivmod(void){
261 asm("b ModOfTwoNumbers");
262 return;
263}
264
265long long __aeabi_llsr(long long a, int b)
266{
267
268}
269#endif
270
271
272/*
273 String Compare function - case sensitive
274 Will compare str1 to str2, character to character, until a NULL character is hit
275 or until maxlength is reached
276 If no NULL character is present, there could be serious issues
277
278 Return values:
279 -1 = str1 < str2
280 0 = Match
281 1 = str1 > str2
282
283 */
284int strcmpl( char* str1, char* str2, int maxlength )
285{
286 int length = maxlength;
287 while((*str1 != NULL) && (*str2 != NULL) && --length)
288 {
289 if (*str1 != *str2)
290 {
291 // check the char that was different to determine results
292 if ( *str1 > *str2 )
293 return 1;
294 else
295 return -1;
296 }
297 str1++; str2++;
298 }
299
300 // strings compared so far, but did we reach the end of both?
301 if ( *str1 != NULL && *str2 != NULL )
302 // did not find the NULLs but have reached the maxlength to compare
303 return 0;
304
305 if ( *str1 == NULL && *str2 == NULL )
306 return 0;
307
308 if ( *str1 != NULL && *str2 == NULL )
309 // "abcde" > "abcd"
310 return 1;
311 else
312 // "abcd" < "abcde"
313 return -1;
314}
315
316
317/*
318 String Compare function - case insensitive
319 Will compare str1 to str2 ignoring case, character to character, until a NULL character is hit
320 or until maxlength is reached
321 If no NULL character is present, there could be serious issues
322
323 Return values:
324 -1 = str1 < str2
325 0 = Match
326 1 = str1 > str2
327 */
328int stricmpl( char* str1, char* str2, int maxlength)
329{
330 int length = maxlength;
331 while((*str1 != NULL) && (*str2 != NULL) && --length)
332 {
333 if ( ((*str1) & 0xDF) != ((*str2) & 0xDF) )
334 {
335 // check the char that was different to determine results
336 if ( ((*str1) & 0xDF) > ((*str2) & 0xDF) )
337 return 1;
338 else
339 return -1;
340 }
341 str1++; str2++;
342 }
343
344 // strings compared so far, but did we reach the end of both?
345 if ( *str1 != NULL && *str2 != NULL )
346 // did not find the NULLs but have reached the maxlength to compare
347 return 0;
348
349 if ( *str1 == NULL && *str2 == NULL )
350 return 0;
351
352 if ( *str1 != NULL && *str2 == NULL )
353 // "abcde" > "abcd"
354 return 1;
355 else
356 // "abcd" < "abcde"
357 return -1;
358}
359
360
361INT_T strlen (const char * str)
362{
363 int i = 0;
364 while(str[i++] != '\0')
365 if(i > 1000)
366 break;
367 return --i;
368}
369
370INT_T memcmpFF( const void *buffer, INT_T count)
371{
372 UINT8_T* buf = (UINT8_T*)buffer;
373
374 while(count--)
375 {
376 if( *(buf) != 0xFF )
377 return -1;
378
379 buf += sizeof(UINT8_T);
380 }
381
382 return 0;
383}
384
385
386//Aligns the pointer on ALIGN boundary
387unsigned long Align_Ptr (unsigned long Address, unsigned long Align)
388{
389 Address = (Address+Align-1) & ~(Align - 1);
390 return Address;
391}
392
393
394void bubble(UINT16_T * ptr, UINT_T n)
395{
396 UINT_T i, j, temp;
397
398 for (i = 0; i < n-1; i++)
399 for (j = i + 1; j < n; j++)
400 if (ptr[i] > ptr[j])
401 {
402 temp = ptr[j];
403 ptr[j] = ptr[i];
404 ptr[i] = temp;
405 }
406}
407
408UINT CalcImageChecksum( UINT_T* DownloadArea, UINT_T ImageLength)
409{
410 UINT ImageChecksum = 0;
411 UINT32* ptr32 = DownloadArea;
412 UINT32* pEnd = ptr32 + (ImageLength / sizeof(UINT32));
413 UINT BytesSummed = 0;
414
415 while ( ptr32 < pEnd )
416 {
417 // checksum format version 2 algorithm as defined by flasher
418 ImageChecksum ^= (*ptr32);
419 ptr32++;
420 BytesSummed += sizeof(UINT32);
421 }
422 return ImageChecksum;
423}
424
425UINT_T CalcMRDChecksum( UINT_T* start, UINT_T length)
426{
427 UINT8_T *pRD_DDR_end = NULL;
428 UINT_T check_sum = 0, num = 0;
429 UINT_T a = 0x0001, b = 0x0000, index = 0;
430 UINT8_T * pRAMbuf;
431
432 pRAMbuf = (UINT8_T *)start;
433 pRD_DDR_end = pRAMbuf + length;
434
435 do
436 {
437 num = (UINT_T)(*pRAMbuf++);
438 a += num;
439 index++;
440 b += a;
441
442 /*
443 Algorithm is defined as mod MOD_ADLER at every modification to a and b.
444 For efficiency reasons this mod can be done once in a while to keep (a) and (b) in range (32-bit signed)
445 The result is invariant of MOD_LOOPS value.
446 a<5550*256; b<(5551*256/2)*5550=3943430400 (in range)
447 */
448 if(index == MOD_LOOPS)
449 {
450 index =0;
451 a %= MOD_ADLER;
452 b %= MOD_ADLER;
453 }
454 // TBD: MISALIGNED 32-BIT ACCESS HERE AT EVERY BYTE ADDRESS, VERY INEFFICIENT & REDUNDANT
455 // Kept here for now for compatibility with old version of the tool that produces RDA with DADADADA at misaligned offset
456
457 } while( pRAMbuf < (UINT8_T *)pRD_DDR_end );
458
459 if(index)
460 {
461 a %= MOD_ADLER;
462 b %= MOD_ADLER;
463 }
464
465 check_sum = (b << 16) | a;
466
467 return check_sum;
468}
469
470const UINT32 crc32_table[] =
471{
472 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
473 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
474 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
475 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
476 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
477 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
478 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
479 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
480 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
481 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
482 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
483 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
484 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
485 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
486 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
487 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
488 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
489 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
490 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
491 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
492 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
493 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
494 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
495 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
496 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
497 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
498 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
499 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
500 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
501 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
502 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
503 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
504 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
505 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
506 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
507 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
508 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
509 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
510 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
511 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
512 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
513 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
514 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
515 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
516 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
517 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
518 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
519 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
520 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
521 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
522 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
523 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
524 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
525 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
526 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
527 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
528 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
529 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
530 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
531 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
532 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
533 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
534 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
535 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
536};
537
538
539UINT32 CalcCRC32 (const unsigned char *buf, int len, unsigned int init)
540{
541 UINT32 crc = init;
542 while (len--)
543 {
544 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
545 buf++;
546 }
547 return crc;
548}
549
550UINT16_T from32to16(UINT x)
551{
552 /* add up 16-bit and 16-bit for 16+c bit */
553 x = (x & 0xffff) + (x >> 16);
554 /* add up carry.. */
555 x = (x & 0xffff) + (x >> 16);
556 return x;
557}
558
559UINT malbrain_crc32(UINT crcu32, const BYTE *ptr, UINT buf_len)
560{
561 static const UINT s_crc32[16] = {
562 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
563 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
564 };
565 if (!ptr)
566 return 0;
567 crcu32 = ~crcu32;
568 while (buf_len--)
569 {
570 BYTE b = *ptr++;
571 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
572 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
573 }
574 return ~crcu32;
575}
576
577CHAR *HexToSwdObmVersion(UINT32 VerHex)
578{
579 static CHAR VerStr[8];
580 memset(VerStr, 0, 8);
581 VerStr[0] = (VerHex >> 24) & 0xFF ;
582 VerStr[1] = '.';
583 VerStr[2] = (VerHex >> 16) & 0xFF;
584 VerStr[3] = '.';
585 VerStr[4] = (VerHex >> 8) & 0xFF;
586 VerStr[5] = '.';
587 VerStr[6] = (VerHex >> 0) & 0xFF;
588
589 return VerStr;
590}
591
592char *ImageID2String(UINT_T id)
593{
594 static char str[5];
595 memset(str, 0, sizeof(str));
596 str[0] = (id >> 24) & 0xff;
597 str[1] = (id >> 16) & 0xff;
598 str[2] = (id >> 8) & 0xff;
599 str[3] = id & 0xff;
600 return str;
601}