/*
 * (C) Copyright Marvell Semiconductors,Inc 2006 All rightes reserved
 */

#include "util.h"
#include "ctypes.h"
#include "string.h"
#include "debug.h"
#include "apb_perf_base.h"
#include "lgpl_printf.h"


/*
 * heap start point
 */
static void *	malloc_base;

void *	UtilMemSet(void *s, int c, int n)
{

	unsigned char *	char_ptr = s;
	unsigned int *	int_ptr = s;
	int		remainer;
	
	if((remainer = ((int)s & 3)) != 0) {
		while (remainer-- > 0) {
			*char_ptr++ = (unsigned char)c;
			n--;
		}
		int_ptr = (unsigned int *)char_ptr;
		remainer = n & 3;
	}

	n >>= 2;
	while (n-- > 0) {
		*int_ptr++ = (unsigned int)c;
	}
	
	if (remainer != 0) {
		unsigned int	temp = *int_ptr;
		unsigned char *	temp_p = (unsigned char *)&temp;
		while (remainer-- > 0) {
			*temp_p++ = (unsigned char)c;
		}
		*int_ptr = temp;
	}
	return(s);
}

void *	UtilMemCpy(void *s1, const void *s2, int n)
{

	unsigned int *		dst = s1;
	const unsigned int *	src = s2;
	int			remainer = n & 3;

	if (((unsigned int)s1 & 3) || ((unsigned int)s2 & 3)) {
		unsigned char *		dst_char = s1;
		const unsigned char *	src_char = s2;

		while (n-- > 0) {
			*dst_char++ = *src_char++;
		}
		return s1;
	}

	n >>= 2;
	while (n-- > 0) {
		*dst++ = *src++;
	}
	
	if (remainer != 0) {
		unsigned int		temp = *dst;
		unsigned char *		temp_p = (unsigned char *)&temp;
		const unsigned char *	src_c = (const unsigned char *)src;
		while (remainer-- > 0) {
			*temp_p++ = (unsigned char)*src_c++;
		}
		*dst = temp;
	}

	return(s1);
}

int	UtilMemCmp(const void *s1, const void *s2, int n)
{

	int			i = 0;
	const unsigned char *	ss1 = s1;
	const unsigned char *	ss2 = s2;
	
	for ( ; i < n; i++) {
		if (ss1[i] > ss2[i]) {
			return(i + 1);
		}
		else if (ss1[i] < ss2[i]) {
			return(-i - 1);
		}
	}

	return 0;
}

void *	UtilMemAllocZ(int size)
{
	if (size > 0) {
		unsigned long malloc_align = (((unsigned long) malloc_base + 31) >> 5) << 5;
		void *	ptr = (void *) malloc_align;
	
		UtilMemSet(ptr, 0, size);
		malloc_base = (void *) malloc_align + size;
		return(ptr);
	}
	return(0);
}

void *	UtilMemAlloc(int size)
{
	if (size > 0) {
		unsigned long malloc_align = (((unsigned long) malloc_base + 31) >> 5) << 5;
		void *	ptr = (void *) malloc_align;
	
		if( (void *)(malloc_align + size) > __user_read_heap_top() )
			return 0;
		malloc_base =  (void *)(malloc_align + size);
		return(ptr);
	}
	return(0);
}

void	UtilMemReset(void)
{
		malloc_base = __user_read_heap_bottom();
}


#define DBG_MEM	                (0x3000000)
#define DBG_PORT_BASE			(SM_APB_UART0_BASE)
#define PUT_CHAR(ch)  BFM_HOST_Bus_Write32((DBG_PORT_BASE+0x00), (UNSG32)ch)
#define	put_char	PUT_CHAR

#define MAX_HISBUF_ENTRY 16
static char his_buf[MAX_HISBUF_ENTRY][80];      //  for Historical commands support
static SIGN32 his_mode=0;
SIGN32 his_next_idx=0;
SIGN32 his_cur_idx=0;
SIGN32 his_cmd_cnt=0;
SIGN32 pre_his_cmd_length;

static void *   malloc_base;

unsigned char GET_CHAR()
{
	UNSG32 data32;
	unsigned char data8;
	BFM_HOST_Bus_Read32((DBG_PORT_BASE+0x00), &data32);

	data8=data32&0xFF;
	return data8;

}

