| /* | 
 |  * (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> | 
 | #include "pub_flags.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) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF) | 
 | 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; | 
 | } | 
 |  | 
 | #if defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF) | 
 | int fs_load_dtb_image(void) | 
 | { | 
 |     char    cmd[64] = {0}; | 
 |     /*1¡¢½«dtbÎļþloadµ½ÁÙʱµØÖ·*/ | 
 | #if defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF) | 
 |     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 *)DDR_BASE_CAP_DTB_ADDR,  | 
 | 			(uchar *)(CONFIG_SYS_SDRAM_TEMP_BASE),  | 
 | 			CAP_DTB_LEN); | 
 |  | 
 | 	BOOT_PRINTF(UBOOT_NOTICE, "dtb load image finished\n"); | 
 | 	 | 
 | 	return 0; | 
 | } | 
 | #endif | 
 |  | 
 | 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) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF) | 
 |     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)  || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF) | 
 |         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) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF) | 
 |         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) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF) | 
 | 	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) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF) | 
 | 	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) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF) | 
 | int load_flags(T_FLAGS_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_FLAGS_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->magic_start != FLAGS_MAGIC) | 
 | 		{	 | 
 | 			flush_dcache_all(); | 
 | 			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->magic_start != 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->magic_start != FLAGS_MAGIC) | 
 | 		{ | 
 |             flush_dcache_all(); | 
 | 			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->magic_start != 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) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF) | 
 | 	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; | 
 | } | 
 |  |