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;
+}
+
+