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;
+
+}
+
+
+