[Feature][ZXW-130]merge P50U02 version

Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: I4f29ec5bb7c59385f23738d2b7ca84e67c100f69
diff --git a/boot/common/src/loader/drivers/efuse.c b/boot/common/src/loader/drivers/efuse.c
old mode 100644
new mode 100755
index c4dc051..2b2cc08
--- a/boot/common/src/loader/drivers/efuse.c
+++ b/boot/common/src/loader/drivers/efuse.c
@@ -47,7 +47,9 @@
 		ddr_flag = CHIP_DDR_64M;
 	}
 	else if(((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOSC_GW_NYC_2G_DDR)
-		||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOGG_GW_NYC_2G_DDR))
+		||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOGG_GW_NYC_2G_DDR)
+		||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOGG_GW_NYC_NOR_2G_DDR)
+		||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOSC_GW_NYC_NOR_2G_DDR))
 	{
 		ddr_flag = CHIP_DDR_256M;
 	}
diff --git a/boot/common/src/loader/drivers/efuse.h b/boot/common/src/loader/drivers/efuse.h
old mode 100644
new mode 100755
index 7089952..791f1b9
--- a/boot/common/src/loader/drivers/efuse.h
+++ b/boot/common/src/loader/drivers/efuse.h
@@ -43,6 +43,8 @@
 #define ZX297520V3ECOSCC_GW_NYB_4G_DDR		0xF86313
 #define ZX297520V3ECOGG_GW_NYC_2G_DDR		0xF86314
 #define ZX297520V3ECOGG_GW_NYB_4G_DDR		0xF86315
+#define ZX297520V3ECOGG_GW_NYC_NOR_2G_DDR	0xF86316
+#define ZX297520V3ECOSC_GW_NYC_NOR_2G_DDR	0xF86317
 
 #define ZX297520V3_ZW_NYB_1G_DDR			0x1E871E
 #define ZX297520V3_ZW_NYC_1G_DDR			0x1E871F
diff --git a/boot/common/src/loader/drivers/image.c b/boot/common/src/loader/drivers/image.c
index 09c296a..4614eb2 100755
--- a/boot/common/src/loader/drivers/image.c
+++ b/boot/common/src/loader/drivers/image.c
@@ -222,7 +222,7 @@
 	uint32_t uiPageSize = 0;
 
 	uint32_t uiImgHdrSizeOld = sizeof(image_header_t);
-	uint32_t uiImgHdrSizeNew = sizeof(sImageHeader);
+	uint32_t uiImgHdrSizeNew = sizeof(sImageNewHeader);
 
 	uint32_t uiUBootSize = 0;
 	uint32_t uiUBootLoadAddr = 0;
@@ -329,7 +329,7 @@
 	writel(remap,0x140000);
 
 	/*3¡¢½âÎöM0µÄ°æ±¾Í·£¬»ñÈ¡ÔËÐеØÖ·ÒÔ¼°´óС*/
-	header = (image_header_t *)CONFIG_SYS_SDRAM_TEMP_BASE;
+	header = (image_header_t *)(CONFIG_SYS_SDRAM_TEMP_BASE + sizeof(sImageNewHeader));
 	m0_size = ___htonl(header->ih_size);    /* m0.bin */
 	m0_load_addr = ___htonl(header->ih_load);
 	*m0_entry_point = ___htonl(header->ih_ep);   
@@ -340,7 +340,7 @@
 	}
 
 	/*4¡¢½«M0µÄ°æ±¾´ÓIRAM0¿½±´µ½load_addr*/
-	memcpy(m0_load_addr, CONFIG_SYS_SDRAM_TEMP_BASE + image_header_size, m0_size); 
+	memcpy(m0_load_addr, CONFIG_SYS_SDRAM_TEMP_BASE + sizeof(sImageNewHeader)+ image_header_size, m0_size); 
 
 	/*5¡¢ÐÞ¸ÄIRAM±ê¼Ç£¬Ê¹BOOT¼ÌÐøÍùÏÂÖ´ÐÐ*/
 	writel(0, M0_IMAGE_READY_FLAG_ADDR);
diff --git a/boot/common/src/loader/drivers/secure_verify.c b/boot/common/src/loader/drivers/secure_verify.c
old mode 100644
new mode 100755
index 98eea5c..30e8473
--- a/boot/common/src/loader/drivers/secure_verify.c
+++ b/boot/common/src/loader/drivers/secure_verify.c
@@ -7,14 +7,10 @@
 #include <asm/string.h>
 #include <sdio.h>
 #include <image.h>
-#include <key.h>
-
-
 #include "efuse.h"
 #include "drv_rsa.h"
 #include "drv_hash.h"
 
-
 #define E_N_LEN 256
 #define HASH_LEN 128
 
@@ -61,21 +57,19 @@
 	u32 uiLen = 0;
 	u32 uiRet = -1;
 	image_header_t *puiLegacyImgAddr = NULL;
-	sImageHeader *psImageHeader = NULL;
+	sImageNewHeader *psImageHeader = NULL;
 	efuse_struct *psEfuseInfo = NULL;
 
 	u32 *puiDataLoadAddr = NULL;
-	u32 *puiArrPubKeyEN = NULL;
 	u32 *puiArrHASH = NULL;
 	u32 uiHashResArr[4] = {0};
 	u32 uiHashResLen = 0;
 	u32 uiHashVerifySize = 0;
 	u32 uiRsaResArr[32] = {0};
+	u32 puiArrPubKey[64] = {0};
 	int guiEfuseStatus = 1;
+	int default_flag = 1;
 
-	u32 sRamKey[5] = {SECURE_EN,SECURE_PUK_HASH0,SECURE_PUK_HASH1,
-					  SECURE_PUK_HASH2,SECURE_PUK_HASH3};
-	
 	T_Rsa_Paramter sRSAInput;
 	u32 *puiRsaResAddr = NULL;
 
@@ -84,15 +78,21 @@
 		return -1;
 	}
 
-	psImageHeader = (sImageHeader *)puiSdrmStartAddr;
-	puiLegacyImgAddr = (image_header_t *)(puiSdrmStartAddr + sizeof(sImageHeader));
+	psImageHeader = (sImageNewHeader *)puiSdrmStartAddr;
+	puiLegacyImgAddr = (image_header_t *)(puiSdrmStartAddr + sizeof(sImageNewHeader));
 	uiHashVerifySize = ___htonl(puiLegacyImgAddr->ih_size) + sizeof(image_header_t);
 
 	guiEfuseStatus = get_secure_verify_status();
 	if(guiEfuseStatus == 0)    //efuse secure verify.
 		psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;
 	else
-		psEfuseInfo = (efuse_struct*)sRamKey;
+	{
+		default_flag = 0;
+#if defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
+        return 0;
+#endif
+	}
+		
 
 	/*
 	 * 0. ¼ì²éPubKeyÊÇ·ñ±»´Û¸Ä¡£
@@ -102,11 +102,12 @@
 	 *    - ²»Í¬£¬·µ»Ø1¡£
 	 */
 	uiLen = E_N_LEN;  //¹«Ô¿EºÍN£¬¹²256byte³¤¶È¡£
-	puiArrPubKeyEN = psImageHeader->uiPubKeyRsaE;
-
+	memcpy((puiArrPubKey+31), psImageHeader->uiPubKeyRsaE, 4);
+	memcpy((puiArrPubKey+32), psImageHeader->uiPubKeyRsaN, 128);
+	
 	uiRet = Hash_Calculate(HASH_MODE_MD5, 
 						   HASH_SMALL_ENDIAN, 
-						   puiArrPubKeyEN, 
+						   puiArrPubKey, 
 						   uiLen, 
 						   NULL, 
 						   0, 
@@ -114,18 +115,21 @@
 						   &uiHashResLen);
 	if(uiRet != 0)
 	{
-		return -1;
-	}
-	
-	if(data_cmp_word((u32 *)psEfuseInfo->puk_hash, 
-						uiHashResArr, uiHashResLen))
-	{
-		printf("Puk hash verify fail!\n");
-		return -1;
+		return 1;
 	}
 
+	if(1 == default_flag)
+	{
+		if(data_cmp_word((u32 *)psEfuseInfo->puk_hash, 
+							uiHashResArr, uiHashResLen))
+		{
+			//printf("Puk hash verify fail!\n");
+			printf("2\n");
+			return 2;
+		}	
+	}
+						
 	puiArrHASH = psImageHeader->uiHashY;
-	uiLen = HASH_LEN;
 
 	/*
 	 * 1. ÀûÓù«Ô¿¶ÔuiHashY'½øÐнâÃÜ£¬µÃµ½1024bit½á¹û¡£
@@ -134,15 +138,16 @@
 	sRSAInput.udNbitLen = 1024;
 	sRSAInput.udEbitLen = 1024;
 	sRSAInput.pudInputM = puiArrHASH;
-	sRSAInput.pudInputE = puiArrPubKeyEN;
-	sRSAInput.pudInputN = (puiArrPubKeyEN + 32);
+	sRSAInput.pudInputE = puiArrPubKey;
+	sRSAInput.pudInputN = (puiArrPubKey + 32);
 	sRSAInput.pudOutputP = uiRsaResArr;
 	
 	uiRet = Rsa_Calculate(sRSAInput);
 	if(uiRet != 0)
 	{
-		printf("Rsa_Calculate fail!\n");
-		return -1;
+		//printf("Rsa_Calculate fail!\n");
+		printf("3\n");
+		return 3;
 	}
 
 	//È¡×îºó4×Ö½Ú×÷ΪPubKey½âÃܺóµÄHASH_MD5Öµ¡£
@@ -160,7 +165,7 @@
 	/* Cleanup Output Buffer. */
 	uiHashResLen = 0;
 	memset(uiHashResArr, 0, 4*sizeof(uiHashResArr[0]));
-	
+		
 	uiRet = Hash_Calculate(HASH_MODE_MD5, 
 						   HASH_SMALL_ENDIAN, 
 						   puiDataLoadAddr, 
@@ -171,16 +176,17 @@
 						   &uiHashResLen);
 	if(uiRet != 0)
 	{
-		printf("Hash_Calculate Fail!\n");
-		return -1;
+		//printf("Hash_Calculate Fail!\n");
+		printf("4\n");
+		return 4;
 	}
 
 	if(data_cmp_word(puiRsaResAddr, uiHashResArr, uiHashResLen))
 	{
-		printf("SignImage Verify Fail!\n");
-		return -1;
+		//printf("SignImage Verify Fail!\n");
+		printf("5\n");
+		return 5;
 	}
-
 	return 0;
 }
 
diff --git a/boot/common/src/loader/drivers/spifc.c b/boot/common/src/loader/drivers/spifc.c
index 61ea186..b41effc 100755
--- a/boot/common/src/loader/drivers/spifc.c
+++ b/boot/common/src/loader/drivers/spifc.c
@@ -77,6 +77,8 @@
 	{0x2C, 0x35, 0x77, 4096, 12, 256, 18, 2048, 0x40000, 1},
 	/*XTX XT26Q04D 512M SPI-NAND*/
 	{0x0B, 0x53, 0x77, 4096, 12, 256, 18, 2048, 0x40000, 1},
+	/*UNIM UM19A0LISW 128M SPI-NAND*/
+	{0xB0, 0x15, 0x77, 2048, 11, 64, 17, 1024, 0x20000, 1},
 	{0}
 };
 
@@ -847,12 +849,19 @@
 	printf("spi-nand:");
 	
 	boot_mode = get_boot_mode();
+#if defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
+    if(boot_mode == NOR_BOOT)
+	{
+		writel(CFG_START_MODE_SPI_NAND, CFG_BOOT_MODE_START_MODE_FOR_UBOOT);
+		return 0; 
+	}
+#else
 	if(boot_mode != SPI_NAND_BOOT)
 	{
 		printf("mode err.\n");
 		return -1; 
 	}
-
+#endif
 	writel(CFG_START_MODE_SPI_NAND, CFG_BOOT_MODE_START_MODE_FOR_UBOOT); 
 	ret = spifc_init();
 	if(ret != 0)
diff --git a/boot/common/src/loader/include/configs/zx297520v3.h b/boot/common/src/loader/include/configs/zx297520v3.h
index c463be8..771f6a8 100755
--- a/boot/common/src/loader/include/configs/zx297520v3.h
+++ b/boot/common/src/loader/include/configs/zx297520v3.h
@@ -60,6 +60,7 @@
 #define M0_PARTITION_NAME       "cpurpm"
 #define UBOOT_IMAGE    			"uboot"
 #define UBOOT_MIRROR_IMAGE    	"uboot-mirr"
+#define ZLOADER_IMAGE    	    "zloader"
 #endif
 
 
diff --git a/boot/common/src/loader/include/image.h b/boot/common/src/loader/include/image.h
index a2865d8..4f2dc68 100755
--- a/boot/common/src/loader/include/image.h
+++ b/boot/common/src/loader/include/image.h
@@ -143,6 +143,33 @@
 	u32 uiHashY[32];
 } sImageHeader;
 
+typedef struct
+{
+	uint16_t   signtype;
+    uint16_t   hashtype;   
+	uint32_t   uiPubKeyRsaELen;
+	uint32_t   uiPubKeyRsaNLen;
+	uint8_t    uiPubKeyRsaE[4];
+	uint8_t    uiPubKeyRsaN[256];
+	uint8_t    reserve[112]; //380 bytes
+    uint8_t    uiHashY[256];    //256 bytes
+} sImageNewHeader;
+
+
+typedef struct
+{
+	u8 		resv;
+	u8 		uart_print;
+	u8		usb_start;
+	u8		usb_timeout;
+	u32		chip_id[2];
+	u32		zdata_length;
+	u32		puk_rsa_d[32];
+	u32		puk_rsa_n[32];
+	u32		hash_y[32];
+	u16		VID;
+	u16		PID;
+} boot_header;
 
 extern int read_uboot_image(uint8_t *name, uint32_t *uboot_entry_point);
 extern  int nand_read_m0(uint32_t *m0_entry_point);