////////////////////////////////////////////////////////////
// dbg port (uart) driver
SIGN32 dbg_port_tx_ready()
{
	UNSG32 status=0;
	do
	{
		BFM_HOST_Bus_Read32((DBG_PORT_BASE+0x7c),&status);
	} while ((status&0x03)!=0x02);
	// add extra protection below
	do
	{
		BFM_HOST_Bus_Read32((DBG_PORT_BASE+0x80),&status);
	} while (status>2);  //delay control
	return 1;
}

/////////////////////////////////////////////////////////////////////////
//
//  showDbgPrompt() - Used by the debugger.  Displays the appropriate
//                debugger prompt.
//
/////////////////////////////////////////////////////////////////////////
void showDbgPrompt(char* prompt)
{
    lgpl_printf("\n\n%s", prompt);
}


SIGN32 dbg_port_rx_ready()
{
	UNSG32 read;
	BFM_HOST_Bus_Read32((DBG_PORT_BASE+0x7c),&read);      // status
	if(read&0x08)
	{
		BFM_HOST_Bus_Read32((DBG_PORT_BASE+0x84),&read);  // RFL
		if (read>0)
		return 1;
	}
	return 0;
}

void dbg_port_print( char* str)
{
	char ch;
	SIGN32 i;
	SIGN32 len=strlen(str);
	dbg_port_tx_ready();
	for (i=0;i<len;i++)
	{
		ch=str[i];
		put_char(ch);
		if (ch=='\n')
		{
			ch='\r';
			put_char(ch);
		}
		//extra delay
		i=i;
		len=len;
		ch=str[i];
	}
}


//////////////////////////////////////////////////////
// read command via UART (RS232)
#define CR_CHAR		13
#define LF_CHAR		10
#define BS_CHAR		8
#define UP_CHAR		'.'
#define DIR1_CHAR	0x1B
#define DIR2_CHAR	'['
#define UP3_CHAR	'A'
#define DOWN3_CHAR	'B'

int getline(char *pCmd)
{
   unsigned char ch;
   SIGN32 i;
#if 0
   SIGN32 comment;
#endif
   unsigned char arrow = 0;
   int	input_cmd_line_length = 0 ; 


   for (i = 0; i < CMD_LINE_BUFFER_SIZE; i++)
    	pCmd[i] = 0;

	i = 0;
	input_cmd_line_length = 0 ; 
	while (1)
	{
		while (dbg_port_rx_ready() == 0);
		ch = GET_CHAR();
		arrow += 2;
		input_cmd_line_length++ ; 
		if(input_cmd_line_length>CMD_LINE_BUFFER_SIZE){
			lgpl_printf("cmd line overflow, please input the command line again\n") ;
			return 1 ; 
		}

		switch (ch)
		{
			case CR_CHAR:
			case LF_CHAR:
			case '\0':
				pCmd[i] = '\0';
#if 0
				comment = 0;
				if (his_mode == 0 && strlen(pCmd))
				{	// only store new command that is not null
					memset(his_buf[his_cur_idx], 0, 80);       // clear buf
					memcpy(his_buf[his_cur_idx], pCmd, strlen(pCmd));
					if (his_cur_idx < MAX_HISBUF_ENTRY - 1)
					{
						his_next_idx = his_cur_idx;
						his_cur_idx++;
					}
					else 
					{
						his_next_idx = MAX_HISBUF_ENTRY - 1;
						his_cur_idx = 0;
					}
					his_cmd_cnt = (his_cmd_cnt < MAX_HISBUF_ENTRY) ? (his_cmd_cnt + 1) : MAX_HISBUF_ENTRY;
				}
				his_mode = 0;
#endif
				return 0 ;

#if 0
			case ';':
			case '/':
				comment = 1;
				break;

			case BS_CHAR:
				i--;
				i--;
				PUT_CHAR(ch);
				PUT_CHAR(' ');
				PUT_CHAR(ch);
				his_mode = 0;		// modify historical command
				arrow = 0;
				break;
#endif
			default:
				pCmd[i] = ch ; 
//				PUT_CHAR(ch);
				PUT_CHAR('*');
#if 0
				if (comment == 0)
				{				
					pCmd[i] = ch;
					if (ch == DIR1_CHAR)
						arrow = 1;
					else if (ch == DIR2_CHAR && arrow == 3)
						arrow = arrow;
					else if (ch == UP3_CHAR && arrow == 5)
					{
						arrow = 0;
						PUT_CHAR(DIR1_CHAR);
						PUT_CHAR(DIR2_CHAR);
						PUT_CHAR(DOWN3_CHAR);
						i = previous_cmd(pCmd, i, 0);
					}
					else if (ch == DOWN3_CHAR && arrow == 5)
					{
						arrow = 0;
						i = next_cmd(pCmd, i);
					}
					else
					{
						his_mode = 0; // modify history command
						arrow = 0;
					}
				}
#endif
				break;
		}
		i++;
	}
}

