blob: 2c9c8e706ba8b145395b28687c893f34f8c20d03 [file] [log] [blame]
/*
* (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))
#define reg32(addr) (*(volatile unsigned long *)(addr))
#define RSA_1024 10
#define RSA_2048 11
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;
extern unsigned int guiOtpStatus;
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;
int rootfs_flag = 0;
int m0_flag = 0;
int zsp_flag = 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;
int ret = 0;
u8 ucRet = 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
ret = run_command(cmd, 0);
if(ret < 0)
return ret;
flush_dcache_all();
#if defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
m0_flag = 1;
if(g_nor_flag == 1)
{
if(guiOtpStatus == 0) //Secure Verify.
{
BOOT_PRINTF(UBOOT_DBG, "rpm image Start Secure Verify...\n");
ucRet = secure_verify((u32 )CONFIG_SYS_SDRAM_TEMP_BASE);
if(ucRet != 0)
{
BOOT_PRINTF(UBOOT_ERR, "rpm image Secure Verify FAILED!\n");
return 1;
}
BOOT_PRINTF(UBOOT_NOTICE, "rpm image Secure Verify PASS!\n");
}
else
{
BOOT_PRINTF(UBOOT_NOTICE, "rpm image Skip Secure Verify...\n");
}
}
else
{
if(guiEfuseStatus == 0) //Secure Verify.
{
BOOT_PRINTF(UBOOT_DBG, "rpm image Start Secure Verify...\n");
ucRet = secure_verify((u32 )CONFIG_SYS_SDRAM_TEMP_BASE);
if(ucRet != 0)
{
BOOT_PRINTF(UBOOT_ERR, "rpm image Secure Verify FAILED!\n");
return 1;
}
BOOT_PRINTF(UBOOT_NOTICE, "rpm image Secure Verify PASS!\n");
}
else
{
BOOT_PRINTF(UBOOT_NOTICE, "rpm image Skip Secure Verify...\n");
}
}
m0_flag = 0;
#endif
/*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;
}
int load_rootfs(void)
{
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;
uchar * part_name = "rootfs";;
nand_info_t *nand = &nand_info[nand_curr_device];
flush_dcache_all();
flash_dmabuf_disable_flag = 1;
flash = get_flash_ops();
type = read_boot_flashtype();
#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
if(imagefs_flag == 1)
{
part_name = "rootfs";
}
else
{
part_name = "rootfs2";
}
#endif
/* ѰÕÒ·ÖÇø */
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;
/* ²éѯµ±Ç°·ÖÇø»µ¿éÊý*/
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_ROOTFS_BASE);
if( ret != 0 )
{
BOOT_PRINTF(UBOOT_ERR, "[%s]: read the rootfs error!\n", part_name);
return 1;
}
memcpy((uchar *)(CONFIG_SYS_SDRAM_ROOTFS_BASE - sizeof(image_header_t)),
(uchar *)(CONFIG_SYS_SDRAM_TEMP_BASE + sizeof(sImageNewHeader) + sizeof(sImageNewHeader)),
sizeof(image_header_t));
flash_dmabuf_disable_flag = 0;
flush_dcache_all();
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 + sizeof(sImageNewHeader) + sizeof(image_header_t));
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 uiRootfsHdrSizeOld = sizeof(image_header_t);
uint32_t uiRootfsHdrSizeNew = sizeof(sImageNewHeader);
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(sImageNewHeader);
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;
}
/*»ñÈ¡¹«Ô¿´«µÝ¸ø´ó°æ±¾Ê¹ÓÃ*/
if(reg16(CONFIG_SYS_SDRAM_TEMP_LZMA)== RSA_1024)
{
memset(CFG_SECURE_PUK_ADDR,0,256);
memcpy(CFG_SECURE_PUK_ADDR+124,CONFIG_SYS_SDRAM_TEMP_BASE+12,132);
}else{
printf("signtype is %s\n", reg16(CONFIG_SYS_SDRAM_TEMP_BASE)== RSA_2048 ? "RSA2048":"UNKNOWN");
}
psImgHdrOld = (image_header_t *)(CONFIG_SYS_SDRAM_TEMP_LZMA + uiImgHdrSizeNew + uiRootfsHdrSizeNew + uiRootfsHdrSizeOld);
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 - uiRootfsHdrSizeOld - uiRootfsHdrSizeNew; /* ÕâÀïʹÓÃ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;
uiLoadPoint += (uiRootfsHdrSizeOld + uiRootfsHdrSizeNew);
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;
int ret = 0;
u8 ucRet = 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
ret = run_command(cmd, 0);
if(ret < 0)
return ret;
#if defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
zsp_flag = 1;
if(g_nor_flag == 1)
{
if(guiOtpStatus == 0) //Secure Verify.
{
BOOT_PRINTF(UBOOT_DBG, "zsp image Start Secure Verify...\n");
ucRet = secure_verify((u32 )image_tmp_buf);
if(ucRet != 0)
{
BOOT_PRINTF(UBOOT_ERR, "zsp image Secure Verify FAILED!\n");
return 1;
}
BOOT_PRINTF(UBOOT_NOTICE, "zsp image Secure Verify PASS!\n");
}
else
{
BOOT_PRINTF(UBOOT_NOTICE, "zsp image Skip Secure Verify...\n");
}
}
else
{
if(guiEfuseStatus == 0) //Secure Verify.
{
BOOT_PRINTF(UBOOT_DBG, "zsp image Start Secure Verify...\n");
ucRet = secure_verify((u32 )image_tmp_buf);
if(ucRet != 0)
{
BOOT_PRINTF(UBOOT_ERR, "zsp image Secure Verify FAILED!\n");
return 1;
}
BOOT_PRINTF(UBOOT_NOTICE, "zsp image Secure Verify PASS!\n");
}
else
{
BOOT_PRINTF(UBOOT_NOTICE, "zsp image Skip Secure Verify...\n");
}
}
zsp_flag = 0;
#endif
reform_zsp_image(image_tmp_buf + sizeof(sImageNewHeader) + sizeof(image_header_t));
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 uiRootfsHdrSizeOld = sizeof(image_header_t);
uint32_t uiImgHdrSizeNew = sizeof(sImageNewHeader);
uint32_t uiRootfsHdrSizeNew = sizeof(sImageNewHeader);
image_header_t *psImgHdrOld = NULL;
image_header_t *psRootfsHdrOld = 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
ret = run_command(cmd, 0);
if(ret < 0)
return ret;
if(strncmp((const char *)image_name, "cpuap", 5) == 0)
{
rootfs_flag = 1;
if(g_nor_flag == 1)
{
/*»ñÈ¡¹«Ô¿´«µÝ¸ø´ó°æ±¾Ê¹ÓÃ*/
memcpy(OTP_SECURE_PUK_BASE,(uchar *)CONFIG_SYS_SDRAM_TEMP_BASE+4,380);
//printf("OTP_SECURE_PUK_BASE is 0x%x\n",OTP_SECURE_PUK_BASE);
/*°²È«Ð£Ñérootfs*/
if(guiOtpStatus == 0) //Secure Verify.
{
BOOT_PRINTF(UBOOT_DBG, "AP rootfs Start Secure Verify...\n");
/*¼ÓÔØrootfs¾µÏñ*/
ret = load_rootfs();
if(ret != 0)
{
printf("rootfs load error.\n");
return 1;
}
ucRet = rootfs_secure_verify((u32 )(CONFIG_SYS_SDRAM_TEMP_BASE + uiImgHdrSizeNew));
if(ucRet != 0)
{
BOOT_PRINTF(UBOOT_ERR, "AP rootfs Secure Verify FAILED!\n");
return 1;
}
BOOT_PRINTF(UBOOT_NOTICE, "AP rootfs Secure Verify PASS!\n");
}
else
{
BOOT_PRINTF(UBOOT_NOTICE, "AP rootfs Skip Secure Verify...\n");
}
}
else
{
/*»ñÈ¡¹«Ô¿´«µÝ¸ø´ó°æ±¾Ê¹ÓÃ*/
if(reg16(CONFIG_SYS_SDRAM_TEMP_BASE)== RSA_1024)
{
memset(CFG_SECURE_PUK_ADDR,0,256);
memcpy(CFG_SECURE_PUK_ADDR+124,CONFIG_SYS_SDRAM_TEMP_BASE+12,132);
}else{
printf("signtype is %s\n", reg16(CONFIG_SYS_SDRAM_TEMP_BASE)== RSA_2048 ? "RSA2048":"UNKNOWN");
//printf("pub key is illegal...\n");
}
/*°²È«Ð£Ñérootfs*/
if(guiEfuseStatus == 0) //Secure Verify.
{
BOOT_PRINTF(UBOOT_DBG, "AP rootfs Start Secure Verify...\n");
/*¼ÓÔØrootfs¾µÏñ*/
ret = load_rootfs();
if(ret != 0)
{
printf("rootfs load error.\n");
return 1;
}
ucRet = rootfs_secure_verify((u32 )(CONFIG_SYS_SDRAM_TEMP_BASE + uiImgHdrSizeNew));
if(ucRet != 0)
{
BOOT_PRINTF(UBOOT_ERR, "AP rootfs Secure Verify FAILED!\n");
return 1;
}
BOOT_PRINTF(UBOOT_NOTICE, "AP rootfs Secure Verify PASS!\n");
}
else
{
BOOT_PRINTF(UBOOT_NOTICE, "AP rootfs Skip Secure Verify...\n");
}
}
/*2¡¢»ñÈ¡°æ±¾µÄ´óСºÍÔËÐеØÖ· */
psImgHdrOld = (image_header_t *)(CONFIG_SYS_SDRAM_TEMP_BASE + uiImgHdrSizeNew + uiRootfsHdrSizeNew + uiRootfsHdrSizeOld);
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 - uiRootfsHdrSizeOld - uiRootfsHdrSizeNew; /* ÕâÀïʹÓÃ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 + uiRootfsHdrSizeOld + uiRootfsHdrSizeNew);
BOOT_PRINTF(UBOOT_NOTICE, "AP image load image finished\n");
}
else
{
/*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(g_nor_flag == 1)
{
if(guiOtpStatus == 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");
}
}
else
{
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;
if(1 == rootfs_flag)
uiLoadPoint += (uiRootfsHdrSizeOld + uiRootfsHdrSizeNew);
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;
}