diff --git a/boot/common/src/uboot/arch/arm/include/asm/arch-zx297520v3/efuse.h b/boot/common/src/uboot/arch/arm/include/asm/arch-zx297520v3/efuse.h
old mode 100644
new mode 100755
index dce9dbd..87c3e39
--- a/boot/common/src/uboot/arch/arm/include/asm/arch-zx297520v3/efuse.h
+++ b/boot/common/src/uboot/arch/arm/include/asm/arch-zx297520v3/efuse.h
@@ -44,8 +44,8 @@
 #define ZX297520V3ECOSCC_GW_NYB_4G_DDR		0xF86313
 #define ZX297520V3ECOGG_GW_NYC_2G_DDR		0xF86314
 #define ZX297520V3ECOGG_GW_NYB_4G_DDR		0xF86315
-
-
+#define ZX297520V3ECOGG_GW_NYC_NOR_2G_DDR	0xF86316
+#define ZX297520V3ECOSC_GW_NYC_NOR_2G_DDR	0xF86317
 
 #define ZX297520V3_ZW_NYB_1G_DDR			0x1E871E
 #define ZX297520V3_ZW_NYC_1G_DDR			0x1E871F
diff --git a/boot/common/src/uboot/arch/arm/lib/bootm.c b/boot/common/src/uboot/arch/arm/lib/bootm.c
index 57bb639..41cc4c1 100755
--- a/boot/common/src/uboot/arch/arm/lib/bootm.c
+++ b/boot/common/src/uboot/arch/arm/lib/bootm.c
@@ -68,6 +68,7 @@
 extern unsigned int g_sys_kernel_sdram_size;
 extern unsigned char g_ddr_size_flag;
 
+#define reg32(addr)			(*(volatile unsigned long *)(addr))
 
 void arch_lmb_reserve(struct lmb *lmb)
 {
@@ -294,10 +295,12 @@
 		if(g_ddr_size_flag == CHIP_DDR_IS_128M)
 		{
 			size[bank] = DDR_BASE_LEN_CAP;
+			reg32(IRAM_BASE_ADDR_BOOT_DDR) = DDR_BASE_LEN_CAP;
 		}		
 		else if(g_ddr_size_flag == CHIP_DDR_IS_256M) 
 		{
 			size[bank] = DDR_BASE_LEN_CAP + 0x8000000;
+			reg32(IRAM_BASE_ADDR_BOOT_DDR) = (DDR_BASE_LEN_CAP + 0x8000000);
 		}
 		else
 		{
diff --git a/boot/common/src/uboot/board/zte/zx297520v3/zx297520v3_vehicle_dc_ref.c b/boot/common/src/uboot/board/zte/zx297520v3/zx297520v3_vehicle_dc_ref.c
index 11db015..e3004ae 100755
--- a/boot/common/src/uboot/board/zte/zx297520v3/zx297520v3_vehicle_dc_ref.c
+++ b/boot/common/src/uboot/board/zte/zx297520v3/zx297520v3_vehicle_dc_ref.c
@@ -906,7 +906,7 @@
 #if VERSION_RELEASE
 	if( ret != 0 )
 	{
-		BOOT_PRINTF(UBOOT_ERR, "load images ERROR !!!\n");
+		BOOT_PRINTF(UBOOT_ERR, "load imagefs ERROR !!!\n");
 #ifdef CONFIG_ZX297520V3E_VEHICLE_DC_REF
         writeback_flags();
 		system_reset();
diff --git a/boot/common/src/uboot/downloader/cmd_compat_read.c b/boot/common/src/uboot/downloader/cmd_compat_read.c
old mode 100644
new mode 100755
index 04c59cc..aac83a2
--- a/boot/common/src/uboot/downloader/cmd_compat_read.c
+++ b/boot/common/src/uboot/downloader/cmd_compat_read.c
@@ -33,7 +33,7 @@
 /****************************************************************************
 *							Global Function Prototypes
 ****************************************************************************/
-
+extern int g_iftype;
 
 /*******************************************************************************
  * Function:do_compat_read
@@ -74,6 +74,19 @@
 	    return -1;
 	}
 
+	if(g_nor_flag == 1)
+	{
+	    if(memcmp(par,"zloader",7) == 0) {
+			g_iftype = IF_TYPE_NOR;
+			nand_init();
+			ret = do_nor_read(part, par, offset,size); 
+			/*Çл»³õʼ»¯spi_nand*/
+			g_iftype = IF_TYPE_SPI_NAND;
+			nand_init();		
+			return ret;
+		}
+	}
+
 	if((read_boot_flashtype() == IF_TYPE_NOR) 
 		&& (strcmp((const char *)part->part_type,"nand") == 0))
 
diff --git a/boot/common/src/uboot/downloader/cmd_compat_write.c b/boot/common/src/uboot/downloader/cmd_compat_write.c
old mode 100644
new mode 100755
index 8ac27dd..f4db84f
--- a/boot/common/src/uboot/downloader/cmd_compat_write.c
+++ b/boot/common/src/uboot/downloader/cmd_compat_write.c
@@ -32,7 +32,8 @@
 /****************************************************************************
 *							Global Function Prototypes
 ****************************************************************************/
-
+extern int g_iftype;
+extern partition_table_t * g_partition_table_dl;
 /*******************************************************************************
  * Function:do_compat_write
  * Description:
@@ -70,6 +71,24 @@
         downloader_serial_write(ack, strlen(ack)+1);
 	    return -1;
 	}
+	
+#if defined (CONFIG_ZX297520V3E_VEHICLE_DC) || defined (CONFIG_ZX297520V3E_VEHICLE_DC_REF)
+	if(g_nor_flag == 1)
+	{
+        if(memcmp(par,"zloader",7) == 0)
+		{
+			g_iftype = IF_TYPE_NOR;
+			nand_init();
+			ret = do_nor_write(part, par, offset,size);	
+			/*Çл»³õʼ»¯spi_nand*/
+			g_iftype = IF_TYPE_SPI_NAND;
+			nand_init();
+			memcpy((char *)(DOWNLOADER_BUFFER_BASE+0x8000),g_partition_table_dl,4096);
+	        ret = downloader_nand_write(part, 0, 0x9000,(unsigned char *)DOWNLOADER_BUFFER_BASE);
+			return ret;
+		}
+	}
+#endif
 
 	if((read_boot_flashtype() == IF_TYPE_NOR) 
 		&& (strcmp((const char *)part->part_type,"nand") == 0))
diff --git a/boot/common/src/uboot/downloader/cmd_dl_nand.c b/boot/common/src/uboot/downloader/cmd_dl_nand.c
old mode 100644
new mode 100755
index d4b0e04..8105776
--- a/boot/common/src/uboot/downloader/cmd_dl_nand.c
+++ b/boot/common/src/uboot/downloader/cmd_dl_nand.c
@@ -96,9 +96,15 @@
 
         if(memcmp(par,"zloader",7) == 0)    /* ÏÂÔØzloader·ÖÇø£¬Í¬Ê±ÏÂÔØ·ÖÇø±í */
         {
+#if defined (CONFIG_ZX297520V3E_VEHICLE_DC) || defined (CONFIG_ZX297520V3E_VEHICLE_DC_REF)
+            memcpy((char *)(DOWNLOADER_BUFFER_BASE+0xA000),g_partition_table_dl,4096);
+            ret = downloader_nand_write(part, offset_par, 0x3000,  
+										(unsigned char *)(DOWNLOADER_BUFFER_BASE+0x8000));
+#else
             memcpy((char *)(DOWNLOADER_BUFFER_BASE+8192),g_partition_table_dl,4096);
             ret = downloader_nand_write(part, offset_par, 0x3000,  
 										(unsigned char *)DOWNLOADER_BUFFER_BASE);
+#endif
         }
 		else
 		{
@@ -275,6 +281,16 @@
         return EINVAL;	/* Invalid argument */
     }
     leftWriteLength = size;
+	
+	if(g_nor_flag == 1)
+	{
+        ret = get_nor_null_slice_flag(&null_slice_flag);
+	    if(ret)
+	    {
+			printf ("nor flash read null_slice_flag error.\n");
+			return 1; 
+	    }
+	}
 
 	if(null_slice_flag == 1)
 	{
@@ -297,8 +313,17 @@
 
         if(memcmp(par,"zloader",7) == 0)    /* ÏÂÔØzloader·ÖÇø£¬Í¬Ê±ÏÂÔØ·ÖÇø±í */
         {
-            memcpy((char *)(DOWNLOADER_BUFFER_BASE+8192),g_partition_table_dl,4096);
-            ret = downloader_nor_write( part, offset_par, 0x3000,  (unsigned char *)DOWNLOADER_BUFFER_BASE);
+			if(g_nor_flag == 1)
+			{
+			    memset((char *)(DOWNLOADER_BUFFER_BASE+0x8000), 0, 4096);
+			    memcpy((char *)(DOWNLOADER_BUFFER_BASE+0x8000),g_partition_table_dl,4096);
+                ret = downloader_nor_write( part, offset_par, 0x9000,  (unsigned char *)DOWNLOADER_BUFFER_BASE);
+			}
+			else
+			{
+			    memcpy((char *)(DOWNLOADER_BUFFER_BASE+8192),g_partition_table_dl,4096);
+                ret = downloader_nor_write( part, offset_par, 0x3000,  (unsigned char *)DOWNLOADER_BUFFER_BASE);
+            }
         }
 		else
 		{
diff --git a/boot/common/src/uboot/downloader/cmd_efuse_program.c b/boot/common/src/uboot/downloader/cmd_efuse_program.c
old mode 100644
new mode 100755
index 3f931ba..ffd2e8f
--- a/boot/common/src/uboot/downloader/cmd_efuse_program.c
+++ b/boot/common/src/uboot/downloader/cmd_efuse_program.c
@@ -243,7 +243,9 @@
 		board_type = BOARD_TYPE_ZX297520V3E64M;
 	}
 	else if((chip_flag == ZX297520V3ECOSC_GW_NYC_2G_DDR)
-			||(chip_flag == ZX297520V3ECOGG_GW_NYC_2G_DDR))
+			||(chip_flag == ZX297520V3ECOGG_GW_NYC_2G_DDR)
+			||(chip_flag == ZX297520V3ECOGG_GW_NYC_NOR_2G_DDR)
+			||(chip_flag == ZX297520V3ECOSC_GW_NYC_NOR_2G_DDR))
 	{
 		printf("chip_flag=0x%x board_type is V3E.\n", chip_flag);
 		board_type = BOARD_TYPE_ZX297520V3E256M;
diff --git a/boot/common/src/uboot/downloader/downloader_nand.c b/boot/common/src/uboot/downloader/downloader_nand.c
old mode 100644
new mode 100755
index d28cfbc..fe24aaa
--- a/boot/common/src/uboot/downloader/downloader_nand.c
+++ b/boot/common/src/uboot/downloader/downloader_nand.c
@@ -476,7 +476,7 @@
  *

  * Others:

  ********************************************************************************/

-int 	downloader_nand_write(partition_entry_t * part, uint offset,  uint size,  unchar * buffer)

+int downloader_nand_write(partition_entry_t * part, uint offset,  uint size,  unchar * buffer)

 {

 	nand_info_t * pNandInfo = NULL;

 	uint  nandPhyBase = 0;

@@ -502,24 +502,40 @@
 	

     /* רÃÅдZ-LOADʱʹÓ㬲»Ê¹ÓÃECC*/

     if( strcmp((const char *)part->part_name , "zloader") == 0 )

-    {   

-        if( size != 12*1024 )

-        {

-            printf("downloader_nand_write z-load size != 12k...\n");

-			return -1;

-        } 

-        int times = 12*1024/pNandInfo->writesize;

-        int i = 0;

+    { 

+        if(g_nor_flag == 1)

+		{

+            int times = 0x9000/pNandInfo->writesize;

+	        int i = 0;

 

-        for(; i<times; i++)

-        {

-            

-            ret += nand_write_page_with_ecc(pNandInfo, 

-											((loff_t)i*(pNandInfo->writesize)),

-											buf );

-            buf += pNandInfo->writesize;

-        }

-        

+	        for(; i<times; i++)

+	        {

+	            

+	            ret += nand_write_page_with_ecc(pNandInfo, 

+												((loff_t)i*(pNandInfo->writesize)),

+												buf );

+	            buf += pNandInfo->writesize;

+	        }

+		}

+		else

+		{

+            if( size != 12*1024 )

+	        {

+	            printf("downloader_nand_write z-load size != 12k...\n");

+				return -1;

+	        } 

+	        int times = 12*1024/pNandInfo->writesize;

+	        int i = 0;

+

+	        for(; i<times; i++)

+	        {

+	            

+	            ret += nand_write_page_with_ecc(pNandInfo, 

+												((loff_t)i*(pNandInfo->writesize)),

+												buf );

+	            buf += pNandInfo->writesize;

+	        }

+		}

     }

         

     else

diff --git a/boot/common/src/uboot/downloader/downloader_nand.h b/boot/common/src/uboot/downloader/downloader_nand.h
old mode 100644
new mode 100755
index ec638d4..806700e
--- a/boot/common/src/uboot/downloader/downloader_nand.h
+++ b/boot/common/src/uboot/downloader/downloader_nand.h
@@ -41,6 +41,7 @@
 /****************************************************************************

 * 	                         Global  Variables

 ****************************************************************************/

+extern unsigned char g_nor_flag;

 

 /****************************************************************************

 * 	                         Function Prototypes

diff --git a/boot/common/src/uboot/drivers/efuse/efuse.c b/boot/common/src/uboot/drivers/efuse/efuse.c
old mode 100644
new mode 100755
index 46bc303..96e4901
--- a/boot/common/src/uboot/drivers/efuse/efuse.c
+++ b/boot/common/src/uboot/drivers/efuse/efuse.c
@@ -25,10 +25,10 @@
 

 #include <../drivers/hash/drv_hash.h>

 #include <../drivers/rsa/drv_rsa.h>

+#include <../drivers/hash/sha256.h>

 #include <secure_verify.h>

 #include <asm/arch/efuse.h>

-

-

+#include <boot_mode.h>

 

 /****************************************************************************

 * 	                                           Local Macros

@@ -51,6 +51,14 @@
 

 static unsigned char gbEfuseReadFlag = 0;

 

+otp_struct otpInfo;

+unsigned int guiOtpStatus = 1;

+extern int rootfs_flag;

+extern int m0_flag;

+extern int zsp_flag;

+extern int g_iftype;

+extern unsigned char g_nor_flag;

+

 /****************************************************************************

 * 	                                           Local Funcs

 ****************************************************************************/

@@ -129,6 +137,62 @@
 	return 1;

 }

 #endif

+

+/*

+* Convert BIGENDIAN To SMALLENDIAN.

+*/

+void BIG2SMALL(u32 *pBuffer, u32 uiLen)

+{

+	u32 uiLoop;

+	u32 uiTmp = 0;

+

+	for (uiLoop = 0; uiLoop < uiLen/sizeof(u32); uiLoop++)

+	{

+		uiTmp = pBuffer[uiLoop];

+		pBuffer[uiLoop] = 0;

+		pBuffer[uiLoop] += (uiTmp & 0x000000FF) << 24;

+		pBuffer[uiLoop] += (uiTmp & 0x0000FF00) << 8;

+		pBuffer[uiLoop] += (uiTmp & 0x00FF0000) >> 8;

+		pBuffer[uiLoop] += (uiTmp & 0xFF000000) >> 24;

+	}

+}

+

+void get_otp_secure_verify_status(void)

+{

+	u32 uiLen;

+	otp_struct *psEfuseInfo = NULL;

+	

+	/*

+	 * 0. Èç¹ûsecure flag²»µÈÓÚ0£¬Í˳ö°²È«boot¡£

+	 */

+	psEfuseInfo = (otp_struct*)&otpInfo;

+	if(psEfuseInfo->secure_flag != 0)

+	{

+		guiOtpStatus = 1;	   //Disable.

+		BOOT_PRINTF(UBOOT_NOTICE, "secure_flag!=0xFF, SecureVerify->Disable.\n");

+		return ;

+	}	

+	

+	/*

+	 * 1.´ÓefuseÖжÁ³öpuk_hash[255:0], ÅжÏÈç¹ûÈ«²¿Îª0Í˳ö°²È«boot¡£

+	 */

+	for(uiLen = 0; uiLen < 8; uiLen++)

+	{

+		if(psEfuseInfo->puk_hash[uiLen] != 0)

+		{

+			break;

+		}

+		if(uiLen == 7)

+		{

+			guiOtpStatus = 1;	   //Disable.

+			BOOT_PRINTF(UBOOT_NOTICE, "PubKey_HASH=Invalid, SecureVerify->Disable.\n");

+			return ;

+		}

+	}

+	BOOT_PRINTF(UBOOT_NOTICE, "All Flag & Param is Valid, SecureVerify->ENABLE.\n");

+	guiOtpStatus = 0;	   //Enable.

+}

+

 static void efuse_get_data(void)

 {

 	efuse_struct *psEfuseInfo = NULL;

@@ -168,7 +232,9 @@
 		BOOT_PRINTF(UBOOT_NOTICE, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);

 	}

 	else if(((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOSC_GW_NYC_2G_DDR)

-		||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOGG_GW_NYC_2G_DDR))

+		||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOGG_GW_NYC_2G_DDR)

+		||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOGG_GW_NYC_NOR_2G_DDR)