int previous_cmd(char *pCmd, int cur_cmd_length, unsigned int loop)
{
	int i, j;
	int erase;

	if (his_cmd_cnt == 0)
		return (cur_cmd_length - 3);

	if (his_mode == 0)
	{
		his_mode = 1;
	}
	else 
	{
		if (loop == 0)
		{
			if (his_next_idx == his_cur_idx + 1)
				return (cur_cmd_length - 3);

			if ((his_next_idx == 0) && (his_cur_idx == his_cmd_cnt))
				return (cur_cmd_length - 3);	
		}

		if (his_next_idx == 0)
			his_next_idx = his_cmd_cnt - 1;
		else
			his_next_idx--;
	}

	// need to clear line, move cursor, and print prompt again
	erase = strlen(PROMPT) + (pre_his_cmd_length > cur_cmd_length ? pre_his_cmd_length : cur_cmd_length);
	put_char('\r');
	for (j = 0; j <= erase ; j++)
	{
		put_char(' ');
	}
	put_char('\r');   		// back to beginning of line
	dbg_port_print(PROMPT);	// show prompt

	dbg_port_print(his_buf[his_next_idx]);

	memcpy(pCmd, his_buf[his_next_idx], strlen(his_buf[his_next_idx]));
	i = strlen(his_buf[his_next_idx]) - 1;
	pre_his_cmd_length = i;		// record the his command length

	return i;
}

int next_cmd(char *pCmd, int cur_cmd_length)
{
	int i, j;
	int erase;

	his_mode = 2;
	if (his_cur_idx == his_next_idx + 1)
		return (cur_cmd_length - 3);

	if ((his_cur_idx == 0) && (his_next_idx == his_cmd_cnt))
		return (cur_cmd_length - 3);
	
	if (his_next_idx == his_cmd_cnt - 1)
		his_next_idx = 0;
	else
		his_next_idx++;

	// need to clear line, move cursor, and print prompt again
	erase = strlen(PROMPT) + (pre_his_cmd_length > cur_cmd_length ? pre_his_cmd_length : cur_cmd_length);
	put_char('\r');
	for (j = 0; j <= erase; j++)
	{
		put_char(' ');
	}
	put_char('\r');   		// back to beginning of line
	dbg_port_print(PROMPT);	// show prompt      				

	dbg_port_print(his_buf[his_next_idx]);

	memcpy(pCmd, his_buf[his_next_idx], strlen(his_buf[his_next_idx]));
	i = strlen(his_buf[his_next_idx]) - 1;
	pre_his_cmd_length = i;		// record the his command length

	return i;
}

/////////////////////////////////////////////////////////////////////////
//
//  skipSpace() - Used by the debugger.  Skips non-text characters at
//                the beginning of a string
//
/////////////////////////////////////////////////////////////////////////
void skipSpace ( char **inStr )
{
    char *s = *inStr;

    while (( *s == ' ' ) || ( *s == '\t' ) || ( *s == '\r' ) || ( *s == '\n' ))
        s++;

    *inStr = s;
}


/////////////////////////////////////////////////////////////////////////
//
//  getTokenLength() - Used by the debugger.  Gets the length of the
//                     next token in a string
//
/////////////////////////////////////////////////////////////////////////
SIGN32 getTokenLength (char *s )
{
    SIGN32     index;
    char    x;

    for ( index = 0; s[ index] != 0; index++ )
    {
        x = s[ index];
        if (( x == ' ' ) || ( x == '\t' ) || ( x == '\r' ) || ( x == '\n' ))
            break;
    }

    return( index );
}

