yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame^] | 1 | /********************************************************************* |
| 2 | Copyright 2016 by ZIXC Corporation. |
| 3 | * |
| 4 | * FileName:: partition.c |
| 5 | * File Mark: |
| 6 | * Description: |
| 7 | * Others: |
| 8 | * Version: v1.0 |
| 9 | * Author: zhouqi |
| 10 | * Date: 2014-1-15 |
| 11 | |
| 12 | * History 1: |
| 13 | * Date: |
| 14 | * Version: |
| 15 | * Author: |
| 16 | * Modification: |
| 17 | * History 2: |
| 18 | **********************************************************************/ |
| 19 | |
| 20 | #include <common.h> |
| 21 | #include <errno.h> |
| 22 | #include <command.h> |
| 23 | #include <malloc.h> |
| 24 | #include <jffs2/load_kernel.h> |
| 25 | #include <linux/list.h> |
| 26 | #include <linux/ctype.h> |
| 27 | #include <linux/err.h> |
| 28 | #include <linux/mtd/mtd.h> |
| 29 | #include <nand.h> |
| 30 | #include <linux/mtd/partitions.h> |
| 31 | #include <asm/io.h> |
| 32 | #include <load_image.h> |
| 33 | #include <boot_mode.h> |
| 34 | #include <config.h> |
| 35 | |
| 36 | |
| 37 | |
| 38 | #define DEFINE_PARTITION_TABLE |
| 39 | #include <partition_table.h> |
| 40 | #include <boot_mode.h> |
| 41 | |
| 42 | |
| 43 | #if defined(CONFIG_CMD_NAND) |
| 44 | #include <linux/mtd/nand.h> |
| 45 | #include <nand.h> |
| 46 | #endif |
| 47 | |
| 48 | #include <linux/mtd/nor_spifc.h> |
| 49 | |
| 50 | u_char * g_table = NULL; /* ¶ÁÈ¡µÄ·ÖÇø±íÐÅÏ¢ 2k+64 */ |
| 51 | partition_table_t * g_partition_table = NULL; /* Ö¸Ïò·ÖÇø±íÐÅÏ¢ */ |
| 52 | extern partition_table_t * g_partition_table_dl; |
| 53 | extern struct fsl_qspi spi_nor_flash; |
| 54 | #ifdef CONFIG_ZX297520V3E_MDL_AB |
| 55 | extern int imagefs_flag; |
| 56 | #endif |
| 57 | |
| 58 | /* ================================================================================ |
| 59 | * add_partition_to_bootargs : Ôö¼Ó·ÖÇøÐÅÏ¢µ½ bootargs |
| 60 | */ |
| 61 | #ifdef CONFIG_ZX297520V3E_MDL_AB |
| 62 | void add_partition_to_bootargs( void ) |
| 63 | { |
| 64 | int ret = 0; |
| 65 | uint32_t part_nums = 0; |
| 66 | uint32_t i = 0; |
| 67 | uint32_t start_entry = 0; /* Æô¶¯·ÖÇøºÅ */ |
| 68 | uchar bootargs_cmd[1024] = {0}; |
| 69 | uchar boot_reason_para[32] = {0}; |
| 70 | uchar boot_mode_para[16] = {0}; |
| 71 | unsigned int *poweron_type = (unsigned int *)POWERON_TYPE_ADDR; //ÁÙʱʹÓà |
| 72 | |
| 73 | part_nums = g_partition_table->entrys; |
| 74 | |
| 75 | partition_entry_t * entry = &g_partition_table->table[0]; |
| 76 | |
| 77 | /* console=ttyS1,115200 no_console_suspend */ |
| 78 | sprintf((char *)bootargs_cmd, "console=ttyS1,921600 no_console_suspend"); |
| 79 | |
| 80 | /* denali-nand: */ |
| 81 | if(read_boot_flashtype() == IF_TYPE_NAND) |
| 82 | { |
| 83 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=denali-nand:"); |
| 84 | } |
| 85 | else if (read_boot_flashtype() == IF_TYPE_SPI_NAND) |
| 86 | { |
| 87 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=spi-nand:"); |
| 88 | } |
| 89 | else if (read_boot_flashtype() == IF_TYPE_NOR) |
| 90 | { |
| 91 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=spi-nor-dt:"); |
| 92 | } |
| 93 | |
| 94 | /* È¥³ý×îºóµÄ2¸ö·ÖÇø ddr raw */ |
| 95 | for( i=0; i<part_nums-VIRTUAL_PART_NUM-1; i++ ) |
| 96 | { |
| 97 | if( (entry->part_size >= 0x100000) && (entry->part_size%0x100000 == 0) ) |
| 98 | { |
| 99 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dm@0x%lx(%s),", |
| 100 | (entry->part_size) >> 20, (entry->part_offset), (entry->part_name)); |
| 101 | } |
| 102 | else |
| 103 | { |
| 104 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dk@0x%lx(%s),", |
| 105 | (entry->part_size) >> 10, (entry->part_offset), (entry->part_name)); |
| 106 | } |
| 107 | |
| 108 | /* »ñÈ¡Æô¶¯·ÖÇøºÅ */ |
| 109 | //if(read_fota_update_flag()) |
| 110 | if(imagefs_flag == 1) |
| 111 | { |
| 112 | if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_ROOTFS_IMAGE ) ) |
| 113 | { |
| 114 | start_entry = i; |
| 115 | } |
| 116 | } |
| 117 | else if(imagefs_flag == 2) |
| 118 | { |
| 119 | if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_ROOTFS2_IMAGE ) ) |
| 120 | { |
| 121 | start_entry = i; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | entry++; |
| 126 | } |
| 127 | |
| 128 | /* »ñÈ¡Æô¶¯·ÖÇøºÅ */ |
| 129 | if(imagefs_flag == 1) |
| 130 | { |
| 131 | if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_ROOTFS_IMAGE) ) |
| 132 | { |
| 133 | start_entry = i + 1; |
| 134 | } |
| 135 | } |
| 136 | else if(imagefs_flag == 2) |
| 137 | { |
| 138 | if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_ROOTFS2_IMAGE ) ) |
| 139 | { |
| 140 | start_entry = i + 1; |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | /* ×îºóÒ»¸ö·ÖÇø */ |
| 145 | if( (entry->part_size >= 0x100000) && (entry->part_size%0x100000 == 0) ) |
| 146 | { |
| 147 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dm@0x%lx(%s)", |
| 148 | (entry->part_size) >> 20, (entry->part_offset), (entry->part_name)); |
| 149 | } |
| 150 | else |
| 151 | { |
| 152 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dk@0x%lx(%s)", |
| 153 | (entry->part_size) >> 10, (entry->part_offset), (entry->part_name)); |
| 154 | } |
| 155 | |
| 156 | /* rootfs=/dev/mtdblock7 rootfs2=/dev/mtdblock8 */ |
| 157 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), |
| 158 | " root=/dev/mtdblock%d ro rootfstype=jffs2", start_entry); |
| 159 | |
| 160 | printf("rootfs%d entry...\n",start_entry); |
| 161 | |
| 162 | if(RB_AMT == read_boot_reason()) |
| 163 | { |
| 164 | *poweron_type = POWER_ON_AMT; |
| 165 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " boot_reason=%d", *poweron_type); |
| 166 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " bootmode=amt"); |
| 167 | } |
| 168 | else |
| 169 | { |
| 170 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " boot_reason=%d", *poweron_type); |
| 171 | } |
| 172 | BOOT_PRINTF(UBOOT_INFO, "CONFIG_SYS_START_FLAG_ADDR = 0x%x, poweron_type = 0x%x.\n", |
| 173 | POWERON_TYPE_ADDR, *poweron_type); |
| 174 | |
| 175 | if(imagefs_flag == 1) |
| 176 | { |
| 177 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " system=system_a"); |
| 178 | } |
| 179 | else if(imagefs_flag == 2) |
| 180 | { |
| 181 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " system=system_b"); |
| 182 | } |
| 183 | |
| 184 | /* save */ |
| 185 | setenv("bootargs", (char *)bootargs_cmd); |
| 186 | } |
| 187 | #else |
| 188 | void add_partition_to_bootargs( void ) |
| 189 | { |
| 190 | int ret = 0; |
| 191 | uint32_t part_nums = 0; |
| 192 | uint32_t i = 0; |
| 193 | uint32_t start_entry = 0; /* Æô¶¯·ÖÇøºÅ */ |
| 194 | uchar bootargs_cmd[1024] = {0}; |
| 195 | uchar boot_reason_para[32] = {0}; |
| 196 | uchar boot_mode_para[16] = {0}; |
| 197 | unsigned int *poweron_type = (unsigned int *)POWERON_TYPE_ADDR; //ÁÙʱʹÓà |
| 198 | |
| 199 | part_nums = g_partition_table->entrys; |
| 200 | |
| 201 | partition_entry_t * entry = &g_partition_table->table[0]; |
| 202 | |
| 203 | /* console=ttyS1,115200 no_console_suspend */ |
| 204 | sprintf((char *)bootargs_cmd, "console=ttyS1,921600 no_console_suspend"); |
| 205 | |
| 206 | /* denali-nand: */ |
| 207 | if(read_boot_flashtype() == IF_TYPE_NAND) |
| 208 | { |
| 209 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=denali-nand:"); |
| 210 | } |
| 211 | else if (read_boot_flashtype() == IF_TYPE_SPI_NAND) |
| 212 | { |
| 213 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=spi-nand:"); |
| 214 | } |
| 215 | else if (read_boot_flashtype() == IF_TYPE_NOR) |
| 216 | { |
| 217 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " mtdparts=spi-nor-dt:"); |
| 218 | } |
| 219 | |
| 220 | /* È¥³ý×îºóµÄ2¸ö·ÖÇø ddr raw */ |
| 221 | for( i=0; i<part_nums-VIRTUAL_PART_NUM-1; i++ ) |
| 222 | { |
| 223 | if( (entry->part_size >= 0x100000) && (entry->part_size%0x100000 == 0) ) |
| 224 | { |
| 225 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dm@0x%lx(%s),", |
| 226 | (entry->part_size) >> 20, (entry->part_offset), (entry->part_name)); |
| 227 | } |
| 228 | else |
| 229 | { |
| 230 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dk@0x%lx(%s),", |
| 231 | (entry->part_size) >> 10, (entry->part_offset), (entry->part_name)); |
| 232 | } |
| 233 | |
| 234 | /* »ñÈ¡Æô¶¯·ÖÇøºÅ */ |
| 235 | if(read_fota_update_flag()) |
| 236 | { |
| 237 | if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_RECOVERY_USERDATA_IMAGE ) ) |
| 238 | { |
| 239 | start_entry = i; |
| 240 | } |
| 241 | } |
| 242 | else |
| 243 | { |
| 244 | if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_USERDATA_IMAGE ) ) |
| 245 | { |
| 246 | start_entry = i; |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | entry++; |
| 251 | } |
| 252 | |
| 253 | /* »ñÈ¡Æô¶¯·ÖÇøºÅ */ |
| 254 | if(read_fota_update_flag()) /* 3±íʾFOTA-RECOVERY */ |
| 255 | { |
| 256 | if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_RECOVERY_USERDATA_IMAGE) ) |
| 257 | { |
| 258 | start_entry = i + 1; |
| 259 | } |
| 260 | } |
| 261 | else /* Õý³£Æô¶¯Á÷³Ì */ |
| 262 | { |
| 263 | if ( 0 == strcmp( (char *)entry->part_name, (char *)ARM_USERDATA_IMAGE ) ) |
| 264 | { |
| 265 | start_entry = i + 1; |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | /* ×îºóÒ»¸ö·ÖÇø */ |
| 270 | if( (entry->part_size >= 0x100000) && (entry->part_size%0x100000 == 0) ) |
| 271 | { |
| 272 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dm@0x%lx(%s)", |
| 273 | (entry->part_size) >> 20, (entry->part_offset), (entry->part_name)); |
| 274 | } |
| 275 | else |
| 276 | { |
| 277 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), "%dk@0x%lx(%s)", |
| 278 | (entry->part_size) >> 10, (entry->part_offset), (entry->part_name)); |
| 279 | } |
| 280 | |
| 281 | if(RB_AMT == read_boot_reason()) |
| 282 | { |
| 283 | *poweron_type = POWER_ON_AMT; |
| 284 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " boot_reason=%d", *poweron_type); |
| 285 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " bootmode=amt"); |
| 286 | } |
| 287 | else |
| 288 | { |
| 289 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " boot_reason=%d", *poweron_type); |
| 290 | } |
| 291 | BOOT_PRINTF(UBOOT_INFO, "CONFIG_SYS_START_FLAG_ADDR = 0x%x, poweron_type = 0x%x.\n", |
| 292 | POWERON_TYPE_ADDR, *poweron_type); |
| 293 | |
| 294 | if(read_fota_update_flag()) |
| 295 | { |
| 296 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " system=recovery"); |
| 297 | } |
| 298 | else |
| 299 | { |
| 300 | sprintf((char *)bootargs_cmd + strlen(bootargs_cmd), " system=normal"); |
| 301 | } |
| 302 | |
| 303 | /* save */ |
| 304 | setenv("bootargs", (char *)bootargs_cmd); |
| 305 | } |
| 306 | #endif |
| 307 | /******************************************************************************* |
| 308 | * Function: read_partition_and_check |
| 309 | * Description: ´ÓFLASHÖжÁÈ¡·ÖÇø±í |
| 310 | * Parameters: |
| 311 | * Input: |
| 312 | * |
| 313 | * Output: |
| 314 | * |
| 315 | * @return 0 : ¶ÁÈ¡·ÖÇø±íÓÐЧ |
| 316 | * @return 1 : ¶ÁÈ¡·ÖÇø±íÎÞЧ |
| 317 | * |
| 318 | * Others: |
| 319 | ********************************************************************************/ |
| 320 | int read_partition_and_check( void ) |
| 321 | { |
| 322 | struct flash_ops *flash = NULL; |
| 323 | nand_info_t *nand = &nand_info[nand_curr_device]; |
| 324 | int table_size = 2048; |
| 325 | int ret = 0; |
| 326 | int type = 0; |
| 327 | int buf_size = 0; |
| 328 | struct fsl_qspi *nor; |
| 329 | |
| 330 | nor = &spi_nor_flash; |
| 331 | |
| 332 | flash = get_flash_ops(); |
| 333 | type = read_boot_flashtype(); |
| 334 | if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND) |
| 335 | { |
| 336 | buf_size = nand->writesize + nand->oobsize; |
| 337 | } |
| 338 | else if(type == IF_TYPE_NOR) |
| 339 | { |
| 340 | buf_size = table_size; |
| 341 | } |
| 342 | |
| 343 | g_table = (u_char *)kzalloc(buf_size, GFP_KERNEL); |
| 344 | if ( g_table == NULL ) |
| 345 | { |
| 346 | BOOT_PRINTF(UBOOT_ERR, "kzalloc Failed!\n"); |
| 347 | return -EIO; |
| 348 | } |
| 349 | |
| 350 | /* ¶ÁÈ¡·ÖÇø±í */ |
| 351 | /* |
| 352 | +------------------------------------------------------------+ |
| 353 | | z-load.bin | partition_table.bin | |
| 354 | +------------------------------------------------------------+ |
| 355 | 8k one page 10k |
| 356 | */ |
| 357 | |
| 358 | if(type == IF_TYPE_NAND || type == IF_TYPE_SPI_NAND) |
| 359 | { |
| 360 | ret = flash->read_with_ecc(nand, (loff_t)8*1024, &table_size, g_table); |
| 361 | if(ret) |
| 362 | { |
| 363 | BOOT_PRINTF(UBOOT_ERR, "read_no_ecc Failed! ret = %d.\n", ret); |
| 364 | return -1; |
| 365 | } |
| 366 | } |
| 367 | else if(type == IF_TYPE_NOR) |
| 368 | { |
| 369 | ret = nand_read(&(nor->nor[0].mtd), (loff_t)8*1024, &table_size, g_table); |
| 370 | if(ret) |
| 371 | { |
| 372 | BOOT_PRINTF(UBOOT_ERR, "nand_read error! ret = %d.\n", ret); |
| 373 | return -1; |
| 374 | } |
| 375 | } |
| 376 | |
| 377 | g_partition_table = (partition_table_t *)g_table; |
| 378 | if( g_partition_table->magic != PARTITION_MAGIC ) |
| 379 | { |
| 380 | BOOT_PRINTF(UBOOT_ERR, "Partition Table Invalid! ret = %d.\n", ret); |
| 381 | return -EIO; |
| 382 | } |
| 383 | |
| 384 | return SUCCESS; |
| 385 | } |
| 386 | |
| 387 | |
| 388 | /******************************************************************************* |
| 389 | * Function: find_partition_para |
| 390 | * Description: ͨ¹ý·ÖÇøÃû²éÕÒ·ÖÇøÊ×µØÖ· |
| 391 | * Parameters: |
| 392 | * Input: |
| 393 | * |
| 394 | * Output: |
| 395 | * |
| 396 | * Returns: |
| 397 | * |
| 398 | * |
| 399 | * Others: |
| 400 | ********************************************************************************/ |
| 401 | partition_entry_t * find_partition_para( uchar * name ) |
| 402 | { |
| 403 | partition_entry_t *entry = NULL; |
| 404 | uint32_t entry_nums = 0; |
| 405 | |
| 406 | if(get_load_mode() == TLOAD_MODE) |
| 407 | { |
| 408 | entry = &g_partition_table_dl->table[0]; |
| 409 | entry_nums = g_partition_table_dl->entrys; |
| 410 | } |
| 411 | else |
| 412 | { |
| 413 | entry = &g_partition_table->table[0]; |
| 414 | entry_nums = g_partition_table->entrys; |
| 415 | } |
| 416 | while( entry_nums-- ) |
| 417 | { |
| 418 | if ( strcmp( (char *)entry->part_name, (char *)name ) == 0 ) |
| 419 | { |
| 420 | return entry; |
| 421 | } |
| 422 | entry++; |
| 423 | } |
| 424 | return NULL; |
| 425 | } |
| 426 | |
| 427 | /******************************************************************************* |
| 428 | * Function: partition_init |
| 429 | * Description: ͨ¹ý·ÖÇøÃû²éÕÒ·ÖÇøÊ×µØÖ· |
| 430 | * Parameters: |
| 431 | * Input: |
| 432 | * |
| 433 | * Output: |
| 434 | * |
| 435 | * Returns: |
| 436 | * |
| 437 | * |
| 438 | * Others: |
| 439 | ********************************************************************************/ |
| 440 | int partition_init(void) |
| 441 | { |
| 442 | int ret = 0; |
| 443 | |
| 444 | ret = read_partition_and_check(); |
| 445 | |
| 446 | if( ret != 0 ) |
| 447 | { |
| 448 | BOOT_PRINTF(UBOOT_ERR, "read_partition ERROR !!!\n"); |
| 449 | return -1; |
| 450 | } |
| 451 | |
| 452 | return 0; |
| 453 | } |
| 454 | |
| 455 | |