[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/boot/common/src/uboot/downloader/cmd_set.c b/boot/common/src/uboot/downloader/cmd_set.c
new file mode 100755
index 0000000..9e98959
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_set.c
@@ -0,0 +1,408 @@
+/*******************************************************************************

+ * Copyright (C) 2016, ZIXC Corporation.

+ *

+ * File Name:cmd_set.c

+ * File Mark:

+ * Description:

+ * Others:

+ * Version:       1.0

+ * Author:        zangxiaofeng

+ * Date:          2013-6-8

+ * 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 <nand.h>

+#include <linux/mtd/spi-nor.h>

+#include <linux/mtd/nor_spifc.h>

+

+#include "downloader_config.h"

+#include "downloader_nand.h"

+#include "downloader_serial.h"

+#include "errno.h"

+#include "boot_mode.h"

+

+

+#define ZLOAD_PARTITION_SIZE	0x3000

+

+

+/****************************************************************************

+*							Global Function Prototypes

+****************************************************************************/

+extern partition_table_t * g_partition_table;

+int set_partitions(unsigned int size);

+partition_entry_t * get_partitions(const char *partname, partition_table_t *table);

+

+partition_table_t * g_partition_table_dl = NULL;

+

+extern char *tsp_console_buffer;

+extern struct fsl_qspi spi_nor_flash;

+

+

+/*******************************************************************************

+ * Function:do_set

+ * Description:

+ * Parameters:

+ *	 Input:

+ *

+ *	 Output:

+ *

+ * Returns:

+ *

+ *

+ * Others:

+ ********************************************************************************/

+int do_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])

+{

+    

+    char *par = NULL;

+	unsigned int size = 0;

+	unsigned int ret = 0;

+	

+	if(argc<3)

+    {

+        return cmd_usage(cmdtp);

+    }

+	par = argv[1];

+	size = (unsigned int)simple_strtoul (argv[2], NULL, 16);

+

+	if(strcmp(par,"partitions") == 0)

+	{

+	    sprintf(tsp_console_buffer,"OKAY RECV_TABLES");

+        downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);

+	    ret = set_partitions(size);

+		return ret;

+	}

+	else

+	{

+	    sprintf(tsp_console_buffer,"FAIL COMMAND ERROR");

+        downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);

+		return -1;

+	}

+	

+

+}

+U_BOOT_CMD(

+	set, CONFIG_SYS_MAXARGS, 0, do_set,

+	"set : set [module] [size]",

+	""

+);

+

+/*******************************************************************************

+ * Function:set_partitions

+ * Description:

+ * Parameters:

+ *	 Input:

+ *

+ *	 Output:

+ *

+ * Returns:

+ *

+ *

+ * Others:

+ ********************************************************************************/

+ int set_partitions(unsigned int size)

+{

+	partition_entry_t *part_nvr = NULL;

+	partition_entry_t *part_nvr_dl = NULL;

+	partition_table_t *table_dl = NULL;

+	char *table_new = (char*)(CONFIG_USB_DMA_BUF_ADDR); /*USB DMA BUFFER*/

+

+	/* UE´ÓPC»ñÈ¡·ÖÇø±í */

+	downloader_serial_read_actuallen((char *)table_new, size); 

+	table_dl = (partition_table_t *)table_new;

+	

+	g_partition_table_dl = kzalloc(4096, GFP_KERNEL);

+	if(g_partition_table_dl == NULL)

+	{

+		printf("set_partitions kzalloc failed.\n");

+		return -1;

+	}

+	

+	memcpy(g_partition_table_dl,table_dl,size);

+	if(table_dl->magic != PARTITION_MAGIC)

+	{

+	    sprintf(tsp_console_buffer,"FAIL INVALID_PARTITION_TABLE");

+        downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);

+		return -1;

+	}

+

+	/* ·ÖÇø±íÆ¥Åä»òûÓзÖÇø±í */

+	if(memcmp( g_partition_table, table_dl, sizeof(partition_table_t))==0

+		|| g_partition_table->magic != PARTITION_MAGIC)   

+	{

+	    g_partition_table = g_partition_table_dl;

+		sprintf(tsp_console_buffer,"OKAY");

+        downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);

+		return 0;

+	}

+	else

+	{

+		/* UE´ÓPC»ñÈ¡NV·ÖÇøÐÅÏ¢ */

+	    part_nvr_dl = get_partitions("nvrofs", table_dl);    

+		if(part_nvr_dl == NULL)

+		{

+			printf("pc part nvrofs get failed.\n");

+			return -1;

+		}

+

+		/* ´ÓUEµÄNAND¶ÁÈ¡NV·ÖÇøÐÅÏ¢ */		

+	    part_nvr = get_partitions("nvrofs", g_partition_table);

+		if(part_nvr == NULL)

+		{

+			printf("part_nvrofs get failed.\n");

+		    sprintf(tsp_console_buffer,"FAIL UNACCEPTABLE_PARTITION_CHANGE");

+            downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);

+			return -1;	

+		}

+		

+		if((part_nvr->part_offset == part_nvr_dl->part_offset)

+			&&(part_nvr->part_size == part_nvr_dl->part_size))

+		{

+            sprintf(tsp_console_buffer,"FAIL ACCEPTABLE_PARTITION_CHANGE");

+            downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);

+		    return 0;

+		}

+		else

+		{

+		    sprintf(tsp_console_buffer,"FAIL UNACCEPTABLE_PARTITION_CHANGE");

+            downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);

+		    return -1;