/////////////////////////////////////////////////////////////////////////
//
//  getIntToken() - Used by the debugger Gets the next token from a string
//
/////////////////////////////////////////////////////////////////////////
char*  getIntToken ( char *inStr, UNSG32 *outVal )
{
    SIGN32  iSum = 0;
    char  c;
    char  *thisStr = inStr;
	SIGN32  bPositive = 1;
    // If first character is ';', we have a comment, so
    // get out of here.
    if ( *thisStr == ';' )
        return thisStr;

    // Process decimal characters
    // a negative number?
    if ( *thisStr == '-' )
    {
        bPositive =0;
        thisStr ++;
    }

    while ( *thisStr )
    {
        c = *thisStr;

        // Check for valid digits.
        if ( !( c >= '0' && c <= '9' ) )
            break;

        // ASCII to decimal conversion
        iSum = iSum * 10 + ( c - '0' );

        thisStr ++;
    }

    // make it negative
    if ( !bPositive )
        iSum = -1 * iSum;

    // Return updated pointer and decoded value.
    *outVal = iSum;
    return thisStr;
}

/////////////////////////////////////////////////////////////////////////
//
//  getSignedIntToken() - Used by the debugger Gets the next token from a string
//
/////////////////////////////////////////////////////////////////////////
char*  getSignedIntToken ( char *inStr, SIGN32 *outVal )
{
    SIGN32  iSum = 0;
    char  c;
    char  *thisStr = inStr;
	SIGN32  bPositive = 1;
    // If first character is ';', we have a comment, so
    // get out of here.
    if ( *thisStr == ';' )
        return thisStr;

    // Process decimal characters
    // a negative number?
    if ( *thisStr == '-' )
    {
        bPositive =0;
        thisStr ++;
    }

    while ( *thisStr )
    {
        c = *thisStr;

        // Check for valid digits.
        if ( !( c >= '0' && c <= '9' ) )
            break;

        // ASCII to decimal conversion
        iSum = iSum * 10 + ( c - '0' );

        thisStr ++;
    }

    // make it negative
    if ( !bPositive )
        iSum = -1 * iSum;

    // Return updated pointer and decoded value.
    *outVal = iSum;
    return thisStr;
}

/////////////////////////////////////////////////////////////////////////
//
//  getHexToken() - Used by the debugger Gets the next token from a string
//
/////////////////////////////////////////////////////////////////////////
char* getHexToken ( char *inStr, UNSG32 *outVal )
{
    UNSG32   thisVal, tVal;
    char    x;
    char    *thisStr = inStr;

    thisVal = 0;

        // If first character is ';', we have a comment, so
        // get out of here.

    if ( *thisStr == ';' )
        return( thisStr );

        // Process hex characters.

    while ( *thisStr )
    {
        // Do uppercase conversion if necessary.

        x = *thisStr;
        if (( x >= 'a') && ( x <= 'f'))
            x &= ~0x20;

        // Check for valid digits.

        if ( !((( x >= '0') && (x <= '9')) || (( x >= 'A') && ( x <= 'F'))))
            break;

        // Hex ASCII to binary conversion.

        tVal = x - '0';
        if ( tVal > 9 )
            tVal -= 7;

        thisVal = (thisVal * 16) + tVal;

        thisStr++;
    }

        // Return updated pointer and decoded value.

    *outVal = thisVal;
    return( thisStr );
}

/////////////////////////////////////////////////////////////////////////
//
//  getToken() - Used by the debugger Gets the next token from a string
//
/////////////////////////////////////////////////////////////////////////
char* getToken ( char *inStr, char **outVal )
{
    char    *thisStr = inStr;

        // If first character is ';', we have a comment, so
        // get out of here.

    if ( *thisStr == ';' )
        return( thisStr );

    while ( *thisStr != ' ' && *thisStr != '\t' && *thisStr != '\0' )
    {
        thisStr++;
    }

    if ( *thisStr != '\0' )
    {
        *thisStr = '\0';
        thisStr ++;
    }

    *outVal = inStr;
    return( thisStr );
}


// Qingwei Huang added for google's toolchain
int raise(int i)
{
    (void)i;
    return 0;
}
