[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/Makefile b/boot/common/src/uboot/downloader/Makefile
new file mode 100644
index 0000000..77d377d
--- /dev/null
+++ b/boot/common/src/uboot/downloader/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+#CFLAGS += -DET_DEBUG -DDEBUG
+
+LIB = $(obj)libdownloader.o
+
+COBJS-y += cmd_downloader.o cmd_getvar.o downloader_nand.o downloader_serial.o boot_usb.o
+COBJS-y += cmd_erase.o cmd_cp_reset.o cmd_ram_start.o cmd_testusb.o
+COBJS-y += cmd_dl_nand.o cmd_dl_yaffs.o cmd_dl_ram.o cmd_set.o cmd_dl_raw.o
+COBJS-y += cmd_compat_read.o cmd_compat_write.o
+COBJS-y += cmd_bbt_count.o cmd_efuse_program.o
+
+COBJS := $(COBJS-y)
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/boot/common/src/uboot/downloader/boot_usb.c b/boot/common/src/uboot/downloader/boot_usb.c
new file mode 100644
index 0000000..a632802
--- /dev/null
+++ b/boot/common/src/uboot/downloader/boot_usb.c
@@ -0,0 +1,248 @@
+#include <usb/global.h>
+#include <usb/config.h>
+extern WORD32 USB_CDC_Enum(WORD32 USB_ADDR);
+//extern void USB_Pll_Clk_Rst_InitEnv(void);
+
+void USB_TstDev_InitEnv(void);
+
+#if 0
+void tsp_usb_init(WORD32 USB_ADDR)
+{
+ WORD32 dwConnect;
+
+ /*ÅäÖÃÍâΧ»·¾³*/
+
+ USB_Pll_Clk_Rst_InitEnv();
+
+ dwConnect=USB_CDC_Enum(USB_ADDR);
+
+ if(0==dwConnect)
+ {
+ printk("NOLINK\n");
+ return ;
+ }
+
+ printk("FAILED\n");
+
+}
+#endif
+
+int tsp_usb_init(void)
+{
+ WORD32 retVal = 0;
+ WORD32 usb_addr = 0;
+// BYTE boot_mode = get_boot_mode();
+ BYTE boot_mode = 1;
+ data_init();
+ /*add by sunyunchen*/
+ if(2 == boot_mode)
+ //if(0)
+ {
+ printf("hsic\n");
+ global.g_USB_MODE = 1;
+ usb_addr = SYS_USB_HSIC_BASE;
+ }
+ else
+ {
+ printf("usb\n");
+ global.g_USB_MODE = 0;
+ usb_addr = SYS_USB_BASE;
+ }
+ if((REG32(usb_addr+DWC_DEV_GLOBAL_REG_OFFSET)&0x7f0)!=0)//dcfg register
+ {
+ //printf("usb_g_enum!\n");
+ global.g_enum =DONOT_NEED_ENUM;
+
+
+ //global.g_enum =NEED_ENUM;
+ }
+ if(NEED_ENUM == global.g_enum)
+ {
+ //printf("need enum\n");
+ USB_TstDev_InitEnv();
+ }
+ else
+ {
+ //printf("global.g_dwc\n");
+ global.g_dwc_otg_pcd_tp.ep0state = EP0_IDLE;
+ global.dwRxQuit = 1;
+ global.dwTxQuit = 1;
+ global.g_dwc_otg_pcd_tp.request_config = 1;
+ }
+
+ retVal = USB_CDC_Enum(usb_addr);
+
+ return retVal;
+}
+
+void USB_TstDev_InitEnv(void)
+{
+#if USE_ASIC
+ WORD32 i;
+ if(0 == global.g_USB_MODE)
+ {
+
+ //ÊÍ·ÅUSB¸ôÀë8bit for usb ctrl
+ REG32(POWER_DOMAIN_ISO) |= (1<<8);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_RST) |= (1<<8);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_POWERON) &= ~(1<<8);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_POWERON) |= (1<<8);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_RST) &= ~(1<<8);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_ISO) &= ~(1<<8);
+ usdelay(10);
+
+ //usb ahb clock enable
+ REG32(SOC_MOD_CLKEN0)&=~(1<<4);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN0)|=(1<<4);
+ //usb phy clock enable
+ REG32(SOC_MOD_CLKEN1)&=~(1<<3);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN1)|=(1<<3);
+
+ // usb ahb reset ÏÈ×ÜÏߺó¹¤×÷
+ REG32(SOC_MOD_RSTEN)&=~(1<<5);
+ usdelay(100);
+ REG32(SOC_MOD_RSTEN)|=(1<<5);
+ usdelay(100);
+
+ // usb work reset
+ REG32(SOC_MOD_RSTEN)&=~(1<<4);
+ usdelay(100);
+ REG32(SOC_MOD_RSTEN)|=(1<<4);
+ usdelay(100);
+
+ //release usb phy reset
+ REG32(SOC_MOD_RSTEN)&=~(1<<3);
+ usdelay(100);
+ REG32(SOC_MOD_RSTEN) |= 1<<3;
+ usdelay(100);
+
+ i = 0;
+ while((REG32(SOC_MOD_USBSTATECTRL)&0x2) == 0)
+ {
+ i++;
+ usdelay(20);
+ if(i>50000) break;
+ }
+ }
+ else
+ {
+ //ÊÍ·ÅUSB_HSIC¸ôÀë9bit for hsic
+ REG32(POWER_DOMAIN_ISO) |= (1<<9);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_RST) |= (1<<9);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_POWERON) &= ~(1<<9);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_POWERON) |= (1<<9);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_RST) &= ~(1<<9);
+ usdelay(10);
+
+ REG32(POWER_DOMAIN_ISO) &= ~(1<<9);
+ usdelay(10);
+
+ //usb hsic ahb clock enable
+ REG32(SOC_MOD_CLKEN0)&=~(1<<2);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN0)|=(1<<2);
+ //usb hsic phy clock enable
+ REG32(SOC_MOD_CLKEN0)&=~(1<<1);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN0)|=(1<<1);
+
+ //usb hsic 480M clock enable
+ REG32(SOC_MOD_CLKEN0)&=~(1<<0);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN0)|=(1<<0);
+
+ // usb hsic ahb reset
+ REG32(SOC_MOD_RSTEN)&=~(1<<2);
+ usdelay(20);
+ REG32(SOC_MOD_RSTEN)|=(1<<2);
+ usdelay(10);
+
+ // usb hsic work reset
+ REG32(SOC_MOD_RSTEN)&=~(1<<1);
+ usdelay(20);
+ REG32(SOC_MOD_RSTEN)|=(1<<1);
+ //release usb hsic phy reset
+ REG32(SOC_MOD_RSTEN)&=~(1<<0);
+ usdelay(20);
+ REG32(SOC_MOD_RSTEN)|=(1<<0);
+
+ usdelay(100);
+ i = 0;
+ while((REG32(SOC_MOD_USBSTATECTRL)&0x1) == 0)
+ {
+ i++;
+ usdelay(20);
+ if(i>50000) break;
+ }
+
+#if SYNC_USB_HSIC
+ usdelay(20);
+ REG32(REG_GPIO_OUT)=1;
+ while(REG32(REG_GPIO_IN)!=0xFF);
+ usdelay(1);
+ REG32(REG_GPIO_OUT)=0;
+#endif
+ }
+#endif
+#if !USE_ASIC
+#if 1
+//usb power on
+ REG32(POWER_DOMAIN_POWERON) |= 0x300;
+ usdelay(10);
+//usb disable reset
+ REG32(POWER_DOMAIN_RST) &= 0xfffffcff; //
+ usdelay(10);
+//usb disable iso
+ REG32(POWER_DOMAIN_ISO) &= 0xfffffcff;
+ usdelay(10);
+
+//open usb0 and usb1
+ //usb ahb clock enable
+ REG32(SOC_MOD_CLKEN0)&=0xeffffffb;
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN0)|=0x10000004;
+ //usb phy clock enable
+ REG32(SOC_MOD_CLKEN1)&=~(3<<16);
+ usdelay(20);
+ REG32(SOC_MOD_CLKEN1)|=(3<<16);
+
+
+ // usb ctr reset
+ REG32(SOC_MOD_RSTEN)&=0xeffffff7;
+ usdelay(20);
+ REG32(SOC_MOD_RSTEN)|=0x10000008;
+
+ // usb ahb reset
+ REG32(SOC_MOD_RSTEN)&=0xf7fffffb;
+ usdelay(20);
+ REG32(SOC_MOD_RSTEN)|=0x8000004;
+#endif
+/*
+ usb ctr and ahb reset release ,delay 60us, check usb reset state,
+ if the reset state is 0, reset ,if 1,reset release.
+*/
+#endif
+}
+
+
+
diff --git a/boot/common/src/uboot/downloader/cmd_bbt_count.c b/boot/common/src/uboot/downloader/cmd_bbt_count.c
new file mode 100644
index 0000000..0f1cf52
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_bbt_count.c
@@ -0,0 +1,398 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_bbt_count.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: lankai
+ * Date: 2017-12-14
+ * History 1:
+ * Date:
+ * Version:
+ * Author:
+ * Modification:
+ * History 2:
+ ********************************************************************************/
+
+
+/****************************************************************************
+* Include files
+****************************************************************************/
+#include <common.h>
+#include <command.h>
+#include <nand.h>
+
+#include "downloader_serial.h"
+#include "errno.h"
+#include <partition_table.h>
+#include <boot_mode.h>
+
+/****************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+int crc_switch_flag = 0;
+extern char *tsp_console_buffer;
+extern partition_table_t *g_partition_table_dl;
+extern partition_table_t *g_partition_table;
+
+
+/*******************************************************************************
+ * Function:do_bbt_count
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int do_bbt_count(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ struct mtd_info *mtd = get_mtd_info();
+ struct nand_chip *this = NULL;
+ int bad_block_num = 0;
+ int total_block_num = 0;
+ char ack[64] = {0};
+
+ if(argc != 1)
+ {
+ return cmd_usage(cmdtp);
+ }
+
+ if (NULL == mtd)
+ {
+ printf("FAIL\n");
+ return ENODEV;
+ }
+
+ this = mtd->priv;
+ bad_block_num = mtd->ecc_stats.badblocks;
+ total_block_num = this->chipsize >> this->bbt_erase_shift;
+
+ sprintf(ack, "bad_block_num:%04d total_block_num:%04d", bad_block_num, total_block_num);
+ downloader_serial_write(ack, strlen(ack) + 1);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ bbt_count, CONFIG_SYS_MAXARGS, 0, do_bbt_count, "bbt_count", ""
+);
+
+/*******************************************************************************
+ * Function:do_crc
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int do_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ u_char *crc_flag = NULL;
+ char *ack = tsp_console_buffer;
+
+ if(argc<2)
+ {
+ return cmd_usage(cmdtp);
+ }
+ crc_flag = argv[1];
+
+ if (strcmp((const char *)crc_flag,"on") == 0)
+ {
+ crc_switch_flag = 1;
+ sprintf(ack,"OKAY");
+ }
+ else if (strcmp((const char *)crc_flag,"off") == 0)
+ {
+ crc_switch_flag = 0;
+ sprintf(ack,"OKAY");
+ }
+ else
+ {
+ sprintf(ack,"FAIL COMMAND ERROR");
+ }
+
+ downloader_serial_write(ack, strlen(ack)+1);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ crc, CONFIG_SYS_MAXARGS, 0, do_crc, "crc_check", ""
+);
+
+
+/*******************************************************************************
+ * Function:do_crc
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int do_partition_bbc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int i, j, len, bad_nums, partition_nums;
+ char *ack = tsp_console_buffer;
+ nand_info_t *nand = &nand_info[nand_curr_device];
+
+ if(argc != 1)
+ {
+ return cmd_usage(cmdtp);
+ }
+
+ partition_entry_t *entry = NULL;
+ uint32_t entry_nums = 0;
+ if(get_load_mode() == TLOAD_MODE)
+ {
+ entry_nums = g_partition_table_dl->entrys;
+ entry = &g_partition_table_dl->table[0];
+ }
+ else
+ {
+ entry_nums = g_partition_table->entrys;
+ entry = &g_partition_table->table[0];
+ }
+
+ sprintf(ack, "partition_nums:%04d", entry_nums - 2);
+
+ printf("entry_nums=%d\n", entry_nums - 2);
+
+ for(i = 0; i < entry_nums - 2; i++)
+ {
+ printf("entry->part_offset=0x%x, entry->part_size=0x%x\n",
+ entry->part_offset, entry->part_size);
+ bad_nums = 0;
+ partition_nums = entry->part_size / nand->erasesize;
+ for(j = 0; j < partition_nums; j++)
+ {
+ if(nand_block_isbad (nand, entry->part_offset + (loff_t)j * nand->erasesize))
+ {
+ printf("bad block addr = 0x%x\n", (entry->part_offset + j * nand->erasesize));
+ bad_nums++;
+ }
+ }
+
+ len = strlen(ack);
+ sprintf(ack + len, " %s,%04d,%04d", entry->part_name, bad_nums, partition_nums);
+ entry++;
+ }
+
+ printf("partition_bbc:%s\n", ack);
+
+ downloader_serial_write(ack, strlen(ack) + 1);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ part_bbc, CONFIG_SYS_MAXARGS, 0, do_partition_bbc, "partition bad block count", ""
+);
+
+
+/*******************************************************************************
+ * Function:do_single_partition_bbc
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int do_single_partition_bbc(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ int j, bad_nums, part_block_nums;
+ u_char *partition_name = NULL;
+ char *ack = tsp_console_buffer;
+ nand_info_t *nand = &nand_info[nand_curr_device];
+ partition_entry_t *entry = NULL;
+
+ if(argc < 2)
+ {
+ return cmd_usage(cmdtp);
+ }
+
+ partition_name = argv[1];
+
+ entry = find_partition_para(partition_name);
+ if(entry == NULL)
+ {
+ BOOT_PRINTF(UBOOT_ERR, "[%s]: can't find the partition...\n", partition_name);
+ return 1;
+ }
+
+ printf("entry->part_offset=0x%x, entry->part_size=0x%x\n",
+ entry->part_offset, entry->part_size);
+ bad_nums = 0;
+ part_block_nums = entry->part_size / nand->erasesize;
+ for(j = 0; j < part_block_nums; j++)
+ {
+ if(nand_block_isbad (nand, entry->part_offset + (loff_t)j * nand->erasesize))
+ {
+ printf("bad block addr = 0x%x\n", (entry->part_offset + j * nand->erasesize));
+ bad_nums++;
+ }
+ }
+
+ sprintf(ack, "%s,%04d,%04d", entry->part_name, bad_nums, part_block_nums);
+ printf("single_partition_bbc:%s\n", ack);
+ downloader_serial_write(ack, strlen(ack) + 1);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ single_part_bbc, CONFIG_SYS_MAXARGS, 0, do_single_partition_bbc,
+ "single partition bad block count", ""
+);
+
+
+/*******************************************************************************
+ * Function:do_badblock_query
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int do_badblock_query(cmd_tbl_t *cmdtp,
+ int flag,
+ int argc,
+ char * const argv[])
+{
+ u_char *crc_flag = NULL;
+ int flash_type = 0;
+ char *ack = tsp_console_buffer;
+
+ if(argc != 1)
+ {
+ return cmd_usage(cmdtp);
+ }
+
+ crc_flag = argv[0];
+ if(strcmp((const char *)crc_flag,"badblock_query") != 0)
+ {
+ sprintf(ack,"COMMAND ERROR");
+ downloader_serial_write(ack, strlen(ack) + 1);
+ return -1;
+ }
+
+ flash_type = read_boot_flashtype();
+ switch(flash_type)
+ {
+ case IF_TYPE_NAND:
+ case IF_TYPE_SPI_NAND:
+ sprintf(ack,"SUPPORT");
+ break;
+ default:
+ sprintf(ack,"UNSUPPORT");
+ break;
+ }
+ downloader_serial_write(ack, strlen(ack) + 1);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ badblock_query, CONFIG_SYS_MAXARGS, 0, do_badblock_query,
+ "is support bad block query", ""
+);
+
+/*
+ ******************************************************************************
+ * Function:do_part_valid_space_query
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+ int do_part_valid_space_query(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ int j, bad_nums, part_block_nums;
+ u_char *partition_name = NULL;
+ char *ack = tsp_console_buffer;
+ nand_info_t *nand = &nand_info[nand_curr_device];
+ partition_entry_t *entry = NULL;
+ int flash_type = 0;
+ unsigned int valid_space_size = 0;
+
+ if(argc < 2)
+ {
+ return cmd_usage(cmdtp);
+ }
+
+ partition_name = argv[1];
+
+ entry = find_partition_para(partition_name);
+ if(entry == NULL)
+ {
+ BOOT_PRINTF(UBOOT_ERR, "[%s]: can't find the partition...\n", partition_name);
+ sprintf(ack,"FAIL INVALID PARTITION");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+
+ flash_type = read_boot_flashtype();
+ if(flash_type == IF_TYPE_NOR)
+ {
+ valid_space_size = entry->part_size;
+ }
+ else
+ {
+ bad_nums = 0;
+ part_block_nums = entry->part_size / nand->erasesize;
+ for(j = 0; j < part_block_nums; j++)
+ {
+ if(nand_block_isbad (nand, entry->part_offset + (loff_t)j * nand->erasesize))
+ {
+ printf("bad block addr = 0x%x\n", (entry->part_offset + j * nand->erasesize));
+ bad_nums++;
+ }
+ }
+ valid_space_size = entry->part_size - bad_nums * nand->erasesize;
+ }
+
+ sprintf(ack, "%s,%08x", entry->part_name, valid_space_size);
+ printf("part_valid_space_query:%s\n", ack);
+ downloader_serial_write(ack, strlen(ack) + 1);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ part_valid_space_query, CONFIG_SYS_MAXARGS, 0, do_part_valid_space_query,
+ "get partition valid physics space size", ""
+);
+
+
+
diff --git a/boot/common/src/uboot/downloader/cmd_compat_read.c b/boot/common/src/uboot/downloader/cmd_compat_read.c
new file mode 100644
index 0000000..04c59cc
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_compat_read.c
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_compat_read.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-3-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 <boot_mode.h>
+
+#include "errno.h"
+/****************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+
+
+/*******************************************************************************
+ * Function:do_compat_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int do_compat_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ partition_entry_t *part = NULL;
+ char *par = NULL;
+ char ack[64]={0};
+ unsigned int offset = 0;
+ unsigned int size = 0;
+ unsigned int ret = 0;
+
+ if(argc<4)
+ {
+ return cmd_usage(cmdtp);
+ }
+
+
+ par = argv[1];
+ offset = (unsigned int)simple_strtoul (argv[2], NULL, 16);
+ size = (unsigned int)simple_strtoul (argv[3], NULL, 16);
+ part = downloader_get_part(par);
+ if(part == NULL)
+ {
+ sprintf(ack,"FAIL INVALID PARTITION TYPE");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+
+ if((read_boot_flashtype() == IF_TYPE_NOR)
+ && (strcmp((const char *)part->part_type,"nand") == 0))
+
+ {
+ ret = do_nor_read(part, par, offset,size);
+ return ret;
+ }
+
+
+ if(strcmp((const char *)part->part_type,"nand") == 0)
+ {
+ ret = do_nand_read(part, par, offset, size);
+ return ret;
+ }
+ else if (strcmp((const char *)part->part_type,"fs") == 0)
+ {
+ ret = do_yaffs_read(part, par, offset, size);
+ return ret;
+ }
+ else if (strcmp((const char *)part->part_type,"ddr") == 0)
+ {
+ ret = do_ram_read(offset, size);
+ return ret;
+ }
+ else if (strcmp((const char *)part->part_type,"raw") == 0)
+ {
+ ret = do_raw_read(offset, size);
+ return ret;
+ }
+ else
+ {
+ sprintf(ack,"FAIL INVALID PARTITION TYPE");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+}
+U_BOOT_CMD(
+ compat_read, CONFIG_SYS_MAXARGS, 0, do_compat_read,
+ "upload: compat_read [partition][offset][size]",
+ ""
+);
+
+
+
+
+
+
diff --git a/boot/common/src/uboot/downloader/cmd_compat_write.c b/boot/common/src/uboot/downloader/cmd_compat_write.c
new file mode 100644
index 0000000..8ac27dd
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_compat_write.c
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_compat_write.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-3-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 <boot_mode.h>
+/****************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+
+/*******************************************************************************
+ * Function:do_compat_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int do_compat_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ partition_entry_t *part = NULL;
+ char *par = NULL;
+ char ack[64]={0};
+ unsigned int offset = 0;
+ unsigned int size = 0;
+ unsigned int ret = 0;
+
+ if(argc<4)
+ {
+ return cmd_usage(cmdtp);
+ }
+
+ par = argv[1];
+ offset = (unsigned int)simple_strtoul (argv[2], NULL, 16);
+ size = (unsigned int)simple_strtoul (argv[3], NULL, 16);
+ part = downloader_get_part_dl(par);
+ if(part == NULL)
+ {
+ sprintf(ack,"FAIL INVALID PARTITION TYPE");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+
+ if((read_boot_flashtype() == IF_TYPE_NOR)
+ && (strcmp((const char *)part->part_type,"nand") == 0))
+ {
+ ret = do_nor_write(part, par, offset,size);
+ return ret;
+ }
+
+ if(strcmp((const char *)part->part_type,"nand") == 0)
+ {
+ ret = do_nand_write(part, par, offset, size);
+ return ret;
+ }
+ else if (strcmp((const char *)part->part_type,"fs") == 0)
+ {
+ ret = do_yaffs_write(part, par, offset, size);
+ return ret;
+ }
+ else if (strcmp((const char *)part->part_type,"ddr") == 0)
+ {
+ ret = do_ram_write(offset, size);
+ return ret;
+ }
+ else if (strcmp((const char *)part->part_type,"raw") == 0)
+ {
+ ret = do_raw_write(offset, size);
+ return ret;
+ }
+ else
+ {
+ sprintf(ack,"FAIL INVALID PARTITION TYPE");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+}
+U_BOOT_CMD(
+ compat_write, CONFIG_SYS_MAXARGS, 0, do_compat_write,
+ "download: compat_write [partition][offset][size]",
+ ""
+);
+
+
+
+
+
+
+
+
+
+
+
diff --git a/boot/common/src/uboot/downloader/cmd_cp_reset.c b/boot/common/src/uboot/downloader/cmd_cp_reset.c
new file mode 100644
index 0000000..fc75ad8
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_cp_reset.c
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_cp_reset.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-4-22
+ * 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_nand.h"
+#include "downloader_config.h"
+#include "errno.h"
+#include <asm/io.h>
+
+/****************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+
+extern int downloader_serial_write(const char * buffer,unsigned int len);
+extern char *tsp_console_buffer;
+
+/*******************************************************************************
+ * Function:do_reboot
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_reboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ char *ack = tsp_console_buffer;
+ uint32_t reg_start = 0;
+
+ if(argc < 1)
+ {
+ return cmd_usage(cmdtp);
+ }
+
+ sprintf(ack,"OKAY REBOOT");
+ downloader_serial_write(ack, strlen(ack)+1);
+
+ run_command("reset",0);
+ return 0;
+}
+
+U_BOOT_CMD(
+ reboot, CONFIG_SYS_MAXARGS, 0, do_reboot,
+ "reboot: reboot",
+ ""
+);
+
+
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;
+
+}
+
+
+
diff --git a/boot/common/src/uboot/downloader/cmd_dl_nand.c b/boot/common/src/uboot/downloader/cmd_dl_nand.c
new file mode 100644
index 0000000..d4b0e04
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_dl_nand.c
@@ -0,0 +1,431 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_load_nand.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-3-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"
+
+extern partition_table_t * g_partition_table_dl;
+extern int downloader_readline (char * buffer);
+extern char *tsp_console_buffer;
+extern int crc_switch_flag;
+extern unsigned int null_slice_flag;
+
+
+/*******************************************************************************
+ * Function:do_nand_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_nand_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;
+ unsigned int read_buf_offset = 0;
+ unsigned long crc = 0;
+ int ret = 0;
+
+ //part = downloader_get_part(par);
+ 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_nand_erase(part,part->part_size);
+ if(ret)
+ {
+ sprintf(ack,"FAIL ERASE ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+
+ while(leftWriteLength>0)
+ {
+ curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
+
+ sprintf(ack,"DATA %08x",curWriteLength);
+ downloader_serial_write(ack, strlen(ack)+1);
+
+ downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength);
+
+ if(memcmp(par,"zloader",7) == 0) /* ÏÂÔØzloader·ÖÇø£¬Í¬Ê±ÏÂÔØ·ÖÇø±í */
+ {
+ memcpy((char *)(DOWNLOADER_BUFFER_BASE+8192),g_partition_table_dl,4096);
+ ret = downloader_nand_write(part, offset_par, 0x3000,
+ (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ }
+ else
+ {
+ ret = downloader_nand_write(part, offset_par, curWriteLength,
+ (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ }
+
+ if(ret)
+ {
+ sprintf(ack,"FAIL NAND 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;
+ }
+
+ if(crc_switch_flag == 0)
+ {
+ sprintf(ack,"OKAY");
+ downloader_serial_write(ack, strlen(ack)+1);
+ }
+ else
+ {
+ leftWriteLength = size;
+ offset_par = offset;
+
+ while(leftWriteLength>0)
+ {
+ curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
+
+ ret = downloader_nand_read(part, offset_par, curWriteLength,
+ (unsigned char *)(DOWNLOADER_BUFFER_BASE + read_buf_offset));
+ if(ret)
+ {
+ sprintf(ack,"FAIL NAND READ %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;
+ read_buf_offset += curWriteLength;
+ }
+
+ crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,size);
+ downloader_serial_write_actuallen((const char *)(&crc), 4);
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Function:do_nand_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_nand_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;
+ int ret = 0;
+
+
+ //part = downloader_get_part(par);
+ 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;
+
+ sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
+ 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 = downloader_nand_read(part, offset_par,
+ curReadLength,
+ (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ if(ret)
+ {
+ sprintf(ack,"FAIL NAND READ %d,%d, ret = %d",offset_par,curReadLength,ret);
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+
+ 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:do_nor_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_nor_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;
+ unsigned int read_buf_offset = 0;
+ unsigned long crc = 0;
+ int ret = 0;
+
+ //part = downloader_get_part(par);
+ 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;
+
+ if(null_slice_flag == 1)
+ {
+ ret = downloader_nor_erase(part,part->part_size);
+ if(ret)
+ {
+ sprintf(ack,"FAIL ERASE ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+ }
+
+ while(leftWriteLength>0)
+ {
+ curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
+
+ sprintf(ack,"DATA %08x",curWriteLength);
+ downloader_serial_write(ack, strlen(ack)+1);
+ downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, curWriteLength);
+
+ if(memcmp(par,"zloader",7) == 0) /* ÏÂÔØzloader·ÖÇø£¬Í¬Ê±ÏÂÔØ·ÖÇø±í */
+ {
+ memcpy((char *)(DOWNLOADER_BUFFER_BASE+8192),g_partition_table_dl,4096);
+ ret = downloader_nor_write( part, offset_par, 0x3000, (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ }
+ else
+ {
+ ret = downloader_nor_write( part, offset_par, curWriteLength, (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ }
+
+ if(ret)
+ {
+ sprintf(ack,"FAIL NAND 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;
+ }
+
+
+ if(crc_switch_flag == 0)
+ {
+ sprintf(ack,"OKAY");
+ downloader_serial_write(ack, strlen(ack)+1);
+ }
+ else
+ {
+ leftWriteLength = size;
+ offset_par = offset;
+ while(leftWriteLength>0)
+ {
+ curWriteLength = MIN(leftWriteLength,DOWNLOADER_BUFFER_SIZE);
+ ret = downloader_nor_read(part,
+ offset_par,
+ curWriteLength,
+ (unsigned char *)(DOWNLOADER_BUFFER_BASE + read_buf_offset));
+ if(ret)
+ {
+ sprintf(ack,"FAIL NAND READ %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;
+ read_buf_offset += curWriteLength;
+ }
+ crc = crc32(0,(unsigned char*)DOWNLOADER_BUFFER_BASE,size);
+ downloader_serial_write_actuallen((const char *)(&crc), 4);
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Function:do_nor_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_nor_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;
+ int ret = 0;
+
+
+ //part = downloader_get_part(par);
+ 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;
+ sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
+
+ 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 = downloader_nor_read( part, offset_par, curReadLength, (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ if(ret)
+ {
+ sprintf(ack,"FAIL NAND READ %d,%d, ret = %d",offset_par,curReadLength,ret);
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+ 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;
+ }
+}
+
+
diff --git a/boot/common/src/uboot/downloader/cmd_dl_ram.c b/boot/common/src/uboot/downloader/cmd_dl_ram.c
new file mode 100644
index 0000000..f1ac2c3
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_dl_ram.c
@@ -0,0 +1,174 @@
+
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_compat_write.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-3-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"
+
+extern int downloader_readline (char * buffer);
+extern char *tsp_console_buffer;
+/*******************************************************************************
+ * Function:do_ram_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_ram_write( unsigned int offset, unsigned int size)
+{
+ char *ack = tsp_console_buffer;
+ unsigned int addr = 0;
+ unsigned int leftWriteLength = 0;
+ unsigned int curWriteLength = 0;
+#ifdef CONFIG_LOAD_CRC
+ unsigned long crc = 0;
+ unsigned long crc1 = 0;
+#endif
+
+ addr = offset ;
+
+ if(size == 0)
+ {
+ sprintf(ack,"FAIL INVALID LENGTH");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL;
+ }
+ leftWriteLength = 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);
+ memcpy(( char *)addr,(char *)DOWNLOADER_BUFFER_BASE, curWriteLength+4 );
+
+
+ crc = crc32(0,(unsigned char*)addr,curWriteLength);
+ memcpy((unsigned char *)(&crc1),(unsigned char*)(addr+curWriteLength),4);
+ 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);
+ memcpy(( char *)addr,(char *)DOWNLOADER_BUFFER_BASE, curWriteLength );
+
+#endif
+ leftWriteLength -= curWriteLength;
+ addr += curWriteLength;
+ }
+
+ sprintf(ack,"OKAY");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return 0;
+
+}
+
+/*******************************************************************************
+ * Function:do_ram_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_ram_read(unsigned int offset, unsigned int size)
+{
+ char *rx_buffer = tsp_console_buffer;
+ char *ack = tsp_console_buffer;
+ unsigned int addr = 0;
+ unsigned int leftReadLength = 0;
+ unsigned int curReadLength = 0;
+
+ addr = offset ;
+
+
+ if((size == 0)||(size > CONFIG_SYS_SDRAM_SIZE))
+ {
+ sprintf(ack,"FAIL INVALID LENGTH");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL; /* Invalid argument */
+ }
+ leftReadLength = size;
+
+ sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
+ 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)
+ {
+ memcpy((char *)DOWNLOADER_BUFFER_BASE, (const char *)addr, curReadLength );
+ 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;
+ addr += 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 EBADRQC; /* Invalid request code */
+ }
+
+}
diff --git a/boot/common/src/uboot/downloader/cmd_dl_raw.c b/boot/common/src/uboot/downloader/cmd_dl_raw.c
new file mode 100644
index 0000000..eb42af5
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_dl_raw.c
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_dl_raw.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-6-9
+ * 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"
+
+extern int downloader_readline (char * buffer);
+extern char *tsp_console_buffer;
+
+/*******************************************************************************
+ * Function:do_raw_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_raw_write(unsigned int offset, unsigned int size)
+{
+ char *ack = tsp_console_buffer;
+ unsigned int leftWriteLength = 0;
+ unsigned int curWriteLength = 0;
+#ifdef CONFIG_LOAD_CRC
+ unsigned long crc = 0;
+ unsigned long crc1 = 0;
+#endif
+ int ret = 0;
+ nand_info_t *pNandInfo = NULL;
+ //struct erase_info instr;
+
+ pNandInfo = &nand_info[nand_curr_device];
+ assert(pNandInfo!=NULL);
+
+ leftWriteLength = size;
+
+ if((size==0)||(offset+size > pNandInfo->size))
+ {
+ sprintf(ack,"FAIL INVALID LENGTH");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL; /* Invalid argument */
+ }
+ ret = do_raw_erase(offset, size);
+ if(ret)
+ {
+ sprintf(ack,"FAIL ERASE ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+
+ 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
+ //printf("start to write\n");
+ ret = nand_write_skip_bad( pNandInfo, offset, &curWriteLength, (unsigned char *)DOWNLOADER_BUFFER_BASE,0);
+ if(ret)
+ {
+ sprintf(ack,"FAIL NAND WRITE %d,%d,ret = %d",offset,curWriteLength,ret);
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+ //printf("finish writing\n");
+ leftWriteLength -= curWriteLength;
+ offset += curWriteLength;
+ }
+ //printf("finish writing, leftlen = %d \n",leftWriteLength);
+ sprintf(ack,"OKAY");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return 0;
+
+
+
+}
+
+/*******************************************************************************
+ * Function:do_raw_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_raw_read(unsigned int offset, unsigned int size)
+{
+ char *rx_buffer = tsp_console_buffer;
+ char *ack = tsp_console_buffer;
+ unsigned int leftReadLength = 0;
+ unsigned int curReadLength = 0;
+ int ret = 0;
+ nand_info_t *pNandInfo = NULL;
+ //struct erase_info instr;
+
+ pNandInfo = &nand_info[nand_curr_device];
+ assert(pNandInfo!=NULL);
+
+ leftReadLength = size;
+ if((size==0)||(offset+size > pNandInfo->size))
+ {
+ sprintf(ack,"FAIL INVALID LENGTH");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL; /* Invalid argument */
+ }
+
+ sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
+ 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 = nand_read_skip_bad( pNandInfo, offset, &curReadLength, (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ if(ret)
+ {
+ sprintf(ack,"FAIL NAND READ %d,%d, ret = %d",offset,curReadLength,ret);
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+ //printf("start to upload LEN=%d \n",curReadLength);
+
+ 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 += 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;
+ }
+}
+
+int do_raw_erase(unsigned int offset, unsigned int partEraseSize)
+{
+ nand_info_t *pNandInfo = NULL;
+ struct erase_info instr;
+ unsigned int size = 0;
+ unsigned int ret = 0;
+
+ pNandInfo = &nand_info[nand_curr_device];
+ assert(pNandInfo!=NULL);
+ instr.mtd = pNandInfo;
+ instr.addr = offset;
+ assert( (instr.addr & (pNandInfo->erasesize - 1)) == 0);
+ instr.callback = 0;
+
+ while((size < partEraseSize) && (instr.addr < (offset+partEraseSize)))
+ {
+ if(nand_block_isbad (pNandInfo, instr.addr))
+ {
+ instr.addr += pNandInfo->erasesize;
+ continue ;
+ }
+ instr.len = pNandInfo->erasesize;
+ instr.state = 0;
+ ret = pNandInfo->erase(pNandInfo, &instr);
+ if(ret && instr.state == MTD_ERASE_FAILED)
+ {
+ pNandInfo->block_markbad(pNandInfo,instr.addr);
+ }
+ else if (ret == 0)
+ {
+ size += pNandInfo->erasesize;
+ }
+ else
+ {
+ printf( "downloader nand: erase error\n");
+ return 1;
+ }
+ instr.addr += pNandInfo->erasesize;
+ }
+ return 0;
+
+}
+
+
diff --git a/boot/common/src/uboot/downloader/cmd_dl_yaffs.c b/boot/common/src/uboot/downloader/cmd_dl_yaffs.c
new file mode 100644
index 0000000..c732457
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_dl_yaffs.c
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_compat_read.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-3-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"
+
+extern int downloader_readline (char * buffer);
+extern char *tsp_console_buffer;
+
+/*******************************************************************************
+ * Function:do_yaffs_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_yaffs_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;
+ unsigned int size_fs = 0;
+ unsigned int pagefullsize = 0;
+#ifdef CONFIG_LOAD_CRC
+ unsigned long crc = 0;
+ unsigned long crc1 = 0;
+#endif
+ int ret = 0;
+ nand_info_t *pNandInfo = NULL;
+
+ if(part == NULL)
+ {
+ sprintf(ack,"FAIL INVALID PARTITION");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL; /* Invalid argument */
+ }
+ pNandInfo = &nand_info[nand_curr_device];
+ assert(pNandInfo!=NULL);
+ pagefullsize=pNandInfo->writesize+pNandInfo->oobsize;
+ if((size==0)||(size>(part->part_size/pNandInfo->writesize)*pagefullsize))
+ {
+ sprintf(ack,"FAIL INVALID LENGTH");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL; /* Invalid argument */
+ }
+
+ leftWriteLength = size;
+ ret = downloader_nand_erase(part,part->part_size);
+ if(ret)
+ {
+ sprintf(ack,"FAIL ERASE ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+
+ 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);
+ 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
+ size_fs = (curWriteLength%pagefullsize)?(curWriteLength/pagefullsize+1)*(pagefullsize): curWriteLength;
+ if(curWriteLength<size_fs)
+ {
+ memset((char *)(DOWNLOADER_BUFFER_BASE+curWriteLength),0xff,size_fs-curWriteLength);
+ }
+ ret = downloader_nand_fs_write( part, offset_par, size_fs, (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ if(ret)
+ {
+ sprintf(ack,"FAIL YAFFS WRITE %d,%d",offset_par,size_fs);
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+ leftWriteLength -= curWriteLength;
+ offset_par += (curWriteLength/pagefullsize)*(pNandInfo->writesize);
+ }
+
+ sprintf(ack,"OKAY");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return 0;
+}
+
+
+
+/*******************************************************************************
+ * Function:do_yaffs_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_yaffs_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 size_fs = 0;
+ unsigned int pagefullsize = 0;
+ nand_info_t *pNandInfo = NULL;
+ unsigned int leftReadLength = 0;
+ unsigned int curReadLength = 0;
+ //unsigned long crc = 0;
+ int ret = 0;
+
+ 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 */
+ }
+ pNandInfo = &nand_info[nand_curr_device];
+ assert(pNandInfo!=NULL);
+ pagefullsize = pNandInfo->writesize+pNandInfo->oobsize;
+ leftReadLength = size;
+
+ sprintf(ack,"DATA %08x",MIN(size,DOWNLOADER_BUFFER_SIZE));
+ downloader_serial_write(ack, strlen(ack)+1);
+
+ while(leftReadLength>0)
+ {
+ curReadLength = MIN(leftReadLength,DOWNLOADER_BUFFER_SIZE);
+ size_fs = (curReadLength%pagefullsize)?(curReadLength/pagefullsize+1)*(pagefullsize): curReadLength;
+ downloader_readline(rx_buffer);
+ if(memcmp(rx_buffer,"OKAY",4)==0)
+ {
+ ret = downloader_nand_fs_read( part, offset_par, size_fs, (unsigned char *)DOWNLOADER_BUFFER_BASE);
+ if(ret)
+ {
+ sprintf(ack,"FAIL YAFFS READ %d,%d, ret = %d",offset_par,size_fs,ret);
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+ 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/pagefullsize)*(pNandInfo->writesize);
+ }
+ printf("prepare to receive OKAY");
+ 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 EBADRQC; /* Invalid request code */
+ }
+
+}
+
diff --git a/boot/common/src/uboot/downloader/cmd_downloader.c b/boot/common/src/uboot/downloader/cmd_downloader.c
new file mode 100644
index 0000000..9d0cbf4
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_downloader.c
@@ -0,0 +1,229 @@
+/*
+ ******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: geanfeng
+ * Date: 2013-3-4
+ * History 1:
+ * Date:
+ * Version:
+ * Author:
+ * Modification:
+ * History 2:
+ *******************************************************************************
+ */
+
+/*
+ ***************************************************************************
+ * Include files
+ ***************************************************************************
+ */
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include "downloader_serial.h"
+#include "partition_table.h"
+
+
+/****************************************************************************
+* Local Macros
+****************************************************************************/
+#define TSP_DOWNLOADER_CBSIZE 256
+
+/****************************************************************************
+* Local Types
+****************************************************************************/
+
+/****************************************************************************
+* Global Variables
+****************************************************************************/
+//char tsp_console_buffer[TSP_DOWNLOADER_CBSIZE + 1]; /* downloader I/O buffer */
+ char *tsp_console_buffer = (char*)(CONFIG_NAND_DMA_BUF_ADDR+0x4000);
+
+unsigned int null_slice_flag = 0;
+
+
+/****************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+extern void downloader_serial_init(void);
+extern int UART_CmdRead(char *pchBuf, int dwLen);
+
+/****************************************************************************
+* Function Definitions
+****************************************************************************/
+/*******************************************************************************
+ * Function:downloader_readline_into_buffer
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_readline_into_buffer (char * buffer)
+{
+ char * p_buf = buffer;
+ unsigned int retSize = 0;
+ unsigned int recvSize = 0;
+
+ while(1)
+ {
+#if CONFIG_USB_DL
+ retSize = downloader_serial_read(p_buf,512);
+#else
+ retSize = UART_CmdRead(p_buf,512);
+#endif
+ if(retSize<=0)
+ {
+ continue;
+ }
+ recvSize += retSize;
+ if(recvSize >= TSP_DOWNLOADER_CBSIZE)
+ {
+ recvSize = 0;
+ p_buf = buffer;
+ }
+ if(buffer[0] == 0x5a) /*filter syc 0x5a*/
+ {
+ printf("readline filter syc 0x5a\n");
+ recvSize = 0;
+ continue;
+ }
+
+ switch(p_buf[retSize-1])
+ {
+ case '\r': /*Enter */
+ case '\n':
+ case '\0':
+ while(retSize>0)
+ {
+ if( (p_buf[retSize-1] >='a' && p_buf[retSize-1]<='z') ||\
+ (p_buf[retSize-1] >='A' && p_buf[retSize-1]<='Z') || \
+ (p_buf[retSize-1] >='0' && p_buf[retSize-1]<='9') ) /*filter invalid character*/
+ {
+ break;
+ }
+ retSize--;
+ }
+ p_buf[retSize]='\0';
+ return 0;
+ default:
+ p_buf += retSize;
+ continue;
+ }
+
+ }
+
+ return 0;
+}
+/*******************************************************************************
+ * Function:downloader_readline
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_readline (char * buffer)
+{
+ /*
+ * If console_buffer isn't 0-length the user will be prompted to modify
+ * it instead of entering it from scratch as desired.
+ */
+ buffer[0] = '\0';
+
+ return downloader_readline_into_buffer(buffer);
+}
+
+/*******************************************************************************
+ * Function:do_downloader
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_downloader(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ret = 0;
+ int type = 0;
+ char ack[20] = {0};
+ printf( "[sys_entry]: do downloader\n");
+
+ ret = read_partition_and_check();
+ if( ret != 0 )
+ {
+ printf( "[sys_entry]: read_partition error...\n");
+ }
+
+ type = read_boot_flashtype();
+ if(type == IF_TYPE_NOR)
+ {
+ ret = get_nor_null_slice_flag(&null_slice_flag);
+ if(ret)
+ {
+ printf ("nor flash read null_slice_flag error.\n");
+ return 1;
+ }
+ }
+
+ downloader_serial_init();
+ printf ("### downloader : serial init success \n");
+
+ /*sync*/
+ while(1)
+ {
+#if CONFIG_USB_DL
+ downloader_serial_read(tsp_console_buffer,512);
+#else
+ downloader_serial_read(tsp_console_buffer,1);
+#endif
+ if(tsp_console_buffer[0]==0x5a)
+ {
+ tsp_console_buffer[0]=0xa7; /*ack*/
+ downloader_serial_write(tsp_console_buffer,1);
+ break;
+ }
+ }
+
+ /*run commands*/
+ while(1)
+ {
+ downloader_readline(tsp_console_buffer);
+ ret = run_command (tsp_console_buffer, 0);
+ if(ret == -2)
+ {
+ sprintf(ack,"UNKNOWN COMMAND");
+ downloader_serial_write(ack, strlen(ack)+1);
+ }
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ downloader, 1, 0, do_downloader,
+ "Perform ZIXC TSP downloader",
+ ""
+);
+
diff --git a/boot/common/src/uboot/downloader/cmd_efuse_program.c b/boot/common/src/uboot/downloader/cmd_efuse_program.c
new file mode 100644
index 0000000..abe9532
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_efuse_program.c
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_efuse_program.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zhangdongdong
+ * Date: 2013-3-13
+ * History 1:
+ * Date:
+ * Version:
+ * Author:
+ * Modification:
+ * History 2:
+ ********************************************************************************/
+
+
+/****************************************************************************
+* Include files
+****************************************************************************/
+#include <common.h>
+#include <command.h>
+#include "downloader_config.h"
+#include "downloader_nand.h"
+#include "downloader_serial.h"
+#include <secure_verify.h>
+#include <asm/arch/efuse.h>
+
+/*
+*******************************************************************
+* Macro define
+*******************************************************************
+*/
+#define BOARD_TYPE_ZX297520V3 0x0
+#define BOARD_TYPE_ZX297520V3E32M 0x1
+#define BOARD_TYPE_ZX297520V3E64M 0x2
+#define BOARD_TYPE_ZX297520V3E256M 0x3
+
+#define BOARD_TYPE_UNKNOWN 0xFF
+
+
+/****************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+extern char *tsp_console_buffer;
+
+/*******************************************************************************
+ * Function:do_efuse_program
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int do_efuse_program(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ char *cmd = NULL;
+ unsigned int secure_en = 0;
+ unsigned int chip_flag = 0;
+ unsigned int puk_hash[4] = {0};
+
+ if(argc<6)
+ {
+ printf("invalid parameter\n");
+ return cmd_usage(cmdtp);
+ }
+
+ cmd = argv[1];
+
+ if (strcmp(cmd, "secure_en") == 0)
+ {
+ printf("argv2 = %4s\n",argv[2]);
+ if(strcmp(argv[2], "enable") == 0)
+ efuse_program_secure_en(1);
+ else if(strcmp(argv[2], "disable") == 0)
+ efuse_program_secure_en(0);
+ else
+ return -1;
+
+ return 0;
+ }
+
+ if (strcmp(cmd, "chip_flag") == 0)
+ {
+ chip_flag = (unsigned int)simple_strtoul (argv[2], NULL, 16);
+ printf("efuse chip_flag=0x%x\n",chip_flag);
+ efuse_program_chip_flag(chip_flag);
+
+ return 0;
+ }
+
+ if (strcmp(cmd, "puk_hash") == 0)
+ {
+ puk_hash[0] = (unsigned int)simple_strtoul (argv[2], NULL, 16);
+ puk_hash[1] = (unsigned int)simple_strtoul (argv[3], NULL, 16);
+ puk_hash[2] = (unsigned int)simple_strtoul (argv[4], NULL, 16);
+ puk_hash[3] = (unsigned int)simple_strtoul (argv[5], NULL, 16);
+ printf("efuse puk hash0=0x%x, hash1=0x%x, hash2=0x%x, hash3=0x%x\n",puk_hash[0],puk_hash[1],puk_hash[2],puk_hash[3]);
+ efuse_program_puk_hash(puk_hash);
+ return 0;
+ }
+
+ return -1;
+}
+
+
+/*******************************************************************************
+ * Function:do_efuse_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ int do_efuse_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ char *cmd = NULL;
+ char *rx_buffer = tsp_console_buffer;
+ char *ack = tsp_console_buffer;
+ efuse_struct efuse_info ={0};
+ unsigned int dev_id[3] = {0};
+
+
+ if(argc < 2)
+ {
+ printf("invalid read parameter\n");
+ return cmd_usage(cmdtp);
+ }
+
+ cmd = argv[1];
+
+ efuse_get_devinfo(&efuse_info);
+
+ if (strcmp(cmd, "dev_id") == 0)
+ {
+
+ dev_id[0] = efuse_info.dev_id[0];
+ dev_id[1] = efuse_info.dev_id[1];
+ dev_id[2] = efuse_info.dev_id[2];
+
+ sprintf(ack,"dev_id:");
+ downloader_serial_write(ack, strlen(ack)+1);
+
+ memcpy((unsigned char*)(DOWNLOADER_BUFFER_BASE),(unsigned char *)(dev_id),12);
+ downloader_serial_write_actuallen((const char *)DOWNLOADER_BUFFER_BASE, 12);
+
+ printf("devid:[id0] =0x%x, [id1]=0x%x, [id2] =0x%x\n",dev_id[0],dev_id[1],dev_id[2]);
+
+ downloader_readline(rx_buffer);
+ if(memcmp(rx_buffer,"OKAY",4)==0)
+ {
+ sprintf(ack,"DEVID SUCCESS");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return 0;
+ }
+ }
+
+ sprintf(ack,"FAIL COMMAND ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+}
+
+
+U_BOOT_CMD(
+ efuse_program, CONFIG_SYS_MAXARGS, 0, do_efuse_program,
+ "efuse_program: program [puk_hash/secure_en/chip_flag] [hash0/enable/SPE][hash1][hash2][hash3]",
+ ""
+);
+
+U_BOOT_CMD(
+ efuse_read, CONFIG_SYS_MAXARGS, 0, do_efuse_read,
+ "efuse_read: read [devid]",
+ ""
+);
+
+/*
+ ******************************************************************************
+ * Function:do_read_board_type
+ * Description:
+ * Parameters:
+ * Input:
+ * Output:
+ * Returns:
+ * Others:
+ *******************************************************************************
+ */
+ int do_read_board_type(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ char *ack = tsp_console_buffer;
+ efuse_struct efuse_info ={0};
+ unsigned int secure_flag = 0;
+ unsigned int chip_flag = 0;
+ unsigned int board_type = 0;
+
+ if(argc != 1)
+ {
+ return cmd_usage(cmdtp);
+ }
+
+ efuse_get_devinfo(&efuse_info);
+
+ secure_flag = efuse_info.secure_flag;
+ chip_flag = secure_flag >> 8;
+ if((chip_flag == ZX297520V3_GW_NYB_1G_DDR)
+ ||(chip_flag == ZX297520V3_GW_NYC_1G_DDR)
+ ||(chip_flag == ZX297520V3ECO_GW_NYB_1G_DDR)
+ ||(chip_flag == ZX297520V3ECO_GW_NYC_1G_DDR)
+ ||(chip_flag == ZX297520V3SC_GW_NYC_1G_DDR)
+ ||(chip_flag == ZX297520V3ECOSCC_GW_UNILC_1G_DDR)
+ ||(chip_flag == ZX297520V3ECOSCC_GW_NYC_1G_DDR)
+ ||(chip_flag == ZX297520V3ECOSC_GW_NYC_1G_DDR)
+ ||(chip_flag == ZX297520V3ECOSC_GW_UNILC_1G_DDR)
+ ||(chip_flag == ZX297520V3_ZW_NYB_1G_DDR)
+ ||(chip_flag == ZX297520V3_ZW_NYC_1G_DDR)
+ ||(chip_flag == ZX297520V3ECO_ZW_NYB_1G_DDR)
+ ||(chip_flag == ZX297520V3ECO_ZW_NYC_1G_DDR))
+ {
+ printf("chip_flag=0x%x board_type is V3.\n", chip_flag);
+ board_type = BOARD_TYPE_ZX297520V3;
+ }
+ else if((chip_flag == ZX297520V3ECO_GW_UNILC_512M_DDR)
+ ||(chip_flag == ZX297520V3ECO_GW_APM_512M_DDR)
+ ||(chip_flag == ZX297520V3ECO_GW_ESMT_512M_DDR)
+ ||(chip_flag == ZX297520V3ECO_ZW_UNILC_512M_DDR)
+ ||(chip_flag == ZX297520V3ECO_AZW_UNILC_512M_DDR)
+ ||(chip_flag == ZX297520V3ECO_ZW_APM_512M_DDR)
+ ||(chip_flag == ZX297520V3ECO_ZW_ESMT_512M_DDR))
+ {
+ printf("chip_flag=0x%x board_type is V3E.\n", chip_flag);
+ board_type = BOARD_TYPE_ZX297520V3E64M;
+ }
+ else if(chip_flag == ZX297520V3ECOSC_GW_NYC_2G_DDR)
+ {
+ printf("chip_flag=0x%x board_type is V3E.\n", chip_flag);
+ board_type = BOARD_TYPE_ZX297520V3E256M;
+ }
+ else if((chip_flag == ZX297520V3ECO_GW_WINBD_256M_DDR)
+ ||(chip_flag == ZX297520V3ECO_GW_UNILC_256M_DDR)
+ ||(chip_flag == ZX297520V3ECO_GW_APM_256M_DDR)
+ ||(chip_flag == ZX297520V3ECO_ZW_WINBD_256M_DDR)
+ ||(chip_flag == ZX297520V3ECO_ZW_UNILC_256M_DDR)
+ ||(chip_flag == ZX297520V3ECO_ZW_APM_256M_DDR))
+ {
+ printf("chip_flag=0x%x board_type is V3T.\n", chip_flag);
+ board_type = BOARD_TYPE_ZX297520V3E32M;
+ }
+ else
+ {
+ printf("chip_flag=0x%x board_type is unknown.\n", chip_flag);
+ board_type = BOARD_TYPE_UNKNOWN;
+ }
+
+ sprintf(ack,"%04x", board_type);
+ downloader_serial_write(ack, strlen(ack)+1);
+ return 0;
+}
+
+U_BOOT_CMD(
+ read_board_type, CONFIG_SYS_MAXARGS, 0, do_read_board_type,
+ "read board type.",
+ ""
+);
+
diff --git a/boot/common/src/uboot/downloader/cmd_erase.c b/boot/common/src/uboot/downloader/cmd_erase.c
new file mode 100644
index 0000000..7d68e95
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_erase.c
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_erase.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-3-15
+ * 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"
+
+/****************************************************************************
+* Function Definitions
+****************************************************************************/
+
+extern partition_table_t * g_partition_table;
+extern char *tsp_console_buffer;
+
+
+/*******************************************************************************
+ * Function:do_erase
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_erase(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ partition_entry_t *part = NULL;
+ char *par=NULL;
+ char *ack=tsp_console_buffer;
+ int ret = 0;
+ int type = 0;
+
+ if(argc<2)
+ {
+ return cmd_usage(cmdtp);
+ }
+ type = read_boot_flashtype();
+ par = argv[1]; /*erase cmd*/
+ if((strcmp(par,"all") == 0) || (strcmp(par,"raw") == 0))
+ {
+ if((type == IF_TYPE_NAND)||(type == IF_TYPE_SPI_NAND))
+ {
+ ret = downloader_nand_eraseall();
+ }
+ else if(type == IF_TYPE_NOR)
+ {
+ ret = downloader_nor_eraseall();
+ }
+
+ if(ret == 0)
+ {
+ sprintf(ack,"OKAY");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return 0;
+ }
+ else
+ {
+ sprintf(ack,"FAIL NAND ERASE");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+ }
+
+ if(strcmp(par,"auto") == 0)
+ {
+ if((type == IF_TYPE_NAND)||(type == IF_TYPE_SPI_NAND))
+ {
+ ret = downloader_nand_erase_auto();
+ }
+ else if(type == IF_TYPE_NOR)
+ {
+ ret = downloader_nor_erase_auto();
+ }
+
+ if(ret == 0)
+ {
+ sprintf(ack,"OKAY");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return 0;
+ }
+ else
+ {
+ sprintf(ack,"FAIL NAND ERASE");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+ }
+
+ part = downloader_get_part(par);
+ if(part == NULL)
+ {
+ sprintf(ack,"FAIL INVALID PARTITION");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EINVAL; /* Invalid argument */
+ }
+
+ if((type == IF_TYPE_NAND)||(type == IF_TYPE_SPI_NAND))
+ {
+ ret = downloader_nand_erase(part,part->part_size);
+ }
+ else if(type == IF_TYPE_NOR)
+ {
+ ret = downloader_nor_erase(part, part->part_size);
+ }
+
+
+ if(ret == 0)
+ {
+ sprintf(ack,"OKAY");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return 0;
+ }
+ else
+ {
+ sprintf(ack,"FAIL NAND ERASE");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return ENOSYS; /* Function not implemented */
+ }
+}
+
+U_BOOT_CMD(
+ erase, CONFIG_SYS_MAXARGS, 0, do_erase,
+ "Erase nand: erase [partition]",
+ ""
+);
+
+
diff --git a/boot/common/src/uboot/downloader/cmd_getvar.c b/boot/common/src/uboot/downloader/cmd_getvar.c
new file mode 100644
index 0000000..72622b6
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_getvar.c
@@ -0,0 +1,411 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name: cmd_getvar.c
+ * File Mark:
+ * Description: get information such as IMEI,SN,NV CONFIG from UE.
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-3-6
+ * History 1:
+ * Date: 2013-11-6
+ * Version:
+ * Author:
+ * Modification: mod for after-sale tool
+ * History 2:
+ ********************************************************************************/
+/****************************************************************************
+* Include files
+****************************************************************************/
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include "downloader_serial.h"
+#include <jffs2/load_kernel.h>
+#include "downloader_nand.h"
+#include "errno.h"
+
+extern char *tsp_console_buffer;
+
+/****************************************************************************
+* Local Macros
+****************************************************************************/
+
+/*NVR AMT LENGTH*/
+#define ZPS_ImeiLen 20
+#define ZPS_ImeiSvLen 20
+#define ZPS_DEV_MSINFO_MAX_BORDNAME_LEN 20
+#define ZPS_DEV_MSINFO_MAX_MSerialNum_LEN 20
+#define ZPS_DEV_MSINFO_MAX_ValidFlag_LEN 4
+#define ZPS_DEV_MSINFO_MAX_InternalMAC_LEN 20
+#define ZPS_DEV_MSINFO_MAX_ExternalMAC_LEN 20
+#define ZPS_DEV_MSINFO_MAX_WIFIMAC_LEN 20
+#define ZPS_DEV_MSINFO_MAX_NvVersion_LEN 40
+#define ZPS_DEV_MSINFO_MAX_TestInfo_LEN 200
+#define ZPS_DEV_MSINFO_MAX_SOFTVERSION_LEN 10
+#define ZPS_NVR_LEN 394
+
+/*NVRW AMT LENGTH*/
+#define SoftVersion_LEN 10
+#define Register_LEN 77
+#define Bflag_LEN 1
+#define Reserve_LEN 40
+#define AfterSaleVersion_LEN 670
+#define InerVersion_LEN 100
+#define ExVersion_LEN 100
+#define HWVersion_LEN 100
+#define PCUIVersion_LEN 100
+#define InerMdelNum_LEN 32
+#define ExModelNum_LEN 32
+#define ModemVersion_LEN 100
+#define ZPS_NVRW_LEN 1362
+
+/****************************************************************************
+* Local Types
+****************************************************************************/
+typedef struct
+{
+ unsigned int nvID; /*NV file ID */
+ unsigned char nvPart[4]; /* NV partition name,nvr or nvrw */
+ unsigned int addr; /*NV file address */
+ unsigned int size; /*NV file size*/
+}Tsp_Nv_Config_Item; /*NV CONFIG ITEM*/
+
+#define TSP_NV_COUNT 7
+Tsp_Nv_Config_Item tspNvConfig[TSP_NV_COUNT]=
+{
+{0,"nvro",0x0,16384},
+{1,"nvro",0x4000,98304},
+{2,"nvro",0x1c000,32768},
+{3,"nvro",0x24000,16384},
+{4,"nvro",0x28000,32768},
+{5,"nvro",0x30000,32768},
+{6,"nvro",0x38000,32768},
+};
+
+
+typedef struct getvar_info_nvr
+{
+
+ /********************************************************************************
+ ¹¦ÄÜ£º Ó²¼þÉ豸ºÅ
+ ȡֵ·¶Î§£ºIMEIÖÐÿһ¸öBCDÂ뷶ΧΪ0-9
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ *********************************************************************************/
+ unsigned char abImei[ZPS_ImeiLen];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º Èí¼þ°æ±¾ºÅ
+ ȡֵ·¶Î§£ºIMEISVÖÐÿһ¸öBCDÂ뷶ΧΪ0-9
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ *********************************************************************************/
+ unsigned char abImeiSv[ZPS_ImeiSvLen];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º Ö÷°åºÅ£¬ÓÉBCDÂë×é³É
+ ȡֵ·¶Î§£ºÖ÷°åºÅÖÐÿһ¸öBCDÂ뷶ΧΪ0-9
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ *********************************************************************************/
+ unsigned char abBordNum[ZPS_DEV_MSINFO_MAX_BORDNAME_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º
+ ȡֵ·¶Î§£ºÈÎÒâ×Ö·û´®,ÒÔ'\0'±íʾ½áÊø
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ *********************************************************************************/
+ unsigned char abMSerialNum[ZPS_DEV_MSINFO_MAX_MSerialNum_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º MACµØÖ·Ñ¡Ôñ±ê־λ
+ ȡֵ·¶Î§£º0x30»òÕß0x31£¬Ä¬ÈÏΪ0x30
+ ³ö³§Öµ£º0x30
+ *********************************************************************************/
+ unsigned char abValidFlag[ZPS_DEV_MSINFO_MAX_ValidFlag_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º ÄÚ²¿MAC µØÖ·
+ ȡֵ·¶Î§£ºBCDÂë
+ ³ö³§Öµ£ºÓÉ´ó°æ±¾Ê×´ÎÆô¶¯Ê±Ð´Èë
+ *********************************************************************************/
+ unsigned char abInternalMAC[ZPS_DEV_MSINFO_MAX_InternalMAC_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º ÍⲿMAC µØÖ·
+ ȡֵ·¶Î§£ºBCDÂë
+ ³ö³§Öµ£ºÓÉ´ó°æ±¾Ê×´ÎÆô¶¯Ê±Ð´Èë
+ *********************************************************************************/
+ unsigned char abExternalMAX[ZPS_DEV_MSINFO_MAX_ExternalMAC_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º WIFI MACµØÖ·
+ ȡֵ·¶Î§£ºBCDÂë
+ ³ö³§Öµ£ºÓÉ´ó°æ±¾Ê×´ÎÆô¶¯Ê±Ð´Èë
+ *********************************************************************************/
+ unsigned char abWiFiMAC[ZPS_DEV_MSINFO_MAX_WIFIMAC_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º ָʾNV°æ±¾
+ ȡֵ·¶Î§£º¿É¼ûASCIIÂë×Ö·û£¬ÒÔ×Ö·û'\0'½áÊø£¬Ê£Óà×Ö½ÚÌî³ä0x00
+ ³ö³§Öµ£ºÓÉ´ó°æ±¾Ê×´ÎÆô¶¯Ê±Ð´Èë
+ *********************************************************************************/
+ unsigned char abNVVersion[ZPS_DEV_MSINFO_MAX_NvVersion_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º Éú²ú²âÊÔ±ê־λ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓÉ´ó°æ±¾Ê×´ÎÆô¶¯Ê±Ð´Èë
+ *********************************************************************************/
+ unsigned char abTestInfo[ZPS_DEV_MSINFO_MAX_TestInfo_LEN];
+
+}getvar_info_nvr_t;
+
+typedef struct getvar_info_nvrw
+{
+
+ /********************************************************************************
+ ¹¦ÄÜ£º Èí¼þ°æ±¾ºÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ *********************************************************************************/
+ unsigned char SoftVersion[SoftVersion_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º ×Ô×¢²áÐÅÏ¢
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ *********************************************************************************/
+ unsigned char Register[Register_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º BFLAGСϵͳÆô¶¯Ä£Ê½ÐÅÏ¢
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char Bflag[Bflag_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º ±£Áô
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char Reserve[Reserve_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º ÊÛºó°æ±¾¿ØÖÆ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char AfterSaleVersion[AfterSaleVersion_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£º ÄÚ²¿°æ±¾ºÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char InerVersion[InerVersion_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£ºÍⲿ°æ±¾ºÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char ExVersion[ExVersion_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£ºÓ²¼þ°æ±¾ºÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char HWVersion[HWVersion_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£ºPCUI °æ±¾ºÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char PCUIVersion[PCUIVersion_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£ºÄÚ²¿ÐͺÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char InerMdelNum[InerMdelNum_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£ºÍⲿÐͺÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char ExModelNum[ExModelNum_LEN];
+
+ /********************************************************************************
+ ¹¦ÄÜ£ºMODEM°æ±¾ºÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char ModemVersion[ModemVersion_LEN];
+}getvar_info_nvrw_t;
+
+typedef struct getvar_info_dl
+{
+ unsigned char abImei[ZPS_ImeiLen];
+ /********************************************************************************
+ ¹¦ÄÜ£º Ó²¼þÉ豸ºÅ
+ ȡֵ·¶Î§£ºIMEIÖÐÿһ¸öBCDÂ뷶ΧΪ0-9
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ *********************************************************************************/
+ unsigned char abBordNum[ZPS_DEV_MSINFO_MAX_BORDNAME_LEN];
+ /********************************************************************************
+ ¹¦ÄÜ£º Ö÷°åºÅ£¬ÓÉBCDÂë×é³É
+ ȡֵ·¶Î§£ºÖ÷°åºÅÖÐÿһ¸öBCDÂ뷶ΧΪ0-9
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ *********************************************************************************/
+ unsigned char InerVersion[InerVersion_LEN];
+ /********************************************************************************
+ ¹¦ÄÜ£º ÄÚ²¿°æ±¾ºÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char ExVersion[ExVersion_LEN];
+ /********************************************************************************
+ ¹¦ÄÜ£ºÍⲿ°æ±¾ºÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+ unsigned char InerMdelNum[InerMdelNum_LEN];
+ /********************************************************************************
+ ¹¦ÄÜ£ºÄÚ²¿ÐͺÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+
+ unsigned char ExModelNum[ExModelNum_LEN];
+ /********************************************************************************
+ ¹¦ÄÜ£ºÍⲿÐͺÅ
+ ȡֵ·¶Î§£º
+ ³ö³§Öµ£ºÓɳö²ú³§É̾ö¶¨
+ ********************************************************************************/
+
+}getvar_info_dl_t;
+
+/*******************************************************************************
+ * Function:do_getvar
+ * Description:Sending UE information to After_sale update toll.
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:0 :success;
+ * -1:fail;
+ *
+ * Others:
+ ********************************************************************************/
+int do_getvar(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+#if 0 //hsy
+ char *ack = NULL;
+ char *cmd = NULL;
+ int ret = 0;
+ partition_entry_t *part = NULL;
+ getvar_info_nvr_t *info_nvr = NULL;
+ getvar_info_nvrw_t *info_nvrw = NULL;
+ getvar_info_dl_t *info_dl = NULL;
+
+ char *data_nvr = kzalloc(ZPS_NVR_LEN, GFP_KERNEL);
+ char *data_nvrw = kzalloc(ZPS_NVRW_LEN, GFP_KERNEL);
+ ack = tsp_console_buffer;
+ info_dl = kzalloc(4096, GFP_KERNEL);
+ cmd = argv[1];
+ if (argc < 2)
+ {
+ return cmd_usage(cmdtp);
+ }
+ part = downloader_get_part("nvro"); /*NVR READ*/
+ ret = downloader_zftl_read( part, 0, ZPS_NVR_LEN, (unsigned char *)data_nvr);
+
+ part = downloader_get_part("nvrw"); /*NVRW READ*/
+ ret = downloader_zftl_read( part, 0, ZPS_NVRW_LEN, (unsigned char *)data_nvrw);
+ if(ret)
+ {
+ sprintf(ack,"FAIL ZFTL READ ");
+ downloader_serial_write(ack, strlen(ack)+1);
+ kfree(data_nvr);
+ kfree(data_nvrw);
+ kfree(info_dl);
+ return ENOSYS; /* Function not implemented */
+ }
+ info_nvr = (getvar_info_nvr_t *)data_nvr;
+ info_nvrw = (getvar_info_nvrw_t *)data_nvrw;
+
+ memcpy(info_dl->abImei,info_nvr->abImei,ZPS_ImeiLen); /*copy information from NV*/
+ memcpy(info_dl->abBordNum,info_nvr->abBordNum,ZPS_DEV_MSINFO_MAX_BORDNAME_LEN);
+ memcpy(info_dl->InerVersion,info_nvrw->InerVersion,InerVersion_LEN);
+ memcpy(info_dl->ExVersion,info_nvrw->ExVersion,ExVersion_LEN);
+ memcpy(info_dl->InerMdelNum,info_nvrw->InerMdelNum,InerMdelNum_LEN);
+ memcpy(info_dl->ExModelNum,info_nvrw->ExModelNum,ExModelNum_LEN);
+
+ if(strcmp(cmd,"version") == 0)
+ {
+ sprintf(ack,"DATA %08x",sizeof(getvar_info_dl_t));
+ downloader_serial_write(ack, strlen(ack)+1); /* send length info*/
+
+ downloader_readline(tsp_console_buffer);
+ if(memcmp(tsp_console_buffer,"OKAY",4)==0) /* receive OKAY*/
+ {
+ memcpy(ack,info_dl,sizeof(getvar_info_dl_t)); /* send information*/
+ downloader_serial_write_actuallen(ack,sizeof(getvar_info_dl_t));
+ }
+ else
+ {
+ sprintf(ack,"FAIL COMMAND ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EBADRQC; /* Invalid request code */
+ }
+ }
+
+ else if(strcmp(cmd,"nv")== 0)
+ {
+ sprintf(ack,"DATA %08x",sizeof(tspNvConfig)+1);
+ downloader_serial_write(ack, strlen(ack)+1); /* send length info*/
+
+ downloader_readline(tsp_console_buffer);
+ if(memcmp(tsp_console_buffer,"OKAY",4)==0) /* receive OKAY*/
+ {
+ ack[0] = TSP_NV_COUNT;
+ memcpy(&ack[1],&tspNvConfig,sizeof(tspNvConfig)); /* send nv config*/
+ downloader_serial_write_actuallen(ack,sizeof(tspNvConfig)+1);
+ }
+ else
+ {
+ sprintf(ack,"FAIL COMMAND ERROR");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return EBADRQC; /* Invalid request code */
+ }
+ }
+ else
+ {
+ sprintf(ack,"FAIL NOINFORMATION");
+ downloader_serial_write(ack,strlen(ack)+1);
+ kfree(data_nvr);
+ kfree(data_nvrw);
+ kfree(info_dl);
+ return -1;
+ }
+ kfree(data_nvr);
+ kfree(data_nvrw);
+ kfree(info_dl);
+#endif
+
+ return 0;
+}
+U_BOOT_CMD(
+ getvar, CONFIG_SYS_MAXARGS, 0, do_getvar,
+ "Downloader get information: getvar [info]",
+ ""
+);
+
+
+
diff --git a/boot/common/src/uboot/downloader/cmd_ram_start.c b/boot/common/src/uboot/downloader/cmd_ram_start.c
new file mode 100644
index 0000000..598182b
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_ram_start.c
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_ram_start.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-4-22
+ * 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_nand.h"
+#include "downloader_config.h"
+#include "downloader_serial.h"
+#include <asm/arch/cpu.h>
+#include <asm/io.h>
+
+
+static is_flush = 0;
+extern char *tsp_console_buffer;
+extern uint32_t arm_ps_ep;
+/****************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+int start_core(uchar *core_name, unsigned int addr);
+
+
+/*******************************************************************************
+ * Function:do_ram_start
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_ram_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ char *ack = tsp_console_buffer;
+ unsigned int i = 0;
+ unsigned int addr = 0;
+
+ if(argc < 1)
+ {
+ return cmd_usage(cmdtp);
+ }
+
+ sprintf(ack,"OKAY ram_start");
+ downloader_serial_write(ack, strlen(ack)+1);
+ for(i=1; i<argc; i=i+2)
+ {
+ addr = (unsigned int)simple_strtoul (argv[i+1], NULL, 16);
+ printf("core is %s, addr is %x\n",(uchar *)argv[i],addr);
+ start_core((uchar *)argv[i], addr);
+ }
+ hang();
+ return 0;
+}
+
+U_BOOT_CMD(
+ ram_start, CONFIG_SYS_MAXARGS, 0, do_ram_start,
+ "ram_start: ram_start",
+ ""
+);
+
+ int start_core(uchar *core_name, unsigned int addr)
+{
+ char *ack = tsp_console_buffer;
+
+ if(strcmp((const char *)core_name,"ps") == 0)
+ {
+ if(addr != 0xffffffff)
+ {
+ /* д PS Ìø×ªÆô¶¯´úÂë */
+
+ /* flush d-cache */
+ if( is_flush != 1 )
+ {
+ is_flush = 1;
+ cleanup_before_linux();
+ }
+ arm_ps_ep = addr;
+ /* ÊÍ·ÅÆô¶¯ ARM_PS */
+ printf("Starting the arm_ps ...\n");
+ start_arm_ps();
+ }
+ else
+ {
+ printf("No Starting the arm_ps ...\n");
+ }
+ }
+ else if (strcmp((const char *)core_name,"phy") == 0)
+ {
+ if(addr != 0xffffffff)
+ {
+ /* д PHY Ìø×ªÆô¶¯´úÂë */
+
+ /* flush d-cache */
+ /*if( is_flush != 1 )
+ {
+ is_flush = 1;
+ cleanup_before_linux();
+ }*/
+ //load_zsp_image(addr);
+ /* ÊÍ·ÅÆô¶¯ ARM_PHY */
+
+ printf("Starting the arm_phy ...\n");
+ }
+ else
+ {
+ printf("No Starting the arm_phy ...\n");
+ }
+ }
+ else
+ {
+ sprintf(ack,"FAIL INVILID CORE NAME");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+ return 0;
+}
+
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]",
+ ""
+);
diff --git a/boot/common/src/uboot/downloader/cmd_testusb.c b/boot/common/src/uboot/downloader/cmd_testusb.c
new file mode 100644
index 0000000..921a66d5f1
--- /dev/null
+++ b/boot/common/src/uboot/downloader/cmd_testusb.c
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:cmd_testusb.c
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: zangxiaofeng
+ * Date: 2013-4-22
+ * 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_nand.h"
+#include "downloader_config.h"
+#include "errno.h"
+/****************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+extern int downloader_serial_write(const char * buffer,unsigned int len);
+extern int downloader_serial_read_actuallen(char * buffer,unsigned int len);
+
+/*******************************************************************************
+ * Function:do_reboot
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int do_testusb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ unsigned int size = 0;
+ char ack[64] = {0};
+
+ if(argc < 2)
+ {
+ return cmd_usage(cmdtp);
+ }
+ size = (unsigned int)simple_strtoul (argv[1], NULL, 16);
+
+ sprintf(ack,"DATA %x",size);
+ downloader_serial_write(ack, strlen(ack)+1);
+ downloader_serial_read_actuallen((char *)DOWNLOADER_BUFFER_BASE, size);
+ sprintf(ack,"OKAY");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return 0;
+}
+
+U_BOOT_CMD(
+ testusb, CONFIG_SYS_MAXARGS, 0, do_testusb,
+ "testusb: testusb [size]",
+ ""
+);
+
diff --git a/boot/common/src/uboot/downloader/downloader_config.h b/boot/common/src/uboot/downloader/downloader_config.h
new file mode 100755
index 0000000..d9efe61
--- /dev/null
+++ b/boot/common/src/uboot/downloader/downloader_config.h
@@ -0,0 +1,14 @@
+#include "config.h"
+
+#define DOWNLOADER_BUFFER_BASE CONFIG_USB_DMA_BUF_ADDR
+
+#ifdef CONFIG_ZX297520V3T_64M_UBOOT
+#define DOWNLOADER_BUFFER_SIZE 0x3000000 /* 48M */
+#else
+#define DOWNLOADER_BUFFER_SIZE 0x1A00000 /*26M*/
+#endif
+
+//#define DOWNLOADER_BUFFER_SIZE (CONFIG_SYS_SDRAM_SIZE-0xA00000)
+//#define DOWNLOADER_BUFFER_SIZE 0x80000
+//#define CONFIG_LOAD_CRC
+
diff --git a/boot/common/src/uboot/downloader/downloader_nand.c b/boot/common/src/uboot/downloader/downloader_nand.c
new file mode 100644
index 0000000..d28cfbc
--- /dev/null
+++ b/boot/common/src/uboot/downloader/downloader_nand.c
@@ -0,0 +1,974 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: geanfeng
+ * Date: 2013-3-4
+ * History 1:
+ * Date:
+ * Version:
+ * Author:
+ * Modification:
+ * History 2:
+ ********************************************************************************/
+
+/****************************************************************************
+* Include files
+****************************************************************************/
+#include "downloader_nand.h"
+#include <asm/errno.h>
+#include "partition_table.h"
+#include <linux/mtd/nor_spifc.h>
+
+
+/****************************************************************************
+* Local Macros
+****************************************************************************/
+#define DATA_WITH_OOB (1 << 0) /* whether write with oob data*/
+/****************************************************************************
+* Local Types
+****************************************************************************/
+/****************************************************************************
+* Global Variables
+****************************************************************************/
+extern partition_table_t * g_partition_table;
+extern partition_table_t * g_partition_table_dl;
+extern partition_entry_t * get_partitions(const char *partname, partition_table_t *table);
+
+/****************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+/****************************************************************************
+* Function Definitions
+****************************************************************************/
+/*******************************************************************************
+ * Function:get_part_offset_skipbase
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *phyBase
+ *
+ * Others:
+ ********************************************************************************/
+static int get_part_offset_skipbase(partition_entry_t * part, uint offset, uint * skipBase)
+{
+ nand_info_t * pNandInfo = NULL;
+ uint offsetSkipBase = 0;
+ uint blockNum = 0;
+ int ret = 0;
+
+ pNandInfo = &nand_info[nand_curr_device];
+ offsetSkipBase = part->part_offset;
+ assert((offset & (pNandInfo->erasesize - 1)) == 0);
+ assert((offsetSkipBase & (pNandInfo->erasesize - 1)) == 0);
+ if(offset != 0)
+ {
+ blockNum = offset /pNandInfo->erasesize;
+ while(blockNum > 0)
+ {
+ ret = nand_block_isbad (pNandInfo, offsetSkipBase);
+ offsetSkipBase += pNandInfo->erasesize;
+ if (ret)
+ {
+ continue;
+ }
+ else
+ {
+ blockNum--;
+ }
+ }
+ }
+ *skipBase = offsetSkipBase;
+
+ return 0;
+}
+
+
+/*******************************************************************************
+ * Function:nand_read_skip_bad_compt
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * NULL:error else: success
+ *
+ * Others:
+ ********************************************************************************/
+int nand_read_skip_bad_compat(nand_info_t *nand, loff_t offset, size_t *length,
+ u_char *buffer, int flags)
+{
+ int rval = 0, blocksize;
+ size_t left_to_read = *length;
+ u_char *p_buffer = buffer;
+
+ if (flags & DATA_WITH_OOB) {
+ int pages;
+ pages = nand->erasesize / nand->writesize;
+ blocksize = (pages * nand->oobsize) + nand->erasesize;
+ if (*length % (nand->writesize + nand->oobsize)) {
+ printf ("Attempt to write incomplete page"
+ " in yaffs mode\n");
+ return -EINVAL;
+ }
+ } else
+ {
+ blocksize = nand->erasesize;
+ }
+
+ if ((offset & (nand->writesize - 1)) != 0) {
+ printf ("Attempt to write non page aligned data\n");
+ *length = 0;
+ return -EINVAL;
+ }
+
+ while (left_to_read > 0) {
+ size_t block_offset = offset & (nand->erasesize - 1);
+ size_t read_size, truncated_read_size;
+
+ if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
+ printf ("Skip bad block 0x%08llx\n",
+ (u64)(offset & ~(nand->erasesize - 1)));
+ offset += nand->erasesize - block_offset;
+ continue;
+ }
+
+ if (left_to_read < (blocksize - block_offset))
+ read_size = left_to_read;
+ else
+ read_size = blocksize - block_offset;
+
+ if (flags & DATA_WITH_OOB) {
+ int page, pages;
+ size_t pagesize = nand->writesize;
+ size_t pagesize_oob = pagesize + nand->oobsize;
+ struct mtd_oob_ops ops;
+ memset(&ops, 0x0, sizeof(ops));
+
+ ops.len = pagesize;
+ ops.ooblen = nand->oobsize;
+ ops.mode = MTD_OOB_RAW;
+ ops.ooboffs = 0;
+
+ pages = read_size / pagesize_oob;
+ for (page = 0; page < pages; page++) {
+ ops.datbuf = p_buffer;
+ ops.oobbuf = ops.datbuf + pagesize;
+ rval = nand->read_oob(nand, offset, &ops);
+ if (rval)
+ break;
+
+ offset += pagesize;
+ p_buffer += pagesize_oob;
+ }
+ }
+ else
+ {
+ truncated_read_size = read_size;
+ rval = nand_read(nand, offset, &truncated_read_size,
+ p_buffer);
+ offset += read_size;
+ p_buffer += read_size;
+ }
+
+ if (rval != 0) {
+ printf ("NAND read from offset %llx failed %d\n",
+ (u64)offset, rval);
+ *length -= left_to_read;
+ return rval;
+ }
+
+ left_to_read -= read_size;
+ }
+
+ return 0;
+}
+/*******************************************************************************
+ * Function:nand_read_skip_bad_compt
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * NULL:error else: success
+ *
+ * Others:
+ ********************************************************************************/
+int nand_write_skip_bad_compat(nand_info_t *nand, loff_t offset, size_t *length,
+ u_char *buffer, int flags)
+{
+ int rval = 0, blocksize;
+ size_t left_to_write = *length;
+ u_char *p_buffer = buffer;
+
+ if (flags & DATA_WITH_OOB) {
+ int pages;
+ pages = nand->erasesize / nand->writesize;
+ blocksize = (pages * nand->oobsize) + nand->erasesize;
+ if (*length % (nand->writesize + nand->oobsize)) {
+ printf ("Attempt to write incomplete page"
+ " in yaffs mode\n");
+ return -EINVAL;
+ }
+ } else
+ {
+ blocksize = nand->erasesize;
+ }
+
+ /*
+ * nand_write() handles unaligned, partial page writes.
+ *
+ * We allow length to be unaligned, for convenience in
+ * using the $filesize variable.
+ *
+ * However, starting at an unaligned offset makes the
+ * semantics of bad block skipping ambiguous (really,
+ * you should only start a block skipping access at a
+ * partition boundary). So don't try to handle that.
+ */
+ if ((offset & (nand->writesize - 1)) != 0) {
+ printf ("Attempt to write non page aligned data\n");
+ *length = 0;
+ return -EINVAL;
+ }
+
+ while (left_to_write > 0) {
+ size_t block_offset = offset & (nand->erasesize - 1);
+ size_t write_size, truncated_write_size;
+
+ if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) {
+ printf ("Skip bad block 0x%08llx\n",
+ (u64)(offset & ~(nand->erasesize - 1)));
+ offset += nand->erasesize - block_offset;
+ continue;
+ }
+
+ if (left_to_write < (blocksize - block_offset))
+ write_size = left_to_write;
+ else
+ write_size = blocksize - block_offset;
+
+ if (flags & DATA_WITH_OOB) {
+ int page, pages;
+ size_t pagesize = nand->writesize;
+ size_t pagesize_oob = pagesize + nand->oobsize;
+ struct mtd_oob_ops ops;
+
+ ops.len = pagesize;
+ ops.ooblen = nand->oobsize;
+ ops.mode = MTD_OOB_RAW;
+ ops.ooboffs = 0;
+
+ pages = write_size / pagesize_oob;
+ for (page = 0; page < pages; page++) {
+ ops.datbuf = p_buffer;
+ ops.oobbuf = ops.datbuf + pagesize;
+ //ops.oobbuf = NULL;
+ if(*(ops.datbuf + pagesize) != 0xFF || *(ops.datbuf + pagesize+1) != 0xFF) {
+ printf ("Fs image format error\n");
+ return -EINVAL;
+ }
+ rval = nand->write_oob(nand, offset, &ops);
+
+
+ if (rval)
+ break;
+
+ offset += pagesize;
+ p_buffer += pagesize_oob;
+ }
+ }
+ else
+ {
+ truncated_write_size = write_size;
+ rval = nand_write(nand, offset, &truncated_write_size,
+ p_buffer);
+ offset += write_size;
+ p_buffer += write_size;
+ }
+
+ if (rval != 0) {
+ printf ("NAND write to offset %llx failed %d\n",
+ (u64)offset, rval);
+ *length -= left_to_write;
+ return rval;
+ }
+
+ left_to_write -= write_size;
+ }
+
+ return 0;
+}
+/*******************************************************************************
+ * Function:downloader_get_part
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * NULL:error else: success
+ *
+ * Others:
+ ********************************************************************************/
+partition_entry_t * downloader_get_part(const char *partname)
+{
+ partition_entry_t *part;
+
+ part = find_partition_para((uchar *)partname);
+ if(part == NULL)
+ return NULL;
+
+ return part;
+}
+/*******************************************************************************
+ * Function:downloader_get_part_dl
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * NULL:error else: success
+ *
+ * Others:
+ ********************************************************************************/
+partition_entry_t * downloader_get_part_dl(const char *partname)
+{
+ partition_entry_t *part;
+
+ part = get_partitions((const char *)partname,g_partition_table_dl);
+ if(part == NULL)
+ {
+ return NULL;
+ }
+ printf("name=%s,part-name=%s,typt=%s\n",partname,part->part_name,part->part_type);
+
+ return part;
+}
+/*******************************************************************************
+ * Function:downloader_get_part_actual_size
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * NULL:error else: success
+ *
+ * Others:
+ ********************************************************************************/
+u32 downloader_get_part_actual_size(partition_entry_t *part)
+{
+ nand_info_t * pNandInfo = NULL;
+ pNandInfo = &nand_info[nand_curr_device];
+ u32 bad_blk_cnt = 0;
+ u32 offset = part->part_offset;
+ while(offset < part->part_offset + part->part_size )
+ {
+ if (nand_block_isbad (pNandInfo, offset) ){
+ bad_blk_cnt = bad_blk_cnt +1 ;
+ offset += pNandInfo->erasesize;
+ continue;
+ }
+ offset += pNandInfo->erasesize;
+ }
+ printf("downloader_get_part_actual_size:[%s] bad_blk_cnt = %d\n",part->part_name, bad_blk_cnt);
+ u32 part_actual_size = part->part_size -(bad_blk_cnt * pNandInfo->erasesize);
+ return part_actual_size;
+}
+
+/*******************************************************************************
+ * Function:downloader_nand_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_read(partition_entry_t * part, uint offset, uint size, unchar * buffer)
+{
+ nand_info_t * pNandInfo = NULL;
+ uint nandPhyBase = 0;
+ int ret = 0;
+
+ char ack[64] = {0};
+ if(part == NULL || \
+ offset>part->part_size || (size>downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
+ {
+ printf(" [downloader_nand_read:][%s]bin_size > actual part_size \n", part->part_name);
+ sprintf(ack, " READ FAIL UNLEGAL SIZE ");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+ pNandInfo = &nand_info[nand_curr_device];
+ get_part_offset_skipbase(part,offset,&nandPhyBase);
+
+ if( strcmp((const char *)part->part_name , "zloader") == 0 )
+ {
+ /* ÕâÀﲻʹÓÃECC¶Áȡʱ£¬Òª¶ÁÈ¡OOB£¬¶øOOBµÃÊý¾Ý»á·ÅÈëdata->buf;
+ ËùÒÔ´æ·ÅÊý¾ÝµÄbuf±ØÐëΪ (1 page + oob),²»ÄÜʹÓÃÉÏÃæ´«ÏÂÀ´µÄ
+ buffer,ÒòΪbufferµÄ´óСΪ²»°üº¬ oob µÄ´óС
+ */
+ u_char *buf = kzalloc(pNandInfo->writesize + pNandInfo->oobsize, GFP_KERNEL);
+ if( buf == NULL )
+ {
+ printf("downloader_nand_read kzalloc error\n");
+ return -1;
+ }
+
+ int times = size/pNandInfo->writesize;
+ int i = 0;
+ for(; i<times; i++)
+ {
+ ret += nand_read_page_with_ecc(pNandInfo,
+ ((loff_t)i*pNandInfo->writesize),
+ &size,
+ (u_char*)buf );
+ memcpy((u_char*)buffer, buf ,pNandInfo->writesize);
+ buffer += pNandInfo->writesize;
+ }
+ kfree(buf);
+
+ }
+
+ else
+ ret = nand_read_skip_bad(pNandInfo,\
+ nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer);
+ if(ret)
+ {
+ printf("downloader_nand_read error\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*******************************************************************************
+ * Function:downloader_nand_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_write(partition_entry_t * part, uint offset, uint size, unchar * buffer)
+{
+ nand_info_t * pNandInfo = NULL;
+ uint nandPhyBase = 0;
+ int ret = 0;
+ uchar * buf = buffer;
+ char ack[64] = {0};
+ if(part == NULL || \
+ offset>part->part_size || (size > downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
+ {
+ printf("[downloader_nand_write:][%s] bin_size > actual part_size \n", part->part_name);
+ sprintf(ack, "WRITE FAIL UNLEGAL SIZE ");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+ /*if(zftl_get_ZFTLrecord(part->part_offset))
+ {
+ printf("Function not allowed write zftl\n");
+ return -1;
+ }*/
+ pNandInfo = &nand_info[nand_curr_device];
+ get_part_offset_skipbase(part,offset,&nandPhyBase);
+ printf("entry nand_write\n");
+
+ /* רÃÅдZ-LOADʱʹÓ㬲»Ê¹ÓÃECC*/
+ if( strcmp((const char *)part->part_name , "zloader") == 0 )
+ {
+ if( size != 12*1024 )
+ {
+ printf("downloader_nand_write z-load size != 12k...\n");
+ return -1;
+ }
+ int times = 12*1024/pNandInfo->writesize;
+ int i = 0;
+
+ for(; i<times; i++)
+ {
+
+ ret += nand_write_page_with_ecc(pNandInfo,
+ ((loff_t)i*(pNandInfo->writesize)),
+ buf );
+ buf += pNandInfo->writesize;
+ }
+
+ }
+
+ else
+ ret = nand_write_skip_bad(pNandInfo,\
+ nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer, 0);
+ printf("write skipbad finish, addr = %d,size = %d\n",nandPhyBase+offset%(pNandInfo->erasesize),size);
+ if(ret)
+ {
+ printf("downloader_nand_write error\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*******************************************************************************
+ * Function:downloader_nand_fs_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_fs_read(partition_entry_t * part, uint offset, uint size, unchar * buffer)
+{
+ nand_info_t * pNandInfo = NULL;
+ uint nandPhyBase = 0;
+ int ret = 0;
+
+ char ack[64] = {0};
+ if(part == NULL || \
+ offset>part->part_size || (size>downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
+ {
+ printf("[downloader_nand_fs_read:][%s] bin_size > actual part_size \n", part->part_name);
+ sprintf(ack, " FS_READ FAIL UNLEGAL SIZE ");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+ pNandInfo = &nand_info[nand_curr_device];
+ assert(pNandInfo!=NULL);
+ get_part_offset_skipbase(part,offset,&nandPhyBase);
+ ret = nand_read_skip_bad_compat(pNandInfo,nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer,DATA_WITH_OOB);
+ if(ret)
+ {
+ printf("downloader_nand_fs_read error\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*******************************************************************************
+ * Function:downloader_nand_fs_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_fs_write(partition_entry_t * part, uint offset, uint size, unchar * buffer)
+{
+ nand_info_t * pNandInfo = NULL;
+ uint nandPhyBase = 0;
+ int ret = 0;
+ char ack[64] = {0};
+ if(part == NULL || \
+ offset>part->part_size || (size>downloader_get_part_actual_size(part)) || (offset+size) > part->part_size)
+ {
+ printf("[downloader_nand_fs_write:][%s] bin_size > actual part_size \n", part->part_name);
+ sprintf(ack, " FS_WRITE FAIL UNLEGAL SIZE ");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+
+ pNandInfo = &nand_info[nand_curr_device];
+ assert(pNandInfo!=NULL);
+ get_part_offset_skipbase(part,offset,&nandPhyBase);
+ ret = nand_write_skip_bad_compat(pNandInfo,nandPhyBase+offset%(pNandInfo->erasesize),&size,(u_char*)buffer, DATA_WITH_OOB);
+ if(ret)
+ {
+ printf("downloader_nand_fs_write error\n");
+ return -1;
+ }
+ return 0;
+}
+/*******************************************************************************
+ * Function:downloader_nand_erase
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_erase(partition_entry_t * part, uint partEraseSize)
+{
+ nand_info_t * pNandInfo = NULL;
+ int ret = 0;
+ struct erase_info instr;
+ uint size = 0;
+
+ if(part == NULL )
+ {
+ return -1;
+ }
+
+ pNandInfo = &nand_info[nand_curr_device];
+ instr.mtd = pNandInfo;
+ instr.addr = part->part_offset;
+ assert( (instr.addr & (pNandInfo->erasesize - 1)) == 0);
+ instr.callback = 0;
+ //ret=nand_erase(pNandInfo, part->part_offset, part->part_size);
+ while(size < partEraseSize && (instr.addr < (part->part_offset+part->part_size)))
+ {
+ if(nand_block_isbad (pNandInfo, instr.addr))
+ {
+ instr.addr += pNandInfo->erasesize;
+ continue ;
+ }
+ instr.len = pNandInfo->erasesize;
+ instr.state = 0;
+ ret = pNandInfo->erase(pNandInfo, &instr);
+ if(ret && instr.state == MTD_ERASE_FAILED)
+ {
+ pNandInfo->block_markbad(pNandInfo,instr.addr);
+ }
+ else if (ret == 0)
+ {
+ size += pNandInfo->erasesize;
+ }
+ else
+ {
+ printf( "downloader nand: erase error\n");
+ return 1;
+ }
+ instr.addr += pNandInfo->erasesize;
+ }
+
+ return ret;
+}
+/*******************************************************************************
+ * Function:downloader_nand_eraseall
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_eraseall(void)
+{
+ nand_info_t * pNandInfo = NULL;
+ struct erase_info instr;
+ int i = 0;
+ int ret = 0;
+
+ for(i=0; i<CONFIG_SYS_MAX_NAND_DEVICE; i++)
+ {
+ pNandInfo = &nand_info[i];
+
+ instr.mtd = pNandInfo;
+ instr.addr = 0x00;
+ assert( (instr.addr & (pNandInfo->erasesize - 1)) == 0);
+ instr.callback = 0;
+ while(instr.addr < pNandInfo->size)
+ {
+ if(nand_block_isbad (pNandInfo, instr.addr))
+ {
+ instr.addr += pNandInfo->erasesize;
+ continue ;
+ }
+ instr.len = pNandInfo->erasesize;
+ instr.state = 0;
+ ret = pNandInfo->erase(pNandInfo, &instr);
+ if(ret && instr.state == MTD_ERASE_FAILED)
+ {
+ pNandInfo->block_markbad(pNandInfo,instr.addr);
+ }
+ instr.addr += pNandInfo->erasesize;
+ }
+ }
+ return ret;
+}
+/*******************************************************************************
+ * Function:downloader_nand_erase_auto
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_erase_auto(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, "nvrofs") == 0 \
+ ||strcmp((const char *)entry->part_name, "ddr") == 0 \
+ ||strcmp((const char *)entry->part_name, "raw") == 0)
+ {
+ entry++;
+ continue;
+ }
+ ret = downloader_nand_erase(entry,entry->part_size);
+ entry++;
+ }
+ return ret;
+}
+
+extern struct fsl_qspi spi_nor_flash;
+
+
+/*******************************************************************************
+ * Function:downloader_nor_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nor_read(partition_entry_t * part, uint offset, uint size, unchar * buffer)
+{
+ int ret = 0;
+ char ack[64] = {0};
+ size_t read_size = size;
+ struct fsl_qspi *nor = NULL;
+
+ if(part == NULL
+ ||offset>part->part_size
+ || (offset+size) > part->part_size)
+ {
+ printf(" [downloader_nor_read:][%s]bin_size > actual part_size \n", part->part_name);
+ sprintf(ack, " READ FAIL UNLEGAL SIZE ");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+
+ nor = &spi_nor_flash;
+ ret = nand_read(&(nor->nor[0].mtd), part->part_offset + offset, &read_size, buffer);
+ if(ret)
+ {
+ printf("downloader_nor_read error\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*******************************************************************************
+ * Function:downloader_nor_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+
+int downloader_nor_write(partition_entry_t * part, uint offset, uint size, unchar * buffer)
+{
+ int ret = 0;
+ size_t write_size=0;
+ char ack[64] = {0};
+ struct fsl_qspi *nor = NULL;
+
+ write_size = size;
+
+ if(part == NULL
+ || offset>part->part_size
+ || (offset+size) > part->part_size)
+ {
+ printf("[downloader_nor_write:][%s] bin_size > actual part_size \n", part->part_name);
+ sprintf(ack, "WRITE FAIL UNLEGAL SIZE ");
+ downloader_serial_write(ack, strlen(ack)+1);
+ return -1;
+ }
+
+ nor = &spi_nor_flash;
+ ret = nand_write(&(nor->nor[0].mtd), part->part_offset + offset, &write_size, buffer);
+ if(ret)
+ {
+ printf("downloader_nor_write error\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Function:downloader_nand_erase
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nor_erase(partition_entry_t * part, uint partEraseSize)
+{
+ int ret = 0;
+ struct fsl_qspi *nor = NULL;
+
+ if(part == NULL)
+ {
+ return -1;
+ }
+
+ nor = &spi_nor_flash;
+ ret = nand_erase(&(nor->nor[0].mtd), part->part_offset, partEraseSize);
+ if(ret)
+ {
+ printf("downloader_nor_erase error\n");
+ return ret;
+ }
+ printf("downloader_nor_erase ok\n");
+ return 0;
+}
+/*******************************************************************************
+ * Function:downloader_nor_eraseall
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nor_eraseall(void)
+{
+ int ret = 0;
+ struct fsl_qspi *nor = NULL;
+
+ nor = &spi_nor_flash;
+ ret = nand_erase(&(nor->nor[0].mtd), 0x0, nor->nor[0].mtd.size);
+ if(ret)
+ {
+ printf("downloader_nor_eraseall error\n");
+ return ret;
+ }
+ printf("downloader_nor_eraseall ok\n");
+ return 0;
+
+}
+/*******************************************************************************
+ * Function:downloader_nor_erase_auto
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ * 0: success else:error
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nor_erase_auto(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, "nvrofs") == 0 \
+ ||strcmp((const char *)entry->part_name, "ddr") == 0 \
+ ||strcmp((const char *)entry->part_name, "raw") == 0)
+ {
+ entry++;
+ continue;
+ }
+ ret = downloader_nor_erase(entry,entry->part_size);
+ if(ret)
+ {
+ printf("downloader_nor_erase_auto error\n");
+ return ret;
+ }
+ entry++;
+ }
+ printf("downloader_nor_erase_auto ok\n");
+ return 0;
+}
+
+int get_nor_null_slice_flag(unsigned int *flag)
+{
+ int ret = 0;
+ size_t read_size = 0x100;
+ unchar buffer[256];
+ struct fsl_qspi *nor = NULL;
+
+ memset(buffer, 0xFF, 0x100);
+
+ nor = &spi_nor_flash;
+ ret = nand_read(&(nor->nor[0].mtd), 0x0, &read_size, buffer);
+ if(ret)
+ {
+ printf("downloader_nor_read error\n");
+ return -1;
+ }
+
+ if(strncmp((const char *)(buffer+4), "ZX7521V1", 8) == 0)
+ {
+ *flag = 1;
+ printf("nor flash not null\n");
+ }
+
+ return 0;
+}
+
+
+
diff --git a/boot/common/src/uboot/downloader/downloader_nand.h b/boot/common/src/uboot/downloader/downloader_nand.h
new file mode 100644
index 0000000..ec638d4
--- /dev/null
+++ b/boot/common/src/uboot/downloader/downloader_nand.h
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name: downloader_nand.h
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: geanfeng
+ * Date: 2013-03-04
+ * History 1:
+ * Date:
+ * Version:
+ * Author:
+ * Modification:
+ * History 2:
+ ********************************************************************************/
+#ifndef _DOWNLOADER_NAND_H
+#define _DOWNLOADER_NAND_H
+/****************************************************************************
+* Include files
+****************************************************************************/
+#include <common.h>
+#include <linux/mtd/mtd.h>
+#include <command.h>
+#include <malloc.h>
+#include <nand.h>
+#include <jffs2/jffs2.h>
+#include <partition_table.h>
+/****************************************************************************
+* Macros
+****************************************************************************/
+
+/****************************************************************************
+* Types
+****************************************************************************/
+/****************************************************************************
+* Constants
+****************************************************************************/
+
+/****************************************************************************
+* Global Variables
+****************************************************************************/
+
+/****************************************************************************
+* Function Prototypes
+****************************************************************************/
+
+/*******************************************************************************
+ * Function:downloader_get_part
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+partition_entry_t * downloader_get_part(const char *partname);
+/*******************************************************************************
+ * Function:downloader_get_part_dl
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+
+partition_entry_t * downloader_get_part_dl(const char *partname);
+/*******************************************************************************
+ * Function:downloader_nand_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_read(partition_entry_t * part, uint offset, uint size, unchar * buffer);
+/*******************************************************************************
+ * Function:downloader_nand_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_write(partition_entry_t * part, uint offset, uint size, unchar * buffer);
+/*******************************************************************************
+ * Function:downloader_zftl_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_zftl_read(partition_entry_t * part, uint offset, uint size, unchar * buffer);
+/*******************************************************************************
+ * Function:downloader_zftl_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_zftl_write(partition_entry_t * part, uint offset, uint size, unchar * buffer);
+/*******************************************************************************
+ * Function:downloader_nand_fs_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_fs_read(partition_entry_t * part, uint offset, uint size, unchar * buffer);
+/*******************************************************************************
+ * Function:downloader_nand_fs_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_fs_write(partition_entry_t * part, uint offset, uint size, unchar * buffer);
+/*******************************************************************************
+ * Function:downloader_nand_erase
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_erase(partition_entry_t * part, uint partEraseSize);
+/*******************************************************************************
+ * Function:downloader_nand_eraseall
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_eraseall(void);
+
+/*******************************************************************************
+ * Function:downloader_nand_auto
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_nand_erase_auto(void);
+
+int do_nand_read(partition_entry_t *part, char *par , unsigned int offset, unsigned int size );
+
+int do_raw_read(unsigned int offset, unsigned int size);
+
+int do_ram_read(unsigned int offset, unsigned int size);
+
+int do_zftl_read(partition_entry_t *part, char *par , unsigned int offset, unsigned int size);
+
+int do_yaffs_read(partition_entry_t *part, char *par , unsigned int offset, unsigned int size);
+
+int do_mmc_read(partition_entry_t *part, char *par , unsigned int offset,unsigned int size );
+
+int do_nand_write(partition_entry_t *part, char *par , unsigned int offset, unsigned int size );
+
+int do_raw_write(unsigned int offset, unsigned int size);
+
+int do_yaffs_write(partition_entry_t *part, char *par , unsigned int offset, unsigned int size );
+
+int do_zftl_write(partition_entry_t *part, char *par , unsigned int offset, unsigned int size);
+
+int do_ram_write( unsigned int offset, unsigned int size);
+
+int do_mmc_write(partition_entry_t *part, char *par , unsigned int offset,unsigned int size );
+
+#endif
+
diff --git a/boot/common/src/uboot/downloader/downloader_serial.c b/boot/common/src/uboot/downloader/downloader_serial.c
new file mode 100755
index 0000000..2d05568
--- /dev/null
+++ b/boot/common/src/uboot/downloader/downloader_serial.c
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name:
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: geanfeng
+ * Date: 2013-3-4
+ * History 1:
+ * Date:
+ * Version:
+ * Author:
+ * Modification:
+ * History 2:
+ ********************************************************************************/
+
+/****************************************************************************
+* Include files
+****************************************************************************/
+#include <linux/types.h>
+#include <usb/common.h>
+#include <command.h>
+#include <common.h>
+#include <net.h>
+#include <usb/usb_config.h>
+/****************************************************************************
+* Local Macros
+****************************************************************************/
+/****************************************************************************
+* Local Types
+****************************************************************************/
+
+/****************************************************************************
+* Global Variables
+****************************************************************************/
+int dl_serial_initial = 0;
+/****************************************************************************
+* Global Function Prototypes
+****************************************************************************/
+extern int tsp_usb_init(void);
+extern WORD32 usb_read(WORD32 dwLen, BYTE *pchBuf);
+
+
+extern WORD32 usb_write(WORD32 dwLen, BYTE *pchBuf);
+
+extern int UART_Read(char *pchBuf, int dwLen);
+extern int UART_Write(char *pchBuf, int dwLen);
+/****************************************************************************
+* Function Definitions
+****************************************************************************/
+
+/*******************************************************************************
+ * Function:downloader_serial_init
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+void downloader_serial_init(void)
+{
+#if CONFIG_USB_DL
+ usb_boot(SYS_USB_BASE); /*usb*/
+#endif
+ dl_serial_initial =1;
+}
+/*******************************************************************************
+ * Function:downloader_serial_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+ unsigned int g_testLen = 0;
+unsigned int g_testAddr = 0;
+unsigned int g_testFlag1 = 0;
+int downloader_serial_read(char * buffer,unsigned int len)
+{
+ int ret = 0;
+
+ if(!dl_serial_initial)
+ return 0;
+ g_testAddr = (unsigned int)&len;
+#if CONFIG_USB_DL
+ ret = usb_read(len,buffer);
+#else
+ ret = UART_Read(buffer,len);
+#endif
+ g_testLen = len;
+ g_testFlag1 = 1;
+ if(!ret)
+ {
+ return 0; /*error return 0*/
+ }
+ else
+ {
+
+ return ret;/*actual length*/
+ }
+}
+/*******************************************************************************
+ * Function:downloader_serial_read_actuallen
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_serial_read_actuallen(char * buffer,unsigned int len)
+{
+ char* pBuffer = buffer;
+ uint readLength = 0;
+ uint length = 0;
+ //printf("start to rececive len = %d \n",len);
+#if CONFIG_USB_DL
+ while(readLength < len)
+ {
+ length = downloader_serial_read(pBuffer,512);
+ //printf(" receiving len = %d \n",length);
+ if(length)
+ {
+ readLength += length;
+ //printf(" readLength = %d \n",readLength);
+ pBuffer += length;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ //printf("finish receiving len = %d \n",len);
+#else
+
+ length = downloader_serial_read(pBuffer,len);
+#endif
+ return 0;
+}
+
+/*******************************************************************************
+ * Function:downloader_serial_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_serial_write(const char * buffer,unsigned int len)
+{
+ if(!dl_serial_initial)
+ return 0;
+
+#if CONFIG_USB_DL
+ return usb_write(len,(char *)buffer);
+#else
+ return UART_Write((char *)buffer,len);
+#endif
+}
+/*******************************************************************************
+ * Function:downloader_serial_write_actuallen
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_serial_write_actuallen(const char * buffer,unsigned int len)
+{
+ const char* pBuffer = buffer;
+ uint writeLength = 0;
+ uint length = 0;
+
+ /*need modify*/
+ while(writeLength < len)
+ {
+
+ length = MIN(len-writeLength,136192);
+ //printf("prepare to write len=%d\n",length);
+ downloader_serial_write(pBuffer,length);
+ //printf("this time usb write len=%d\n",length);
+ writeLength += length;
+ //printf("usb have writen len=%d\n",writeLength);
+
+ pBuffer += length;
+ }
+ return 0;
+}
+
diff --git a/boot/common/src/uboot/downloader/downloader_serial.h b/boot/common/src/uboot/downloader/downloader_serial.h
new file mode 100644
index 0000000..2360101
--- /dev/null
+++ b/boot/common/src/uboot/downloader/downloader_serial.h
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (C) 2016, ZIXC Corporation.
+ *
+ * File Name: downloader_serial.h
+ * File Mark:
+ * Description:
+ * Others:
+ * Version: 1.0
+ * Author: geanfeng
+ * Date: 2013-03-04
+ * History 1:
+ * Date:
+ * Version:
+ * Author:
+ * Modification:
+ * History 2:
+ ********************************************************************************/
+#ifndef _DOWNLOADER_SERIAL_H
+#define _DOWNLOADER_SERIAL_H
+/****************************************************************************
+* Include files
+****************************************************************************/
+
+/****************************************************************************
+* Macros
+****************************************************************************/
+
+/****************************************************************************
+* Types
+****************************************************************************/
+/****************************************************************************
+* Constants
+****************************************************************************/
+
+/****************************************************************************
+* Global Variables
+****************************************************************************/
+
+/****************************************************************************
+* Function Prototypes
+****************************************************************************/
+
+/*******************************************************************************
+ * Function:downloader_serial_read
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_serial_read(char * buffer,unsigned int len);
+/*******************************************************************************
+ * Function:downloader_serial_read_actuallen
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_serial_read_actuallen(char * buffer,unsigned int len);
+/*******************************************************************************
+ * Function:downloader_serial_write
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_serial_write(const char * buffer,unsigned int len);
+/*******************************************************************************
+ * Function:downloader_serial_write_actuallen
+ * Description:
+ * Parameters:
+ * Input:
+ *
+ * Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/
+int downloader_serial_write_actuallen(const char * buffer,unsigned int len);
+#endif