+		||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOSC_GW_NYC_NOR_2G_DDR))

 	{

 		g_ddr_size_flag = CHIP_DDR_IS_256M;

 		BOOT_PRINTF(UBOOT_NOTICE, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);

@@ -217,98 +283,440 @@
 	return 0;

 }

 

+u8 rootfs_secure_verify(u32 addr)

+{

+    if(g_nor_flag == 1)

+	{

+		

+	    u32 uiLen = 0;

+		u32 uiRet = -1;

+		u32 uiLoop = 0;

+		image_header_t *puiLegacyRootfsAddr = NULL;

+		sImageNewHeader *psRootfsHeader = NULL;

+		u32 *puiDataLoadAddr = NULL;

+		u32 *puiArrPubKeyEN = NULL;

+		u32 *puiArrPubKey = NULL;

+		u32 *puiArrHASH = NULL;

+		otp_struct *psEfuseInfo = NULL;

+		u32 uiHashResArr[8] = {0};

+		u32 uiHashResLen = 0;

+		u32 uiHashVerifySize = 0;

+		u32 uiRsaResArr[64] = {0};

+		u32 puiArrPubKeyE[64] = {0};

+		T_Rsa_Paramter sRSAInput;

+		u32 *puiRsaResAddr = NULL;

+		u32 sRamKey[9] = {0x0,0x33fa3e31,0x90d8d15a,0x073cee04,0x82ac24aa,0x2262748e,0x1a3663c7,0x4b603f6f,0xd098e0d8};

+		if(NULL == addr)

+		{

+			BOOT_PRINTF(UBOOT_ERR, "Bad Parameter(Empty Pointer)!\n");

+			return -1;

+		}

+	

+		psRootfsHeader = (sImageNewHeader *)addr;

+		puiLegacyRootfsAddr = (image_header_t *)(addr + sizeof(sImageNewHeader));

+		uiHashVerifySize = ___htonl(puiLegacyRootfsAddr->ih_size) + sizeof(image_header_t);

+	

+		//psEfuseInfo = (otp_struct*)sRamKey;

+		psEfuseInfo = (otp_struct*)&otpInfo;

+		

+		/*

+		 * step 0

+		 */

+		puiArrPubKeyEN = psRootfsHeader->uiPubKeyRsaE;

+		uiLen = 380;

+		puiArrPubKey = &(psRootfsHeader->uiPubKeyRsaELen);

+		sha256_csum_wd((const unsigned char *)puiArrPubKey, uiLen, (unsigned char *)uiHashResArr);

+		uiHashResLen = 8;	

+		/*´óС¶Ëת»»*/

+		BIG2SMALL(uiHashResArr, 32);

+		

+		BOOT_PRINTF(UBOOT_DBG, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);

+	

+		if(efuse_cmp_word(psEfuseInfo->puk_hash, uiHashResArr, uiHashResLen))

+		{

+			BOOT_PRINTF(UBOOT_ERR, "PubKey Hash Verify -> Failed !\n");

+			return 1;

+		}

+		puiArrHASH = psRootfsHeader->uiHashY;

+	

+		/*

+		 * step 1

+		 */

+		memcpy(puiArrPubKeyE+63, puiArrPubKeyEN, 4);

+		sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;

+		sRSAInput.udNbitLen = 2048;

+		sRSAInput.udEbitLen = 2048;

+		sRSAInput.pudInputM = puiArrHASH;

+		sRSAInput.pudInputE = puiArrPubKeyE;

+		sRSAInput.pudInputN = psRootfsHeader->uiPubKeyRsaN;

+		sRSAInput.pudOutputP = uiRsaResArr;

+		

+		uiRet = Rsa_Calculate(sRSAInput);

+		if(uiRet != 0)

+		{

+			BOOT_PRINTF(UBOOT_ERR, "Rsa_Calculate ERROR(0x%x)!\n", uiRet);

+			return 2;

+		}

+		puiRsaResAddr = sRSAInput.pudOutputP + (64 - uiHashResLen);

+	

+		/*

+		 * step 2

+		 */

+		uiLen = uiHashVerifySize;

+		puiDataLoadAddr = CONFIG_SYS_SDRAM_ROOTFS_BASE - sizeof(image_header_t);

+	

+		/* Cleanup Output Buffer. */

+		uiHashResLen = 0;

+		memset(uiHashResArr, 0, 8*sizeof(uiHashResArr[0]));

+	

+		sha256_csum_wd((const unsigned char *)puiDataLoadAddr, uiLen, (unsigned char *)uiHashResArr);

+		uiHashResLen = 8;

+		/*´óС¶Ëת»»*/

+		BIG2SMALL(uiHashResArr, 32);

+	

+		if(efuse_cmp_word(puiRsaResAddr, uiHashResArr, uiHashResLen))

+		{

+			BOOT_PRINTF(UBOOT_ERR, "LegacyRootfs Verify -> Failed !\n");

+			return 3;

+		}

+

+	}

+	else

+	{

+	    

+	    u32 uiLen = 0;

+		u32 uiRet = -1;

+		u32 uiLoop = 0;

+		image_header_t *puiLegacyRootfsAddr = NULL;

+		sImageNewHeader *psRootfsHeader = NULL;

+		u32 *puiDataLoadAddr = NULL;

+		u32 *puiArrPubKeyEN = NULL;

+		u32 *puiArrHASH = NULL;

+		efuse_struct *psEfuseInfo = NULL;

+		u32 uiHashResArr[4] = {0};

+		u32 uiHashResLen = 0;

+		u32 uiHashVerifySize = 0;

+		u32 uiRsaResArr[32] = {0};

+		u32 puiArrPubKeyE[32] = {0};

+		u32 puiArrPubKey[64] = {0};

+		T_Rsa_Paramter sRSAInput;

+		u32 *puiRsaResAddr = NULL;

+		{

+			BOOT_PRINTF(UBOOT_ERR, "Bad Parameter(Empty Pointer)!\n");

+			return -1;

+		}

+	

+		psRootfsHeader = (sImageNewHeader *)addr;

+		puiLegacyRootfsAddr = (image_header_t *)(addr + sizeof(sImageNewHeader));

+		uiHashVerifySize = ___htonl(puiLegacyRootfsAddr->ih_size) + sizeof(image_header_t);

+	

+		psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;

+		

+		/*

+		 * step 0

+		 */

+	    

+		uiLen = E_N_LEN;

+		puiArrPubKeyEN = psRootfsHeader->uiPubKeyRsaE;

+		memcpy(puiArrPubKeyE+31, puiArrPubKeyEN, 4);

+		memcpy(puiArrPubKey+31, puiArrPubKeyEN, 4);

+		memcpy(puiArrPubKey+32, psRootfsHeader->uiPubKeyRsaN, 128);

+

+		Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, puiArrPubKey, uiLen, NULL, 0, uiHashResArr, &uiHashResLen);

+

+		BOOT_PRINTF(UBOOT_DBG, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);

+

+		if(efuse_cmp_word(psEfuseInfo->puk_hash, uiHashResArr, uiHashResLen))

+		{

+			BOOT_PRINTF(UBOOT_ERR, "PubKey Hash Verify -> Failed !\n");

+			return 1;

+		}

+		puiArrHASH = psRootfsHeader->uiHashY;

+		

+		/*

+		 * step 1

+		 */

+		sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;

+		sRSAInput.udNbitLen = 1024;

+		sRSAInput.udEbitLen = 1024;

+		sRSAInput.pudInputM = puiArrHASH;

+		sRSAInput.pudInputE = puiArrPubKeyE;

+		sRSAInput.pudInputN = psRootfsHeader->uiPubKeyRsaN;

+		sRSAInput.pudOutputP = uiRsaResArr;

+		

+		uiRet = Rsa_Calculate(sRSAInput);

+		if(uiRet != 0)

+		{

+			BOOT_PRINTF(UBOOT_ERR, "Rsa_Calculate ERROR(0x%x)!\n", uiRet);

+			return 2;

+		}

+		puiRsaResAddr = sRSAInput.pudOutputP + (32 - uiHashResLen);

+	

+		/*

+		 * step 2

+		 */

+		uiLen = uiHashVerifySize;

+		puiDataLoadAddr = CONFIG_SYS_SDRAM_ROOTFS_BASE - sizeof(image_header_t);

+	

+		/* Cleanup Output Buffer. */

+		uiHashResLen = 0;

+		memset(uiHashResArr, 0, 4*sizeof(uiHashResArr[0]));

+	

+		uiRet = Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, puiDataLoadAddr, uiLen, NULL, 0, uiHashResArr, &uiHashResLen);

+		if(uiRet != 0)

+		{

+			BOOT_PRINTF(UBOOT_ERR, "Hash_Calculate ERROR(0x%x)!\n", uiRet);

+			return -1;

+		}

+	

+		if(efuse_cmp_word(puiRsaResAddr, uiHashResArr, uiHashResLen))

+		{

+			BOOT_PRINTF(UBOOT_ERR, "LegacyRootfs Verify -> Failed !\n");

+			return 3;

+		}

+	}

+    

+	return 0;

+}

