Commit ed915f7d455a34ede75d9962919181b8b8ba57ec

Authored by Ji Luo
1 parent 648a4c5376

MA-14916-4 support dual bootloader for imx8m/imx8q

This commit enables dual bootloader feature for imx8m/imx8q, but
as commit 'a2018ab' already brings in some dual bootloader codes
when enabling fastboot support, so this commit won't be a complete
and standalone patch to introduce the dual bootloader feature.

This commit will do the following:
  1. clean up dual bootloader flow and add missing implementation.
  2. Merge the dual bootloader entry for fit and container to one
     function 'mmc_load_image_raw_sector_dual_uboot'.

Change-Id: Ic9410a48092cc05de599dd897fc912177e2a1fe1
Signed-off-by: Ji Luo <ji.luo@nxp.com>

Showing 8 changed files with 90 additions and 158 deletions Side-by-side Diff

arch/arm/mach-imx/imx8/parse-container.c
... ... @@ -192,6 +192,12 @@
192 192 }
193 193 }
194 194  
  195 +#if defined(CONFIG_SPL_BUILD) && \
  196 + defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_IMX_TRUSTY_OS)
  197 + /* Everything checks out, get the sw_version now. */
  198 + spl_image->rbindex = (uint64_t)container->sw_version;
  199 +#endif
  200 +
195 201 end_auth:
196 202 #ifdef CONFIG_AHAB_BOOT
197 203 if (sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0))
common/spl/spl_fit.c
... ... @@ -63,6 +63,10 @@
63 63 return -ENOENT;
64 64 }
65 65  
  66 +#ifdef CONFIG_DUAL_BOOTLOADER
  67 +extern int spl_fit_get_rbindex(const void *fit, int images);
  68 +#endif
  69 +
66 70 /**
67 71 * spl_fit_get_image_name(): By using the matching configuration subnode,
68 72 * retrieve the name of an image, specified by a property name and an index
... ... @@ -571,6 +575,16 @@
571 575 debug("%s: Cannot find /images node: %d\n", __func__, images);
572 576 return -1;
573 577 }
  578 +
  579 +#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_IMX_TRUSTY_OS)
  580 + int rbindex;
  581 + rbindex = spl_fit_get_rbindex(fit, images);
  582 + if (rbindex < 0) {
  583 + printf("Error! Can't get rollback index!\n");
  584 + return -1;
  585 + } else
  586 + spl_image->rbindex = rbindex;
  587 +#endif
574 588  
575 589 #ifdef CONFIG_SPL_FPGA_SUPPORT
576 590 node = spl_fit_get_image_node(fit, images, "fpga", 0);
common/spl/spl_mmc.c
... ... @@ -41,7 +41,7 @@
41 41 return 0;
42 42 }
43 43  
44   -static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
  44 +ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
45 45 ulong count, void *buf)
46 46 {
47 47 struct mmc *mmc = load->dev;
... ... @@ -62,6 +62,8 @@
62 62 #if defined(CONFIG_IMX_TRUSTY_OS)
63 63 /* Pre-declaration of check_rpmb_blob. */
64 64 int check_rpmb_blob(struct mmc *mmc);
  65 +int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image,
  66 + struct mmc *mmc);
65 67 #endif
66 68  
67 69 static __maybe_unused
68 70  
... ... @@ -116,21 +118,10 @@
116 118 return -1;
117 119 }
118 120  
119   - /* Images loaded, now check the rpmb keyblob for Trusty OS.
120   - * Skip this step when the dual bootloader feature is enabled
121   - * since the blob should be checked earlier.
122   - */
123   -#if defined(CONFIG_IMX_TRUSTY_OS)
124   - if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
125   -#if !defined(CONFIG_DUAL_BOOTLOADER)
  121 + /* Images loaded, now check the rpmb keyblob for Trusty OS. */
  122 +#if defined(CONFIG_IMX_TRUSTY_OS) && !defined(CONFIG_AVB_ATX)
126 123 ret = check_rpmb_blob(mmc);
127 124 #endif
128   - } else {
129   -#if !defined(CONFIG_AVB_ATX)
130   - ret = check_rpmb_blob(mmc);
131   -#endif
132   - }
133   -#endif
134 125  
135 126 return ret;
136 127 }
137 128  
... ... @@ -383,11 +374,18 @@
383 374 * 1 and 2 match up to boot0 / boot1 and 7 is user data
384 375 * which is the first physical partition (0).
385 376 */
  377 +#ifdef CONFIG_DUAL_BOOTLOADER
  378 + /* Bootloader is stored in eMMC user partition for
  379 + * dual bootloader.
  380 + */
  381 + part = 0;
  382 +#else
