/** ****************************************************************************** * @file cmd.c * @author StarFive Technology * @version V1.0 * @date 07/20/2020 * @brief ****************************************************************************** * @copy * * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd. */ #include "cmd.h" #include "comdef.h" #include "uart.h" #define CMD_MAXNUM 4 #define UART_CMD_BUFFER 0x18010000 //TAG_CMD_T _CmdBuffer; //:0719 del, use memory directly P_TAG_CMD_T StdHdl = ( P_TAG_CMD_T ) UART_CMD_BUFFER; int gcurCmd = CMD_MAXNUM; /* ?: cmd help show: display memory in byte/short/long do: do a procedure, and return to uart control run: remap, and jump to 0 , and not return to uart control */ const CMDTBLITEM CmdHandle[CMD_MAXNUM] = { { "?" , 0x00000000 , CmdHelpProc, 0x01 }, { "show" , 0x00000000 , ShowProc , 0x01 }, { "load" , 0x00000000 , LoadProc , 0x01 }, { "do" , 0x00000000 , Do32Proc , 0x01 }, }; unsigned char showMode = 0x10; void* pCurShow = ( void * )0x00 ; unsigned long Showlength = 0x100; void ShowByte( unsigned char * pbuf , int length ); void ShowShort( unsigned short * pbuf , int length ); void ShowLong( unsigned long * pbuf , int length ); /* C720 uart cmd line init*/ void StdInit( P_TAG_CMD_T hdl ) { hdl->ver = 0x100; hdl->length = 0x400; hdl->maxlen = 0x3FF; hdl->startbuf = ( unsigned char * )hdl->buf + 0x80; hdl->curbuf = hdl->startbuf; hdl->curitem = 0x000000; hdl->inputflag = 0x00000000; } void CmdInit( void ) { //:StdHdl = &_CmdBuffer; // 0719 del //PrintIntHex(( unsigned long ) StdHdl , 0x8 ); StdInit( StdHdl ); } void RelayProc( void ) { int item; unsigned int retflag; if( CmdString(( char * ) StdHdl->argvList[0] , "" )){ return; } for( item = 0x00 ; item < gcurCmd ; item++ ){ if( CmdString(( char * ) StdHdl->argvList[0] , ( char * ) CmdHandle[item].cmdCode )){ CmdHandle[item].cmdScriptProc( CmdHandle[item].context , ( int ) StdHdl->curArgc , ( char ** )StdHdl->argvList ); return; } } //************************************************* if( StdHdl->curArgc == 0x02 ){ if( CmdString(( char * )( StdHdl->argvList[0x00]) , "rb" )){ item = A2Int(( char * ) StdHdl->argvList[0x01] ); retflag = (( unsigned char * )item)[0x00]; rlSendString( "\r\n Read Byte : 0x" ); PrintIntHex(( unsigned long ) retflag , 0x2 ); rlSendString( "\r\n" ); return; } if( CmdString(( char * )( StdHdl->argvList[0x00]) , "rh" )){ item = A2Int(( char * ) StdHdl->argvList[0x01] ); if( item & 0x0001 ){ rlSendString( "\r\n Error address: 0x" ); PrintIntHex(( unsigned long ) item , 0x8 ); rlSendString( "\r\n" ); return; } retflag = (( unsigned short * )item)[0x00]; rlSendString( "\r\n Read Half : 0x" ); PrintIntHex(( unsigned long ) retflag , 0x4 ); rlSendString( "\r\n" ); return; } if( CmdString(( char * )( StdHdl->argvList[0x00]) , "rl" )){ item = A2Int(( char * ) StdHdl->argvList[0x01] ); if( item & 0x0003 ){ rlSendString( "\r\n Error address: 0x" ); PrintIntHex(( unsigned long ) item , 0x8 ); rlSendString( "\r\n" ); return; } retflag = (( unsigned long * )item)[0x00]; rlSendString( "Read Long : 0x" ); PrintIntHex(( unsigned long ) retflag , 0x8 ); rlSendString( "\r\n" ); return; } } if( StdHdl->curArgc == 0x03 ){ if( CmdString(( char * )( StdHdl->argvList[0x00]) , "wb" )){ item = A2Int(( char * ) StdHdl->argvList[0x01] ); retflag = A2Int(( char * ) StdHdl->argvList[0x02] ); (( unsigned char * )item)[0x00] = ( unsigned char )retflag; rlSendString( "\r\n Write Byte: 0x" ); PrintIntHex(( unsigned long ) retflag , 0x2 ); rlSendString( "\r\n" ); return; } if( CmdString(( char * )( StdHdl->argvList[0x00]) , "wh" )){ item = A2Int(( char * ) StdHdl->argvList[0x01] ); retflag = A2Int(( char * ) StdHdl->argvList[0x02] ); if( item & 0x0001 ){ rlSendString( "\r\n Write Half Error address: 0x" ); PrintIntHex(( unsigned long ) item , 0x8 ); rlSendString( "\r\n" ); return; } (( unsigned short * )item)[0x00] = ( unsigned short )retflag; rlSendString( "\r\n Write Half: 0x" ); PrintIntHex(( unsigned long ) retflag , 0x4 ); rlSendString( "\r\n" ); return; } if( CmdString(( char * )( StdHdl->argvList[0x00]) , "wl" )){ item = A2Int(( char * ) StdHdl->argvList[0x01] ); retflag = A2Int(( char * ) StdHdl->argvList[0x02] ); if( item & 0x0003 ){ rlSendString( "\r\n Write Long Error address: 0x" ); PrintIntHex(( unsigned long ) item , 0x8 ); rlSendString( "\r\n" ); return; } (( unsigned long * )item)[0x00] = ( unsigned long )retflag; rlSendString( "\r\n Write Long: 0x" ); PrintIntHex(( unsigned long ) retflag , 0x8 ); rlSendString( "\r\n" ); return; } } rlSendString( "\r\nWarning : Error command, Type ? or help to get CMD info\r\n" ); } int ReadString( unsigned char * buf , int length ) { int curitem; int retflag; curitem = 0x00000000; length--; while( 0x01 ){ retflag = serial_getc( ); if( curitem < length ){ if( retflag >= 0x20 ){ buf[curitem] = ( unsigned char )retflag; _putc(( char ) buf[curitem] ); curitem++; continue; } } if(( retflag == '\r' ) || ( retflag == '\n' )){ buf[curitem] = 0x00; _putc( '\r' ); _putc( '\n' ); break; } if( retflag == '\b' ){ if( curitem > 0x00 ){ curitem--; _putc( '\b' ); _putc( ' ' ); _putc( '\b' ); } continue; } continue; } return curitem; } int CmdString( char * srccmd , char * basecmd ) { while(( *srccmd == *basecmd ) && ( *srccmd != 0x00 )){ srccmd++; basecmd++; } if( *srccmd == 0x00 ){ return 0x01; } return 0x00; } int piteCmdLine( char * curRead , char **pargv , int maxArgc ) { int curItem; curItem = 0x00000000; while( curItem < maxArgc ){ while(( *curRead ) == ' ' ){ curRead++; } pargv[curItem] = curRead; if(( *curRead ) == 0x00 ){ break; } while((( *curRead ) != ' ' ) && (( *curRead ) != 0x00 )){ curRead++; } curItem++; if(( *curRead ) == ' ' ){ *curRead = 0x00; curRead++; continue; } if(( *curRead ) == 0x00 ){ break; } } return curItem; } int CmdHelpProc( void * Context , int argc , char ** argv ) { int item; rlSendString( "\r\n Command list :\r\n " ); for( item = 0x01 ; item < gcurCmd ; item++ ){ rlSendString( CmdHandle[item].cmdCode ); rlSendString( " \r\n" ); } rlSendString( "rb/rh/rl addr\r\n" ); rlSendString( "wb/wh/wl addr val\r\n" ); return 0x01; } int CmdErrorProc( void * Context , int argc , char ** argv ) { int i; rlSendString( " msg : error cmd ->\r\n" ); for( i = 0x00 ; i < argc ; i++ ){ rlSendString( "\t" ); rlSendString( argv[i] ); rlSendString( "\r\n" ); } rlSendString( "\r\n" ); return 0x01; } //file:length <= 0x08 int U2Hex( unsigned long value , char * buf , int length ) { int temp; int retflag; buf[0x00] = 0x00; buf[length] = 0x00; retflag = 0x00; while( length > 0x00 ){ temp = value & 0x0F; value >>= 0x04; length--; retflag++; if( temp < 0x0A ){ buf[length] = ( char )temp + '0'; continue; } buf[length] = ( char )temp + ('A' - 0x0A ); } return retflag; } int A2Int( char * buf ) { int retflag; int flag; retflag = 0x00; do{ if(( buf[0x00] == '0' ) && (( buf[0x01] == 'x' ) || ( buf[0x01] == 'X' ))){ buf += 0x02; while( 0x01 ){ if(( *buf >= '0' ) && ( *buf <= '9' )){ retflag <<= 0x04; retflag += *buf - '0'; buf++; continue; } if(( *buf >= 'a' ) && ( *buf <= 'f' )){ retflag <<= 0x04; retflag += *buf - ( 'a' - 0x0a ); buf++; continue; } if(( *buf >= 'A' ) && ( *buf <= 'F' )){ retflag <<= 0x04; retflag += *buf - ( 'A' - 0x0A ); buf++; continue; } break; } break; } flag = 0x01; if( *buf == '+' ){ buf++; }else{ if( *buf == '-' ){ flag = -1; buf++; } } while( 0x01 ){ if(( *buf >= '0' ) && ( *buf <= '9' )){ retflag *= 0x0A; retflag += *buf - '0'; buf++; continue; } retflag *= flag; break; } }while( 0x00 ); return retflag; } /* load addr : use xmodem protocol, to load a binary file to memory */ int LoadProc( void * Context , int argc , char ** argv ) { unsigned long pStart; int retflag; retflag = 0; if( argc == 0x02 ) { pStart = A2Int(( char * ) StdHdl->argvList[0x01] ); if( pStart & 0x03 ){ rlSendString( "\r\n Error : load error for 0x" ); PrintIntHex(( unsigned long ) pStart , 0x8 ); rlSendString( "\r\n" ); retflag = 2; } else { // retflag = xmodem_recv_file((unsigned char *)pStart, 0); retflag = xmodemReceive((unsigned char *)pStart, 0); rlSendString( "\r\nLoad file " ); if(retflag == TRUE) { rlSendString( " ok\r\n" ); } else { rlSendString( " Error\r\n" ); } } } else { rlSendString( "\r\nCMD format: load startaddr\r\n" ); retflag = 2; } return retflag; } int Do32Proc( void * Context , int argc , char ** argv ) { unsigned long pStart; int retflag; UINT32 return_pc; retflag = 0; if( argc == 0x02 ){ pStart = A2Int(( char * ) StdHdl->argvList[0x01] ); //rlSendString( "\r\nDo procedure at : 0x" ); //PrintIntHex(( unsigned int ) pStart , 0x8); //rlSendString( "\r\n" ); if((pStart &0x3)==0) { /* importent@20060615 */ /* save the return PC here */ return_pc =(UINT32 )(&sys_cmd_main_loop); //MA_OUTW(EXIT_MINIBOOT_PC, return_pc); start2run32(pStart); //do_go_exec ((void *)pStart, argc - 1, argv + 1); retflag = 0; } else { rlSendString( "\r\nError, it's invalid Address: 0x" ); PrintIntHex(( unsigned long ) pStart , 0x8 ); rlSendString( "\r\n" ); retflag = 1; } } else { rlSendString( "\r\nCMD format: do startaddr\r\n" ); retflag = 2; } return retflag; } int ShowProc( void * Context , int argc , char ** argv ) { unsigned long pStart; unsigned long pEnd; int retflag; unsigned char mode; mode = 0x000000; if( argc <= 0x03 ){ do{ if( argc == 0x01 ){ pStart = ( unsigned long )pCurShow; pEnd = Showlength; break; } if( argc == 0x02 ){ if( CmdString( argv[1] , "byte" )){ mode = 0x01; } if( CmdString( argv[1] , "half" )){ mode = 0x02; } if( CmdString( argv[1] , "long" )){ mode = 0x04; } if(( mode == 0x00 ) && (( argv[0x01][0x00] < '0' ) || ( argv[0x01][0x00] > '9' ))){ mode = 0x10; } pStart = ( unsigned long )pCurShow; pEnd = Showlength; if( mode == 0x00 ){ pStart = A2Int( argv[1] ); } break; } if( CmdString( argv[1] , "byte" )){ mode = 0x01; } if( CmdString( argv[1] , "half" )){ mode = 0x02; } if( CmdString( argv[1] , "long" )){ mode = 0x04; } if(( mode == 0x00 ) && (( argv[0x01][0x00] < '0' ) || ( argv[0x01][0x00] > '9' ))){ mode = 0x10; } pEnd = Showlength; if( mode == 0x00 ){ pStart = A2Int( argv[1] ); pEnd = A2Int( argv[2] ); }else{ pStart = A2Int( argv[2] ); } break; }while( 0x00 ); if( mode == 0x00 ){ mode = showMode; } pEnd += pStart; pEnd += 0x0f; pStart &= 0xFFFFFFF0; pEnd &= 0xFFFFFFF0; pEnd -= pStart; if( mode != 0x10 ){ pCurShow = ( void * )( pStart + pEnd ); Showlength = pEnd; showMode = mode; } switch( mode ){ case 0x01: ShowByte(( void * ) pStart , pEnd ); break; case 0x02: ShowShort(( void * ) pStart , pEnd ); break; case 0x04: ShowLong(( void * ) pStart , pEnd ); break; default: rlSendString( "\r\nCMD format: show [ byte | half | long ] startAddress [ length ]" ); break; } return 1; } pStart = A2Int( argv[2] ); pEnd = 0x0100; if( argc >= 0x04 ){ pEnd = A2Int( argv[3] ); } retflag = 0x00000001; do{ if( CmdString( argv[1] , "byte" )){ mode = 0x01; pEnd += pStart; pEnd += 0x0f; pStart &= 0xFFFFFFF0; pEnd &= 0xFFFFFFF0; pEnd -= pStart; ShowByte(( void * ) pStart , pEnd ); break; } if( CmdString( argv[1] , "half" )){ mode = 0x02; //pEnd <<= 0x0001; pEnd += pStart; pEnd += 0x0f; pStart &= 0xFFFFFFF0; pEnd &= 0xFFFFFFF0; pEnd -= pStart; ShowShort(( void * ) pStart , pEnd ); break; } if( CmdString( argv[1] , "long" )){ mode = 0x04; //pEnd <<= 0x0002; pEnd += pStart; pEnd += 0x0f; pStart &= 0xFFFFFFF0; pEnd &= 0xFFFFFFF0; pEnd -= pStart; ShowLong(( void * ) pStart , pEnd ); break; } rlSendString( "\r\n show [ byte | half | long ] startAddress [ length ]" ); retflag = -2; }while( FALSE ); if( retflag > 0x000000 ){ pCurShow = ( void * )( pStart + pEnd ); Showlength = pEnd; showMode = mode; } return retflag; } void ShowHexChar( unsigned char * pbuf ) { int item; rlSendString( " " ); for( item = 0x00 ; item < 0x10 ; item++ ){ if(( pbuf[item] >= 0x20 ) && ( pbuf[item] < 0x80 )) { _putc( pbuf[item] ); continue; } _putc( '.' ); } } //****************************************** //start , length = nBytes void ShowByte( unsigned char * pbuf , int length ) { unsigned long endPbuf; unsigned char *pCurBuf; pCurBuf = pbuf; for( endPbuf = (( unsigned long ) pbuf ) + length ; ( unsigned long )pbuf < endPbuf ; pbuf++ ){ if(((( unsigned long ) pbuf ) & 0x0000000F ) == 0x00000000 ){ PrintIntHex(( unsigned long ) pbuf , 0x08 ); pCurBuf = pbuf; } _putc( ' ' ); PrintIntHex(( unsigned long )( *pbuf ) , 0x00000002 ); if(((( unsigned long ) pbuf ) & 0x0000000F ) == 0x0000000F ){ ShowHexChar( pCurBuf ); rlSendString( "\r\n" ); if( CtrlBreak( )){ break; } } } } //****************************************** //start , length = nBytes void ShowShort( unsigned short * pbuf , int length ) { unsigned long endPbuf; unsigned char *pCurBuf; pCurBuf = ( unsigned char * )pbuf; for( endPbuf = (( unsigned long ) pbuf ) + length ; ( unsigned long )pbuf < endPbuf ; pbuf++ ){ if(((( unsigned long ) pbuf ) & 0x0000000F ) == 0x00000000 ){ PrintIntHex(( unsigned long ) pbuf , 0x08 ); pCurBuf = ( unsigned char * )pbuf; } _putc( ' ' ); PrintIntHex(( unsigned long )( *pbuf ) , 0x00000004 ); if(((( unsigned long ) pbuf ) & 0x0000000E ) == 0x0000000E ){ ShowHexChar( pCurBuf ); rlSendString( "\r\n" ); if( CtrlBreak( )){ break; } } } } void ShowLong( unsigned long * pbuf , int length ) { unsigned long endPbuf; unsigned char *pCurBuf; pCurBuf = ( unsigned char * )pbuf; for( endPbuf = (( unsigned long ) pbuf ) + length ; ( unsigned long )pbuf < endPbuf ; pbuf++ ){ if(((( unsigned long ) pbuf ) & 0x0000000F ) == 0x00000000 ){ PrintIntHex(( unsigned long ) pbuf , 0x08 ); pCurBuf = ( unsigned char * )pbuf; } _putc( ' ' ); PrintIntHex(( unsigned long )( *pbuf ) , 0x00000008 ); if(((( unsigned long ) pbuf ) & 0x0000000C ) == 0x0000000C ){ ShowHexChar( pCurBuf ); rlSendString( "\r\n" ); if( CtrlBreak( )){ break; } } } } void PrintIntHex( unsigned long hexData , int length ) { int curItem; unsigned int temp; char msgbuf[0x10]; msgbuf[0x0A] = 0x00; curItem = 0x09; while( curItem > 0x01 ){ temp = hexData & 0x0F; hexData >>= 0x04; if( temp <= 0x09 ){ msgbuf[curItem] = '0' + temp; curItem--; continue; } msgbuf[curItem] = ( 'A' - 0x0A ) + temp; curItem--; } rlSendString( msgbuf + ( 0x0A - length )); } void sys_cmd_proc( void ) { StdHdl = ( P_TAG_CMD_T ) UART_CMD_BUFFER; gcurCmd = CMD_MAXNUM; CmdInit( ); rlSendString( "\r\n" ); rlSendString( "(C)SiFive" ); /* command line main loop */ sys_cmd_main_loop(); } void sys_cmd_main_loop(void) { unsigned int retflag; rlSendString( "\r\n# " ); while( TRUE){ retflag = ReadString(( unsigned char * ) StdHdl->curbuf , 0x3FF ); retflag = piteCmdLine(( char * ) StdHdl->curbuf , ( char ** )StdHdl->argvList , 0x20 ); StdHdl->curArgc = retflag; RelayProc( ); rlSendString( "\r\n# " ); } }