| /********************************************************************* |
| 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; |
| } |
| |
| |