+

 u8 secure_verify(u32 addr)

 {

-	u32 uiLen = 0;

-	u32 uiRet = -1;

-	u32 uiLoop = 0;

-	image_header_t *puiLegacyImgAddr = NULL;

-	sImageHeader *psImageHeader = NULL;

-	u32 *puiDataLoadAddr = NULL;

-	u32 *puiArrPubKeyEN = NULL;

-	u32 *puiArrHASH = NULL;

+    if(g_nor_flag != 1){

+		u32 uiLen = 0;

+		u32 uiRet = -1;

+		u32 uiLoop = 0;

+		image_header_t *puiLegacyImgAddr = NULL;

+		sImageNewHeader *psImageHeader = NULL;

+		u32 *puiDataLoadAddr = NULL;

+		u32 *puiArrPubKeyEN = NULL;

+		u32 *puiArrHASH = NULL;

 

-	efuse_struct *psEfuseInfo = NULL;

+		efuse_struct *psEfuseInfo = NULL;

 

-	u32 uiHashResArr[4] = {0};

-	u32 uiHashResLen = 0;

-	u32 uiHashVerifySize = 0;

-	u32 uiRsaResArr[32] = {0};

+		u32 uiHashResArr[4] = {0};

+		u32 uiHashResLen = 0;

+		u32 uiHashVerifySize = 0;

+		u32 uiRsaResArr[32] = {0};

+		u32 puiArrPubKeyE[32] = {0};

+		u32 puiArrPubKey[64] = {0};

 

-	T_Rsa_Paramter sRSAInput;

-	u32 *puiRsaResAddr = NULL;

+		T_Rsa_Paramter sRSAInput;

+		u32 *puiRsaResAddr = NULL;

 

-	if(NULL == addr)

-	{

-		BOOT_PRINTF(UBOOT_ERR, "Bad Parameter(Empty Pointer)!\n");

-		return -1;

+		if(NULL == addr)

+		{

+			BOOT_PRINTF(UBOOT_ERR, "Bad Parameter(Empty Pointer)!\n");

+			return -1;

+		}

+

+		psImageHeader = (sImageNewHeader *)addr;

+

+		if(rootfs_flag == 1)

+		{

+	        puiLegacyImgAddr = (image_header_t *)(addr + sizeof(sImageNewHeader) + sizeof(sImageNewHeader) + sizeof(image_header_t));

+		    uiHashVerifySize = ___htonl(puiLegacyImgAddr->ih_size) + sizeof(image_header_t) + sizeof(image_header_t) + sizeof(sImageNewHeader);

+		}

+		else

+		{

+	        puiLegacyImgAddr = (image_header_t *)(addr + sizeof(sImageNewHeader));

+		    uiHashVerifySize = ___htonl(puiLegacyImgAddr->ih_size) + sizeof(image_header_t);

+		}

+

+		psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;

+

+		BOOT_PRINTF(UBOOT_NOTICE, "uiHashVerifySize=0x%x, EFUSE_RAM_BASE=0x%x.\n", uiHashVerifySize, EFUSE_RAM_BASE);

+

+		/*

+		 * step 0

+		 */

+		uiLen = E_N_LEN;

+		puiArrPubKeyEN = psImageHeader->uiPubKeyRsaE;

+		memcpy(puiArrPubKeyE+31, puiArrPubKeyEN, 4);

+		memcpy(puiArrPubKey+31, puiArrPubKeyEN, 4);

+		memcpy(puiArrPubKey+32, psImageHeader->uiPubKeyRsaN, 128);

+

+		Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, puiArrPubKey, uiLen, NULL, 0, uiHashResArr, &uiHashResLen);

+

+		BOOT_PRINTF(UBOOT_DBG, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);

+

+		if(efuse_cmp_word(psEfuseInfo->puk_hash, uiHashResArr, uiHashResLen))

+		{

+			BOOT_PRINTF(UBOOT_ERR, "PubKey Hash Verify -> Failed !\n");

+			return 1;

+		}

+		puiArrHASH = psImageHeader->uiHashY;

+

+		/*

+		 * step 1

+		 */

+		sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;

+		sRSAInput.udNbitLen = 1024;

+		sRSAInput.udEbitLen = 1024;

+		sRSAInput.pudInputM = puiArrHASH;

+		sRSAInput.pudInputE = puiArrPubKeyE;

+		sRSAInput.pudInputN = psImageHeader->uiPubKeyRsaN;

+		sRSAInput.pudOutputP = uiRsaResArr;

+

+		uiRet = Rsa_Calculate(sRSAInput);

+		if(uiRet != 0)

+		{

+			BOOT_PRINTF(UBOOT_ERR, "Rsa_Calculate ERROR(0x%x)!\n", uiRet);

+			return 2;

+		}

+		puiRsaResAddr = sRSAInput.pudOutputP + (32 - uiHashResLen);

+

+		/*

+		 * step 2

+		 */

+		uiLen = uiHashVerifySize;

+		if(rootfs_flag == 1)

+		{

+	        puiDataLoadAddr = ___htonl(puiLegacyImgAddr->ih_load) - sizeof(image_header_t) - sizeof(image_header_t) - sizeof(sImageNewHeader);

+		}

+		else

+		{

+		    if(1 == m0_flag || 1 == zsp_flag){

+				puiDataLoadAddr = (uchar *)addr + sizeof(sImageNewHeader);

+

+			}else{

+				puiDataLoadAddr = ___htonl(puiLegacyImgAddr->ih_load) - sizeof(image_header_t);

+			}			

+

+		}

+		

+		/* Cleanup Output Buffer. */

+		uiHashResLen = 0;

+		memset(uiHashResArr, 0, 4*sizeof(uiHashResArr[0]));

+

+		uiRet = Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, puiDataLoadAddr, uiLen, NULL, 0, uiHashResArr, &uiHashResLen);

+		if(uiRet != 0)

+		{

+			BOOT_PRINTF(UBOOT_ERR, "Hash_Calculate ERROR(0x%x)!\n", uiRet);

+			return -1;

+		}

+

+		if(efuse_cmp_word(puiRsaResAddr, uiHashResArr, uiHashResLen))

+		{

+			BOOT_PRINTF(UBOOT_ERR, "LegacyImg Verify -> Failed !\n");

+			return 3;

+		}

+

 	}

+	else

+    {

+        u32 uiLen = 0;

+		u32 uiRet = -1;

+		u32 uiLoop = 0;

+		image_header_t *puiLegacyImgAddr = NULL;

+		sImageNewHeader *psImageHeader = NULL;

+		u32 *puiDataLoadAddr = NULL;

+		u32 *puiArrPubKeyEN = NULL;

+		u32 *puiArrPubKey = NULL;

+		u32 *puiArrHASH = NULL;

+		otp_struct *psEfuseInfo = NULL;

+		u32 uiHashResArr[8] = {0};

+		u32 uiHashResLen = 0;

+		u32 uiHashVerifySize = 0;

+		u32 uiRsaResArr[64] = {0};

+        u32 puiArrPubKeyE[64] = {0};

+		T_Rsa_Paramter sRSAInput;

+		u32 *puiRsaResAddr = NULL;

+        u32 sRamKey[9] = {0x0,0x33fa3e31,0x90d8d15a,0x073cee04,0x82ac24aa,0x2262748e,0x1a3663c7,0x4b603f6f,0xd098e0d8};

+		if(NULL == addr)

+		{

+			BOOT_PRINTF(UBOOT_ERR, "Bad Parameter(Empty Pointer)!\n");

+			return -1;

+		}

 

-	psImageHeader = (sImageHeader *)addr;

-	puiLegacyImgAddr = (image_header_t *)(addr + sizeof(sImageHeader));

-	uiHashVerifySize = ___htonl(puiLegacyImgAddr->ih_size) + sizeof(image_header_t);

+		psImageHeader = (sImageNewHeader *)addr;

 

-	psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;

+	    if(rootfs_flag == 1)

+		{

+	        puiLegacyImgAddr = (image_header_t *)(addr + sizeof(sImageNewHeader) + sizeof(sImageNewHeader) + sizeof(image_header_t));

+		    uiHashVerifySize = ___htonl(puiLegacyImgAddr->ih_size) + sizeof(image_header_t) + sizeof(image_header_t) + sizeof(sImageNewHeader);

+		}

+		else

+		{

+	        puiLegacyImgAddr = (image_header_t *)(addr + sizeof(sImageNewHeader));

+		    uiHashVerifySize = ___htonl(puiLegacyImgAddr->ih_size) + sizeof(image_header_t);

+		}

 

-	BOOT_PRINTF(UBOOT_NOTICE, "uiHashVerifySize=0x%x, EFUSE_RAM_BASE=0x%x.\n", uiHashVerifySize, EFUSE_RAM_BASE);

+		psEfuseInfo = (otp_struct*)&otpInfo;

+		//psEfuseInfo = (otp_struct*)sRamKey;

+		

+		/*

+		 * step 0

+		 */

+		uiLen = 380;

+		puiArrPubKey = &(psImageHeader->uiPubKeyRsaELen);

+		puiArrPubKeyEN = psImageHeader->uiPubKeyRsaE;

+        sha256_csum_wd((const unsigned char *)puiArrPubKey, uiLen, (unsigned char *)uiHashResArr);

+	    uiHashResLen = 8;	

+		/*´óС¶Ëת»»*/

+	    BIG2SMALL(uiHashResArr, 32);

 

-	/*

-	 * step 0

-	 */

-	uiLen = E_N_LEN;

-	puiArrPubKeyEN = psImageHeader->uiPubKeyRsaE;

+		BOOT_PRINTF(UBOOT_DBG, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);

 

-	Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, puiArrPubKeyEN, uiLen, NULL, 0, uiHashResArr, &uiHashResLen);

+		if(efuse_cmp_word(psEfuseInfo->puk_hash, uiHashResArr, uiHashResLen))

+		{

+			BOOT_PRINTF(UBOOT_ERR, "PubKey Hash Verify -> Failed !\n");

+			return 1;

+		}

+		puiArrHASH = psImageHeader->uiHashY;

 

-	BOOT_PRINTF(UBOOT_DBG, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);

+		/*

+		 * step 1

+		 */

+		memcpy(puiArrPubKeyE+63, puiArrPubKeyEN, 4);

+		sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;

+		sRSAInput.udNbitLen = 2048;

+		sRSAInput.udEbitLen = 2048;

+		sRSAInput.pudInputM = puiArrHASH;

+		sRSAInput.pudInputE = puiArrPubKeyE;

+		sRSAInput.pudInputN = psImageHeader->uiPubKeyRsaN;

+		sRSAInput.pudOutputP = uiRsaResArr;

 

-	if(efuse_cmp_word(psEfuseInfo->puk_hash, uiHashResArr, uiHashResLen))

-	{

-		BOOT_PRINTF(UBOOT_ERR, "PubKey Hash Verify -> Failed !\n");

-		return 1;

-	}

-	puiArrHASH = psImageHeader->uiHashY;

+		uiRet = Rsa_Calculate(sRSAInput);

+		if(uiRet != 0)

+		{

+			BOOT_PRINTF(UBOOT_ERR, "Rsa_Calculate ERROR(0x%x)!\n", uiRet);

+			return 2;

+		}

+		puiRsaResAddr = sRSAInput.pudOutputP + (64 - uiHashResLen);

 

-	/*

-	 * step 1

-	 */

-	sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;

-	sRSAInput.udNbitLen = 1024;

-	sRSAInput.udEbitLen = 1024;

-	sRSAInput.pudInputM = puiArrHASH;

-	sRSAInput.pudInputE = puiArrPubKeyEN;

-	sRSAInput.pudInputN = (puiArrPubKeyEN + 32);

-	sRSAInput.pudOutputP = uiRsaResArr;

+		/*

+		 * step 2

+		 */

+		uiLen = uiHashVerifySize;

+		if(rootfs_flag == 1)

+		{

+	        puiDataLoadAddr = ___htonl(puiLegacyImgAddr->ih_load) - sizeof(image_header_t) - sizeof(image_header_t) - sizeof(sImageNewHeader);

+		}

+		else

+		{

+		    if(1 == m0_flag || 1 == zsp_flag){

+				puiDataLoadAddr = (uchar *)addr + sizeof(sImageNewHeader);

+				

+			}else{

+			    puiDataLoadAddr = ___htonl(puiLegacyImgAddr->ih_load) - sizeof(image_header_t);

 

-	uiRet = Rsa_Calculate(sRSAInput);

-	if(uiRet != 0)

-	{

-		BOOT_PRINTF(UBOOT_ERR, "Rsa_Calculate ERROR(0x%x)!\n", uiRet);

-		return 2;

-	}

-	puiRsaResAddr = sRSAInput.pudOutputP + (32 - uiHashResLen);

+			}

+		}

+	   

+		uiHashResLen = 0;

+		memset(uiHashResArr, 0, 8*sizeof(uiHashResArr[0]));

 

-	/*

-	 * step 2

-	 */

-	uiLen = uiHashVerifySize;

-	puiDataLoadAddr = ___htonl(puiLegacyImgAddr->ih_load) - sizeof(image_header_t);

+		sha256_csum_wd((const unsigned char *)puiDataLoadAddr, uiLen, (unsigned char *)uiHashResArr);

+		uiHashResLen = 8;

+		/*´óС¶Ëת»»*/

+	    BIG2SMALL(uiHashResArr, 32);

 

-	/* Cleanup Output Buffer. */

-	uiHashResLen = 0;

-	memset(uiHashResArr, 0, 4*sizeof(uiHashResArr[0]));

+		if(efuse_cmp_word(puiRsaResAddr, uiHashResArr, uiHashResLen))

+		{

+			BOOT_PRINTF(UBOOT_ERR, "LegacyImg Verify -> Failed !\n");

+			return 3;

+		}

 

-	uiRet = Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, puiDataLoadAddr, uiLen, NULL, 0, uiHashResArr, &uiHashResLen);

-	if(uiRet != 0)

-	{

-		BOOT_PRINTF(UBOOT_ERR, "Hash_Calculate ERROR(0x%x)!\n", uiRet);

-		return -1;

-	}

-

