[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]",
+ ""
+);