ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/obm/Common/Misc/misc.c b/marvell/obm/Common/Misc/misc.c
new file mode 100644
index 0000000..51e2f3c
--- /dev/null
+++ b/marvell/obm/Common/Misc/misc.c
@@ -0,0 +1,601 @@
+/******************************************************************************
+ *
+ *  (C)Copyright 2005 - 2011 Marvell. All Rights Reserved.
+ *
+ *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
+ *  The copyright notice above does not evidence any actual or intended
+ *  publication of such source code.
+ *  This Module contains Proprietary Information of Marvell and should be
+ *  treated as Confidential.
+ *  The information in this file is provided for the exclusive use of the
+ *  licensees of Marvell.
+ *  Such users have the right to use, modify, and incorporate this code into
+ *  products for purposes authorized by the license agreement provided they
+ *  include this notice and the associated copyright notice with any such
+ *  product.
+ *  The information in this file is provided "AS IS" without warranty.
+ *
+ *
+ *  FILENAME:	Misc.c
+ *
+ *  PURPOSE: 	Contain helpful misc. functions
+ *
+******************************************************************************/
+
+#include "misc.h"
+
+
+static unsigned char* 		StrPtr8;
+static unsigned int   		DataWidth;
+
+// Very simple routine to reverse bytes on up to a 512 byte buffer.
+UINT_T ReverseBytes (UINT8_T* Address, UINT_T Size)
+{
+	UINT8_T Buffer[512];
+	UINT_T i;
+
+	if (Size > 512)
+		return InvalidSizeError;
+
+	// First copy to a Buffer
+	for (i=0; (i < Size); i++)
+		Buffer[i] = Address[i];
+
+	// Next copy to Address in reverse order
+	for (i=0; (i < Size); i++)
+		Address[Size - 1 - i] = Buffer[i];
+
+	return NoError;
+}
+
+//endian conversion function: self explanatory
+unsigned int Endian_Convert (unsigned int in)
+{
+	unsigned int out;
+	out = in << 24;
+	out |= (in & 0xFF00) << 8;
+	out |= (in & 0xFF0000) >> 8;
+	out |= (in & 0xFF000000) >> 24;
+	return out;
+}
+
+// return 1 if majority of right-most numBits in Word are 1
+// return 0 if majority of right-most numBits in Word are 0
+// return 0 if 1s are equal to 0s (this means numBits is even) 
+unsigned int MajorityVote (unsigned int Word, unsigned int numBits)
+{
+	int i;
+	int numOnes = 0;
+	int numZeros = 0;
+	for (i=1; i<=numBits; i++)
+	{
+		if ( (Word & 1) == 1 ) 	numOnes++;
+		else					numZeros++;
+
+		Word = Word>>1;
+	}
+	if (numOnes > numZeros) return 1;
+	else return 0; // If majority voting is requested for even number of bits and numOnes == numZeros, zero wins
+}
+
+/**
+ * Memory set function
+ **/
+void memset(void *Addr, unsigned char Val, unsigned long Size)
+{
+
+	unsigned long i;
+	for(i=0; i < Size; i++ )
+	{
+		((unsigned char*)Addr)[i] = Val;
+	}
+}
+
+void *memcpy(void *dest, const void *src, unsigned int n)
+{
+	const unsigned char *s = (const unsigned char*)src;
+	unsigned char *d = (unsigned char *)dest;
+
+	//don't copy if we don't need to
+	if(dest == src)
+		return dest;
+
+	//smart copy, in case of overlap:
+	while(n-- > 0)
+		if(s > d)	//copy 'forwards'
+			*d++ = *s++;
+		else		//copy 'in reverse'
+			d[n] = s[n];
+
+	return dest;
+}
+
+void *memmove(void *dest, const void *src, unsigned int n)
+{
+	return memcpy(dest, src, n);
+}
+
+int memcmp( const void *buffer1, const void *buffer2, int count)
+{
+    UINT8_T* buf1 = (UINT8_T*)buffer1;
+    UINT8_T* buf2 = (UINT8_T*)buffer2;
+
+  while(count)
+  {
+    if( *(buf1) != *(buf2) )
+      return( (*buf1 < *buf2) ? -1 : 1 );
+
+    buf1 += sizeof(UINT8_T);
+    buf2 += sizeof(UINT8_T);
+    count--;
+  }
+
+  return 0;
+}
+
+int ConvertStringToInteger8(const unsigned char* StringPtr, unsigned int Count)
+{
+	int  Output = 0;
+	unsigned char c;
+	while (*StringPtr)
+	{
+		Output *= Count;
+		c = *StringPtr++;
+		if (c >= '0' && c <= '9')
+			Output += (c-'0');
+		else
+			Output += ((c|' ')-'a'+10);
+	}
+	return (Output);
+}
+
+int DivideTwoNumbers(int Numerator,int Denominator)
+{
+	int Tmp    = 0;
+	int Output = 0;
+	int Count;
+    if(!Denominator)
+        return Numerator;
+        
+	for (Count = 28; Count >= 0; Count -= 4)
+	{
+		Tmp    <<= 4;
+		Output <<= 4;
+		Tmp |= (Numerator >> Count)&0xf;
+		while(Tmp >= 0)
+		{
+			Tmp -= Denominator;
+			Output++;
+		}
+		Tmp += Denominator;
+		Output--;
+	}
+	return(Output);
+}
+
+int ModOfTwoNumbers(int Numerator, int Denominator)
+{
+	//return(Numerator - (Denominator * DivideTwoNumbers(Numerator, Denominator)));
+	int Tmp;
+	Tmp = DivideTwoNumbers(Numerator, Denominator);
+	Tmp = Tmp * Denominator;
+	Tmp = Numerator - Tmp;
+#if LINUX_BUILD
+	// The GCC compiler assigns the value in R1(Quotient) to variable on the left side of the "="
+	// in the calling code. So we need to move the Remainder (in Tmp) to R1 so we get the Remainder
+	// returned and not the quotient.
+	// Syntax below informs the compiler we modified R1 intentionally and don't mess with it.
+	asm("mov r1, %[value]" :: [value] "r" (Tmp): "r1");   // this move the contents of temp into r1
+#endif
+	return Tmp;
+}
+
+
+void ConvertLongIntToBuf8(int DataValue, int Count)
+{
+	if (DataValue >= Count)
+	{
+		ConvertLongIntToBuf8(DivideTwoNumbers(DataValue, Count), Count);
+		StrPtr8++;
+		DataWidth--;
+		DataValue = ModOfTwoNumbers(DataValue, Count);
+	}
+	if (DataWidth > 0)
+		*StrPtr8 = (unsigned char)(DataValue + (DataValue < 10 ? '0' : ('a'-10)));
+}
+
+
+void ConvertIntToBuf8(unsigned char* StringPtr,unsigned int Value, int Width,unsigned int Count)
+{
+	int i;
+	StrPtr8    = StringPtr;
+	DataWidth  = Width;
+	if (Value >= Count)
+	{
+		ConvertLongIntToBuf8(DivideTwoNumbers(Value,Count),Count);
+		StrPtr8++;
+		DataWidth--;
+		Value=ModOfTwoNumbers(Value,Count);
+	}
+	if (DataWidth-->0)
+		*StrPtr8=(unsigned char)(Value + (Value < 10 ? '0' : ('a'-10)));
+
+	// If DataWidth=0, the following will do nothing, so just return here
+	if (DataWidth == 0) return;
+
+	// Shift the contents of the buffer to right by DataWidth to achieve right alignment
+	for (i=Width; i > DataWidth; i--)
+	{ 
+		*(StrPtr8+DataWidth) = *(StrPtr8);
+		StrPtr8--;
+	}
+	// Prepend leading zeros if necessary
+	while (DataWidth-- > 0)
+		*++StrPtr8 = '0';
+}
+
+void __aeabi_idiv0( void ){
+
+	//dummy function for the compiler
+	// need to investigate the in32t_divide.o and x0_a000.o libraries from XDB
+	return;
+}
+
+//The below functions are pulled in from a library when built by RVCT or SDT compiler (NDT flag)
+//When built by the linux compiler, we need to define the calls ourselves
+#if LINUX_BUILD
+
+void __aeabi_idiv(void){
+//void __divsi3(void){
+	asm("b DivideTwoNumbers");
+	return;
+}
+
+void __aeabi_uidiv(void){
+//void __udivsi3(void){
+	asm("b DivideTwoNumbers");
+	return;
+}
+
+void __aeabi_uidivmod(void){
+	asm("b ModOfTwoNumbers");
+	return;
+}
+
+long long __aeabi_llsr(long long a, int b)
+{
+
+}
+#endif
+
+
+/*
+   String Compare function - case sensitive
+   Will compare str1 to str2, character to character, until a NULL character is hit
+   or until maxlength is reached
+   If no NULL character is present, there could be serious issues
+
+      Return values:
+      -1 = str1 < str2
+       0 = Match
+       1 = str1 > str2
+
+ */
+int strcmpl( char* str1, char* str2, int maxlength )
+{
+    int length = maxlength;
+    while((*str1 != NULL) && (*str2 != NULL) && --length)
+    {
+        if (*str1 != *str2)
+        {
+            // check the char that was different to determine results
+            if ( *str1 > *str2 )
+                return 1;
+            else
+                return -1;
+        }
+        str1++; str2++;
+    }
+
+    // strings compared so far, but did we reach the end of both?
+    if ( *str1 != NULL && *str2 != NULL )
+        // did not find the NULLs but have reached the maxlength to compare
+        return 0;
+
+    if ( *str1 == NULL && *str2 == NULL )
+        return 0;
+
+    if ( *str1 != NULL && *str2 == NULL )
+        // "abcde" > "abcd"
+        return 1;
+    else
+        // "abcd" < "abcde"
+        return -1;
+}
+
+
+/*
+   String Compare function - case insensitive
+   Will compare str1 to str2 ignoring case, character to character, until a NULL character is hit
+   or until maxlength is reached
+   If no NULL character is present, there could be serious issues
+
+      Return values:
+      -1 = str1 < str2
+       0 = Match
+       1 = str1 > str2
+ */
+int stricmpl( char* str1, char* str2, int maxlength)
+{
+    int length = maxlength;
+    while((*str1 != NULL) && (*str2 != NULL) && --length)
+    {
+        if ( ((*str1) & 0xDF) != ((*str2) & 0xDF) )
+        {
+            // check the char that was different to determine results
+            if ( ((*str1) & 0xDF) > ((*str2) & 0xDF) )
+                return 1;
+            else
+                return -1;
+        }
+        str1++; str2++;
+    }
+
+    // strings compared so far, but did we reach the end of both?
+    if ( *str1 != NULL && *str2 != NULL )
+        // did not find the NULLs but have reached the maxlength to compare
+        return 0;
+
+    if ( *str1 == NULL && *str2 == NULL )
+        return 0;
+
+    if ( *str1 != NULL && *str2 == NULL )
+        // "abcde" > "abcd"
+        return 1;
+    else
+        // "abcd" < "abcde"
+        return -1;
+}
+
+
+INT_T strlen (const char * str)
+{
+    int i = 0;
+    while(str[i++] != '\0')
+        if(i > 1000)
+            break;
+    return --i;
+}
+
+INT_T memcmpFF( const void *buffer, INT_T count)
+{
+    UINT8_T* buf = (UINT8_T*)buffer;
+
+    while(count--)
+    {
+        if( *(buf) != 0xFF )
+          return -1;
+
+        buf += sizeof(UINT8_T);
+    }
+
+    return 0;
+}
+
+
+//Aligns the pointer on ALIGN boundary
+unsigned long Align_Ptr (unsigned long Address, unsigned long Align)
+{
+    Address = (Address+Align-1) & ~(Align - 1); 
+    return Address;
+}
+
+
+void bubble(UINT16_T * ptr, UINT_T n)
+{
+	UINT_T i, j, temp;
+
+	for (i = 0; i < n-1; i++)
+		for (j = i + 1; j < n; j++)
+			if (ptr[i] > ptr[j])
+				{
+					temp = ptr[j];
+					ptr[j] = ptr[i];
+					ptr[i] = temp;
+				}
+}
+
+UINT CalcImageChecksum( UINT_T* DownloadArea, UINT_T ImageLength)
+{
+	UINT ImageChecksum = 0;
+	UINT32* ptr32 = DownloadArea;
+	UINT32* pEnd = ptr32 + (ImageLength / sizeof(UINT32));
+	UINT BytesSummed = 0;
+
+	while ( ptr32 < pEnd )
+	{
+		// checksum format version 2 algorithm as defined by flasher
+		ImageChecksum ^= (*ptr32);
+		ptr32++;
+		BytesSummed += sizeof(UINT32);
+	}
+	return ImageChecksum;
+}
+
+UINT_T CalcMRDChecksum( UINT_T* start, UINT_T length)
+{
+	UINT8_T *pRD_DDR_end = NULL;
+	UINT_T check_sum = 0, num = 0;
+	UINT_T a = 0x0001, b = 0x0000, index = 0;
+	UINT8_T * pRAMbuf;
+
+	pRAMbuf = (UINT8_T *)start;
+	pRD_DDR_end = pRAMbuf + length;
+	
+	do
+	{
+		num = (UINT_T)(*pRAMbuf++);
+		a += num;
+		index++;
+		b += a;
+		
+		/*
+		Algorithm is defined as mod MOD_ADLER at every modification to a and b.
+		For efficiency reasons this mod can be done once in a while to keep (a) and (b) in range (32-bit signed)
+		The result is invariant of MOD_LOOPS value.
+		a<5550*256; b<(5551*256/2)*5550=3943430400 (in range) 
+		*/
+		if(index == MOD_LOOPS)
+		{
+			index =0;
+			a %= MOD_ADLER;
+			b %= MOD_ADLER;
+		}
+		// TBD: MISALIGNED 32-BIT ACCESS HERE AT EVERY BYTE ADDRESS, VERY INEFFICIENT & REDUNDANT
+		// Kept here for now for compatibility with old version of the tool that produces RDA with DADADADA at misaligned offset
+
+	} while( pRAMbuf < (UINT8_T *)pRD_DDR_end );
+
+	if(index)
+	{
+		a %= MOD_ADLER;
+		b %= MOD_ADLER;
+	}
+
+	check_sum =  (b << 16) | a;
+
+	return check_sum;
+}
+
+const UINT32 crc32_table[] =
+{
+  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
+  0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
+  0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+  0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
+  0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
+  0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
+  0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
+  0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
+  0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
+  0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+  0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
+  0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
+  0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+  0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
+  0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
+  0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
+  0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
+  0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
+  0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
+  0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+  0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
+  0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
+  0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+  0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
+  0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
+  0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
+  0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
+  0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
+  0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
+  0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+  0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
+  0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
+  0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+  0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
+  0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
+  0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
+  0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
+  0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
+  0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
+  0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+  0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
+  0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
+  0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+};
+
+
+UINT32 CalcCRC32 (const unsigned char *buf, int len, unsigned int init)
+{
+  UINT32 crc = init;
+  while (len--)
+    {
+      crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
+      buf++;
+    }
+  return crc;
+}
+
+UINT16_T from32to16(UINT x)
+{
+	/* add up 16-bit and 16-bit for 16+c bit */
+	x = (x & 0xffff) + (x >> 16);
+	/* add up carry.. */
+	x = (x & 0xffff) + (x >> 16);
+	return x;
+}
+
+UINT malbrain_crc32(UINT crcu32, const BYTE *ptr, UINT buf_len)
+{
+	static const UINT s_crc32[16] = {
+		0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
+	};
+	if (!ptr)
+		return 0;
+	crcu32 = ~crcu32;
+	while (buf_len--)
+	{
+		BYTE b = *ptr++;
+		crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
+		crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
+	}
+	return ~crcu32;
+}
+
+CHAR *HexToSwdObmVersion(UINT32 VerHex)
+{
+	static CHAR VerStr[8];
+	memset(VerStr, 0, 8);
+	VerStr[0] = (VerHex >> 24) & 0xFF ;
+	VerStr[1] = '.';
+	VerStr[2] = (VerHex >> 16) & 0xFF;
+	VerStr[3] = '.';
+	VerStr[4] = (VerHex >> 8) & 0xFF;
+	VerStr[5] = '.';
+	VerStr[6] = (VerHex >> 0) & 0xFF;
+
+	return VerStr;
+}
+
+char *ImageID2String(UINT_T id)
+{
+	static char str[5];
+	memset(str, 0, sizeof(str));
+	str[0] = (id >> 24) & 0xff;
+	str[1] = (id >> 16) & 0xff;
+	str[2] = (id >> 8) & 0xff;
+	str[3] = id & 0xff;
+	return str;
+}