386 383 part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
387 384  
388 385 if (part == 7)
389 386 part = 0;
390 387 #endif
  388 +#endif
391 389  
392 390 if (CONFIG_IS_ENABLED(MMC_TINY))
393 391 err = mmc_switch_part(mmc, part);
394 392  
... ... @@ -410,7 +408,9 @@
410 408 return err;
411 409 }
412 410  
  411 +#ifndef CONFIG_DUAL_BOOTLOADER
413 412 raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
  413 +#endif
414 414  
415 415 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
416 416 err = mmc_load_image_raw_partition(spl_image, mmc, raw_part,
417 417  
... ... @@ -419,8 +419,12 @@
419 419 return err;
420 420 #endif
421 421 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
  422 +#ifdef CONFIG_DUAL_BOOTLOADER
  423 + err = mmc_load_image_raw_sector_dual_uboot(spl_image, mmc);
  424 +#else
422 425 err = mmc_load_image_raw_sector(spl_image, mmc,
423 426 raw_sect + spl_mmc_raw_uboot_offset(part));
  427 +#endif
424 428 if (!err)
425 429 return err;
426 430 #endif
... ... @@ -266,8 +266,10 @@
266 266 printf("\tguid:\t%s\n", uuid);
267 267 }
268 268  
  269 +#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
269 270 /* Remember to free pte */
270 271 free(gpt_pte);
  272 +#endif
271 273 return;
272 274 }
273 275  
274 276  
... ... @@ -291,7 +293,9 @@
291 293 !is_pte_valid(&gpt_pte[part - 1])) {
292 294 debug("%s: *** ERROR: Invalid partition number %d ***\n",
293 295 __func__, part);
  296 +#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
294 297 free(gpt_pte);
  298 +#endif
295 299 return -1;
296 300 }
297 301  
298 302  
... ... @@ -318,8 +322,14 @@
318 322 debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__,
319 323 info->start, info->size, info->name);
320 324  
321   - /* Remember to free pte */
  325 +#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
  326 + /* Heap memory is very limited in SPL, if the dual bootloader is
  327 + * enabled, just load pte to dram instead of oc-ram. In such case,
  328 + * this part of memory shouldn't be freed. But in common routine,
  329 + * don't forget to free the memory after use.
  330 + */
322 331 free(gpt_pte);
  332 +#endif
323 333 return 0;
324 334 }
325 335  
326 336  
327 337  
... ... @@ -1106,10 +1116,19 @@
1106 1116 (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry),
1107 1117 (ulong)count);
1108 1118  
1109   - /* Allocate memory for PTE, remember to FREE */
  1119 + /* Allocate memory for PTE.
  1120 + * Heap memory is very limited in SPL, if the dual bootloader is
  1121 + * enabled, just load pte to dram instead of oc-ram. In such case,
  1122 + * this part of memory shouldn't be freed. But in common routine,
  1123 + * don't forget to free the memory after use.
  1124 + */
1110 1125 if (count != 0) {
  1126 +#if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD)
  1127 + pte = (gpt_entry *)CONFIG_SYS_SPL_PTE_RAM_BASE;
  1128 +#else
1111 1129 pte = memalign(ARCH_DMA_MINALIGN,
1112 1130 PAD_TO_BLOCKSIZE(count, dev_desc));
  1131 +#endif
1113 1132 }
1114 1133  
1115 1134 if (count == 0 || pte == NULL) {
1116 1135  
... ... @@ -1123,7 +1142,9 @@
1123 1142 blk_cnt = BLOCK_CNT(count, dev_desc);
1124 1143 if (blk_dread(dev_desc, blk, (lbaint_t)blk_cnt, pte) != blk_cnt) {
1125 1144 printf("*** ERROR: Can't read GPT Entries ***\n");
  1145 +#if !defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
1126 1146 free(pte);
  1147 +#endif
1127 1148 return NULL;
1128 1149 }
1129 1150 return pte;
... ... @@ -270,7 +270,8 @@
270 270 #ifdef CONFIG_SPL_BUILD
271 271 # define part_print_ptr(x) NULL
272 272 # if defined(CONFIG_SPL_FS_EXT4) || defined(CONFIG_SPL_FS_FAT) || \
273   - defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION)
  273 + defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION) || \
  274 + defined(CONFIG_DUAL_BOOTLOADER)
274 275 # define part_get_info_ptr(x) x
275 276 # else
276 277 # define part_get_info_ptr(x) NULL
... ... @@ -145,6 +145,9 @@
145 145 ulong dcrc_length;
146 146 ulong dcrc;
147 147 #endif
  148 +#ifdef CONFIG_DUAL_BOOTLOADER
  149 + uint64_t rbindex;
  150 +#endif