-	if(efuse_cmp_word(puiRsaResAddr, uiHashResArr, uiHashResLen))

-	{

-		BOOT_PRINTF(UBOOT_ERR, "LegacyImg Verify -> Failed !\n");

-		return 3;

 	}

 

 	return 0;

@@ -360,6 +768,19 @@
 	/* Efuse Status decide ENABLE/DISABLE SecureVerify. */

 	efuse_get_data();

 

+	/*OTP status*/

+

+	if(g_nor_flag == 1)

+	{	

+        g_iftype = IF_TYPE_NOR;

+		nand_init();

+		/*Çл»³õʼ»¯spi_nand*/

+		g_iftype = IF_TYPE_SPI_NAND;

+		nand_init();

+

+		get_otp_secure_verify_status();

+	}

+		

 	return 0;

 }

 

diff --git a/boot/common/src/uboot/drivers/hash/Makefile b/boot/common/src/uboot/drivers/hash/Makefile
old mode 100644
new mode 100755
index da7afab..bc1ab96
--- a/boot/common/src/uboot/drivers/hash/Makefile
+++ b/boot/common/src/uboot/drivers/hash/Makefile
@@ -26,6 +26,7 @@
 LIB 	:= $(obj)libdrv_hash.o
 
 COBJS-y	+= drv_hash.o
+COBJS-y	+= sha256.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/boot/common/src/uboot/drivers/hash/sha256.c b/boot/common/src/uboot/drivers/hash/sha256.c
new file mode 100755
index 0000000..65c7e3d
--- /dev/null
+++ b/boot/common/src/uboot/drivers/hash/sha256.c
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * FIPS-180-2 compliant SHA-256 implementation
+ *
+ * Copyright (C) 2001-2003  Christophe Devine
+ */
+
+#ifndef USE_HOSTCC
+#include <common.h>
+#include <linux/string.h>
+#else
+#include <string.h>
+#endif /* USE_HOSTCC */
+#include <watchdog.h>
+#include "sha256.h"
+
+const uint8_t sha256_der_prefix[SHA256_DER_LEN] = {
+	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+	0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+	0x00, 0x04, 0x20
+};
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i) {				\
+	(n) = ( (unsigned long) (b)[(i)    ] << 24 )	\
+	    | ( (unsigned long) (b)[(i) + 1] << 16 )	\
+	    | ( (unsigned long) (b)[(i) + 2] <<  8 )	\
+	    | ( (unsigned long) (b)[(i) + 3]       );	\
+}
+#endif
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i) {				\
+	(b)[(i)    ] = (unsigned char) ( (n) >> 24 );	\
+	(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );	\
+	(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );	\
+	(b)[(i) + 3] = (unsigned char) ( (n)       );	\
+}
+#endif
+
+void sha256_starts(sha256_context * ctx)
+{
+	ctx->total[0] = 0;
+	ctx->total[1] = 0;
+
+	ctx->state[0] = 0x6A09E667;
+	ctx->state[1] = 0xBB67AE85;
+	ctx->state[2] = 0x3C6EF372;
+	ctx->state[3] = 0xA54FF53A;
+	ctx->state[4] = 0x510E527F;
+	ctx->state[5] = 0x9B05688C;
+	ctx->state[6] = 0x1F83D9AB;
+	ctx->state[7] = 0x5BE0CD19;
+}
+
+static void sha256_process(sha256_context *ctx, const uint8_t data[64])
+{
+	uint32_t temp1, temp2;
+	uint32_t W[64];
+	uint32_t A, B, C, D, E, F, G, H;
+
+	GET_UINT32_BE(W[0], data, 0);
+	GET_UINT32_BE(W[1], data, 4);
+	GET_UINT32_BE(W[2], data, 8);
+	GET_UINT32_BE(W[3], data, 12);
+	GET_UINT32_BE(W[4], data, 16);
+	GET_UINT32_BE(W[5], data, 20);
+	GET_UINT32_BE(W[6], data, 24);
+	GET_UINT32_BE(W[7], data, 28);
+	GET_UINT32_BE(W[8], data, 32);
+	GET_UINT32_BE(W[9], data, 36);
+	GET_UINT32_BE(W[10], data, 40);
+	GET_UINT32_BE(W[11], data, 44);
+	GET_UINT32_BE(W[12], data, 48);
+	GET_UINT32_BE(W[13], data, 52);
+	GET_UINT32_BE(W[14], data, 56);
+	GET_UINT32_BE(W[15], data, 60);
+
+#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
+
+#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
+#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
+
+#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
+#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
+
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+
+#define R(t)					\
+(						\
+	W[t] = S1(W[t - 2]) + W[t - 7] +	\
+		S0(W[t - 15]) + W[t - 16]	\
+)
+
+#define P(a,b,c,d,e,f,g,h,x,K) {		\
+	temp1 = h + S3(e) + F1(e,f,g) + K + x;	\
+	temp2 = S2(a) + F0(a,b,c);		\
+	d += temp1; h = temp1 + temp2;		\
+}
+
+	A = ctx->state[0];
+	B = ctx->state[1];
+	C = ctx->state[2];
+	D = ctx->state[3];
+	E = ctx->state[4];
+	F = ctx->state[5];
+	G = ctx->state[6];
+	H = ctx->state[7];
+
+	P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
+	P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
+	P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
+	P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
+	P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
+	P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
+	P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
+	P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
+	P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
+	P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
+	P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
+	P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
+	P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
+	P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
+	P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
+	P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
+	P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
+	P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
+	P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
+	P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
+	P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
+	P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
+	P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
+	P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
+	P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
+	P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
+	P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
+	P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
+	P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
+	P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
+	P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
+	P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
+	P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
+	P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
+	P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
+	P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
+	P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
+	P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
+	P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
+	P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
+	P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
+	P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
+	P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
+	P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
+	P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
+	P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
+	P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
+	P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
+	P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
+	P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
+	P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
+	P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
+	P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
+	P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
+	P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
+	P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
+	P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
+	P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
+	P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
+	P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
+	P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
+	P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
+	P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
+	P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
+
+	ctx->state[0] += A;
+	ctx->state[1] += B;
+	ctx->state[2] += C;
+	ctx->state[3] += D;
+	ctx->state[4] += E;
+	ctx->state[5] += F;
+	ctx->state[6] += G;
+	ctx->state[7] += H;
+}
+
+void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
+{
+	uint32_t left, fill;
+
+	if (!length)
+		return;
+
+	left = ctx->total[0] & 0x3F;
+	fill = 64 - left;
+
+	ctx->total[0] += length;
+	ctx->total[0] &= 0xFFFFFFFF;
+
+	if (ctx->total[0] < length)
+		ctx->total[1]++;
+
+	if (left && length >= fill) {
+		memcpy((void *) (ctx->buffer + left), (void *) input, fill);
+		sha256_process(ctx, ctx->buffer);
+		length -= fill;
+		input += fill;
+		left = 0;
+	}
+
+	while (length >= 64) {
+		sha256_process(ctx, input);
+		length -= 64;
+		input += 64;
+	}
+
+	if (length)
+		memcpy((void *) (ctx->buffer + left), (void *) input, length);
+}
+
+static uint8_t sha256_padding[64] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+void sha256_finish(sha256_context * ctx, uint8_t digest[32])
+{
+	uint32_t last, padn;
+	uint32_t high, low;
+	uint8_t msglen[8];
+
+	high = ((ctx->total[0] >> 29)
+		| (ctx->total[1] << 3));
+	low = (ctx->total[0] << 3);
+
+	PUT_UINT32_BE(high, msglen, 0);
+	PUT_UINT32_BE(low, msglen, 4);
+
+	last = ctx->total[0] & 0x3F;
+	padn = (last < 56) ? (56 - last) : (120 - last);
+
+	sha256_update(ctx, sha256_padding, padn);
+	sha256_update(ctx, msglen, 8);
+
+	PUT_UINT32_BE(ctx->state[0], digest, 0);
+	PUT_UINT32_BE(ctx->state[1], digest, 4);
+	PUT_UINT32_BE(ctx->state[2], digest, 8);
+	PUT_UINT32_BE(ctx->state[3], digest, 12);
+	PUT_UINT32_BE(ctx->state[4], digest, 16);
+	PUT_UINT32_BE(ctx->state[5], digest, 20);
+	PUT_UINT32_BE(ctx->state[6], digest, 24);
+	PUT_UINT32_BE(ctx->state[7], digest, 28);
+}
+
+/*
+ * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz'
+ * bytes of input processed.
+ */
+void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
+		unsigned char *output)
+{
+	sha256_context ctx;
+
+	sha256_starts(&ctx);
+
+	sha256_update(&ctx, input, ilen);
+
+	sha256_finish(&ctx, output);
+}
diff --git a/boot/common/src/uboot/drivers/hash/sha256.h b/boot/common/src/uboot/drivers/hash/sha256.h
new file mode 100755
index 0000000..2da2952
--- /dev/null
+++ b/boot/common/src/uboot/drivers/hash/sha256.h
@@ -0,0 +1,25 @@
+#ifndef _SHA256_H
+#define _SHA256_H
+
+#define SHA256_SUM_LEN	32
+#define SHA256_DER_LEN	19
+
+extern const uint8_t sha256_der_prefix[];
+
+/* Reset watchdog each time we process this many bytes */
+#define CHUNKSZ_SHA256	(64 * 1024)
+
+typedef struct {
+	uint32_t total[2];
+	uint32_t state[8];
+	uint8_t buffer[64];
+} sha256_context;
+
+void sha256_starts(sha256_context * ctx);
+void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length);
+void sha256_finish(sha256_context * ctx, uint8_t digest[SHA256_SUM_LEN]);
+
+void sha256_csum_wd(const unsigned char *input, unsigned int ilen,
+		unsigned char *output);
+
+#endif /* _SHA256_H */
diff --git a/boot/common/src/uboot/drivers/misc/load.c b/boot/common/src/uboot/drivers/misc/load.c
index bbb6c27..2c9c8e7 100755
--- a/boot/common/src/uboot/drivers/misc/load.c
+++ b/boot/common/src/uboot/drivers/misc/load.c
@@ -47,6 +47,9 @@
 #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;
 
@@ -79,6 +82,7 @@
 
 /* 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;
@@ -100,7 +104,9 @@
 int rd_offset = 0;
 int rd_size = 0;
 
-
+int rootfs_flag = 0;
+int m0_flag = 0;
+int zsp_flag = 0;
 /* ================================================================================
  *  page_align  :  Ò³¶ÔÆë
  */
@@ -325,8 +331,8 @@
 	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");
+	
+	BOOT_PRINTF(UBOOT_NOTICE, "dtb load image finished.\n");
 	
 	return 0;
 }
@@ -336,7 +342,8 @@
 {
 	char    cmd[64] = {0};
 	int remap = 0;
-
+	int ret = 0;
+    u8 ucRet = 0;
 	remap = readl(0x140000);
 	remap |= 0x800000;
 	writel(remap,0x140000);
@@ -351,9 +358,54 @@
 #else
 	sprintf(cmd, "fsload imagefs 0x%x %s", (ulong)CONFIG_SYS_SDRAM_TEMP_BASE, M0_IMAGE_PATH);
 #endif
-	run_command(cmd, 0);
+	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);
 
@@ -365,6 +417,76 @@
 	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,
@@ -484,7 +606,7 @@
 	}
 
 	/* °´ÕÕZSPµÄ¸ñÊ½ÖØÅÅ */
-	reform_zsp_image(image_tmp_buf);
+	reform_zsp_image(image_tmp_buf + sizeof(sImageNewHeader) + sizeof(image_header_t));
 	BOOT_PRINTF(UBOOT_NOTICE, "zsp image load finished.\n");
 
 	return 0;
@@ -514,6 +636,8 @@
 #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;
 
@@ -522,7 +646,7 @@
 
 	BOOT_PRINTF(UBOOT_NOTICE, "AP image load begin...\n");
 
-	uiImgHdrSizeNew = sizeof(sImageHeader); 
+	uiImgHdrSizeNew = sizeof(sImageNewHeader); 
 
 	image_header_t *psImgHdrOld = NULL;
 
@@ -582,20 +706,27 @@
 					return -1;
 				}
 
-				/*»ñÈ¡¹«Ô¿´«µÝ¸ø´ó°æ±¾Ê¹ÓÃ*/
-				memcpy(CFG_SECURE_PUK_ADDR,CONFIG_SYS_SDRAM_TEMP_LZMA,256);
+				 /*»ñÈ¡¹«Ô¿´«µÝ¸ø´ó°æ±¾Ê¹ÓÃ*/
+			    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);
+			    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;   /* ÕâÀïʹÓÃLOADµØÖ· */
+				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);
@@ -657,6 +788,7 @@
 	{
 		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);
 	}
@@ -680,7 +812,8 @@
 {
 	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
@@ -692,9 +825,56 @@
 #else
 	sprintf(cmd, "fsload imagefs 0x%x %s", (ulong)image_tmp_buf, ZSP_IMAGE_PATH);
 #endif
-	run_command(cmd, 0);
+	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;
 	
-	reform_zsp_image(image_tmp_buf);
+#endif
+
+    reform_zsp_image(image_tmp_buf + sizeof(sImageNewHeader) + sizeof(image_header_t));
+
 	BOOT_PRINTF(UBOOT_NOTICE, "zsp image load finished.\n");
 
 	return 0;
@@ -714,11 +894,13 @@
 	uint32_t uiCRCCalRes = 0;
 #endif
 	uint32_t uiImgHdrSizeOld = sizeof(image_header_t);
-	uint32_t uiImgHdrSizeNew = 0;
+	uint32_t uiRootfsHdrSizeOld = sizeof(image_header_t);
 
-	uiImgHdrSizeNew = sizeof(sImageHeader); 
+	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
@@ -733,57 +915,185 @@
 	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);
