1 /* 2 * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <string.h> 9 10 #include <arch_helpers.h> 11 #include <common/debug.h> 12 #include <common/desc_image_load.h> 13 #include <drivers/fwu/fwu.h> 14 #include <drivers/fwu/fwu_metadata.h> 15 #include <drivers/io/io_block.h> 16 #include <drivers/io/io_driver.h> 17 #include <drivers/io/io_encrypted.h> 18 #include <drivers/io/io_fip.h> 19 #include <drivers/io/io_memmap.h> 20 #include <drivers/io/io_mtd.h> 21 #include <drivers/io/io_storage.h> 22 #include <drivers/mmc.h> 23 #include <drivers/partition/efi.h> 24 #include <drivers/partition/partition.h> 25 #include <drivers/raw_nand.h> 26 #include <drivers/spi_nand.h> 27 #include <drivers/spi_nor.h> 28 #include <drivers/st/stm32_fmc2_nand.h> 29 #include <drivers/st/stm32_qspi.h> 30 #include <drivers/st/stm32_sdmmc2.h> 31 #include <drivers/usb_device.h> 32 #include <lib/fconf/fconf.h> 33 #include <lib/mmio.h> 34 #include <lib/utils.h> 35 #include <plat/common/platform.h> 36 #include <tools_share/firmware_image_package.h> 37 38 #include <platform_def.h> 39 #include <stm32cubeprogrammer.h> 40 #include <stm32mp_efi.h> 41 #include <stm32mp_fconf_getter.h> 42 #include <stm32mp_io_storage.h> 43 #include <usb_dfu.h> 44 45 /* IO devices */ 46 uintptr_t fip_dev_handle; 47 uintptr_t storage_dev_handle; 48 49 static const io_dev_connector_t *fip_dev_con; 50 static uint32_t nand_block_sz __maybe_unused; 51 52 #ifndef DECRYPTION_SUPPORT_none 53 static const io_dev_connector_t *enc_dev_con; 54 uintptr_t enc_dev_handle; 55 #endif 56 57 #if STM32MP_SDMMC || STM32MP_EMMC 58 static struct mmc_device_info mmc_info; 59 60 static uint8_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); 61 62 static io_block_dev_spec_t mmc_block_dev_spec = { 63 /* It's used as temp buffer in block driver */ 64 .buffer = { 65 .offset = (size_t)&block_buffer, 66 .length = MMC_BLOCK_SIZE, 67 }, 68 .ops = { 69 .read = mmc_read_blocks, 70 .write = NULL, 71 }, 72 .block_size = MMC_BLOCK_SIZE, 73 }; 74 75 static const io_dev_connector_t *mmc_dev_con; 76 #endif /* STM32MP_SDMMC || STM32MP_EMMC */ 77 78 #if STM32MP_SPI_NOR 79 static io_mtd_dev_spec_t spi_nor_dev_spec = { 80 .ops = { 81 .init = spi_nor_init, 82 .read = spi_nor_read, 83 }, 84 }; 85 #endif 86 87 #if STM32MP_RAW_NAND 88 static io_mtd_dev_spec_t nand_dev_spec = { 89 .ops = { 90 .init = nand_raw_init, 91 .read = nand_read, 92 .seek = nand_seek_bb 93 }, 94 }; 95 96 static const io_dev_connector_t *nand_dev_con; 97 #endif 98 99 #if STM32MP_SPI_NAND 100 static io_mtd_dev_spec_t spi_nand_dev_spec = { 101 .ops = { 102 .init = spi_nand_init, 103 .read = nand_read, 104 .seek = nand_seek_bb 105 }, 106 }; 107 #endif 108 109 #if STM32MP_SPI_NAND || STM32MP_SPI_NOR 110 static const io_dev_connector_t *spi_dev_con; 111 #endif 112 113 #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER 114 static const io_dev_connector_t *memmap_dev_con; 115 #endif 116 117 io_block_spec_t image_block_spec = { 118 .offset = 0U, 119 .length = 0U, 120 }; 121 122 int open_fip(const uintptr_t spec) 123 { 124 return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 125 } 126 127 #ifndef DECRYPTION_SUPPORT_none 128 int open_enc_fip(const uintptr_t spec) 129 { 130 int result; 131 uintptr_t local_image_handle; 132 133 result = io_dev_init(enc_dev_handle, (uintptr_t)ENC_IMAGE_ID); 134 if (result != 0) { 135 return result; 136 } 137 138 result = io_open(enc_dev_handle, spec, &local_image_handle); 139 if (result != 0) { 140 return result; 141 } 142 143 VERBOSE("Using encrypted FIP\n"); 144 io_close(local_image_handle); 145 146 return 0; 147 } 148 #endif 149 150 int open_storage(const uintptr_t spec) 151 { 152 return io_dev_init(storage_dev_handle, 0); 153 } 154 155 #if STM32MP_EMMC_BOOT 156 static uint32_t get_boot_part_fip_header(void) 157 { 158 io_block_spec_t emmc_boot_fip_block_spec = { 159 .offset = STM32MP_EMMC_BOOT_FIP_OFFSET, 160 .length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */ 161 }; 162 uint32_t magic = 0U; 163 int io_result; 164 size_t bytes_read; 165 uintptr_t fip_hdr_handle; 166 167 io_result = io_open(storage_dev_handle, (uintptr_t)&emmc_boot_fip_block_spec, 168 &fip_hdr_handle); 169 assert(io_result == 0); 170 171 io_result = io_read(fip_hdr_handle, (uintptr_t)&magic, sizeof(magic), 172 &bytes_read); 173 if ((io_result != 0) || (bytes_read != sizeof(magic))) { 174 panic(); 175 } 176 177 io_close(fip_hdr_handle); 178 179 VERBOSE("%s: eMMC boot magic at offset 256K: %08x\n", 180 __func__, magic); 181 182 return magic; 183 } 184 #endif 185 186 static void print_boot_device(boot_api_context_t *boot_context) 187 { 188 switch (boot_context->boot_interface_selected) { 189 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 190 INFO("Using SDMMC\n"); 191 break; 192 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 193 INFO("Using EMMC\n"); 194 break; 195 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: 196 INFO("Using SPI NOR\n"); 197 break; 198 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 199 INFO("Using FMC NAND\n"); 200 break; 201 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI: 202 INFO("Using SPI NAND\n"); 203 break; 204 case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: 205 INFO("Using UART\n"); 206 break; 207 case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 208 INFO("Using USB\n"); 209 break; 210 default: 211 ERROR("Boot interface %u not found\n", 212 boot_context->boot_interface_selected); 213 panic(); 214 break; 215 } 216 217 if (boot_context->boot_interface_instance != 0U) { 218 INFO(" Instance %d\n", boot_context->boot_interface_instance); 219 } 220 } 221 222 #if STM32MP_SDMMC || STM32MP_EMMC 223 static void boot_mmc(enum mmc_device_type mmc_dev_type, 224 uint16_t boot_interface_instance) 225 { 226 int io_result __maybe_unused; 227 struct stm32_sdmmc2_params params; 228 229 zeromem(¶ms, sizeof(struct stm32_sdmmc2_params)); 230 231 mmc_info.mmc_dev_type = mmc_dev_type; 232 233 switch (boot_interface_instance) { 234 case 1: 235 params.reg_base = STM32MP_SDMMC1_BASE; 236 break; 237 case 2: 238 params.reg_base = STM32MP_SDMMC2_BASE; 239 break; 240 case 3: 241 params.reg_base = STM32MP_SDMMC3_BASE; 242 break; 243 default: 244 WARN("SDMMC instance not found, using default\n"); 245 if (mmc_dev_type == MMC_IS_SD) { 246 params.reg_base = STM32MP_SDMMC1_BASE; 247 } else { 248 params.reg_base = STM32MP_SDMMC2_BASE; 249 } 250 break; 251 } 252 253 if (mmc_dev_type != MMC_IS_EMMC) { 254 params.flags = MMC_FLAG_SD_CMD6; 255 } 256 257 params.device_info = &mmc_info; 258 if (stm32_sdmmc2_mmc_init(¶ms) != 0) { 259 ERROR("SDMMC%u init failed\n", boot_interface_instance); 260 panic(); 261 } 262 263 /* Open MMC as a block device to read FIP */ 264 io_result = register_io_dev_block(&mmc_dev_con); 265 if (io_result != 0) { 266 panic(); 267 } 268 269 io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec, 270 &storage_dev_handle); 271 assert(io_result == 0); 272 273 #if STM32MP_EMMC_BOOT 274 if (mmc_dev_type == MMC_IS_EMMC) { 275 io_result = mmc_part_switch_current_boot(); 276 assert(io_result == 0); 277 278 if (get_boot_part_fip_header() != TOC_HEADER_NAME) { 279 WARN("%s: Can't find FIP header on eMMC boot partition. Trying GPT\n", 280 __func__); 281 io_result = mmc_part_switch_user(); 282 assert(io_result == 0); 283 return; 284 } 285 286 VERBOSE("%s: FIP header found on eMMC boot partition\n", 287 __func__); 288 image_block_spec.offset = STM32MP_EMMC_BOOT_FIP_OFFSET; 289 image_block_spec.length = mmc_boot_part_size() - STM32MP_EMMC_BOOT_FIP_OFFSET; 290 } 291 #endif 292 } 293 #endif /* STM32MP_SDMMC || STM32MP_EMMC */ 294 295 #if STM32MP_SPI_NOR 296 static void boot_spi_nor(boot_api_context_t *boot_context) 297 { 298 int io_result __maybe_unused; 299 300 io_result = stm32_qspi_init(); 301 assert(io_result == 0); 302 303 io_result = register_io_dev_mtd(&spi_dev_con); 304 assert(io_result == 0); 305 306 /* Open connections to device */ 307 io_result = io_dev_open(spi_dev_con, 308 (uintptr_t)&spi_nor_dev_spec, 309 &storage_dev_handle); 310 assert(io_result == 0); 311 } 312 #endif /* STM32MP_SPI_NOR */ 313 314 #if STM32MP_RAW_NAND || STM32MP_SPI_NAND 315 /* 316 * This function returns 0 if it can find an alternate 317 * image to be loaded or a negative errno otherwise. 318 */ 319 static int try_nand_backup_partitions(unsigned int image_id) 320 { 321 static unsigned int backup_id; 322 static unsigned int backup_block_nb; 323 324 /* Check if NAND storage used */ 325 if (nand_block_sz == 0U) { 326 return -ENODEV; 327 } 328 329 if (backup_id != image_id) { 330 backup_block_nb = PLATFORM_MTD_MAX_PART_SIZE / nand_block_sz; 331 backup_id = image_id; 332 } 333 334 if (backup_block_nb-- == 0U) { 335 return -ENOSPC; 336 } 337 338 image_block_spec.offset += nand_block_sz; 339 340 return 0; 341 } 342 343 static const struct plat_try_images_ops try_img_ops = { 344 .next_instance = try_nand_backup_partitions, 345 }; 346 #endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */ 347 348 #if STM32MP_RAW_NAND 349 static void boot_fmc2_nand(boot_api_context_t *boot_context) 350 { 351 int io_result __maybe_unused; 352 353 plat_setup_try_img_ops(&try_img_ops); 354 355 io_result = stm32_fmc2_init(); 356 assert(io_result == 0); 357 358 /* Register the IO device on this platform */ 359 io_result = register_io_dev_mtd(&nand_dev_con); 360 assert(io_result == 0); 361 362 /* Open connections to device */ 363 io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec, 364 &storage_dev_handle); 365 assert(io_result == 0); 366 367 nand_block_sz = nand_dev_spec.erase_size; 368 } 369 #endif /* STM32MP_RAW_NAND */ 370 371 #if STM32MP_SPI_NAND 372 static void boot_spi_nand(boot_api_context_t *boot_context) 373 { 374 int io_result __maybe_unused; 375 376 plat_setup_try_img_ops(&try_img_ops); 377 378 io_result = stm32_qspi_init(); 379 assert(io_result == 0); 380 381 io_result = register_io_dev_mtd(&spi_dev_con); 382 assert(io_result == 0); 383 384 /* Open connections to device */ 385 io_result = io_dev_open(spi_dev_con, 386 (uintptr_t)&spi_nand_dev_spec, 387 &storage_dev_handle); 388 assert(io_result == 0); 389 390 nand_block_sz = spi_nand_dev_spec.erase_size; 391 } 392 #endif /* STM32MP_SPI_NAND */ 393 394 #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER 395 static void mmap_io_setup(void) 396 { 397 int io_result __maybe_unused; 398 399 io_result = register_io_dev_memmap(&memmap_dev_con); 400 assert(io_result == 0); 401 402 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 403 &storage_dev_handle); 404 assert(io_result == 0); 405 } 406 407 #if STM32MP_UART_PROGRAMMER 408 static void stm32cubeprogrammer_uart(void) 409 { 410 int ret __maybe_unused; 411 boot_api_context_t *boot_context = 412 (boot_api_context_t *)stm32mp_get_boot_ctx_address(); 413 uintptr_t uart_base; 414 415 uart_base = get_uart_address(boot_context->boot_interface_instance); 416 ret = stm32cubeprog_uart_load(uart_base, DWL_BUFFER_BASE, DWL_BUFFER_SIZE); 417 assert(ret == 0); 418 } 419 #endif 420 421 #if STM32MP_USB_PROGRAMMER 422 static void stm32cubeprogrammer_usb(void) 423 { 424 int ret __maybe_unused; 425 struct usb_handle *pdev; 426 427 /* Init USB on platform */ 428 pdev = usb_dfu_plat_init(); 429 430 ret = stm32cubeprog_usb_load(pdev, DWL_BUFFER_BASE, DWL_BUFFER_SIZE); 431 assert(ret == 0); 432 } 433 #endif 434 #endif /* STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER */ 435 436 void stm32mp_io_setup(void) 437 { 438 int io_result __maybe_unused; 439 boot_api_context_t *boot_context = 440 (boot_api_context_t *)stm32mp_get_boot_ctx_address(); 441 442 print_boot_device(boot_context); 443 444 if ((boot_context->boot_partition_used_toboot == 1U) || 445 (boot_context->boot_partition_used_toboot == 2U)) { 446 INFO("Boot used partition fsbl%u\n", 447 boot_context->boot_partition_used_toboot); 448 } 449 450 io_result = register_io_dev_fip(&fip_dev_con); 451 assert(io_result == 0); 452 453 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 454 &fip_dev_handle); 455 456 #ifndef DECRYPTION_SUPPORT_none 457 io_result = register_io_dev_enc(&enc_dev_con); 458 assert(io_result == 0); 459 460 io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL, 461 &enc_dev_handle); 462 assert(io_result == 0); 463 #endif 464 465 switch (boot_context->boot_interface_selected) { 466 #if STM32MP_SDMMC 467 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 468 dmbsy(); 469 boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); 470 break; 471 #endif 472 #if STM32MP_EMMC 473 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 474 dmbsy(); 475 boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); 476 break; 477 #endif 478 #if STM32MP_SPI_NOR 479 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: 480 dmbsy(); 481 boot_spi_nor(boot_context); 482 break; 483 #endif 484 #if STM32MP_RAW_NAND 485 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 486 dmbsy(); 487 boot_fmc2_nand(boot_context); 488 break; 489 #endif 490 #if STM32MP_SPI_NAND 491 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI: 492 dmbsy(); 493 boot_spi_nand(boot_context); 494 break; 495 #endif 496 #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER 497 #if STM32MP_UART_PROGRAMMER 498 case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: 499 #endif 500 #if STM32MP_USB_PROGRAMMER 501 case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 502 #endif 503 dmbsy(); 504 mmap_io_setup(); 505 break; 506 #endif 507 508 default: 509 ERROR("Boot interface %d not supported\n", 510 boot_context->boot_interface_selected); 511 panic(); 512 break; 513 } 514 } 515 516 int bl2_plat_handle_pre_image_load(unsigned int image_id) 517 { 518 static bool gpt_init_done __maybe_unused; 519 uint16_t boot_itf = stm32mp_get_boot_itf_selected(); 520 521 switch (boot_itf) { 522 #if STM32MP_SDMMC || STM32MP_EMMC 523 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 524 #if STM32MP_EMMC_BOOT 525 if (image_block_spec.offset == STM32MP_EMMC_BOOT_FIP_OFFSET) { 526 break; 527 } 528 #endif 529 /* fallthrough */ 530 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 531 if (!gpt_init_done) { 532 /* 533 * With FWU Multi Bank feature enabled, the selection of 534 * the image to boot will be done by fwu_init calling the 535 * platform hook, plat_fwu_set_images_source. 536 */ 537 #if !PSA_FWU_SUPPORT 538 const partition_entry_t *entry; 539 const struct efi_guid fip_guid = STM32MP_FIP_GUID; 540 541 partition_init(GPT_IMAGE_ID); 542 entry = get_partition_entry_by_type(&fip_guid); 543 if (entry == NULL) { 544 entry = get_partition_entry(FIP_IMAGE_NAME); 545 if (entry == NULL) { 546 ERROR("Could NOT find the %s partition!\n", 547 FIP_IMAGE_NAME); 548 549 return -ENOENT; 550 } 551 } 552 553 image_block_spec.offset = entry->start; 554 image_block_spec.length = entry->length; 555 #endif 556 gpt_init_done = true; 557 } else { 558 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 559 560 assert(bl_mem_params != NULL); 561 562 mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base; 563 mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size; 564 } 565 566 break; 567 #endif 568 569 #if STM32MP_RAW_NAND || STM32MP_SPI_NAND 570 #if STM32MP_RAW_NAND 571 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 572 #endif 573 #if STM32MP_SPI_NAND 574 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_SPI: 575 #endif 576 image_block_spec.offset = STM32MP_NAND_FIP_OFFSET; 577 break; 578 #endif 579 580 #if STM32MP_SPI_NOR 581 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: 582 /* 583 * With FWU Multi Bank feature enabled, the selection of 584 * the image to boot will be done by fwu_init calling the 585 * platform hook, plat_fwu_set_images_source. 586 */ 587 #if !PSA_FWU_SUPPORT 588 image_block_spec.offset = STM32MP_NOR_FIP_OFFSET; 589 #endif 590 break; 591 #endif 592 593 #if STM32MP_UART_PROGRAMMER 594 case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: 595 if (image_id == FW_CONFIG_ID) { 596 stm32cubeprogrammer_uart(); 597 /* FIP loaded at DWL address */ 598 image_block_spec.offset = DWL_BUFFER_BASE; 599 image_block_spec.length = DWL_BUFFER_SIZE; 600 } 601 break; 602 #endif 603 #if STM32MP_USB_PROGRAMMER 604 case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 605 if (image_id == FW_CONFIG_ID) { 606 stm32cubeprogrammer_usb(); 607 /* FIP loaded at DWL address */ 608 image_block_spec.offset = DWL_BUFFER_BASE; 609 image_block_spec.length = DWL_BUFFER_SIZE; 610 } 611 break; 612 #endif 613 614 default: 615 ERROR("FIP Not found\n"); 616 panic(); 617 } 618 619 return 0; 620 } 621 622 /* 623 * Return an IO device handle and specification which can be used to access 624 * an image. Use this to enforce platform load policy. 625 */ 626 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 627 uintptr_t *image_spec) 628 { 629 int rc; 630 const struct plat_io_policy *policy; 631 632 policy = FCONF_GET_PROPERTY(stm32mp, io_policies, image_id); 633 rc = policy->check(policy->image_spec); 634 if (rc == 0) { 635 *image_spec = policy->image_spec; 636 *dev_handle = *(policy->dev_handle); 637 } 638 639 return rc; 640 } 641 642 #if (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT 643 /* 644 * In each boot in non-trial mode, we set the BKP register to 645 * FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata. 646 * 647 * As long as the update agent didn't update the "accepted" field in metadata 648 * (i.e. we are in trial mode), we select the new active_index. 649 * To avoid infinite boot loop at trial boot we decrement a BKP register. 650 * If this counter is 0: 651 * - an unexpected TAMPER event raised (that resets the BKP registers to 0) 652 * - a power-off occurs before the update agent was able to update the 653 * "accepted' field 654 * - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode. 655 * we select the previous_active_index. 656 */ 657 uint32_t plat_fwu_get_boot_idx(void) 658 { 659 /* 660 * Select boot index and update boot counter only once per boot 661 * even if this function is called several times. 662 */ 663 static uint32_t boot_idx = INVALID_BOOT_IDX; 664 665 if (boot_idx == INVALID_BOOT_IDX) { 666 const struct fwu_metadata *data = fwu_get_metadata(); 667 668 boot_idx = data->active_index; 669 670 if (data->bank_state[boot_idx] == FWU_BANK_STATE_VALID) { 671 if (stm32_get_and_dec_fwu_trial_boot_cnt() == 0U) { 672 WARN("Trial FWU fails %u times\n", 673 FWU_MAX_TRIAL_REBOOT); 674 boot_idx = fwu_get_alternate_boot_bank(); 675 } 676 } else if (data->bank_state[boot_idx] == 677 FWU_BANK_STATE_ACCEPTED) { 678 stm32_set_max_fwu_trial_boot_cnt(); 679 } else { 680 ERROR("The active bank(%u) of the platform is in Invalid State.\n", 681 boot_idx); 682 boot_idx = fwu_get_alternate_boot_bank(); 683 stm32_clear_fwu_trial_boot_cnt(); 684 } 685 } 686 687 return boot_idx; 688 } 689 690 static void *stm32_get_image_spec(const struct efi_guid *img_type_guid) 691 { 692 unsigned int i; 693 694 for (i = 0U; i < MAX_NUMBER_IDS; i++) { 695 if ((guidcmp(&policies[i].img_type_guid, img_type_guid)) == 0) { 696 return (void *)policies[i].image_spec; 697 } 698 } 699 700 return NULL; 701 } 702 703 void plat_fwu_set_images_source(const struct fwu_metadata *metadata) 704 { 705 unsigned int i; 706 uint32_t boot_idx; 707 const partition_entry_t *entry __maybe_unused; 708 const struct fwu_image_entry *img_entry; 709 const void *img_type_guid; 710 const void *img_guid; 711 io_block_spec_t *image_spec; 712 const uint16_t boot_itf = stm32mp_get_boot_itf_selected(); 713 714 boot_idx = plat_fwu_get_boot_idx(); 715 assert(boot_idx < NR_OF_FW_BANKS); 716 VERBOSE("Selecting to boot from bank %u\n", boot_idx); 717 718 img_entry = (void *)&metadata->fw_desc.img_entry; 719 for (i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) { 720 img_type_guid = &img_entry[i].img_type_guid; 721 722 img_guid = &img_entry[i].img_bank_info[boot_idx].img_guid; 723 724 image_spec = stm32_get_image_spec(img_type_guid); 725 if (image_spec == NULL) { 726 ERROR("Unable to get image spec for the image in the metadata\n"); 727 panic(); 728 } 729 730 switch (boot_itf) { 731 #if (STM32MP_SDMMC || STM32MP_EMMC) 732 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 733 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 734 entry = get_partition_entry_by_guid(img_guid); 735 if (entry == NULL) { 736 ERROR("No partition with the uuid mentioned in metadata\n"); 737 panic(); 738 } 739 740 image_spec->offset = entry->start; 741 image_spec->length = entry->length; 742 break; 743 #endif 744 #if STM32MP_SPI_NOR 745 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: 746 if (guidcmp(img_guid, &STM32MP_NOR_FIP_A_GUID) == 0) { 747 image_spec->offset = STM32MP_NOR_FIP_A_OFFSET; 748 } else if (guidcmp(img_guid, &STM32MP_NOR_FIP_B_GUID) == 0) { 749 image_spec->offset = STM32MP_NOR_FIP_B_OFFSET; 750 } else { 751 ERROR("Invalid uuid mentioned in metadata\n"); 752 panic(); 753 } 754 break; 755 #endif 756 default: 757 panic(); 758 break; 759 } 760 } 761 } 762 763 static int plat_set_image_source(unsigned int image_id, 764 uintptr_t *handle, 765 uintptr_t *image_spec) 766 { 767 struct plat_io_policy *policy; 768 io_block_spec_t *spec __maybe_unused; 769 const partition_entry_t *entry __maybe_unused; 770 const uint16_t boot_itf = stm32mp_get_boot_itf_selected(); 771 772 policy = &policies[image_id]; 773 spec = (io_block_spec_t *)policy->image_spec; 774 775 switch (boot_itf) { 776 #if (STM32MP_SDMMC || STM32MP_EMMC) 777 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 778 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 779 partition_init(GPT_IMAGE_ID); 780 781 if (image_id == FWU_METADATA_IMAGE_ID) { 782 entry = get_partition_entry(METADATA_PART_1); 783 } else { 784 entry = get_partition_entry(METADATA_PART_2); 785 } 786 787 if (entry == NULL) { 788 ERROR("Unable to find a metadata partition\n"); 789 return -ENOENT; 790 } 791 792 spec->offset = entry->start; 793 spec->length = entry->length; 794 break; 795 #endif 796 797 #if STM32MP_SPI_NOR 798 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_SPI: 799 if (image_id == FWU_METADATA_IMAGE_ID) { 800 spec->offset = STM32MP_NOR_METADATA1_OFFSET; 801 } else { 802 spec->offset = STM32MP_NOR_METADATA2_OFFSET; 803 } 804 805 spec->length = sizeof(struct fwu_metadata); 806 break; 807 #endif 808 default: 809 panic(); 810 break; 811 } 812 813 *image_spec = policy->image_spec; 814 *handle = *policy->dev_handle; 815 816 return 0; 817 } 818 819 int plat_fwu_set_metadata_image_source(unsigned int image_id, 820 uintptr_t *handle, 821 uintptr_t *image_spec) 822 { 823 assert((image_id == FWU_METADATA_IMAGE_ID) || 824 (image_id == BKUP_FWU_METADATA_IMAGE_ID)); 825 826 return plat_set_image_source(image_id, handle, image_spec); 827 } 828 #endif /* (STM32MP_SDMMC || STM32MP_EMMC || STM32MP_SPI_NOR) && PSA_FWU_SUPPORT */ 829