148 151 };
149 152  
150 153 /*
lib/avb/fsl/fsl_avb_ab_flow.c
... ... @@ -214,7 +214,7 @@
214 214 }
215 215 }
216 216  
217   -#ifndef CONFIG_XEN
  217 +#if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS)
218 218 static int spl_verify_rbidx(struct mmc *mmc, AvbABSlotData *slot,
219 219 struct spl_image_info *spl_image)
220 220 {
221 221  
222 222  
223 223  
224 224  
... ... @@ -274,19 +274,21 @@
274 274 }
275 275  
276 276 }
277   -#endif /* CONFIG_XEN */
  277 +#endif /* !CONFIG_XEN && CONFIG_IMX_TRUSTY_OS */
278 278  
279   -#ifdef CONFIG_PARSE_CONTAINER
280   -int mmc_load_image_parse_container_dual_uboot(
281   - struct spl_image_info *spl_image, struct mmc *mmc)
  279 +int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image,
  280 + struct mmc *mmc)
282 281 {
  282 + unsigned long count;
283 283 disk_partition_t info;
284 284 int ret = 0, n = 0;
285 285 char partition_name[PARTITION_NAME_LEN];
286 286 struct blk_desc *dev_desc;
  287 + struct image_header *header;
  288 + struct spl_load_info load;
287 289 AvbABData ab_data, ab_data_orig;
288 290 size_t slot_index_to_boot, target_slot;
289   -#ifndef CONFIG_XEN
  291 +#if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS)
290 292 struct keyslot_package kp;
291 293 #endif
292 294  
... ... @@ -302,8 +304,7 @@
302 304 return -1;
303 305 }
304 306  
305   -#ifndef CONFIG_XEN
306   - /* Read RPMB keyslot package, xen won't check this. */
  307 +#if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS)
307 308 read_keyslot_package(&kp);
308 309 if (strcmp(kp.magic, KEYPACK_MAGIC)) {
309 310 if (rpmbkey_is_set()) {
... ... @@ -347,126 +348,6 @@
347 348 ret = -1;
348 349 goto end;
349 350 } else {
350   - ret = mmc_load_image_parse_container(spl_image, mmc, info.start);
351   -
352   - /* Don't need to check rollback index for xen. */
353   -#ifndef CONFIG_XEN
354   - /* Image loaded successfully, go to verify rollback index */
355   - if (!ret && rpmbkey_is_set())
356   - ret = spl_verify_rbidx(mmc, &ab_data.slots[target_slot], spl_image);
357   -
358   - /* Copy rpmb keyslot to secure memory. */
359   - if (!ret)
360   - fill_secure_keyslot_package(&kp);
361   -#endif
362   - }
363   -
364   - /* Set current slot to unbootable if load/verify fail. */
365   - if (ret != 0) {
366   - printf("Load or verify bootloader%s fail, setting unbootable..\n",
367   - slot_suffixes[target_slot]);
368   - fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
369   - /* Switch to another slot. */
370   - target_slot = (target_slot == 1 ? 0 : 1);
371   - } else {
372   - slot_index_to_boot = target_slot;
373   - n = 2;
374   - }
375   - }
376   -
377   - if (slot_index_to_boot == 2) {
378   - /* No bootable slots! */
379   - printf("No bootable slots found.\n");
380   - ret = -1;
381   - goto end;
382   - } else if (!ab_data.slots[slot_index_to_boot].successful_boot &&
383   - (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) {
384   - /* Set the bootloader_verified flag if current slot only has one chance. */
385   - if (ab_data.slots[slot_index_to_boot].tries_remaining == 1)
386   - ab_data.slots[slot_index_to_boot].bootloader_verified = 1;
387   - ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
388   - }
389   - printf("Booting from bootloader%s...\n", slot_suffixes[slot_index_to_boot]);
390   -
391   -end:
392   - /* Save metadata if changed. */
393   - if (fsl_save_metadata_if_changed_dual_uboot(dev_desc, &ab_data, &ab_data_orig)) {
394   - ret = -1;
395   - }
396   -
397   - if (ret)
398   - return -1;
399   - else
400   - return 0;
401   -}
402   -#else /* CONFIG_PARSE_CONTAINER */
403   -int mmc_load_image_raw_sector_dual_uboot(
404   - struct spl_image_info *spl_image, struct mmc *mmc)
405   -{
406   - unsigned long count;
407   - disk_partition_t info;
408   - int ret = 0, n = 0;
409   - char partition_name[PARTITION_NAME_LEN];
410   - struct blk_desc *dev_desc;
411   - struct image_header *header;
412   - AvbABData ab_data, ab_data_orig;
413   - size_t slot_index_to_boot, target_slot;
414   - struct keyslot_package kp;
415   -
416   - /* Check if gpt is valid */
417   - dev_desc = mmc_get_blk_desc(mmc);
418   - if (dev_desc) {
419   - if (part_get_info(dev_desc, 1, &info)) {
420   - printf("GPT is invalid, please flash correct GPT!\n");
421   - return -1;
422   - }
423   - } else {
424   - printf("Get block desc fail!\n");
425   - return -1;
426   - }
427   -
428   - /* Init RPMB keyslot package if not initialized before. */
429   - read_keyslot_package(&kp);
430   - if (strcmp(kp.magic, KEYPACK_MAGIC)) {
431   - printf("keyslot package magic error. Will generate new one\n");
432   - if (gen_rpmb_key(&kp)) {
433   - printf("Generate keyslot package fail!\n");
434   - return -1;
435   - }
436   - }
437   - /* Set power-on write protection to boot1 partition. */
438   - if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) {
439   - printf("Unable to set power-on write protection to boot1!\n");
440   - return -1;
441   - }
442   -
443   - /* Load AB metadata from misc partition */
444   - if (fsl_load_metadata_dual_uboot(dev_desc, &ab_data,
445   - &ab_data_orig)) {
446   - return -1;
447   - }
448   -
449   - slot_index_to_boot = 2; // Means not 0 or 1
450   - target_slot =
451   - (ab_data.slots[1].priority > ab_data.slots[0].priority) ? 1 : 0;
452   -
453   - for (n = 0; n < 2; n++) {
454   - if (!fsl_slot_is_bootable(&ab_data.slots[target_slot])) {
455   - target_slot = (target_slot == 1 ? 0 : 1);
456   - continue;
457   - }
458   - /* Choose slot to load. */
459   - snprintf(partition_name, PARTITION_NAME_LEN,
460   - PARTITION_BOOTLOADER"%s",
461   - slot_suffixes[target_slot]);
462   -
463   - /* Read part info from gpt */
464   - if (part_get_info_by_name(dev_desc, partition_name, &info) == -1) {
465   - printf("Can't get partition info of partition bootloader%s\n",
466   - slot_suffixes[target_slot]);
467   - ret = -1;
468   - goto end;
469   - } else {
470 351 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
471 352 sizeof(struct image_header));
472 353  
473 354  
474 355  
475 356  
476 357  
477 358  
... ... @@ -477,30 +358,32 @@
477 358 goto end;
478 359 }
479 360  
480   - /* Load fit and check HAB */
  361 + /* Load fit/container and check HAB */
  362 + load.dev = mmc;
  363 + load.priv = NULL;
  364 + load.filename = NULL;
  365 + load.bl_len = mmc->read_bl_len;
  366 + load.read = h_spl_load_read;