+	ret = run_command(cmd, 0);
+    if(ret < 0)
+		return ret;
 	
-	/*2¡¢»ñÈ¡°æ±¾µÄ´óСºÍÔËÐеØÖ· */
-	psImgHdrOld = (image_header_t *)(CONFIG_SYS_SDRAM_TEMP_BASE + uiImgHdrSizeNew);
-	if(___htonl(psImgHdrOld->ih_magic) != IH_MAGIC)
+    if(strncmp((const char *)image_name, "cpuap", 5) == 0)
 	{
-		BOOT_PRINTF(UBOOT_ERR, "Magic Num Check Failed,Maybe no AP bin !!!\n");
-		return 1;
-	}
+        rootfs_flag = 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)
+		if(g_nor_flag == 1)
 		{
-			BOOT_PRINTF(UBOOT_ERR, "AP image Secure Verify FAILED!\n");
+		    /*»ñÈ¡¹«Ô¿´«µÝ¸ø´ó°æ±¾Ê¹ÓÃ*/
+		    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;
 		}
-		BOOT_PRINTF(UBOOT_NOTICE, "AP image Secure Verify PASS!\n");
+
+		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
 	{
-		BOOT_PRINTF(UBOOT_NOTICE, "AP image Skip Secure Verify...\n");
-	}
+        if(guiEfuseStatus == 0)    //Secure Verify.
+		{
+			BOOT_PRINTF(UBOOT_DBG, "AP image Start Secure Verify...\n");
 
-	if(strncmp((const char *)image_name, "cpucap", 6) == 0)
+			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");
@@ -792,7 +1102,8 @@
 	{
 		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);
 	}
diff --git a/boot/common/src/uboot/drivers/mtd/nand/nand.c b/boot/common/src/uboot/drivers/mtd/nand/nand.c
index ec3f79a..7abfca0 100755
--- a/boot/common/src/uboot/drivers/mtd/nand/nand.c
+++ b/boot/common/src/uboot/drivers/mtd/nand/nand.c
@@ -26,13 +26,14 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <part.h>
-
+#include <secure_verify.h>
 #include <boot_mode.h>
-
+#include <asm/arch/efuse.h>
 
 #ifndef CONFIG_SYS_NAND_BASE_LIST
 #define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
 #endif
+#define reg32(addr)			(*(volatile unsigned long *)(addr))
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -47,7 +48,7 @@
 static const char default_nand_name[] = "nand";
 struct flash_ops flash;
 
-
+unsigned char g_nor_flag = 0;
 /*******************************************************************************
  * Function:    
  * Description: 
@@ -161,6 +162,15 @@
 {
 	int i;
 	unsigned int size = 0;
+
+	/*¶ÁȡоƬid*/
+	if((reg32(0x0121b040)>>8) == ZX297520V3ECOGG_GW_NYC_NOR_2G_DDR
+	||(reg32(0x0121b040)>>8) == ZX297520V3ECOSC_GW_NYC_NOR_2G_DDR)
+	{
+        g_nor_flag = 1;
+		printf("g_nor_flag is %d.\n",g_nor_flag);
+	}
+	
 	for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) 
 	{
 		nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);
diff --git a/boot/common/src/uboot/drivers/mtd/nand/nand_ids.c b/boot/common/src/uboot/drivers/mtd/nand/nand_ids.c
index ae834a8..6d54c1e 100755
--- a/boot/common/src/uboot/drivers/mtd/nand/nand_ids.c
+++ b/boot/common/src/uboot/drivers/mtd/nand/nand_ids.c
@@ -92,6 +92,8 @@
 	{0xC8,0x45,0x00,0,2048,128,0,0,0x20000,64,4096,1,1,0,{2,1,1,9,0,0,0,0,0,0},{0,0}},
 	/*XTX XT26Q04D-B 512M SPI-NAND*/
 	{0x0B,0x53,0x00,0,4096,256,0,0,0x40000,64,2048,1,1,0,{2,1,1,9,0,0,0,0,0,0},{0,0}},
+	/*UNIM UM19A0LISW 128M SPI-NAND*/
+	{0xB0,0x15,0x00,0,2048,64,0,0,0x20000,64,1024,1,1,0,{2,1,1,9,0,0,0,0,0,0},{0,0}},
 	{0,}
 }; 
 /*
@@ -133,6 +135,7 @@
 	{"SPI-NAND 512MiB 1,8V",	0x35, 4096, 512, 0x40000, 0},	//F50D44G41XB (2X)
 	{"SPI-NAND 512MiB 1,8V",	0x45, 2048, 512, 0x20000, 0},	//GD5F4GQ6REY2G
 	{"SPI-NAND 512MiB 1,8V",	0x53, 4096, 512, 0x40000, 0},	//XT26Q04D-B
+	{"SPI-NAND 128MiB 1,8V",	0x15, 2048, 128, 0x20000, 0},	//UM19A0LISW
 	{NULL,}
 };
 
@@ -160,6 +163,7 @@
 	{NAND_MFR_EMST, "emst"},
 	{NAND_MFR_FORESEE, "foresee"},
 	{NAND_MFR_XTX, "xtx"},
+	{NAND_MFR_UNIM, "unim"},
 	{0x0, "Unknown"}
 };
 
diff --git a/boot/common/src/uboot/drivers/mtd/nand/spi_nand_devices.c b/boot/common/src/uboot/drivers/mtd/nand/spi_nand_devices.c
index 09556f6..4062428 100755
--- a/boot/common/src/uboot/drivers/mtd/nand/spi_nand_devices.c
+++ b/boot/common/src/uboot/drivers/mtd/nand/spi_nand_devices.c
@@ -116,6 +116,10 @@
 	 .oobfree = {{2,62}}
   };
 
+ static struct nand_ecclayout nand_unim_oob_64= {
+    .oobfree = {{2,62}}
+ };
+
 static void	spi_nand_winbond_init(struct spi_nand_info *spi_nand)
 {
 	uint8_t dev_id = spi_nand->para->device_id;	
@@ -203,6 +207,7 @@
 			||((g_maf_id == NAND_MFR_EMST) && (g_dev_id == NAND_DEVID_EMST_F50D1G41LB_1G))
 			|| (g_maf_id == NAND_MFR_FORESEE)
 			|| (g_maf_id == NAND_MFR_XTX)
+			|| (g_maf_id == NAND_MFR_UNIM)
 			|| (g_maf_id == NAND_MFR_MICRON))
 			return RDX4_MODE;
 		else
@@ -334,6 +339,12 @@
 			chip->ecc.layout =&nand_xtx_oob_256;
 		}
 		break;
+	case NAND_MFR_UNIM:
+		if(mtd->oobsize==64 && mtd->writesize==2048)
+		{
+			chip->ecc.layout =&nand_unim_oob_64;
+		}
+		break;
 	default:
 		break;
 	}
diff --git a/boot/common/src/uboot/drivers/mtd/nand/zxic_spifc.c b/boot/common/src/uboot/drivers/mtd/nand/zxic_spifc.c
index 683b2a3..844b288 100755
--- a/boot/common/src/uboot/drivers/mtd/nand/zxic_spifc.c
+++ b/boot/common/src/uboot/drivers/mtd/nand/zxic_spifc.c
@@ -39,6 +39,7 @@
 extern struct nand_flash_device_para *g_nand_dev_info;
 extern unsigned char  g_maf_id;
 extern unsigned char g_dev_id;
+extern g_nor_flag;
 struct spi_nand_info spifc_nand;
 struct spi_nand_info *g_spifc = &spifc_nand;
 
@@ -595,6 +596,10 @@
                                 };
     do
     {
+        if(g_nor_flag == 1)
+		{
+		    zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
         spi_fc_clear_fifo();
         spi_fc_clear_int();
         spi_fc_config_ctrl(FC_DMA_NONE);        
@@ -611,7 +616,12 @@
         {
             continue;   /* ´«Êäʧ°Ü£¬½áÊø±¾´ÎÑ­»·²¢ÖØ´« */
         }
-        
+		
+		if(g_nor_flag == 1)
+		{
+		    zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+		}
+      
         break;        
     } while( --retries != 0 );
      
@@ -651,6 +661,10 @@
                                 };
     do
     {
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
         spi_fc_clear_fifo();
         spi_fc_clear_int();
         spi_fc_config_ctrl(FC_DMA_NONE);        
@@ -662,6 +676,12 @@
         {
             continue;   /* ´«Êäʧ°Ü£¬½áÊø±¾´ÎÑ­»·²¢ÖØ´« */
         }
+		
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+		}
+
         break;        
     } while( --retries != 0 );
      
@@ -697,11 +717,22 @@
                                 };
     do
     {
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
         spi_fc_setup_cmd(&cmd, 0, 0);       /* ÃüÁîÅäÖà */
         spi_fc_start();                     /* ¿ªÊ¼´«Êä */
         ret = spi_fc_wait_cmd_end();        /* µÈ´ýÃüÁî½áÊø */
         if( ret != SUCCESS )    
             continue;   /* ´«Êäʧ°Ü£¬½áÊø±¾´ÎÑ­»·²¢ÖØ´« */
+		
+		if(g_nor_flag == 1)
+		{
+		    zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+			udelay(5);
+		}		
+
 		/* µÈ´ýRESETÖ´ÐÐÍê³É */ //sunzhaoxing must wait
 		do
 		{
@@ -735,6 +766,10 @@
 	
     do
     {
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
         spi_fc_clear_fifo();
         spi_fc_clear_int();
         spi_fc_config_ctrl(FC_DMA_NONE);       
@@ -746,6 +781,12 @@
         {
             continue;   /* ¡ä?¨º?¨º¡ì¡ã¨¹¡ê??¨¢¨º?¡À?¡ä??-?¡¤2¡é??¡ä? */
         }
+		
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+		}
+
         break;        
     } while( --retries != 0 );
 
@@ -781,6 +822,11 @@
                                 };
 	while(1)
 	{
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
+
 		do
 		{
 			spi_fc_clear_fifo();
@@ -797,7 +843,13 @@
 			break;
 		}
 		while ( --retries != 0 );
-	
+
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+            udelay(5);
+		}
+		
 		/* µÈ´ýÉÏ´ÎÃüÁîÖ´ÐÐÍê³É */
 		do
 		{
@@ -844,6 +896,10 @@
                                 };
     do
     {
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
         spi_fc_clear_fifo();
         spi_fc_clear_int();
         spi_fc_config_ctrl(FC_DMA_NONE);        
@@ -854,6 +910,11 @@
         {
             continue;   /* ´«Êäʧ°Ü£¬½áÊø±¾´ÎÑ­»·²¢ÖØ´« */
         }
+		
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+		}  
 
        break;        
     } while( --retries != 0 );
@@ -940,6 +1001,10 @@
 
     do
     {
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
         spi_fc_clear_fifo();
         spi_fc_clear_int();
         spi_fc_config_ctrl(FC_DMA_NONE);        
@@ -958,6 +1023,11 @@
             //spi_fc_disable();
             continue;   /* ´«Êäʧ°Ü£¬½áÊø±¾´ÎÑ­»·²¢ÖØ´« */
         }
+		
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+		}
 
         break;        
     } while( --retries != 0 );
@@ -1001,6 +1071,11 @@
                                 };
     do
     {
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
+
         spi_fc_clear_fifo();
         spi_fc_clear_int();
         spi_fc_config_ctrl(FC_DMA_NONE);        
@@ -1012,6 +1087,12 @@
             continue;   /* ´«Êäʧ°Ü£¬½áÊø±¾´ÎÑ­»·²¢ÖØ´« */
         }
 
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+       		udelay(5);
+		}
+
         /* µÈ´ýÃüÁîÖ´ÐÐÍê³É */
         do
         {
@@ -1065,6 +1146,10 @@
                                 };
     do
     {
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
         spi_fc_clear_fifo();
         spi_fc_clear_int();
         spi_fc_config_ctrl(FC_DMA_NONE);        
@@ -1075,7 +1160,12 @@
         {
             continue;   /* ´«Êäʧ°Ü£¬½áÊø±¾´ÎÑ­»·²¢ÖØ´« */
         }
-
+		
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+		    udelay(5);
+		}
         /* µÈ´ýÃüÁîÖ´ÐÐÍê³É */
         do
         {
@@ -1213,6 +1303,10 @@
 
     do
     {
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
         spi_fc_clear_fifo();
         spi_fc_clear_int();
         spi_fc_setup_cmd(&cmd, column_addr, len);       /* ÃüÁîÅäÖà */      
@@ -1243,6 +1337,13 @@
 		spifc_wait_dma_done(FC_DMA_RX);
 		spi_fc_config_ctrl(FC_DMA_NONE); 
 #endif
+
+        if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+		}
+
+
         break;        
     } while( --retries != 0 );
 
@@ -1295,6 +1396,10 @@
                               
     do
     {
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
 		spi_fc_clear_fifo();
         spi_fc_clear_int();
         spi_fc_setup_cmd(&cmd, column_addr, page_len+oob_len);       /* ÃüÁîÅäÖà */ 
@@ -1321,7 +1426,13 @@
 		spifc_wait_dma_done(FC_DMA_TX);
 		spi_fc_config_ctrl(FC_DMA_NONE); 
 #endif
-	
+
+        if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+		}
+
+
         break;        
     } while( --retries != 0 );
      
@@ -1362,6 +1473,10 @@
                                 };
     do
     {
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_LOW);
+		}
         spi_fc_clear_fifo();
         spi_fc_clear_int();
         spi_fc_config_ctrl(FC_DMA_NONE);        
