zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/boot/common/src/uboot/downloader/cmd_dl_mmc.c b/boot/common/src/uboot/downloader/cmd_dl_mmc.c
new file mode 100644
index 0000000..1950ef2
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_dl_mmc.c
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_dl_mmc.c
+ * File Mark:
+ * Description: download or upload bin from eMMC,compat with SD
+ * Others:
+ * Version:       1.0
+ * Author:        zangxiaofeng
+ * Date:          2014-1-13
+ * History 1:
+ *     Date:
+ *     Version:
+ *     Author:
+ *     Modification:
+ * History 2:
+  ********************************************************************************/
+
+
+
+/****************************************************************************
+* 	                                     Include files
+****************************************************************************/
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <jffs2/load_kernel.h>
+#include "downloader_config.h"
+#include "downloader_nand.h"
+#include "downloader_serial.h"
+#include "errno.h"
+
+#include <mmc.h>
+
+extern partition_table_t * g_partition_table_dl;
+extern int downloader_readline (char * buffer);
+extern int downloader_mmc_erase(partition_entry_t * part, uint  partEraseSize);
+extern char *tsp_console_buffer;
+
+/*******************************************************************************
+ * Function:do_mmc_write
+ * Description:
+ * Parameters:
+ *	 Input:
+ *
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_mmc_write(partition_entry_t *part, char *par , unsigned int offset,unsigned int size )
+{
+    char *ack = tsp_console_buffer;
+    unsigned int offset_par = offset;
+    unsigned int leftWriteLength = 0;
+    unsigned int curWriteLength = 0;
+#ifdef CONFIG_LOAD_CRC
+
+    unsigned long crc = 0;
+    unsigned long crc1 = 0;
+#endif
+    int ret = 0;
+    int zload_len = 8192;
+
+    nand_info_t *nand = NULL;
+
+    if(part==NULL)
+    {
+        sprintf(ack,"FAIL INVALID PARTITION");
+        downloader_serial_write(ack, strlen(ack)+1);
+        return EINVAL;	/* Invalid argument */
+    }
+    
+    if((size==0)||(size>part->part_size))
+    {
+        sprintf(ack,"FAIL INVALID LENGTH");
+        downloader_serial_write(ack, strlen(ack)+1);
+        return EINVAL;	/* Invalid argument */
+    }
+    leftWriteLength = size;
+	ret = downloader_mmc_erase( part, part->part_size);
+    while(leftWriteLength>0)
+    {
+        curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
+#ifdef CONFIG_LOAD_CRC
+        sprintf(ack,"DATACRC %08x",curWriteLength);
+#else
+        sprintf(ack,"DATA %08x",curWriteLength);
+#endif
+        downloader_serial_write(ack, strlen(ack)+1); 
+#ifdef CONFIG_LOAD_CRC
+        downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength+4);
+        crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,curWriteLength);
+        memcpy((unsigned char *)(&crc1),(unsigned char*)(DOWNLOADER_BUFFER_BASE+curWriteLength),4);
+        //printf("CRC_calc= %x,CRC_rec=%x \n",crc,crc1);
+        if(crc != crc1)
+        {
+            sprintf(ack,"FAIL CRC ERROR");
+            downloader_serial_write(ack, strlen(ack)+1);
+            return ENOSYS;  /* Function not implemented */
+        }
+#else
+        downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength);
+#endif
+        if(memcmp(par,"zloader",7) == 0)    /* ÏÂÔØzloader·ÖÇø£¬Í¬Ê±ÏÂÔØ·ÖÇø±í */
+        {
+            memcpy((char *)(DOWNLOADER_BUFFER_BASE+4096),g_partition_table_dl,4096);
+            ret = mmc_write( nand,(loff_t)(part->part_offset + offset_par) , &zload_len,  (unsigned char *)DOWNLOADER_BUFFER_BASE, 0);
+        }
+		else
+		{
+		    ret = mmc_write( nand,(loff_t)(part->part_offset + offset_par) , &curWriteLength,  (unsigned char *)DOWNLOADER_BUFFER_BASE, 0); 
+		}
+
+		if(ret)
+        {
+            sprintf(ack,"FAIL MMC WRITE %d,%d,ret = %d",offset_par,curWriteLength,ret);
+            downloader_serial_write(ack, strlen(ack)+1);
+            return ENOSYS;  /* Function not implemented */
+        }
+	    leftWriteLength -= curWriteLength;
+	    offset_par += curWriteLength;
+    }
+    sprintf(ack,"OKAY");
+    downloader_serial_write(ack, strlen(ack)+1);
+    return 0;
+}
+
+/*******************************************************************************
+ * Function:do_mmc_read
+ * Description:
+ * Parameters:
+ *	 Input:
+ *
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_mmc_read(partition_entry_t *part, char *par , unsigned int offset,unsigned int size )
+{
+    char *rx_buffer = tsp_console_buffer;
+    char *ack = tsp_console_buffer;
+    unsigned int offset_par = offset;
+    unsigned int leftReadLength = 0;
+    unsigned int curReadLength = 0;
+#ifdef CONFIG_LOAD_CRC
+    unsigned long crc = 0;
+#endif
+    int ret = 0;
+	nand_info_t *nand = NULL;
+
+    if(part == NULL)
+    {
+        sprintf(ack,"FAIL INVALID PARTITION");
+        downloader_serial_write(ack, strlen(ack)+1);
+        return EINVAL;	/* Invalid argument */
+    }
+    if((size == 0)||(size>part->part_size))
+    {
+        sprintf(ack,"FAIL INVALID LENGTH");
+        downloader_serial_write(ack, strlen(ack)+1);
+        return EINVAL;	/* Invalid argument */
+    }
+    leftReadLength = size;
+#ifdef CONFIG_LOAD_CRC
+    sprintf(ack,"DATACRC %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
+#else
+    sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
+#endif
+    downloader_serial_write(ack, strlen(ack)+1); 
+    
+    while(leftReadLength>0)
+    {
+        curReadLength = MIN(leftReadLength,DOWNLOADER_BUFFER_SIZE);
+        downloader_readline(rx_buffer); 
+	    if(memcmp(rx_buffer,"OKAY",4)==0)
+	    {
+            ret = mmc_read( nand,(loff_t)(part->part_offset+offset_par), &curReadLength,  (unsigned char *)DOWNLOADER_BUFFER_BASE);
+            if(ret)
+            {
+                sprintf(ack,"FAIL MMC READ %d,%d, ret = %d",offset_par,curReadLength,ret);
+                downloader_serial_write(ack, strlen(ack)+1);
+                return ENOSYS;  /* Function not implemented */ 
+            }
+            //printf("start to upload LEN=%d \n",curReadLength);
+#ifdef CONFIG_LOAD_CRC
+            crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,curReadLength);
+            memcpy((unsigned char*)(DOWNLOADER_BUFFER_BASE+curReadLength),(unsigned char *)(&crc),4);
+            downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, curReadLength+4);
+#else
+            downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, curReadLength); 
+#endif           
+            //downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, curReadLength); 
+       
+	    }
+	    else
+	    {
+            sprintf(ack,"FAIL COMMAND ERROR");
+            downloader_serial_write(ack, strlen(ack)+1);
+	        return EBADRQC;		/* Invalid request code */
+	    }
+	    leftReadLength -= curReadLength;
+	    offset_par += curReadLength;
+    }
+
+    downloader_readline(rx_buffer); 
+    if(memcmp(rx_buffer,"OKAY",4)==0)
+    {
+        return 0;
+    }
+    else
+    {
+       sprintf(ack,"FAIL COMMAND ERROR");
+       downloader_serial_write(ack, strlen(ack)+1);
+       return -1;
+    }
+}
+
+
+/*******************************************************************************
+ * Function:downloader_mmc_erase
+ * Description:erase mmc partition
+ * Parameters:
+ *	 Input:partEraseSize: must be multiple of 512KBytes
+ *               part:part information,offset and size must be multiple of 512KBytes
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+
+int downloader_mmc_erase(partition_entry_t * part, uint  partEraseSize)
+{
+	unsigned int blksize = 512;
+	int ret = 0;
+
+	if(part == NULL )
+	{
+		return -1;
+	}
+	ret = mmc_erase( (u64)part->part_offset, (lbaint_t)partEraseSize/blksize);
+
+	return ret;
+}
+/*******************************************************************************
+ * Function:do_mmc_eraseall
+ * Description:erase all mmc partitions
+ * Parameters:
+ *	 Input:
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+
+int downloader_mmc_eraseall(void)
+{
+
+	int  ret = 0;
+	partition_entry_t *entry = &g_partition_table->table[0];
+	uint32_t entry_nums = g_partition_table->entrys;
+		
+	while( entry_nums-- )
+	{
+	    if ( strcmp((const char *)entry->part_name, "ddr") == 0 \
+				||strcmp((const char *)entry->part_name, "raw") == 0)
+	    {
+	        entry++;
+	        continue;
+	    }
+		ret = downloader_mmc_erase(entry,entry->part_size);
+		entry++;
+	}
+	return ret;
+
+}
+/*******************************************************************************
+ * Function:do_mmc_eraseauto
+ * Description:erase mmc except nvr
+ * Parameters:
+ *	 Input:
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_mmc_eraseauto(void)
+{
+	int  ret = 0;
+	partition_entry_t *entry = &g_partition_table->table[0];
+	uint32_t entry_nums = g_partition_table->entrys;
+				
+	while( entry_nums-- )
+	{
+		if (strcmp((const char *)entry->part_name, "nvro") == 0||\
+			strcmp((const char *)entry->part_name, "ddr") == 0 \
+				||strcmp((const char *)entry->part_name, "raw") == 0)
+		{
+			entry++;
+			continue;
+		}
+		ret = downloader_mmc_erase(entry,entry->part_size);
+		entry++;
+	}
+	return ret;
+}
+
+
+/*
+ ******************************************************************************
+ * Function:set_mmc_dlflag 
+ * Description: open or close USB DL PORT, based on mmc
+ *                   dl on :open DL port ; dl off :close DL port
+ * Parameters:
+ *	 Input:
+ *
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ *******************************************************************************
+ */
+int set_mmc_dlflag( char * sign)
+{   
+	int ret = 0;
+	char value = 0;
+	int bootflag = 0;
+	int size = 8192;
+
+	u_char *buffer = kzalloc(0x3000,GFP_KERNEL);    
+	if( buffer == NULL )
+	    return -1;
+
+	if (strcmp((const char *)sign,"on") == 0)
+	{
+	    bootflag = 0x00;
+        memset(&value, bootflag, 1);
+	}
+	else if (strcmp((const char *)sign,"off") == 0)
+	{
+	    bootflag = 0x5a;
+        memset(&value, bootflag, 1);
+	}
+	memcpy(buffer+2, &value, 1);
+	ret = mmc_write( 0, 0, &size,buffer, 0);	
+		
+	sprintf(tsp_console_buffer,"DL OKAY");
+	downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);
+			
+	kfree(buffer);
+	return 0;
+
+}
+
+
+