481 367 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
482 368 image_get_magic(header) == FDT_MAGIC) {
483   - struct spl_load_info load;
484   -
485   - debug("Found FIT\n");
486   - load.dev = mmc;
487   - load.priv = NULL;
488   - load.filename = NULL;
489   - load.bl_len = mmc->read_bl_len;
490   - load.read = h_spl_load_read;
  369 + /* Fit */
491 370 ret = spl_load_simple_fit(spl_image, &load,
492 371 info.start, header);
493   - } else {
  372 + } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
  373 + /* container */
  374 + ret = spl_load_imx_container(spl_image, &load, info.start);
  375 + } else
494 376 ret = -1;
495   - }
496 377  
497   - /* Fit image loaded successfully, go to verify rollback index */
  378 +#if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS)
  379 + /* Image loaded successfully, go to verify rollback index */
498 380 if (!ret)
499 381 ret = spl_verify_rbidx(mmc, &ab_data.slots[target_slot], spl_image);
500 382  
501 383 /* Copy rpmb keyslot to secure memory. */
502 384 if (!ret)
503 385 fill_secure_keyslot_package(&kp);
  386 +#endif
504 387 }
505 388  
506 389 /* Set current slot to unbootable if load/verify fail. */
... ... @@ -572,7 +455,6 @@
572 455  
573 456 return index;
574 457 }
575   -#endif /* CONFIG_PARSE_CONTAINER */
576 458  
577 459 /* For normal build */
578 460 #elif !defined(CONFIG_SPL_BUILD)
scripts/config_whitelist.txt
... ... @@ -3867,6 +3867,7 @@
3867 3867 CONFIG_SYS_SPL_LEN
3868 3868 CONFIG_SYS_SPL_MALLOC_SIZE
3869 3869 CONFIG_SYS_SPL_MALLOC_START
  3870 +CONFIG_SYS_SPL_PTE_RAM_BASE
3870 3871 CONFIG_SYS_SPR
3871 3872 CONFIG_SYS_SRAM_BASE
3872 3873 CONFIG_SYS_SRAM_SIZE