zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/boot/common/src/uboot/drivers/mtd/partition/partition.c b/boot/common/src/uboot/drivers/mtd/partition/partition.c
new file mode 100755
index 0000000..7f632ed
--- /dev/null
+++ b/boot/common/src/uboot/drivers/mtd/partition/partition.c
@@ -0,0 +1,455 @@
+/*********************************************************************
+ Copyright 2016 by  ZIXC Corporation.
+*
+* FileName::    partition.c
+* File Mark:
+* Description:  
+* Others:
+* Version:   v1.0
+* Author:   zhouqi
+* Date:   2014-1-15
+
+* History 1:
+*     Date: 
+*     Version:
+*     Author: 
+*     Modification:
+* History 2:
+**********************************************************************/
+
+#include <common.h>
+#include <errno.h>
+#include <command.h>
+#include <malloc.h>
+#include <jffs2/load_kernel.h>
+#include <linux/list.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/mtd/mtd.h>
+#include <nand.h>  
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>  
+#include <load_image.h>
+#include <boot_mode.h>
+#include <config.h>
+
+
+
+#define DEFINE_PARTITION_TABLE
+#include <partition_table.h>      
+#include <boot_mode.h>
+
+
+#if defined(CONFIG_CMD_NAND)
+#include <linux/mtd/nand.h>
+#include <nand.h>
+#endif
+
+#include <linux/mtd/nor_spifc.h>
+
+u_char * g_table = NULL;                        /* ¶ÁÈ¡µÄ·ÖÇø±íÐÅÏ¢ 2k+64 */
+partition_table_t * g_partition_table = NULL;   /* Ö¸Ïò·ÖÇø±íÐÅÏ¢ */
+extern partition_table_t * g_partition_table_dl;
+extern struct fsl_qspi spi_nor_flash;
+#ifdef CONFIG_ZX297520V3E_MDL_AB
+extern int imagefs_flag;
+#endif
+
+/* ================================================================================
+ *  add_partition_to_bootargs  :  Ôö¼Ó·ÖÇøÐÅÏ¢µ½ bootargs
+ */
+ #ifdef CONFIG_ZX297520V3E_MDL_AB
+ void add_partition_to_bootargs( void )
+{
+	int ret = 0;
+	uint32_t part_nums = 0;
+	uint32_t i = 0;
+	uint32_t start_entry = 0;               /* Æô¶¯·ÖÇøºÅ */
+	uchar bootargs_cmd[1024] = {0};
+	uchar boot_reason_para[32] = {0};
+	uchar boot_mode_para[16] = {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];
+
+	/* console=ttyS1,115200 no_console_suspend */
+	sprintf((char *)bootargs_cmd, "console=ttyS1,921600 no_console_suspend");
+
+	/* denali-nand: */
+	if(read_boot_flashtype() == IF_TYPE_NAND)
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=denali-nand:");
+	}
+	else if (read_boot_flashtype() == IF_TYPE_SPI_NAND)
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=spi-nand:");
+	}
+	else if (read_boot_flashtype() == IF_TYPE_NOR)
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=spi-nor-dt:");
+	}
+
+	/* È¥³ý×îºóµÄ2¸ö·ÖÇø ddr raw */
+	for( i=0; i<part_nums-VIRTUAL_PART_NUM-1; i++ )
+	{
+		if( (entry->part_size >= 0x100000) && (entry->part_size%0x100000 == 0) )
+		{
+			sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dm@0x%lx(%s),", 
+				(entry->part_size) >> 20, (entry->part_offset), (entry->part_name));
+		}
+		else
+		{
+			sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dk@0x%lx(%s),", 
+				 (entry->part_size) >> 10, (entry->part_offset), (entry->part_name));
+		}
+
+		/* »ñÈ¡Æô¶¯·ÖÇøºÅ */
+		//if(read_fota_update_flag())
+		if(imagefs_flag == 1)
+		{
+			if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_ROOTFS_IMAGE ) )
+			{
+				start_entry = i;
+			}
+		}
+		else if(imagefs_flag == 2)
+		{
+			if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_ROOTFS2_IMAGE ) )
+			{
+				start_entry = i;
+			}
+		}
+
+		entry++;
+	}
+
+	/* »ñÈ¡Æô¶¯·ÖÇøºÅ */ 
+	if(imagefs_flag == 1)    
+    {
+		if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_ROOTFS_IMAGE) )
+		{
+			start_entry = i + 1;
+		}
+	}
+	else if(imagefs_flag == 2)   
+	{
+		if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_ROOTFS2_IMAGE ) )
+		{
+			start_entry = i + 1;
+		}
+	}
+
+	/* ×îºóÒ»¸ö·ÖÇø */
+	if( (entry->part_size >= 0x100000) && (entry->part_size%0x100000 == 0) )
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dm@0x%lx(%s)",
+			(entry->part_size) >> 20, (entry->part_offset), (entry->part_name));
+	}
+	else
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dk@0x%lx(%s)",
+			(entry->part_size) >> 10, (entry->part_offset), (entry->part_name));
+	}
+	
+	/* rootfs=/dev/mtdblock7 rootfs2=/dev/mtdblock8 */
+    sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), 
+		" root=/dev/mtdblock%d ro rootfstype=jffs2", start_entry);
+	
+	printf("rootfs%d entry...\n",start_entry);
+
+	if(RB_AMT == read_boot_reason())
+	{
+		*poweron_type = POWER_ON_AMT;
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " boot_reason=%d", *poweron_type);
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " bootmode=amt");
+	}
+	else
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " boot_reason=%d", *poweron_type);
+	}
+	BOOT_PRINTF(UBOOT_INFO, "CONFIG_SYS_START_FLAG_ADDR = 0x%x, poweron_type = 0x%x.\n",
+		 POWERON_TYPE_ADDR, *poweron_type);
+
+	if(imagefs_flag == 1)    
+   	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " system=system_a");
+	}
+	else if(imagefs_flag == 2)   
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " system=system_b");
+	}	
+
+	/* save */
+	setenv("bootargs", (char *)bootargs_cmd);
+}
+ #else
+void add_partition_to_bootargs( void )
+{
+	int ret = 0;
+	uint32_t part_nums = 0;
+	uint32_t i = 0;
+	uint32_t start_entry = 0;               /* Æô¶¯·ÖÇøºÅ */
+	uchar bootargs_cmd[1024] = {0};
+	uchar boot_reason_para[32] = {0};
+	uchar boot_mode_para[16] = {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];
+
+	/* console=ttyS1,115200 no_console_suspend */
+	sprintf((char *)bootargs_cmd, "console=ttyS1,921600 no_console_suspend");
+
+	/* denali-nand: */
+	if(read_boot_flashtype() == IF_TYPE_NAND)
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=denali-nand:");
+	}
+	else if (read_boot_flashtype() == IF_TYPE_SPI_NAND)
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=spi-nand:");
+	}
+	else if (read_boot_flashtype() == IF_TYPE_NOR)
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=spi-nor-dt:");
+	}
+
+	/* È¥³ý×îºóµÄ2¸ö·ÖÇø ddr raw */
+	for( i=0; i<part_nums-VIRTUAL_PART_NUM-1; i++ )
+	{
+		if( (entry->part_size >= 0x100000) && (entry->part_size%0x100000 == 0) )
+		{
+			sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dm@0x%lx(%s),", 
+				(entry->part_size) >> 20, (entry->part_offset), (entry->part_name));
+		}
+		else
+		{
+			sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dk@0x%lx(%s),", 
+				 (entry->part_size) >> 10, (entry->part_offset), (entry->part_name));
+		}
+
+		/* »ñÈ¡Æô¶¯·ÖÇøºÅ */
+		if(read_fota_update_flag())
+		{
+			if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_RECOVERY_USERDATA_IMAGE ) )
+			{
+				start_entry = i;
+			}
+		}
+		else
+		{
+			if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_USERDATA_IMAGE ) )
+			{
+				start_entry = i;
+			}
+		}
+
+		entry++;
+	}
+
+	/* »ñÈ¡Æô¶¯·ÖÇøºÅ */ 
+	if(read_fota_update_flag())    /* 3±íʾFOTA-RECOVERY */
+    	{
+		if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_RECOVERY_USERDATA_IMAGE) )
+		{
+			start_entry = i + 1;
+		}
+	}
+	else    /* Õý³£Æô¶¯Á÷³Ì */
+	{
+		if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_USERDATA_IMAGE ) )
+		{
+			start_entry = i + 1;
+		}
+	}
+
+	/* ×îºóÒ»¸ö·ÖÇø */
+	if( (entry->part_size >= 0x100000) && (entry->part_size%0x100000 == 0) )
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dm@0x%lx(%s)",
+			(entry->part_size) >> 20, (entry->part_offset), (entry->part_name));
+	}
+	else
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dk@0x%lx(%s)",
+			(entry->part_size) >> 10, (entry->part_offset), (entry->part_name));
+	}
+	 
+	if(RB_AMT == read_boot_reason())
+	{
+		*poweron_type = POWER_ON_AMT;
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " boot_reason=%d", *poweron_type);
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " bootmode=amt");
+	}
+	else
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " boot_reason=%d", *poweron_type);
+	}
+	BOOT_PRINTF(UBOOT_INFO, "CONFIG_SYS_START_FLAG_ADDR = 0x%x, poweron_type = 0x%x.\n",
+		 POWERON_TYPE_ADDR, *poweron_type);
+
+    if(read_fota_update_flag())    
+   	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " system=recovery");
+	}
+	else  
+	{
+		sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " system=normal");
+	}	
+	
+	/* save */
+	setenv("bootargs", (char *)bootargs_cmd);
+}
+#endif
+/*******************************************************************************
+ * Function:    read_partition_and_check
+ * Description: ´ÓFLASHÖжÁÈ¡·ÖÇø±í
+ * Parameters:
+ *	 Input:
+ *
+ *	 Output:
+ *
+ * @return 0        :  ¶ÁÈ¡·ÖÇø±íÓÐЧ
+ * @return 1        :  ¶ÁÈ¡·ÖÇø±íÎÞЧ
+ *
+ * Others:
+ ********************************************************************************/
+int read_partition_and_check( void )
+{
+	struct flash_ops *flash = NULL;
+	nand_info_t *nand = &nand_info[nand_curr_device];
+	int table_size = 2048;
+	int ret = 0;
+	int type = 0;
+	int buf_size = 0;
+	struct fsl_qspi *nor;
+
+	nor = &spi_nor_flash;
+    
+	flash = get_flash_ops();
+	type = read_boot_flashtype();
+	if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND)
+	{
+		buf_size = nand->writesize + nand->oobsize;
+	}
+	else if(type == IF_TYPE_NOR)
+	{
+		buf_size = table_size;
+	}
+	
+	g_table = (u_char *)kzalloc(buf_size, GFP_KERNEL);
+	if ( g_table == NULL ) 
+	{
+		BOOT_PRINTF(UBOOT_ERR, "kzalloc Failed!\n");
+		return -EIO;
+	}
+    
+	/* ¶ÁÈ¡·ÖÇø±í */
+	/*
+    +------------------------------------------------------------+
+    |       z-load.bin                 |    partition_table.bin  |                
+    +------------------------------------------------------------+
+                                       8k           one page     10k
+    */ 
+
+	if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND)
+	{
+		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;
+		}
+	}
+
+	g_partition_table = (partition_table_t *)g_table;
+	if( g_partition_table->magic != PARTITION_MAGIC )
+	{
+		BOOT_PRINTF(UBOOT_ERR, "Partition Table Invalid! ret = %d.\n", ret);
+		return -EIO; 
+	}
+
+	return SUCCESS;
+}
+
+
+/*******************************************************************************
+ * Function:    find_partition_para
+ * Description:  ͨ¹ý·ÖÇøÃû²éÕÒ·ÖÇøÊ×µØÖ·
+ * Parameters:
+ *	 Input:
+ *
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/ 
+partition_entry_t * find_partition_para( uchar * name )
+{
+	partition_entry_t *entry = NULL;
+	uint32_t entry_nums = 0;
+	
+	if(get_load_mode() == TLOAD_MODE) 
+	{
+		entry = &g_partition_table_dl->table[0];
+		entry_nums = g_partition_table_dl->entrys;
+	}
+	else
+	{
+		entry = &g_partition_table->table[0];
+		entry_nums = g_partition_table->entrys;
+	}
+	while( entry_nums-- )
+	{
+		if ( strcmp( (char *)entry->part_name, (char *)name ) == 0 )
+		{
+			return entry;
+		}
+		entry++;
+	}
+	return NULL;
+}
+
+/*******************************************************************************
+ * Function:    partition_init
+ * Description:  ͨ¹ý·ÖÇøÃû²éÕÒ·ÖÇøÊ×µØÖ·
+ * Parameters:
+ *	 Input:
+ *
+ *	 Output:
+ *
+ * Returns:
+ *
+ *
+ * Others:
+ ********************************************************************************/ 
+int partition_init(void)
+{
+	int ret = 0;
+
+	ret = read_partition_and_check();
+
+	if( ret != 0 )
+	{
+		BOOT_PRINTF(UBOOT_ERR, "read_partition ERROR !!!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+