@@ -1373,6 +1488,12 @@
             continue;   /* ´«Êäʧ°Ü£¬½áÊø±¾´ÎÑ­»·²¢ÖØ´« */
         }
 
+		if(g_nor_flag == 1)
+		{
+			zDrvGpio_SetOutputValue(GPIO86,GPIO_HIGH);
+            udelay(5);
+		}
+
         /* µÈ´ýÃüÁîÖ´ÐÐÍê³É */
         do
         {
@@ -1416,6 +1537,13 @@
 	zDrvGpio_SetFunc(GPIO96, GPIO96_SPIFC_DATA1);
 	zDrvGpio_SetFunc(GPIO95, GPIO95_SPIFC_DATA0);
 	zDrvGpio_SetFunc(GPIO93,GPIO93_SPIFC_CS);
+    if(g_nor_flag == 1)
+	{
+        zDrvGpio_SetFunc(GPIO93,GPIO93_GPIO93);
+	  	zDrvGpio_SetOutputValue(GPIO93, GPIO_HIGH);
+	  	zDrvGpio_SetFunc(GPIO86,GPIO86_GPIO86);
+	  	zDrvGpio_SetDirection(GPIO86, GPIO_OUT);
+	}
 	zDrvGpio_SetFunc(GPIO94,GPIO94_SPIFC_CLK);
 
 	spi_fc_enable();
diff --git a/boot/common/src/uboot/drivers/mtd/partition/partition.c b/boot/common/src/uboot/drivers/mtd/partition/partition.c
index 0da27ea..7b200e6 100755
--- a/boot/common/src/uboot/drivers/mtd/partition/partition.c
+++ b/boot/common/src/uboot/drivers/mtd/partition/partition.c
@@ -32,8 +32,12 @@
 #include <load_image.h>
 #include <boot_mode.h>
 #include <config.h>
-
-
+#include <boot_mode.h>
+#include <../drivers/hash/drv_hash.h>
+#include <../drivers/rsa/drv_rsa.h>
+#include <../drivers/hash/sha256.h>
+#include <secure_verify.h>
+#include <asm/arch/efuse.h>
 
 #define DEFINE_PARTITION_TABLE
 #include <partition_table.h>      
@@ -51,11 +55,32 @@
 partition_table_t * g_partition_table = NULL;   /* Ö¸Ïò·ÖÇø±íÐÅÏ¢ */
 extern partition_table_t * g_partition_table_dl;
 extern struct fsl_qspi spi_nor_flash;
+extern unsigned int guiOtpStatus;
+extern unsigned int guiEfuseStatus;
+
 //#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;
 #endif
 
+unsigned char key_hash[128] = {0};
+unsigned char *bin2hex(const unsigned char *old, const size_t oldlen)
+{
+    size_t i, j;
+    int b = 0;
+
+    for (i = j = 0; i < oldlen; i++)
+    {
+        b = old[i] >> 4;
+        key_hash[j++] = (char)(87 + b + (((b - 10) >> 31) & -39));
+        b = old[i] & 0xf;
+        key_hash[j++] = (char)(87 + b + (((b - 10) >> 31) & -39));
+    }
+    key_hash[j] = '\0';
+    return key_hash;
+}
+
+
 /* ================================================================================
  *  add_partition_to_bootargs  :  Ôö¼Ó·ÖÇøÐÅÏ¢µ½ bootargs
  */
@@ -71,15 +96,51 @@
 	uchar bootargs_cmd_cap[1024] = {0};
 	uchar boot_reason_para[32] = {0};
 	uchar boot_mode_para[16] = {0};
+	uint32_t otp_pubkey_hash[8] = {0};
+	uint32_t efuse_pubkey_hash[4] = {0};
+	uint32_t uiHashResLen = 0;
 	unsigned int *poweron_type = (unsigned int *)POWERON_TYPE_ADDR;  //ÁÙʱʹÓÃ
 	
 	part_nums = g_partition_table->entrys;    
 
 	partition_entry_t * entry = &g_partition_table->table[0];
 
+	if(g_nor_flag == 1)
+	{
+	    sha256_csum_wd((const unsigned char *)OTP_SECURE_PUK_BASE, 380, (unsigned char *)otp_pubkey_hash);
+		bin2hex((unsigned char *)otp_pubkey_hash, 32);
+	}   
+	else
+	{
+        Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, CFG_SECURE_PUK_ADDR, 256, NULL, 0, efuse_pubkey_hash, &uiHashResLen);
+		bin2hex((unsigned char *)efuse_pubkey_hash, 16);
+	}
+	
 	/* console=ttyS1,115200 no_console_suspend */
-	sprintf((char *)bootargs_cmd, "console=ttyS1,921600 no_console_suspend");
-    sprintf((char *)bootargs_cmd_cap, "console=ttyS1,921600n8 earlycon no_console_suspend");
+	sprintf((char *)bootargs_cmd, "console=ttyS1,921600 no_console_suspend ");
+    sprintf((char *)bootargs_cmd_cap, "console=ttyS1,921600n8 earlycon no_console_suspend ");
+
+	if(g_nor_flag == 1)
+	{
+        sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "EnhancedSecurity=1 ");
+		sprintf((char *)bootargs_cmd_cap + strlen(bootargs_cmd_cap), "EnhancedSecurity=1 ");
+		if(guiOtpStatus == 0)
+		{
+			sprintf((char *)bootargs_cmd_cap + strlen(bootargs_cmd_cap), "pubkeyhash=");
+		    sprintf((char *)bootargs_cmd_cap + strlen(bootargs_cmd_cap), key_hash);
+
+		}	
+	}
+	else
+	{
+	    sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "EnhancedSecurity=0 ");
+		sprintf((char *)bootargs_cmd_cap + strlen(bootargs_cmd_cap), "EnhancedSecurity=0 ");
+		if(guiEfuseStatus == 0)
+		{
+			sprintf((char *)bootargs_cmd_cap + strlen(bootargs_cmd_cap), "pubkeyhash=");
+            sprintf((char *)bootargs_cmd_cap + strlen(bootargs_cmd_cap), key_hash);
+		}
+	}
 	/* denali-nand: */
 	if(read_boot_flashtype() == IF_TYPE_NAND)
 	{
@@ -234,6 +295,8 @@
 	/* console=ttyS1,115200 no_console_suspend */
 	sprintf((char *)bootargs_cmd, "console=ttyS1,921600 no_console_suspend");
 
+	sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " EnhancedSecurity=0");
+	
 	/* denali-nand: */
 	if(read_boot_flashtype() == IF_TYPE_NAND)
 	{
@@ -385,23 +448,46 @@
     +------------------------------------------------------------+
                                        8k           one page     10k
     */ 
-
-	if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND)
+    if(g_nor_flag == 1)
 	{
-		ret = flash->read_with_ecc(nand, (loff_t)8*1024, &table_size, g_table);
-		if(ret)
+        if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND)
 		{
-			BOOT_PRINTF(UBOOT_ERR, "read_no_ecc Failed! ret = %d.\n", ret);
-			return -1;
+			ret = flash->read_with_ecc(nand, (loff_t)0x8000, &table_size, g_table);
+			if(ret)
+			{
+				BOOT_PRINTF(UBOOT_ERR, "read_no_ecc Failed! ret = %d.\n", ret);
+				return -1;
+			}
+		}
+		else if(type == IF_TYPE_NOR)
+		{
+			ret = nand_read(&(nor->nor[0].mtd), (loff_t)0x8000, &table_size, g_table);
+			if(ret)
+			{
+				BOOT_PRINTF(UBOOT_ERR, "nand_read error! ret = %d.\n", ret);
+				return -1;
+			}
 		}
 	}
-	else if(type == IF_TYPE_NOR)
+	else
 	{
-		ret = nand_read(&(nor->nor[0].mtd), (loff_t)8*1024, &table_size, g_table);
-		if(ret)
+	     if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND)
 		{
-			BOOT_PRINTF(UBOOT_ERR, "nand_read error! ret = %d.\n", ret);
-			return -1;
+			ret = flash->read_with_ecc(nand, (loff_t)8*1024, &table_size, g_table);
+			if(ret)
+			{
+				BOOT_PRINTF(UBOOT_ERR, "read_no_ecc Failed! ret = %d.\n", ret);
+				return -1;
+			}
+		}
+		else if(type == IF_TYPE_NOR)
+		{
+			ret = nand_read(&(nor->nor[0].mtd), (loff_t)8*1024, &table_size, g_table);
+			if(ret)
+			{
+				BOOT_PRINTF(UBOOT_ERR, "nand_read error! ret = %d.\n", ret);
+				return -1;
+			}
 		}
 	}
 
diff --git a/boot/common/src/uboot/drivers/mtd/spi-nor/nor_spifc.c b/boot/common/src/uboot/drivers/mtd/spi-nor/nor_spifc.c
old mode 100644
new mode 100755
index 11b84d8..5775e14
--- a/boot/common/src/uboot/drivers/mtd/spi-nor/nor_spifc.c
+++ b/boot/common/src/uboot/drivers/mtd/spi-nor/nor_spifc.c
@@ -25,7 +25,7 @@
 #include <linux/mtd/nor_spifc.h>
 #include <../drivers/dma/zx29_dma.h>
 #include <nand.h>
-
+#include <secure_verify.h>
 
 
 spinor_cmd_t nor_cmd_table[]=
@@ -51,7 +51,10 @@
 	{CMD_REMS, TX_DMA_DIS, RX_DMA_DIS, ADDR_TX_DIS, ADDR_WIDTH_24, DATA_TX_DIS, DATA_RX_EN, DUMY_TX_DIS, 0, 0, ADDR_MULTI_LINE_DIS, DATA_MULTI_LINE_DIS, TRANS_MOD_SINGLE, "read manufacture device id"},	
 	{CMD_RDID, TX_DMA_DIS, RX_DMA_DIS, ADDR_TX_DIS, ADDR_WIDTH_24, DATA_TX_DIS, DATA_RX_EN, DUMY_TX_DIS, 0, 0, ADDR_MULTI_LINE_DIS, DATA_MULTI_LINE_DIS, TRANS_MOD_SINGLE, "read identification"},
 	{CMD_ENRESET, TX_DMA_DIS, RX_DMA_DIS, ADDR_TX_DIS, ADDR_WIDTH_24, DATA_TX_DIS, DATA_RX_DIS, DUMY_TX_DIS, 0, 0, ADDR_MULTI_LINE_DIS, DATA_MULTI_LINE_DIS, TRANS_MOD_SINGLE, "reset enable"},	
-	{CMD_RESET, TX_DMA_DIS, RX_DMA_DIS, ADDR_TX_DIS, ADDR_WIDTH_24, DATA_TX_DIS, DATA_RX_DIS, DUMY_TX_DIS, 0, 0, ADDR_MULTI_LINE_DIS, DATA_MULTI_LINE_DIS, TRANS_MOD_SINGLE, "reset"},			
+	{CMD_RESET, TX_DMA_DIS, RX_DMA_DIS, ADDR_TX_DIS, ADDR_WIDTH_24, DATA_TX_DIS, DATA_RX_DIS, DUMY_TX_DIS, 0, 0, ADDR_MULTI_LINE_DIS, DATA_MULTI_LINE_DIS, TRANS_MOD_SINGLE, "reset"},
+	{CMD_ESR, TX_DMA_DIS, RX_DMA_DIS, ADDR_TX_EN, ADDR_WIDTH_24, DATA_TX_DIS, DATA_RX_DIS, DUMY_TX_DIS, 0, 0, ADDR_MULTI_LINE_DIS, DATA_MULTI_LINE_DIS, TRANS_MOD_SINGLE, "erase security registers"},
+	{CMD_PSR, TX_DMA_DIS, RX_DMA_DIS, ADDR_TX_EN, ADDR_WIDTH_24, DATA_TX_EN, DATA_RX_DIS, DUMY_TX_DIS, 0, 0, ADDR_MULTI_LINE_DIS, DATA_MULTI_LINE_DIS, TRANS_MOD_SINGLE, "program security registers"},
+	{CMD_RSR, TX_DMA_DIS, RX_DMA_DIS, ADDR_TX_EN, ADDR_WIDTH_24, DATA_TX_DIS, DATA_RX_EN, DUMY_TX_EN, 1, 0, ADDR_MULTI_LINE_DIS, DATA_MULTI_LINE_DIS, TRANS_MOD_SINGLE, "read security registers"},
 	{0}
 };
 
@@ -639,13 +642,209 @@
 	return 0;
 }
 