+		}

+	}

+}

+

+/*******************************************************************************

+ * Function:get_partitions

+ * Description:

+ * Parameters:

+ *	 Input:

+ *

+ *	 Output:

+ *

+ * Returns:

+ *

+ *

+ * Others:

+ ********************************************************************************/

+ partition_entry_t * get_partitions(const char *partname, partition_table_t *table)

+{

+    

+    partition_entry_t *entry = &table->table[0];

+    uint32_t entry_nums = table->entrys;

+    while( entry_nums-- )
+    {
+        if ( strcmp((const char *)entry->part_name,partname) == 0 )

+            return entry;
+        entry++;
+    }
+    return NULL;

+}

+

+/*******************************************************************************

+ * Function:set_nand_dlflag 

+ * Description: open or close USB DL PORT, based on nand

+ *                   dl on :open DL port ; dl off :close DL port

+ * Parameters:

+ *	 Input:

+ *

+ *	 Output:

+ *

+ * Returns:

+ *

+ *

+ * Others:

+ ********************************************************************************/

+ int set_nand_dlflag( char * sign)

+{   

+	char value = 0;

+	int bootflag = 0;

+	int times = 0;

+	int i =0;

+	int ret = 0;

+	struct erase_info ei;

+ 	nand_info_t *nand = &nand_info[nand_curr_device];

+	

+	u_char *buffer = kzalloc(6*(nand->writesize + nand->oobsize),GFP_KERNEL);

+	u_char *p_buffer = buffer;

+    

+	if( buffer == NULL )

+        return 1;

+	

+	times = 12*1024/nand->writesize;

+	for(i=0;i<times;i++)

+	{

+        nand_read_page_with_ecc(nand, 

+								((loff_t)i*nand->writesize), 

+								0,

+								p_buffer);

+		p_buffer += nand->writesize;

+	}

+

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

+	

+	memset(&ei, 0, sizeof(struct erase_info));

+	ei.mtd	= nand;

+	ei.addr = (uint64_t)(0);

+	ei.len	= (uint64_t)nand->erasesize;	

+	ret = nand->erase(nand, &ei);  /*²Á³ýµÚÒ»¿é*/

+

+	p_buffer = buffer;

+

+	for(i=0;i<times;i++)

+	{

+        nand_write_page_with_ecc(nand, ((loff_t)i*nand->writesize), p_buffer);

+		p_buffer += nand->writesize;

+	}

+

+    sprintf(tsp_console_buffer,"DL OKAY");

+    downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);

+		

+	kfree(buffer);

+

+	return 0;

+

+}

+

+

+/*******************************************************************************

+ * Function:set_nor_dlflag 

+ * Description: open or close USB DL PORT, based on nand

+ *                   dl on :open DL port ; dl off :close DL port

+ * Parameters:

+ *	 Input:

+ *

+ *	 Output:

+ *

+ * Returns:

+ *

+ *

+ * Others:

+ ********************************************************************************/

+ int set_nor_dlflag(char *sign)

+{   

+	int ret = 0;

+	char value = 0;

+	int bootflag = 0;

+	uint32_t load_addr = 0x0;

+	uint32_t size_read = ZLOAD_PARTITION_SIZE;

+	uint32_t size_write = ZLOAD_PARTITION_SIZE;

+	struct fsl_qspi *nor = &spi_nor_flash;	

+	u_char *buffer = kzalloc(ZLOAD_PARTITION_SIZE,GFP_KERNEL);

+	

+	if(buffer == NULL)

+	{

+		return -1;

+	}

+        

+	ret = nand_read(&(nor->nor[0].mtd), load_addr, &size_read, buffer);

+	if(ret != 0)

+	{

+		printf("nand_read error.\n");

+		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 = nand_erase(&(nor->nor[0].mtd), load_addr, nor->nor[0].mtd.erasesize);

+	if(ret != 0)

+	{

+		printf("nand_erase error.\n");

+		return -1;

+	}

+

+    ret = nand_write(&(nor->nor[0].mtd), load_addr, &size_write, buffer);

+	if(ret != 0)

+	{

+		printf("nand_write error.\n");

+		return -1;

+	}

+

+    sprintf(tsp_console_buffer,"DL OKAY");

+    downloader_serial_write(tsp_console_buffer, strlen(tsp_console_buffer)+1);

+		

+	kfree(buffer);

+

+	return 0;

+}

+

+

+/*******************************************************************************

+ * Function:do_dlflag

+ * Description: open or close USB DL PORT, 

+ *                   dl on :open DL port ; dl off :close DL port

+ * Parameters:

+ *	 Input:

+ *

+ *	 Output:

+ *

+ * Returns:

+ *

+ *

+ * Others:

+ ********************************************************************************/

+int do_dlflag(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])

+{   

+    int ret = 0;

+	u_char *sign = NULL;

+	int type = 0;

+ 	

+	if(argc<2)

+    {

+        return cmd_usage(cmdtp);

+    }

+	sign = argv[1];	

+	type = read_boot_flashtype();

+

+	if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND)

+	{

+        ret = set_nand_dlflag(sign);

+	}

+	else if(type == IF_TYPE_NOR)

+	{

+		ret = set_nor_dlflag(sign);

+	}

+

+	if(ret != 0)

+	{

+		return -1;

+	}

+		

+	return 0;

+

+}

+U_BOOT_CMD(

+	dl, CONFIG_SYS_MAXARGS, 0, do_dlflag,

+	"dl : dl [sign]",

+	""

+);