[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/drivers/misc/load.c b/boot/common/src/uboot/drivers/misc/load.c
new file mode 100755
index 0000000..8419dca
--- /dev/null
+++ b/boot/common/src/uboot/drivers/misc/load.c
@@ -0,0 +1,1368 @@
+/*
+ * (C) Copyright 2016, ZIXC Corporation.
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <command.h>
+#include <malloc.h>
+#include <jffs2/load_kernel.h>
+#include <linux/list.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+#include <image.h>
+#include <partition_table.h>
+#include <board.h>
+#include <mmc.h>
+#include <boot_mode.h>
+#include <led.h>
+
+#if defined(CONFIG_CMD_NAND)
+#include <linux/mtd/nand.h>
+#include <nand.h>
+#endif
+
+#include <config.h>
+#include <load_image.h>
+#include <asm/arch/cpu.h>
+#include <secure_verify.h>
+#include <linux/mtd/nor_spifc.h>
+
+#if	LOAD_IMAGE_DEBUG
+#define load_debug_printf(fmt,args...)	printf (fmt ,##args)
+#else
+#define load_debug_printf(fmt,args...)
+#endif	/* LOAD_IMAGE_DEBUG */
+
+#if	TIME_DEBUG
+#define time_debug_reset(fmt)   fmt = get_timer(0)
+#define time_debug_printf(fmt, val)	printf(fmt ,get_timer(val))
+#else
+#define time_debug_reset(fmt)
+#define time_debug_printf(fmt, val)
+#endif	/* TIME_DEBUG */
+#define reg16(addr)         (*(volatile unsigned short*)(addr))
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define ZSP_IMAGE_PATH "/evb_cpuphy.bin"
+#define M0_IMAGE_PATH "/evb_cpurpm.img"
+#define DTB_IMAGE_PATH "/ap_cpucap.dtb"
+#define FOTAFLAG_PATH "/fotaflag"
+
+#if defined(CONFIG_ZX297520V3E_JFFS2_COMPRESS)
+typedef struct lzmaheader_p{
+	uint8_t p_properties;
+	uint8_t p_dict[4];
+	uint8_t p_uncompress_size[8];
+}lzma_header_t;
+
+extern uint32_t ztelzma_compresssize;
+extern int lzmanodeflag;
+#endif
+
+//#ifdef CONFIG_ZX297520V3E_MDL_AB
+#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
+extern int imagefs_flag;
+static uint32_t flags;
+#endif
+extern int nand_curr_device;
+extern nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
+extern partition_table_t * g_partition_table;
+extern int flash_dmabuf_disable_flag;
+extern struct fsl_qspi spi_nor_flash;
+
+/* Secure Verify Flag. 1->Disable, 0->Enable */
+extern unsigned int guiEfuseStatus;
+
+uint32_t arm_ps_ep = 0;          /* Entry Point Address */
+uint32_t arm_cpucap_ep = 0;
+static uint32_t arm_phy_ep = 0;         /* Entry Point Address */
+
+static uint32_t fota_upflag = FOTA_NORMAL;
+static uint32_t fota_psup_flag = FOTA_PS_NORMAL;
+
+uint32_t g_gmac_init_flag = 0;
+uint32_t g_gmac_init_overtime = 0;
+ 
+static uint32_t sys_ddr_kernel_start = 0;   /* kernel ÔËÐпռä Ê×µØÖ· */
+
+master_header_t *master_head = NULL;
+int update_start_time = 0;
+int update_recent_time = 0;
+int led_state = 0;
+
+int rd_offset = 0;
+int rd_size = 0;
+
+
+/* ================================================================================
+ *  page_align  :  Ò³¶ÔÆë
+ */
+static uint32_t page_align(uint32_t offset)
+{
+	struct flash_ops *flash = NULL;
+	uint32_t page_size = 0;
+
+	flash = get_flash_ops();
+	page_size = flash->page_size;
+	if( offset & (page_size - 1) )
+	{
+		offset &= (~(page_size - 1));
+		offset += page_size;
+	}
+	return offset;
+}
+
+/* ================================================================================
+ *  page_align  :  Ò³¶ÔÆë
+ */
+int set_entry_point(uchar * part_name, uint32_t entry_point)
+{
+	if ( strcmp( (char *)ARM_PS_IMAGE, (char *)part_name ) == 0 )
+	{
+		arm_ps_ep = entry_point;
+		return 0;
+	}
+	else if ( strcmp( (char *)ARM_PHY_IMAGE, (char *)part_name ) == 0 )
+	{
+		arm_phy_ep = entry_point;
+		return 0;
+	}
+	else if ( strcmp( (char *)ARM_RAMDISK_IMAGE, (char *)part_name ) == 0 )
+	{
+		return 0;
+	}
+	else
+	{
+		return 1;
+	}
+}
+
+static int arm_image_crc_calc(char* pcPartName,
+									uint32_t uiCRCChkSum,
+									uint32_t uiEntryPoint,
+									uint32_t uiImgSize)
+{
+	uint32_t uiCRCCalRes = 0;
+	
+    BOOT_PRINTF(UBOOT_NOTICE, "(%s)CRC Calculate start\n",pcPartName);
+	uiCRCCalRes = crc32(0, (unsigned char*)uiEntryPoint, uiImgSize);
+	BOOT_PRINTF(UBOOT_NOTICE, "(%s) CRC Calculate Res=0x%0x, Size=%d Bytes\n",
+	pcPartName, uiCRCCalRes, uiImgSize);
+	if(uiCRCChkSum != uiCRCCalRes||uiCRCCalRes == 0)
+	{
+		BOOT_PRINTF(UBOOT_ERR, "(%s) CRC Check Failed!\n", pcPartName);
+		return 1;
+	}
+	BOOT_PRINTF(UBOOT_NOTICE, "(%s) CRC Check PASS!\n", pcPartName);
+	return 0;
+}
+
+/* ================================================================================
+ *  reform_zsp_image  :  ´ÓDDRÖжÁÈ¡ZSPÏà¹ØµÄ°æ±¾
+ * @return 0              :  ³É¹¦
+ * @return 1              :  ʧ°Ü
+ */
+static int reform_zsp_image(uint32_t addr)
+{
+	int ret = 0;
+	int offSet = 0;
+	int lenToRead = 0;
+	int length = 0;
+
+	offSet = addr;	/*DDR address for zsp,0x25000000*/
+	uint32_t arm_size = ((reg16(offSet))+(reg16(offSet+2)<<16));/*zsp bin length*/
+
+	/*move zsp's bin from zsp buf to ddr address*/
+	offSet = offSet + 0x4;
+	
+	while(1)
+	{		
+		if(length >= arm_size - 0x4)
+		{
+			break;
+		}
+		if((reg16(offSet+0x4)+(reg16(offSet+0x4+2)<<16))*2 <0x20000000)//not in ddr
+		{
+			lenToRead = (reg16(offSet+0x8)+(reg16(offSet+0x8+2)<<16))*2;
+			length += lenToRead + 0xc;
+			offSet = offSet + lenToRead+0xc;
+			continue;
+		}
+
+		lenToRead = (reg16(offSet+0x8)+(reg16(offSet+0x8+2)<<16))*2;
+		memcpy((void*)((reg16(offSet+0x4)+(reg16(offSet+0x4+2)<<16))*2),(const void *)(offSet+0xc),lenToRead);
+		length += lenToRead + 0xc;
+		offSet = offSet + lenToRead+0xc;
+	}
+	return 0;
+
+}
+
+
+/* ================================================================================
+ *  load_arm_image  :  ´ÓFLASHÖжÁÈ¡ARM°æ±¾
+ * @return 0        :  ³É¹¦
+ * @return 1        :  ʧ°Ü
+ */
+int load_arm_image( uchar * part_name )
+{
+	int ret = 0;
+	struct flash_ops *flash = NULL;
+
+#if	TIME_DEBUG
+	ulong start_time = 0;
+#endif
+
+	flush_dcache_all();
+    flash_dmabuf_disable_flag = 1;
+	flash = get_flash_ops();
+	time_debug_reset(start_time);
+	load_debug_printf("\n");
+
+	/* ѰÕÒ·ÖÇø */
+	partition_entry_t * entry = find_partition_para(part_name);
+	if( entry == NULL )
+	{
+		BOOT_PRINTF(UBOOT_ERR, "[%s]: can't find the partition...\n", part_name);
+		return 1;
+	}
+
+	/* »ñµÃ·ÖÇøÊ×µØÖ· */
+	uint32_t part_offset = entry->part_offset;
+	nand_info_t *nand = &nand_info[nand_curr_device];
+
+	/* ¶ÁÈ¡°æ±¾ËùÔÚµØÖ·µÄµÚÒ»Ò³Êý¾Ý */
+	uint32_t page_size = flash->page_size; /*¶ÁÈ¡arm °æ±¾mmcµÚÒ»¿éÊý¾Ý*/
+	ret = flash->read(nand,(loff_t)part_offset,&page_size,(u_char *)CONFIG_SYS_SDRAM_TEMP_BASE);
+	if( ret != 0 )
+	{
+		BOOT_PRINTF(UBOOT_ERR, "[%s]: read the first page error!\n", part_name);
+		return 1;
+	}
+
+	/* »ñÈ¡°æ±¾µÄ´óСºÍÔËÐеØÖ· */
+	image_header_t *header = (image_header_t *)CONFIG_SYS_SDRAM_TEMP_BASE;
+	if( ___htonl(header->ih_magic) != IH_MAGIC )
+	{
+		BOOT_PRINTF(UBOOT_ERR, "[%s]: NO bin !!!\n", part_name );
+		return 1;
+	}
+
+	uint32_t arm_size = ___htonl(header->ih_size);
+	uint32_t entey_point = ___htonl(header->ih_ep);
+	if( set_entry_point(part_name, entey_point) )
+	{
+		BOOT_PRINTF(UBOOT_ERR, "[%s][set_entry_point]: error!\n", part_name );
+	}
+
+	BOOT_PRINTF(UBOOT_NOTICE, "[%s] [size=0x%0x] from [0x%0x] to [0x%0x]\n",
+		part_name, arm_size, part_offset, entey_point);
+
+#if	LOAD_IMAGE_CRC
+	uint32_t crc_bin = ___htonl(header->ih_dcrc);
+	BOOT_PRINTF(UBOOT_NOTICE, "[%s][crc_bin] ------------------- [0x%0x]\n", part_name, crc_bin);
+#endif
+
+	/* Õû¸öÍ·ºÍ·ÖÇø±íµÄ´óС */
+	uint32_t image_header_size = sizeof(image_header_t);
+	uint32_t arm_is_read_size = flash->page_size  - image_header_size;
+	uint32_t arm_size_left = arm_size - arm_is_read_size;  /* »¹Ã»ÓжÁÈ¡µÄ³¤¶È */
+	arm_size_left = page_align(arm_size_left);                /* Ò³¶ÔÆë */
+
+	/* ¸´ÖƵÚÒ»Ò³ÖеÄÊý¾Ý */
+	memcpy((uchar *)entey_point, (uchar *)(CONFIG_SYS_SDRAM_TEMP_BASE + image_header_size), arm_is_read_size);
+	/* ¶ÁȡʣÓàµÄÊý¾Ý */
+
+	ret = flash->read(nand,(loff_t)(part_offset + page_size), &arm_size_left,(u_char *)(entey_point + arm_is_read_size));
+	if( ret != 0 )
+	{
+		BOOT_PRINTF(UBOOT_ERR, "[%s]: read the others page error...\n", part_name);
+		return 1;
+	}
+
+	BOOT_PRINTF(UBOOT_NOTICE, "[loading...] -------------------- takes [%ld] us\n", start_time);
+
+#if LOAD_IMAGE_CRC
+	time_debug_reset(start_time);
+	uint32_t crc_cal = crc32(0,(unsigned char*)entey_point, arm_size);
+	BOOT_PRINTF(UBOOT_NOTICE, "[%s][crc_bin] ------------------- [0x%0x]\n", part_name, crc_cal);
+	if( crc_bin != crc_cal )
+	{
+		BOOT_PRINTF(UBOOT_ERR, "[%s] ---------------- crc error...\n", part_name);
+		return 1;
+	}
+	BOOT_PRINTF(UBOOT_NOTICE, "[crc...] ------------------------ takes [%ld] us\n", start_time);
+#endif /* LOAD_IMAGE_CRC */
+	
+	flash_dmabuf_disable_flag = 0; 
+
+	return 0;
+}
+
+int fs_load_dtb_image(void)
+{
+    char    cmd[64] = {0};
+    /*1¡¢½«dtbÎļþloadµ½ÁÙʱµØÖ·*/
+#ifdef CONFIG_ZX297520V3E_VEHICLE_DC
+    if(imagefs_flag == 1)
+		sprintf(cmd, "fsload imagefs 0x%x %s", (ulong)CONFIG_SYS_SDRAM_TEMP_BASE, DTB_IMAGE_PATH);
+	else
+		sprintf(cmd, "fsload imagefs2 0x%x %s", (ulong)CONFIG_SYS_SDRAM_TEMP_BASE, DTB_IMAGE_PATH);
+#else
+	sprintf(cmd, "fsload imagefs 0x%x %s", (ulong)CONFIG_SYS_SDRAM_TEMP_BASE, DTB_IMAGE_PATH);
+#endif
+	run_command(cmd, 0);
+	flush_dcache_all();
+	/*2¡¢¿½±´°æ±¾Êý¾Ýµ½ÔËÐеØÖ· */
+	memcpy((uchar *)CAP_DTB_ADDR, 
+			(uchar *)(CONFIG_SYS_SDRAM_TEMP_BASE), 
+			CAP_DTB_LEN);
+
+	BOOT_PRINTF(UBOOT_NOTICE, "dtb load image finished\n");
+	
+	return 0;
+}
+
+int fs_load_m0_image(void)
+{
+	char    cmd[64] = {0};
+	int remap = 0;
+
+	remap = readl(0x140000);
+	remap |= 0x800000;
+	writel(remap,0x140000);
+
+	/*1¡¢½«m0 imgÎļþloadµ½ÁÙʱµØÖ·*/
+//#ifdef CONFIG_ZX297520V3E_MDL_AB
+#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
+    if(imagefs_flag == 1)
+		sprintf(cmd, "fsload imagefs 0x%x %s", (ulong)CONFIG_SYS_SDRAM_TEMP_BASE, M0_IMAGE_PATH);
+	else
+		sprintf(cmd, "fsload imagefs2 0x%x %s", (ulong)CONFIG_SYS_SDRAM_TEMP_BASE, M0_IMAGE_PATH);
+#else
+	sprintf(cmd, "fsload imagefs 0x%x %s", (ulong)CONFIG_SYS_SDRAM_TEMP_BASE, M0_IMAGE_PATH);
+#endif
+	run_command(cmd, 0);
+	flush_dcache_all();
+	
+	/*2¡¢ÉèÖÃM0µÄÈë¿ÚµØÖ·ÒÔ¼°M0°æ±¾°áÔËÍê³Éflagµ½iramÖÐ */
+	writel(1, M0_IMAGE_READY_FLAG_ADDR);
+
+	/*3¡¢µÈ´ýM0¿½±´Íê³É*/
+	while(readl(M0_IMAGE_READY_FLAG_ADDR));
+
+	printf("M0 image load success!\n");
+	
+	return 0;
+}
+
+
+#if defined(CONFIG_ZX297520V3E_JFFS2_COMPRESS)
+uint32_t lzma_header(uint32_t *ztelzma_dict,
+						int *ztelzma_lc,
+						int *ztelzma_lp,
+						int *ztelzma_pb)
+{
+	uint8_t temp_properties = 0;
+	uint32_t temp_dict = 0;
+	uint32_t temp_uncompress_size = 0;
+	uint32_t  lzma_uncompresssize = 0;
+    lzma_header_t *lzmaheader;
+	
+	lzmaheader = (lzma_header_t *)CONFIG_SYS_SDRAM_TEMP_BASE;
+	
+    temp_properties = lzmaheader->p_properties;
+	temp_dict = (lzmaheader->p_dict[3]<<24)
+					|(lzmaheader->p_dict[2]<<16)
+					|(lzmaheader->p_dict[1]<<8)
+					|lzmaheader->p_dict[0];
+	temp_uncompress_size = (lzmaheader->p_uncompress_size[3]<<24)
+							|(lzmaheader->p_uncompress_size[2]<<16)
+							|(lzmaheader->p_uncompress_size[1]<<8)
+							|lzmaheader->p_uncompress_size[0];
+
+    *ztelzma_pb = temp_properties / (9 * 5);
+	temp_properties -= *ztelzma_pb * 9 * 5;
+	*ztelzma_lp = temp_properties / 9 ;
+	*ztelzma_lc = temp_properties - *ztelzma_lp * 9;
+	*ztelzma_dict = temp_dict;
+	lzma_uncompresssize = temp_uncompress_size;
+	
+	return lzma_uncompresssize;  
+}
+
+int fs_load_zsp_image(void)
+{
+	uint32_t image_tmp_buf = 0;
+	int zspimagenum=0;	
+	uint32_t ztelzma_uncompresssize = 0;
+	uint32_t ztelzma_dict=0;
+	int ztelzma_lc=0;
+	int ztelzma_lp=0;
+	int ztelzma_pb=0;
+	int firstlzma_flag = 0;
+	int lzma_init_flag = 0;
+	int lzmainit_ret = 0;
+	int lzmadecompr_ret = 1;
+	uint32_t lzmaoffsize = 0;
+	char    cmd[64] = {0};
+	uint32_t uiImgHdrlzma = 13;
+	
+	BOOT_PRINTF(UBOOT_NOTICE, "zsp image load begin...\n");
+
+	lzmanodeflag = 1;
+
+	/* ÁÙʱ´æ·Å½âѹºóµÄzsp°æ±¾ */
+	image_tmp_buf = CONFIG_SYS_SDRAM_TEMP_LZMA;
+
+	while(lzmanodeflag == 1)
+	{
+		/* ½«zsp imgÎļþloadµ½ÁÙʱµØÖ·*/
+//#ifdef CONFIG_ZX297520V3E_MDL_AB
+#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
+        if(imagefs_flag == 1)
+		    sprintf(cmd, "fsload imagefs 0x%x cpuphy_%02d.lzma", 
+				(ulong)CONFIG_SYS_SDRAM_TEMP_BASE, 
+				zspimagenum);
+	    else
+		    sprintf(cmd, "fsload imagefs2 0x%x cpuphy_%02d.lzma", 
+				(ulong)CONFIG_SYS_SDRAM_TEMP_BASE, 
+				zspimagenum);
+#else
+		sprintf(cmd, "fsload imagefs 0x%x cpuphy_%02d.lzma", 
+				(ulong)CONFIG_SYS_SDRAM_TEMP_BASE, 
+				zspimagenum);
+#endif
+		run_command(cmd, 0);
+
+		if(ztelzma_compresssize)
+		{
+			/* ½âѹС°üÎļþ*/
+			ztelzma_uncompresssize=lzma_header(&ztelzma_dict,
+												&ztelzma_lc,
+												&ztelzma_lp,
+												&ztelzma_pb);
+
+			if(lzma_init_flag == 0)
+			{
+				lzmainit_ret = lzma_init(&ztelzma_dict,
+										 &ztelzma_lc,
+										 &ztelzma_lp,
+										 &ztelzma_pb);
+				if(lzmainit_ret < 0)
+				{
+					printf("lzma_init failed\n");
+					return -1;
+				}
+				else
+				{
+					lzma_init_flag = 1;
+				}
+			}
+
+			lzmadecompr_ret=lzma_decompress((unsigned char *)(CONFIG_SYS_SDRAM_TEMP_BASE + uiImgHdrlzma),
+											(unsigned char *)(image_tmp_buf + lzmaoffsize), 
+											ztelzma_compresssize, 
+											ztelzma_uncompresssize);
+			if(lzmadecompr_ret)
+			{
+				printf("lzma_decompress failed\n");
+				return -1;
+			}
+			lzmaoffsize += ztelzma_uncompresssize ;
+			zspimagenum++;
+		}
+	}
+
+	/* °´ÕÕZSPµÄ¸ñÊ½ÖØÅÅ */
+	reform_zsp_image(image_tmp_buf);
+	BOOT_PRINTF(UBOOT_NOTICE, "zsp image load finished.\n");
+
+	return 0;
+}
+
+int fs_load_arm_image_linux(char* image_name)
+{
+	char cmd[64] = {0};
+	int ret = 0;
+	int lzmainit_ret = 0;
+	int lzmadecompr_ret = 1;
+	u8 ucRet = 0;
+	int apimagenum=0;	
+	uint32_t uiImgSize = 0;
+	uint32_t uiEntryPoint = 0;
+	uint32_t uiLoadPoint = 0;
+	uint32_t lzmaLoadPoint = 0;
+	uint32_t ztelzma_uncompresssize = 0;
+	uint32_t ztelzma_dict=0;
+	int ztelzma_lc=0;
+	int ztelzma_lp=0;
+	int ztelzma_pb=0;
+	int firstlzma_flag = 0;
+#if LOAD_IMAGE_CRC
+	uint32_t uiCRCChkSum = 0;
+	uint32_t uiCRCCalRes = 0;
+#endif
+	uint32_t uiImgHdrSizeOld = sizeof(image_header_t);
+	uint32_t uiImgHdrSizeNew = 0;
+	uint32_t uiImgHdrlzma = 13;
+	uint32_t lastlzmaSize = 0;
+
+	int lzma_init_flag = 0;
+	lzmanodeflag = 1;
+
+	BOOT_PRINTF(UBOOT_NOTICE, "AP image load begin...\n");
+
+	uiImgHdrSizeNew = sizeof(sImageHeader); 
+
+	image_header_t *psImgHdrOld = NULL;
+
+	while(lzmanodeflag == 1)
+	{
+		/*1¡¢½«ap imgÎļþloadµ½ÁÙʱµØÖ·*/
+//#ifdef CONFIG_ZX297520V3E_MDL_AB
+#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
+        if(imagefs_flag == 1)
+			sprintf(cmd, "fsload imagefs 0x%x /%s_%02d.lzma", 
+				(ulong)CONFIG_SYS_SDRAM_TEMP_BASE, image_name, apimagenum);
+		else
+			sprintf(cmd, "fsload imagefs2 0x%x /%s_%02d.lzma", 
+				(ulong)CONFIG_SYS_SDRAM_TEMP_BASE, image_name, apimagenum);
+#else
+		sprintf(cmd, "fsload imagefs 0x%x /%s_%02d.lzma", 
+#endif
+				(ulong)CONFIG_SYS_SDRAM_TEMP_BASE, image_name, apimagenum);
+	
+		run_command(cmd, 0);
+
+		if(ztelzma_compresssize)
+		{
+			/*2¡¢½âѹС°üÎļþ*/
+			ztelzma_uncompresssize=lzma_header(&ztelzma_dict,
+											   &ztelzma_lc,
+											   &ztelzma_lp,
+											   &ztelzma_pb);
+
+			if(lzma_init_flag == 0)
+			{
+				lzmainit_ret = lzma_init(&ztelzma_dict,
+										 &ztelzma_lc,
+										 &ztelzma_lp,
+										 &ztelzma_pb);
+				if(lzmainit_ret < 0)
+				{
+					printf("lzma_init failed\n");
+					return -1;
+				}
+				else
+				{
+					lzma_init_flag = 1;
+				}
+			}
+
+			/*3¡¢»ñÈ¡°æ±¾µÄ´óСºÍÔËÐеØÖ· */
+			if(firstlzma_flag == 0)
+			{
+				lzmadecompr_ret=lzma_decompress((unsigned char *)(CONFIG_SYS_SDRAM_TEMP_BASE+uiImgHdrlzma), 
+												(unsigned char *)(CONFIG_SYS_SDRAM_TEMP_LZMA), 
+												ztelzma_compresssize, 
+												ztelzma_uncompresssize);
+				if(lzmadecompr_ret)
+				{
+					printf("lzma_decompress failed\n");
+					return -1;
+				}
+
+				/*»ñÈ¡¹«Ô¿´«µÝ¸ø´ó°æ±¾Ê¹ÓÃ*/
+				memcpy(CFG_SECURE_PUK_ADDR,CONFIG_SYS_SDRAM_TEMP_LZMA,256);
+	
+			    psImgHdrOld = (image_header_t *)(CONFIG_SYS_SDRAM_TEMP_LZMA + uiImgHdrSizeNew);
+						
+				if(___htonl(psImgHdrOld->ih_magic) != IH_MAGIC)
+				{
+					BOOT_PRINTF(UBOOT_ERR, "Magic Num Check Failed,Maybe no AP bin !!!\n");
+					return 1;
+				}
+
+				uiImgSize = ___htonl(psImgHdrOld->ih_size);
+				uiEntryPoint = ___htonl(psImgHdrOld->ih_ep);
+				uiLoadPoint = ___htonl(psImgHdrOld->ih_load) - uiImgHdrSizeOld;   /* ÕâÀïʹÓÃLOADµØÖ· */
+		        lzmaLoadPoint = uiLoadPoint;
+				BOOT_PRINTF(UBOOT_NOTICE, "Load AP image, Size=0x%0x, to 0x%0x.\n",
+						uiImgSize, uiLoadPoint);
+
+#if LOAD_IMAGE_CRC
+				uiCRCChkSum = ___htonl(psImgHdrOld->ih_dcrc);
+				BOOT_PRINTF(UBOOT_NOTICE, "AP image CRC Checksum=0x%0x.\n", uiCRCChkSum);
+#endif
+				/*4¡¢¿½±´µÚÒ»°ü°æ±¾Êý¾Ýµ½ÔËÐеØÖ· */
+	   			memcpy((uchar *)(uiLoadPoint - uiImgHdrSizeNew), 
+	   				   (uchar *)(CONFIG_SYS_SDRAM_TEMP_LZMA), 
+	   				   ztelzma_uncompresssize);
+				firstlzma_flag = 1;
+				lastlzmaSize = ztelzma_uncompresssize - uiImgHdrSizeNew;
+			}
+			else
+			{
+				lzmaLoadPoint = lzmaLoadPoint + lastlzmaSize ;
+				lastlzmaSize = ztelzma_uncompresssize;
+				/*5¡¢¿½±´Ê£Óà°ü°æ±¾Êý¾Ýµ½ÔËÐеØÖ· */
+				
+				lzmadecompr_ret=lzma_decompress((unsigned char *)(CONFIG_SYS_SDRAM_TEMP_BASE+uiImgHdrlzma), 
+												(unsigned char *)(lzmaLoadPoint), 
+												ztelzma_compresssize, lastlzmaSize);
+				if(lzmadecompr_ret)
+				{
+					printf("lzma_decompress failed\n");
+					return -1;
+				}
+			}
+			apimagenum++;
+		}
+	}
+	
+	BOOT_PRINTF(UBOOT_NOTICE, "AP image load finished\n");
+
+	if(guiEfuseStatus == 0)    //Secure Verify.
+	{
+		BOOT_PRINTF(UBOOT_DBG, "AP image Start Secure Verify...\n");
+
+		ucRet = secure_verify((u32 )uiLoadPoint - uiImgHdrSizeNew);
+		if(ucRet != 0)
+		{
+			BOOT_PRINTF(UBOOT_ERR, "AP image Secure Verify FAILED!\n");
+			return 1;
+		}
+		BOOT_PRINTF(UBOOT_NOTICE, "AP image Secure Verify PASS!\n");
+	}
+	else
+	{
+		BOOT_PRINTF(UBOOT_NOTICE, "AP image Skip Secure Verify...\n");
+	}
+
+	if(strncmp((const char *)image_name, "cpucap", 6) == 0)
+	{
+		arm_cpucap_ep = uiEntryPoint;    /* usually */
+	}
+	else
+	{
+		sys_ddr_kernel_start = uiEntryPoint - 0x8000;    /* usually */
+		gd->bd->bi_boot_params = sys_ddr_kernel_start + 0x100;
+		sprintf((char *)cmd," bootm 0x%0x", uiLoadPoint);
+		setenv("bootcmd", (char *)cmd);
+	}
+
+#if	LOAD_IMAGE_CRC
+	//invalidate_dcache_range(uiEntryPoint, uiEntryPoint + uiImgSize);
+	ret = arm_image_crc_calc(ARM_APP_IMAGE, uiCRCChkSum, uiEntryPoint, uiImgSize);
+	if(ret != 0)
+	{
+		BOOT_PRINTF(UBOOT_ERR, "ap image crc calc failed, ret = %d! \n", ret);
+		return -1;
+	}
+#endif
+
+	return 0;
+
+}
+#else
+
+int fs_load_zsp_image(void)
+{
+	char cmd[64] = {0};
+	uint32_t image_tmp_buf = 0;
+
+	BOOT_PRINTF(UBOOT_NOTICE, "zsp image load begin...\n");
+	image_tmp_buf = CONFIG_SYS_SDRAM_TEMP_BASE;
+//#ifdef CONFIG_ZX297520V3E_MDL_AB
+#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
+	if(imagefs_flag == 1)
+        sprintf(cmd, "fsload imagefs 0x%x %s", (ulong)image_tmp_buf, ZSP_IMAGE_PATH);
+	else
+		sprintf(cmd, "fsload imagefs2 0x%x %s", (ulong)image_tmp_buf, ZSP_IMAGE_PATH);
+#else
+	sprintf(cmd, "fsload imagefs 0x%x %s", (ulong)image_tmp_buf, ZSP_IMAGE_PATH);
+#endif
+	run_command(cmd, 0);
+	
+	reform_zsp_image(image_tmp_buf);
+	BOOT_PRINTF(UBOOT_NOTICE, "zsp image load finished.\n");
+
+	return 0;
+}
+
+int fs_load_arm_image_linux(char* image_name )
+{
+	char	cmd[64] = {0};
+	int ret = 0;
+	u8 ucRet = 0;
+		
+	uint32_t uiImgSize = 0;
+	uint32_t uiEntryPoint = 0;
+	uint32_t uiLoadPoint = 0;
+#if LOAD_IMAGE_CRC
+	uint32_t uiCRCChkSum = 0;
+	uint32_t uiCRCCalRes = 0;
+#endif
+	uint32_t uiImgHdrSizeOld = sizeof(image_header_t);
+	uint32_t uiImgHdrSizeNew = 0;
+
+	uiImgHdrSizeNew = sizeof(sImageHeader); 
+
+	image_header_t *psImgHdrOld = NULL;
+
+	/*1¡¢½«ap imgÎļþloadµ½ÁÙʱµØÖ·*/
+//#ifdef CONFIG_ZX297520V3E_MDL_AB
+#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
+	if(imagefs_flag == 1)
+		sprintf(cmd, "fsload imagefs 0x%x /ap_%s.bin", 
+				(ulong)CONFIG_SYS_SDRAM_TEMP_BASE, image_name);
+	else
+		sprintf(cmd, "fsload imagefs2 0x%x /ap_%s.bin", 
+				(ulong)CONFIG_SYS_SDRAM_TEMP_BASE, image_name);
+#else
+	sprintf(cmd, "fsload imagefs 0x%x /ap_%s.bin", 
+				(ulong)CONFIG_SYS_SDRAM_TEMP_BASE, image_name);
+#endif	
+	run_command(cmd, 0);
+
+	/*»ñÈ¡¹«Ô¿´«µÝ¸ø´ó°æ±¾Ê¹ÓÃ*/
+	memcpy(CFG_SECURE_PUK_ADDR,CONFIG_SYS_SDRAM_TEMP_BASE,256);
+	
+	/*2¡¢»ñÈ¡°æ±¾µÄ´óСºÍÔËÐеØÖ· */
+	psImgHdrOld = (image_header_t *)(CONFIG_SYS_SDRAM_TEMP_BASE + uiImgHdrSizeNew);
+	if(___htonl(psImgHdrOld->ih_magic) != IH_MAGIC)
+	{
+		BOOT_PRINTF(UBOOT_ERR, "Magic Num Check Failed,Maybe no AP bin !!!\n");
+		return 1;
+	}
+
+	uiImgSize = ___htonl(psImgHdrOld->ih_size);
+	uiEntryPoint = ___htonl(psImgHdrOld->ih_ep);
+	uiLoadPoint = ___htonl(psImgHdrOld->ih_load) - uiImgHdrSizeOld;   /* ÕâÀïʹÓÃLOADµØÖ· */
+
+	BOOT_PRINTF(UBOOT_NOTICE, "Load AP image, Size=0x%0x, to 0x%0x.\n",
+			uiImgSize, uiLoadPoint);
+
+#if LOAD_IMAGE_CRC
+	uiCRCChkSum = ___htonl(psImgHdrOld->ih_dcrc);
+	BOOT_PRINTF(UBOOT_NOTICE, "AP image CRC Checksum=0x%0x.\n", uiCRCChkSum);
+#endif
+	BOOT_PRINTF(UBOOT_NOTICE, "AP image uiLoadPoint=0x%0x.\n", uiLoadPoint);
+
+	/*3¡¢¿½±´°æ±¾Êý¾Ýµ½ÔËÐеØÖ· */
+	memcpy((uchar *)uiLoadPoint, 
+			(uchar *)(CONFIG_SYS_SDRAM_TEMP_BASE + uiImgHdrSizeNew), 
+			uiImgSize +uiImgHdrSizeOld);
+
+	BOOT_PRINTF(UBOOT_NOTICE, "AP image load image finished\n");
+
+	if(guiEfuseStatus == 0)    //Secure Verify.
+	{
+		BOOT_PRINTF(UBOOT_DBG, "AP image Start Secure Verify...\n");
+
+		ucRet = secure_verify((u32 )CONFIG_SYS_SDRAM_TEMP_BASE);
+		if(ucRet != 0)
+		{
+			BOOT_PRINTF(UBOOT_ERR, "AP image Secure Verify FAILED!\n");
+			return 1;
+		}
+		BOOT_PRINTF(UBOOT_NOTICE, "AP image Secure Verify PASS!\n");
+	}
+	else
+	{
+		BOOT_PRINTF(UBOOT_NOTICE, "AP image Skip Secure Verify...\n");
+	}
+
+	if(strncmp((const char *)image_name, "cpucap", 6) == 0)
+	{
+		arm_cpucap_ep = uiEntryPoint;    /* usually */
+		printf("cpucap load finish....\n");
+	}
+	else
+	{
+		sys_ddr_kernel_start = uiEntryPoint - 0x8000;    /* usually */
+		gd->bd->bi_boot_params = sys_ddr_kernel_start + 0x100;
+
+		sprintf((char *)cmd," bootm 0x%0x", uiLoadPoint);
+		setenv("bootcmd", (char *)cmd);
+	}
+#if	LOAD_IMAGE_CRC
+	//invalidate_dcache_range(uiEntryPoint, uiEntryPoint + uiImgSize);
+	ret = arm_image_crc_calc(ARM_APP_IMAGE, uiCRCChkSum, uiEntryPoint, uiImgSize);
+	if(ret != 0)
+	{
+		BOOT_PRINTF(UBOOT_ERR, "ap image crc calc failed, ret = %d! \n", ret);
+		return -1;
+	}
+#endif
+
+	return 0;
+}
+
+#endif 
+
+int load_imagefs(uchar * part_name)
+{
+	int ret = 0;
+	int type = 0;
+	struct flash_ops *flash = NULL;
+	uint32_t i = 0;
+	uint32_t bad_nums = 0;
+	uint32_t part_block_nums = 0;
+	uint32_t part_offset = 0;
+	uint32_t part_size = 0;
+	nand_info_t *nand = &nand_info[nand_curr_device];
+	struct fsl_qspi *nor = &spi_nor_flash;
+
+	/* ´Ë´¦±ØÐëÇå0xFF£¬±£Ö¤¾µÏñÍêÕû£¬²»ÊÜÉÏ´ÎÒÅÁôÊý¾ÝÓ°Ïì*/
+	memset(CONFIG_SYS_SDRAM_IMAGEFS_BASE, 0xFF, CONFIG_SYS_SDRAM_IMAGEFS_SIZE);
+	flush_dcache_all();
+
+    flash_dmabuf_disable_flag = 1;
+	flash = get_flash_ops();
+	type = read_boot_flashtype();
+
+	/* ѰÕÒ·ÖÇø */
+	partition_entry_t * entry = find_partition_para(part_name);
+	if( entry == NULL )
+	{
+		BOOT_PRINTF(UBOOT_ERR, "[%s]: can't find the partition...\n", part_name);
+		return 1;
+	}
+
+	/* »ñµÃ·ÖÇøÊ×µØÖ· */
+	part_offset = entry->part_offset;
+	part_size = entry->part_size;
+
+	if(part_size > CONFIG_SYS_SDRAM_IMAGEFS_SIZE)
+	{
+		BOOT_PRINTF(UBOOT_ERR, "[%s] part size more than SDRAM IMAGEFS space !!!\n", part_name);
+		return 1;
+	}
+	
+	if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND)
+	{
+		/* ²éѯµ±Ç°·ÖÇø»µ¿éÊý*/
+		bad_nums = 0;
+		part_block_nums = entry->part_size / nand->erasesize;
+		for(i = 0; i < part_block_nums; i++)
+		{
+			if(nand_block_isbad (nand, entry->part_offset + (loff_t)i * nand->erasesize))
+			{
+				printf("bad block addr = 0x%x\n", (entry->part_offset + i * nand->erasesize));
+				bad_nums++;
+			}
+		}
+		
+		part_size = part_size - bad_nums * nand->erasesize;
+		ret = flash->read(nand,(loff_t)part_offset,
+						  &part_size,(u_char *)CONFIG_SYS_SDRAM_IMAGEFS_BASE);
+		if( ret != 0 )
+		{
+			BOOT_PRINTF(UBOOT_ERR, "[%s]: read the imagefs error!\n", part_name);
+			return 1;
+		}
+	}
+	else if(type == IF_TYPE_NOR)
+	{
+		ret = nand_read(&(nor->nor[0].mtd), (loff_t)part_offset, 
+						&part_size, (u_char *)CONFIG_SYS_SDRAM_IMAGEFS_BASE);
+		if(ret)
+		{
+			BOOT_PRINTF(UBOOT_ERR, "[%s]: read the imagefs error!\n", part_name);
+			return -1;
+		}
+	}
+	
+	flash_dmabuf_disable_flag = 0; 
+	flush_dcache_all();
+
+	return 0;
+}
+
+//#ifdef CONFIG_ZX297520V3E_MDL_AB
+#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
+int load_flags(T_FOTA_FLAG_INFO *fotaFlagInfo)
+{
+	int ret = 0;
+	int type = 0;
+	uchar * part_name = "flags";
+	struct flash_ops *flash = NULL;
+	uint32_t i = 0;
+	uint32_t off = 0;
+	uint32_t bad_nums = 0;
+	uint32_t part_block_nums = 0;
+	uint32_t part_offset = 0;
+	uint32_t part_size = 0;
+	uint32_t blockNum = 0;
+	uint32_t work_area_offset = 0;
+	uint32_t backup_area_offset = 0;
+	uint32_t flag_one = 0;
+	uint32_t  fota_size = sizeof(T_FOTA_FLAG_INFO);
+	nand_info_t *nand = &nand_info[nand_curr_device];
+	struct fsl_qspi *nor = &spi_nor_flash;
+
+	flush_dcache_all();
+    flash_dmabuf_disable_flag = 1;
+	flash = get_flash_ops();
+	type = read_boot_flashtype();
+
+	/* ѰÕÒ·ÖÇø */
+	partition_entry_t * entry = find_partition_para(part_name);
+	if( entry == NULL )
+	{
+		BOOT_PRINTF(UBOOT_ERR, "[%s]: can't find the partition...\n", part_name);
+		return 1;
+	}
+
+	/* »ñµÃ·ÖÇøÊ×µØÖ· */
+	part_offset = entry->part_offset;
+	part_size = entry->part_size;
+	//while(flag);
+	if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND)
+	{
+        /*È·¶¨¹¤×÷ÇøºÍ±¸·ÝÇøÆ«ÒÆµØÖ·*/
+		for (off = part_offset; off < part_offset+part_size; off += nand->erasesize)
+		{
+            if (!(nand_block_isbad(nand,off)))
+			{
+	            blockNum += 1;
+			}   
+		
+			if((blockNum == 1) && (flag_one == 0))
+			{
+	            work_area_offset = off;
+				flag_one = 1;
+			}
+			
+			else if(blockNum == 2)
+			{
+	             backup_area_offset = off;
+				 break;
+			}		
+		}
+
+		if(blockNum < 2)
+		{
+	        printf("flags partition have not enough space!\n");
+				
+			return -1;
+		}
+	   
+		ret = flash->read(nand,(loff_t)work_area_offset,
+						  &fota_size,(u_char *)(fotaFlagInfo));
+		if( ret != 0 )
+		{
+			BOOT_PRINTF(UBOOT_ERR, "[%s]: read the flags error!\n", part_name);
+			return 1;
+		}
+		
+		if(fotaFlagInfo->boot_flag.magic != FLAGS_MAGIC)
+		{
+			ret = flash->read(nand,(loff_t)backup_area_offset,
+						  &fota_size,(u_char *)(fotaFlagInfo));
+			if(ret != 0)
+			{
+				printf("read flags backup partition err.\n");
+				
+				return -1;
+			}
+			
+			if(fotaFlagInfo->boot_flag.magic != FLAGS_MAGIC)
+			{
+	            printf("flags magic err.\n");
+			    return -1;
+			}	
+		}
+	}
+	else if(type == IF_TYPE_NOR)
+	{
+        work_area_offset = part_offset;
+	    backup_area_offset = part_offset + nor->nor[0].mtd.erasesize;
+		ret = nand_read(&(nor->nor[0].mtd), (loff_t)work_area_offset, 
+						&fota_size, (u_char *)(fotaFlagInfo));
+		if(ret)
+		{
+			BOOT_PRINTF(UBOOT_ERR, "[%s]: read the flags error!\n", part_name);
+			return -1;
+		}
+		if(fotaFlagInfo->boot_flag.magic != FLAGS_MAGIC)
+		{
+			ret = nand_read(&(nor->nor[0].mtd), (loff_t)backup_area_offset, 
+						&fota_size, (u_char *)(fotaFlagInfo));
+			if(ret != 0)
+			{
+				printf("read flags backup partition err.\n");
+				
+				return -1;
+			}
+			
+			if(fotaFlagInfo->boot_flag.magic != FLAGS_MAGIC)
+			{
+	            printf("flags magic err.\n");
+			    return -1;
+			}	
+		}
+	}
+	
+	flash_dmabuf_disable_flag = 0;
+	flush_dcache_all();
+
+	return 0;
+}
+
+#endif
+/* ================================================================================
+ *  get_fota_update_flag  :
+ * @return 0              :  not fota update
+ * @return 1              :  fota update
+ * @return -1             :  error
+ */
+int get_fota_update_flag( void )
+{
+	char cmd[64] = {0};
+//#ifdef CONFIG_ZX297520V3E_MDL_AB
+#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
+	if(imagefs_flag == 1)
+	    sprintf(cmd, "fsload imagefs 0x%x %s", (ulong)CONFIG_SYS_SDRAM_TEMP_BASE, FOTAFLAG_PATH);
+	else
+		sprintf(cmd, "fsload imagefs2 0x%x %s", (ulong)CONFIG_SYS_SDRAM_TEMP_BASE, FOTAFLAG_PATH);
+#else	
+	sprintf(cmd, "fsload imagefs 0x%x %s", (ulong)CONFIG_SYS_SDRAM_TEMP_BASE, FOTAFLAG_PATH);
+#endif
+	run_command(cmd, 0);
+
+	if( strncmp( (char *)CONFIG_SYS_SDRAM_TEMP_BASE, (char *)ARM_FOTA_FLAG, strlen(ARM_FOTA_FLAG)) == 0)
+	{
+		fota_upflag = FOTA_UPDATE;
+	}
+	else if( strncmp( (char *)CONFIG_SYS_SDRAM_TEMP_BASE, (char *)ARM_LOCAL_UPDATE_FLAG, strlen(ARM_LOCAL_UPDATE_FLAG)) == 0)
+	{
+		fota_upflag = FOTA_LOCALUPDATE;
+	}
+	else if( strncmp( (char *)CONFIG_SYS_SDRAM_TEMP_BASE, (char *)ARM_RECOVERY_FLAG, strlen(ARM_RECOVERY_FLAG)) == 0)  
+	{
+		fota_upflag = FOTA_RECOVERY;
+	}
+	else
+	{
+		fota_upflag = FOTA_NORMAL;
+	}
+
+	BOOT_PRINTF(UBOOT_NOTICE, "fota_upflag=%d\n", fota_upflag);
+	
+	return 0;
+}
+
+/* ================================================================================
+ *  get_gmac_init_flag  :
+ * @return 0              : 
+ * @return 1              :  
+ * @return -1             : 
+ */
+int get_gmac_init_flag( void )
+{
+	//hsy
+	return 0;
+}
+
+/* ================================================================================
+ * read_gmac_init_flag  :
+ * @return 0              : not init
+ * @return 1              :  init
+ */
+int read_gmac_init_flag( void )
+{
+	return g_gmac_init_flag;
+}
+
+/* ================================================================================
+ * read_gmac_init_overtime  :
+ * @return : Ãë
+ */
+int read_gmac_init_overtime( void )
+{
+	return g_gmac_init_overtime;
+}
+
+/* ================================================================================
+ * read_fota_update_flag  :
+ * @return 0              :  not fota update
+ * @return 1              :  fota update
+ */
+int read_fota_update_flag( void )
+{
+	return fota_upflag;
+}
+
+/* ================================================================================
+ * read_fota_update_flag  :
+ * @return 0              :  not fota update
+ * @return 1              :  fota update
+ */
+
+int read_fota_psup_flag( void )
+{
+	return fota_psup_flag;
+}
+
+/* ================================================================================
+ *  start_arm_ps  :  Æô¶¯ ARM_PS °æ±¾
+ */
+void start_arm_ps( void )
+{
+	void	(*ps_start)();
+
+	printf("Starting the arm_ps ...\n");
+	ps_start = (void (*)())arm_ps_ep;
+	ps_start();
+}
+
+/* ================================================================================
+ *  start_arm_phy  :  Æô¶¯ ARM_PHY °æ±¾
+ */
+void start_arm_phy( void )
+{
+	/* д PHY Ìø×ªÆô¶¯´úÂë */
+	writel(0xE59ff000, SYS_IRAM3_BASE);
+	writel(arm_phy_ep, SYS_IRAM3_BASE + 8);
+
+	/* ÊÍ·ÅÆô¶¯ ARM_PHY  */
+	printf("Starting the arm_phy ...\n");
+	writel(CPU_PHY_SW_RSTEN, CPU_PHY_SUBSYS_CFG);
+}
+
+/* ================================================================================
+ *  start_cpucap_cores  :  Æô¶¯°æ±¾
+ */
+void start_cpucap_cores( void )
+{
+	writel(0xE59ff000, SYS_CPUCAP_BOOT_BASE);
+	writel(arm_cpucap_ep, SYS_CPUCAP_BOOT_BASE + 8);
+	printf("cap addr is 0x%x\n",arm_cpucap_ep);
+	BOOT_PRINTF(UBOOT_NOTICE, "Starting the cpu cap ...\n");
+	writel(CPU_CAP_SW_RSTEN, CPU_CAP_SUBSYS_CFG);
+}
+
+static void usdelay(volatile int count)
+{
+    	volatile int cnt = 0;
+	count =count *8;
+	
+	while(cnt<count)
+	{
+		cnt++;
+	}
+	return;
+}
+void cap_poweron(void)
+{
+	u32 tmp;
+	
+	BOOT_PRINTF(UBOOT_NOTICE, "cap_poweron  ...\n");
+	
+	tmp = readl(CORE_OUTPUT_SW_CONFIG_REG2) ;/*ap mg on*/
+	tmp |=  (0x1<<3);
+	writel(tmp, CORE_OUTPUT_SW_CONFIG_REG2);
+
+	usdelay(1);
+	
+	tmp = readl(CORE_OUTPUT_SW_CONFIG_REG2) ;/*ap mg rst*/
+	tmp &=  ~(0x1<<4);
+	writel(tmp, CORE_OUTPUT_SW_CONFIG_REG2);
+	
+	usdelay(1);
+	
+	tmp = readl(CORE_OUTPUT_SW_CONFIG_REG2) ;/*ap mg iso*/
+	tmp &=  ~(0x1<<5);
+	writel(tmp, CORE_OUTPUT_SW_CONFIG_REG2);
+	
+	usdelay(1);
+	
+	tmp = readl(CORE_OUTPUT_SW_CONFIG_REG1) ;/*ap clk on*/
+	tmp |=  (0x1<<2);
+	writel(tmp, CORE_OUTPUT_SW_CONFIG_REG1);	
+
+	tmp = readl(CORE_OUTPUT_SWITCH_CONFIG_REG) ; /*ap clk&mg control by hw*/
+	tmp |= ((0x1<<2)|(0x1<<5));
+	writel(tmp, CORE_OUTPUT_SWITCH_CONFIG_REG);	
+	//__REG(0x0013a0ac) |= ((0x1<<2)|(0x1<<5));    /*ap clk&mg control by hw*/
+	//__REG(0x0013a0bc)       |= (0x1<<3);              /*ap mg off*/
+	//__REG(0x0013a0bc)       &= ~(0x1<<4);               /*ap mg rst*/
+	//__REG(0x0013a0bc)       &= ~(0x1<<5);               /*ap mg iso*/
+	//__REG(0x0013a0b8)       |= (0x1<<2);               /*ap clk off*/
+
+}
+	
+/* ================================================================================
+ *  read_sys_ddr_kernel_start  :  »ñÈ¡ kernel ÔËÐпռä Ê×µØÖ·
+ */
+uint32_t read_sys_ddr_kernel_start(void)
+{
+	/* Get Addr from Image Header. */
+	return sys_ddr_kernel_start;
+}
+
+/* ================================================================================
+ *  update_led_enable  : enable led
+ * @return 0        :  ³É¹¦
+ * @return 1        :  ʧ°Ü
+ */
+int update_led_enable(int enable)
+{
+	int ret = 0;
+
+	if(enable)
+	{
+#ifdef CONFIG_BOARD_7520_UFI_956
+		ret = sn3216_SetStatus(LED_CHANNEL_WAN_GREEN,SN3216_LED_STATUS_ON);
+		ret = sn3216_SetStatus(LED_CHANNEL_LAN_GREEN,SN3216_LED_STATUS_ON);
+		ret = sn3216_SetStatus(LED_CHANNEL_BAT_GREEN,SN3216_LED_STATUS_ON);
+		ret = sn3216_SetStatus(LED_CHANNEL_SMS_GREEN,SN3216_LED_STATUS_ON);
+#endif
+	}
+	else
+	{
+#ifdef CONFIG_BOARD_7520_UFI_956
+		ret = sn3216_SetStatus(LED_CHANNEL_WAN_GREEN,SN3216_LED_STATUS_OFF);
+		ret = sn3216_SetStatus(LED_CHANNEL_LAN_GREEN,SN3216_LED_STATUS_OFF);
+		ret = sn3216_SetStatus(LED_CHANNEL_BAT_GREEN,SN3216_LED_STATUS_OFF);
+		ret = sn3216_SetStatus(LED_CHANNEL_SMS_GREEN,SN3216_LED_STATUS_OFF);
+#endif
+	}
+	return ret;
+}
+
+/* ================================================================================
+ *  update_led_twinkle  :  config led in local update
+ * @return 0        :  ³É¹¦
+ * @return 1        :  ʧ°Ü
+ */
+void update_led_twinkle(void)
+{
+	int start_time = 0;
+	if(update_start_time)
+	{
+		update_recent_time = get_timer(0);
+		if(update_recent_time-update_start_time > 6000000) /*1s*/
+		{
+			led_state = (~led_state)& 0x00000001;
+			update_led_enable(led_state); /*LED on/off*/
+			update_start_time = update_recent_time;
+		}
+	}
+	return ;
+}
+
+/* ================================================================================
+ *  copy_write_part  : write data to flash
+ * @return 0        :  ³É¹¦
+ * @return 1        :  ʧ°Ü
+ */
+int copy_write_part_gmac(int cnt)
+{
+	int ret = 0;
+	nand_info_t *nand = &nand_info[nand_curr_device];
+	image_bin_header_t * img_head = &(master_head->image[cnt]);
+	int filesize = img_head->filelength;
+	char *partname = (char *)(img_head->partitonname);
+	int bin_offset = img_head->fileaddr;
+	int part_offset = img_head->partitonoffset;
+	//uchar * buf = malloc(12*1024);
+	uchar *buf = NULL;
+	partition_entry_t * part = NULL;
+
+	buf =  kzalloc(12*1024, GFP_KERNEL);
+	if(buf == NULL)
+	{
+		return -1;
+	}
+	
+	part = find_partition_para((uchar *)partname);
+	if(part == NULL)
+	{
+		return -1;
+	}
+
+	/* µ±Ç°ÊÇÔÚµçÄÔÉÏÖ´ÐУ¬Ã»ÓеôµçΣÏÕ£¬ËùÒÔ¿ÉÒÔ²Á³ýzloader */
+	/* zloaderÓÐÁ½²¿·Ö×é³É: 8kµÄbin + 4kµÄ·ÖÇø±í */
+	if(!strcmp(partname, "zloader"))
+	{
+		BOOT_PRINTF(UBOOT_NOTICE, "write part %s, offset=0x%x, filesize=0x%x.\n",
+			partname, part->part_offset, filesize);
+		ret = downloader_nand_erase(part,part->part_size);
+
+		//memcpy(buf,(u_char *)(CONFIG_SYS_SDRAM_BASE+bin_offset),8192);//zloader
+		memcpy(buf, (u_char *)(CONFIG_LOADADDR+bin_offset), 8192);//zloader
+		memcpy((char *)(buf+8192), g_partition_table, 4096);//part
+
+		int times = 12*1024/nand->writesize;
+		int i;
+		for(i = 0; i < times; i++)
+		{      
+			ret += nand_write_page_with_no_ecc(nand, 
+											   ((loff_t)i*(nand->writesize)), 
+											   buf );                
+			buf += nand->writesize;
+		}
+	       // free(buf);    
+		return ret;
+	}
+	
+	if(strcmp(img_head->partitontype,"nand") == 0)
+	{
+		BOOT_PRINTF(UBOOT_NOTICE, "write part %s, offset=0x%x, filesize=0x%x\n",
+			partname, part->part_offset, filesize);
+		ret = downloader_nand_erase(part,part->part_size);
+		//ret = nand_write_skip_bad(nand, part->part_offset, &filesize, (u_char *)(CONFIG_SYS_SDRAM_BASE+bin_offset),0);
+		ret = nand_write_skip_bad(nand, part->part_offset, &filesize, (u_char *)(CONFIG_LOADADDR+bin_offset),0);
+		
+	}
+
+	return ret;
+}
+
+/* ================================================================================
+ *  copy_ddr_allbin  :  webui local update
+ * @return 0        :  ³É¹¦
+ * @return 1        :  ʧ°Ü
+ */
+int copy_ddr_allbin(void)
+{
+	int ret = 0;
+	int i = 0;
+	int head_size = 0x2000;    //total 6608 bytes
+	nand_info_t *nand = &nand_info[nand_curr_device];
+
+	master_head = kzalloc(0x2000, GFP_KERNEL);
+	if(master_head == NULL)
+	{
+		BOOT_PRINTF(UBOOT_ERR, "kzalloc fail!\n");
+		return -1;
+	}
+	
+	memcpy(( u_char *)master_head,(char *)CONFIG_LOADADDR, head_size);
+
+	BOOT_PRINTF(UBOOT_NOTICE, "file number = %d\n", master_head->dwFileNumber);
+
+	for(i = 0; i < (sizeof(master_head->image)/sizeof(image_bin_header_t))
+		&& i < master_head->dwFileNumber; i++) /* update each partition */
+	{
+		ret = copy_write_part_gmac(i);
+		if(ret != 0)
+		{
+			BOOT_PRINTF(UBOOT_ERR, "write from ddr to nand ERROR !!!\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+