+ int nor_write_security_register(struct spi_nor *nor, loff_t to,
+						   size_t len, size_t *retlen, const u_char *buf)
+ {
+	int ret;
+	int nor_status = 0;
+	struct fsl_qspi *q = nor->priv;
+	spinor_cmd_t *cmd = NULL;
+	
+	cmd = cmd_seek(CMD_PSR);
+	if(cmd == NULL)
+	{
+		printf("cmd_seek unkown cmd = 0x%x error.\n", nor->program_opcode);
+		return -1;
+	}
+ 
+#if TRANS_USE_DMA
+	cmd->tx_dma_en = TX_DMA_EN;
+#else
+	cmd->tx_dma_en = TX_DMA_DIS;
+#endif
+	spifc_setup_cmd(q, cmd, to, len);				
+	
+ 
+#if TRANS_USE_DMA
+	spifc_config_dma(buf, len, FC_DMA_TX);
+	spifc_start(q);
+#else
+	spifc_start(q);
+	ret = spifc_write_data(q, buf, len);
+	if(ret < 0)
+	{
+		printf("spifc_write_fifo error.\n");
+		return ret;
+	}
+#endif
+ 
+	ret = spifc_wait_cmd_end(q);			 
+	if(ret != 0)
+	{
+		printf("spifc_wait_cmd_end error.\n");
+		return ret;
+	}
+ 
+#if TRANS_USE_DMA
+	spifc_wait_dma_done(FC_DMA_TX);
+#endif
+ 
+	do{
+		ret = fsl_qspi_read_reg(nor, CMD_RDSR0, &nor_status, 1);
+		if(ret != 0)
+		{
+			printf("read WIP fail.\n");
+		}
+	}while(nor_status & 0x1);
+	
+	return 0;
+ }
+ 
+ int fsl_qspi_write_security_register(struct spi_nor *nor, loff_t to,
+						   size_t len, size_t *retlen, const u_char *buf)
+ {
+	int ret = 0;
+	struct fsl_qspi *q = NULL;
+ 
+	if((nor == NULL) || (nor->priv == NULL) || (retlen == NULL) || (buf == NULL))
+	{
+		printk("fsl_qspi_write_security_register is error.\n");
+		return -1;
+	}
+	q = nor->priv;
+	memcpy((void*)q->buf.buf, buf, len);
+	
+	ret = nor_write_security_register(nor, to, len, retlen, q->buf.dma_buf);
+	if(ret != 0)
+	{
+		printk("nor_write_otp error.\n");
+		return -1;
+	}
+	*retlen += len;
+ 
+	return 0;
+	
+ }
+
+int nor_read_security_register(struct spi_nor *nor, loff_t from,
+						size_t len, size_t *retlen, u_char *buf)
+{
+   int ret;
+   struct fsl_qspi *q = nor->priv;
+   spinor_cmd_t *cmd = NULL;
+   
+   cmd = cmd_seek(CMD_RSR);
+   if(cmd == NULL)
+   {
+	   printf("cmd_seek unkown cmd = 0x%x error.\n", nor->read_opcode);
+	   return -1;
+   }
+
+#if TRANS_USE_DMA
+   cmd->rx_dma_en = RX_DMA_EN;
+#else
+   cmd->rx_dma_en = RX_DMA_DIS;
+#endif
+   spifc_setup_cmd(q, cmd, from, len);			   
+   
+#if TRANS_USE_DMA
+   spifc_config_dma(buf, len, FC_DMA_RX);
+   spifc_start(q);
+#else
+   spifc_start(q);
+   ret = spifc_read_fifo(q, buf, len);
+   if(ret < 0)
+   {
+	   printf("spifc_read_fifo error.\n");
+	   return ret;
+   }
+#endif
+
+   ret = spifc_wait_cmd_end(q); 			
+   if(ret != 0)
+   {
+	   printf("spifc_wait_cmd_end error.\n");
+	   return ret;
+   }
+   
+#if TRANS_USE_DMA
+   spifc_wait_dma_done(FC_DMA_RX);
+#endif
+
+   return 0;
+}
+
+int fsl_qspi_read_security_register(struct spi_nor *nor, loff_t from,
+					size_t len, size_t *retlen, u_char *buf)
+{
+   int ret = 0;
+   struct fsl_qspi *q = NULL;
+   loff_t from_alligned = 0;
+
+   if((nor == NULL) || (nor->priv == NULL) || (retlen == NULL) || (buf == NULL))
+   {
+	   printk("fsl_qspi_read security register is error.\n");
+	   return -1;
+   }
+   from_alligned = from&(~(nor->page_size - 1));
+   q = nor->priv;
+   
+   ret = nor_read_security_register(nor, from_alligned, nor->page_size, retlen, q->buf.dma_buf);
+   if(ret != 0)
+   {
+	   printk("nor_read_security_register error.\n");
+	   return -1;
+   }
+
+   memcpy(buf, (void*)q->buf.buf + (from&(nor->page_size - 1)), len);
+   *retlen += len;
+
+   return 0; 
+}
+
+ int fsl_qspi_erase_security_register(struct spi_nor *nor, loff_t offs)
+{
+	int ret;
+	int nor_status = 0;
+	struct fsl_qspi *q = nor->priv;
+	spinor_cmd_t *cmd = NULL;
+
+	cmd = cmd_seek(CMD_ESR);
+	if(cmd == NULL)
+	{
+		printf("cmd_seek unkown cmd = 0x%x error.\n", nor->read_opcode);
+		return -1;
+	}
+	spifc_setup_cmd(q, cmd, offs, 0);
+
+	spifc_start(q);
+	ret = spifc_wait_cmd_end(q);			 
+	if(ret != 0)
+	{
+		printf("spifc_wait_cmd_end error.\n");
+		return ret;
+	}
+
+	do{
+		ret = fsl_qspi_read_reg(nor, CMD_RDSR0, &nor_status, 1);
+		if(ret != 0)
+		{
+			printf("read WIP fail.\n");
+		}
+	}while(nor_status & 0x1);
+	
+	return 0;
+}
+
 int fsl_qspi_probe(void)
 {
 	struct fsl_qspi *q;
 	struct spi_nor *nor;
 	struct mtd_info *mtd;
 	int ret, i = 0;
-
+    int32_t offset = 0x1000;
+	uint32_t len = sizeof(otpInfo);
+	
 	q = &spi_nor_flash;
 
 	spifc_hwinit();
@@ -674,6 +873,9 @@
 	nor->read = fsl_qspi_read;
 	nor->write = fsl_qspi_write;
 	nor->erase = fsl_qspi_erase;
+	nor->read_security_register = fsl_qspi_read_security_register;
+	nor->write_security_register = fsl_qspi_write_security_register;
+	nor->erase_security_register = fsl_qspi_erase_security_register;
 	nor->prepare = NULL;
 	nor->unprepare = NULL;
 	
@@ -687,6 +889,14 @@
 		return ret;
 	}
 
+	/*¶ÁÈ¡OTPÇøÓòÊý¾Ý*/
+	ret = fsl_qspi_read_security_register(nor, offset, len, (size_t *)len, &otpInfo);
+	if(ret !=0){
+        printf("read otp error.\n");
+	}else{
+        printf("otp secure_flag is 0x%x,puk hash is 0x%x.\n",otpInfo.secure_flag,otpInfo.puk_hash[0]);
+	}
+	
 	return 0;
 }
 
diff --git a/boot/common/src/uboot/drivers/mtd/spi-nor/spi-nor.c b/boot/common/src/uboot/drivers/mtd/spi-nor/spi-nor.c
index 131625a..23f612c 100755
--- a/boot/common/src/uboot/drivers/mtd/spi-nor/spi-nor.c
+++ b/boot/common/src/uboot/drivers/mtd/spi-nor/spi-nor.c
@@ -624,6 +624,8 @@
 static const struct flash_info spi_nor_ids[] = {
 	/* GigaDevice */
 	{"gd25q128", INFO(0xc86018, 0, 32 * 1024, 512, SPI_NOR_QUAD_READ)},
+	{"gd25ld10c", INFO(0xc86011, 0, 32 * 1024, 4, SPI_NOR_DUAL_READ)},
+	{"gd25ld20e", INFO(0xc86012, 0, 32 * 1024, 8, SPI_NOR_DUAL_READ)},
 	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
 	{"w25q128fw", INFO(0xef6018, 0, 32 * 1024, 512, SPI_NOR_QUAD_READ)},
 	/* dosilicon */
@@ -648,6 +650,8 @@
 static const struct flash_info spi_nor_ids[] = {
 	/* GigaDevice */
 	{"gd25q128", INFO(0xc86018, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ)},
+	{"gd25ld10c", INFO(0xc86011, 0, 64 * 1024, 2, SPI_NOR_DUAL_READ)},
+	{"gd25ld20e", INFO(0xc86012, 0, 64 * 1024, 4, SPI_NOR_DUAL_READ)},
 	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
 	{"w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ)},
 	/* dosilicon */
diff --git a/boot/common/src/uboot/include/boot_mode.h b/boot/common/src/uboot/include/boot_mode.h
old mode 100644
new mode 100755
index d1fdc26..6d8ea1a
--- a/boot/common/src/uboot/include/boot_mode.h
+++ b/boot/common/src/uboot/include/boot_mode.h
@@ -7,6 +7,8 @@
 #ifndef __BOOT_MODE__
 #define __BOOT_MODE__
 
+extern unsigned char g_nor_flag;
+
 typedef enum
 {
 	TLOAD_MODE = 1,
diff --git a/boot/common/src/uboot/include/configs/zx297520v3.h b/boot/common/src/uboot/include/configs/zx297520v3.h
index e218408..ea771fa 100755
--- a/boot/common/src/uboot/include/configs/zx297520v3.h
+++ b/boot/common/src/uboot/include/configs/zx297520v3.h
@@ -131,6 +131,7 @@
 #define CONFIG_SYS_SDRAM_IMAGEFS_BASE	0x25000000
 #define CONFIG_SYS_SDRAM_IMAGEFS_END	0x27000000
 #define CONFIG_SYS_SDRAM_IMAGEFS_SIZE	(CONFIG_SYS_SDRAM_IMAGEFS_END - CONFIG_SYS_SDRAM_IMAGEFS_BASE)
+
 #else
 #define PHYS_SDRAM_1_SIZE	        	0x02000000     	/* 32MB */
 #define CONFIG_SYS_SDRAM_SIZE	    	0x02000000	   	/* 32MB in DDR */
@@ -141,6 +142,7 @@
 
 #define CONFIG_SYS_SDRAM_TEMP_BASE		0x21400000  	/* ddrÊý¾Ý°æ±¾ÁÙʱ»º´æµØÖ· */
 #define CONFIG_SYS_SDRAM_TEMP_LZMA  	0X21600000  	/* »º´æµØÖ·£¬ÓÃÓÚ½âѹ°æ±¾Ê±Ê¹Óà */
+#define CONFIG_SYS_SDRAM_ROOTFS_BASE	0x25000000
 
 #define CONFIG_SYS_SDRAM_UPDATE_ALIGNED_OFFSET	0x5000000 	/* 80MB for LocalUpdate Use. */
 
diff --git a/boot/common/src/uboot/include/linux/mtd/nand.h b/boot/common/src/uboot/include/linux/mtd/nand.h
index efdfb54..f1c4aa1 100755
--- a/boot/common/src/uboot/include/linux/mtd/nand.h
+++ b/boot/common/src/uboot/include/linux/mtd/nand.h
@@ -519,10 +519,11 @@
 #define NAND_MFR_ZETTA  	0xBA
 #define NAND_MFR_DOSILICON  0xE5
 #define NAND_MFR_FUDANWEI   0xA1
-#define NAND_MFR_HOSIN	   0xD6
-#define NAND_MFR_EMST			0xC8
-#define NAND_MFR_FORESEE		0xCD
+#define NAND_MFR_HOSIN	    0xD6
+#define NAND_MFR_EMST		0xC8
+#define NAND_MFR_FORESEE	0xCD
 #define NAND_MFR_XTX		0x0B
+#define NAND_MFR_UNIM		0xB0
 
 
 #define NAND_DEVID_GD5F1GQ5R_1G 0x41
diff --git a/boot/common/src/uboot/include/linux/mtd/spi-nor.h b/boot/common/src/uboot/include/linux/mtd/spi-nor.h
index b3cef24..310dbb1 100755
--- a/boot/common/src/uboot/include/linux/mtd/spi-nor.h
+++ b/boot/common/src/uboot/include/linux/mtd/spi-nor.h
@@ -191,8 +191,14 @@
 	void (*write)(struct spi_nor *nor, loff_t to,
 			size_t len, size_t *retlen, const u_char *write_buf);
 	int (*erase)(struct spi_nor *nor, loff_t offs);
-
-	int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
+	
+    int (*read_security_register)(struct spi_nor *nor, loff_t from,
+			size_t len, size_t *retlen, u_char *read_buf);
+	void (*write_security_register)(struct spi_nor *nor, loff_t to,
+			size_t len, size_t *retlen, const u_char *write_buf);
+	int (*erase_security_register)(struct spi_nor *nor, loff_t offs);
+	
+	int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len);	
 	int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
 	int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
 
diff --git a/boot/common/src/uboot/include/secure_verify.h b/boot/common/src/uboot/include/secure_verify.h
old mode 100644
new mode 100755
index 34c2ce5..2132a03
--- a/boot/common/src/uboot/include/secure_verify.h
+++ b/boot/common/src/uboot/include/secure_verify.h
@@ -51,6 +51,13 @@
 	u32		dev_id[3];	
 } efuse_struct;
 
+typedef volatile struct
+{
+	u32		secure_flag;
+	u32		puk_hash[8];
+	u32		dev_id[3];	
+} otp_struct;
+
 typedef struct
 {
 	u32 uiPubKeyRsaE[32];
@@ -58,9 +65,24 @@
 	u32 uiHashY[32];
 } sImageHeader;
 
+typedef struct
+{
+	uint16_t   signtype;
+    uint16_t   hashtype;   
+	uint32_t   uiPubKeyRsaELen;
+	uint32_t   uiPubKeyRsaNLen;
+	uint8_t    uiPubKeyRsaE[4];
+	uint8_t    uiPubKeyRsaN[256];
+	uint8_t    reserve[112]; //380 bytes
+    uint8_t    uiHashY[256];    //256 bytes
+} sImageNewHeader;
+
+extern otp_struct otpInfo;
+
 static void get_efuse_data(void);
 static u32 SMALL2BIG(u32 *puiArrIn, u32 *puiArrOut, u32 uiLen);
 u8 secure_verify(u32 addr);
+u8 rootfs_secure_verify(u32 addr);
 static u8 data_cmp_word(u32* src, u32* dst, u32 cnt);
 int efuse_init(void);
 void efuse_get_devinfo(efuse_struct *efuse_info);