1 /* 2 * Copyright (c) 2015-2022, 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/io_mmc.h> 29 #include <drivers/st/stm32_fmc2_nand.h> 30 #include <drivers/st/stm32_qspi.h> 31 #include <drivers/st/stm32_sdmmc2.h> 32 #include <drivers/usb_device.h> 33 #include <lib/fconf/fconf.h> 34 #include <lib/mmio.h> 35 #include <lib/utils.h> 36 #include <plat/common/platform.h> 37 #include <tools_share/firmware_image_package.h> 38 39 #include <platform_def.h> 40 #include <stm32cubeprogrammer.h> 41 #include <stm32mp_efi.h> 42 #include <stm32mp_fconf_getter.h> 43 #include <stm32mp_io_storage.h> 44 #include <usb_dfu.h> 45 46 /* IO devices */ 47 uintptr_t fip_dev_handle; 48 uintptr_t storage_dev_handle; 49 50 static const io_dev_connector_t *fip_dev_con; 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 uint32_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_QSPI: 196 INFO("Using QSPI 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_QSPI: 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 __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 __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 315 static void boot_fmc2_nand(boot_api_context_t *boot_context) 316 { 317 int io_result __unused; 318 319 io_result = stm32_fmc2_init(); 320 assert(io_result == 0); 321 322 /* Register the IO device on this platform */ 323 io_result = register_io_dev_mtd(&nand_dev_con); 324 assert(io_result == 0); 325 326 /* Open connections to device */ 327 io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec, 328 &storage_dev_handle); 329 assert(io_result == 0); 330 } 331 #endif /* STM32MP_RAW_NAND */ 332 333 #if STM32MP_SPI_NAND 334 static void boot_spi_nand(boot_api_context_t *boot_context) 335 { 336 int io_result __unused; 337 338 io_result = stm32_qspi_init(); 339 assert(io_result == 0); 340 341 io_result = register_io_dev_mtd(&spi_dev_con); 342 assert(io_result == 0); 343 344 /* Open connections to device */ 345 io_result = io_dev_open(spi_dev_con, 346 (uintptr_t)&spi_nand_dev_spec, 347 &storage_dev_handle); 348 assert(io_result == 0); 349 } 350 #endif /* STM32MP_SPI_NAND */ 351 352 #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER 353 static void mmap_io_setup(void) 354 { 355 int io_result __unused; 356 357 io_result = register_io_dev_memmap(&memmap_dev_con); 358 assert(io_result == 0); 359 360 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 361 &storage_dev_handle); 362 assert(io_result == 0); 363 } 364 365 #if STM32MP_UART_PROGRAMMER 366 static void stm32cubeprogrammer_uart(void) 367 { 368 int ret __unused; 369 boot_api_context_t *boot_context = 370 (boot_api_context_t *)stm32mp_get_boot_ctx_address(); 371 uintptr_t uart_base; 372 373 uart_base = get_uart_address(boot_context->boot_interface_instance); 374 ret = stm32cubeprog_uart_load(uart_base, DWL_BUFFER_BASE, DWL_BUFFER_SIZE); 375 assert(ret == 0); 376 } 377 #endif 378 379 #if STM32MP_USB_PROGRAMMER 380 static void stm32cubeprogrammer_usb(void) 381 { 382 int ret __unused; 383 struct usb_handle *pdev; 384 385 /* Init USB on platform */ 386 pdev = usb_dfu_plat_init(); 387 388 ret = stm32cubeprog_usb_load(pdev, DWL_BUFFER_BASE, DWL_BUFFER_SIZE); 389 assert(ret == 0); 390 } 391 #endif 392 #endif /* STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER */ 393 394 395 void stm32mp_io_setup(void) 396 { 397 int io_result __unused; 398 boot_api_context_t *boot_context = 399 (boot_api_context_t *)stm32mp_get_boot_ctx_address(); 400 401 print_boot_device(boot_context); 402 403 if ((boot_context->boot_partition_used_toboot == 1U) || 404 (boot_context->boot_partition_used_toboot == 2U)) { 405 INFO("Boot used partition fsbl%u\n", 406 boot_context->boot_partition_used_toboot); 407 } 408 409 io_result = register_io_dev_fip(&fip_dev_con); 410 assert(io_result == 0); 411 412 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 413 &fip_dev_handle); 414 415 #ifndef DECRYPTION_SUPPORT_none 416 io_result = register_io_dev_enc(&enc_dev_con); 417 assert(io_result == 0); 418 419 io_result = io_dev_open(enc_dev_con, (uintptr_t)NULL, 420 &enc_dev_handle); 421 assert(io_result == 0); 422 #endif 423 424 switch (boot_context->boot_interface_selected) { 425 #if STM32MP_SDMMC 426 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 427 dmbsy(); 428 boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); 429 break; 430 #endif 431 #if STM32MP_EMMC 432 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 433 dmbsy(); 434 boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); 435 break; 436 #endif 437 #if STM32MP_SPI_NOR 438 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: 439 dmbsy(); 440 boot_spi_nor(boot_context); 441 break; 442 #endif 443 #if STM32MP_RAW_NAND 444 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 445 dmbsy(); 446 boot_fmc2_nand(boot_context); 447 break; 448 #endif 449 #if STM32MP_SPI_NAND 450 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: 451 dmbsy(); 452 boot_spi_nand(boot_context); 453 break; 454 #endif 455 #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER 456 #if STM32MP_UART_PROGRAMMER 457 case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: 458 #endif 459 #if STM32MP_USB_PROGRAMMER 460 case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 461 #endif 462 dmbsy(); 463 mmap_io_setup(); 464 break; 465 #endif 466 467 default: 468 ERROR("Boot interface %d not supported\n", 469 boot_context->boot_interface_selected); 470 panic(); 471 break; 472 } 473 } 474 475 int bl2_plat_handle_pre_image_load(unsigned int image_id) 476 { 477 static bool gpt_init_done __unused; 478 uint16_t boot_itf = stm32mp_get_boot_itf_selected(); 479 480 switch (boot_itf) { 481 #if STM32MP_SDMMC || STM32MP_EMMC 482 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 483 #if STM32MP_EMMC_BOOT 484 if (image_block_spec.offset == STM32MP_EMMC_BOOT_FIP_OFFSET) { 485 break; 486 } 487 #endif 488 /* fallthrough */ 489 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 490 if (!gpt_init_done) { 491 /* 492 * With FWU Multi Bank feature enabled, the selection of 493 * the image to boot will be done by fwu_init calling the 494 * platform hook, plat_fwu_set_images_source. 495 */ 496 #if !PSA_FWU_SUPPORT 497 const partition_entry_t *entry; 498 const struct efi_guid img_type_guid = STM32MP_FIP_GUID; 499 uuid_t img_type_uuid; 500 501 guidcpy(&img_type_uuid, &img_type_guid); 502 partition_init(GPT_IMAGE_ID); 503 entry = get_partition_entry_by_type(&img_type_uuid); 504 if (entry == NULL) { 505 entry = get_partition_entry(FIP_IMAGE_NAME); 506 if (entry == NULL) { 507 ERROR("Could NOT find the %s partition!\n", 508 FIP_IMAGE_NAME); 509 510 return -ENOENT; 511 } 512 } 513 514 image_block_spec.offset = entry->start; 515 image_block_spec.length = entry->length; 516 #endif 517 gpt_init_done = true; 518 } else { 519 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 520 assert(bl_mem_params != NULL); 521 522 mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base; 523 mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size; 524 } 525 526 break; 527 #endif 528 529 #if STM32MP_RAW_NAND || STM32MP_SPI_NAND 530 #if STM32MP_RAW_NAND 531 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 532 #endif 533 #if STM32MP_SPI_NAND 534 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: 535 #endif 536 image_block_spec.offset = STM32MP_NAND_FIP_OFFSET; 537 break; 538 #endif 539 540 #if STM32MP_SPI_NOR 541 case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: 542 image_block_spec.offset = STM32MP_NOR_FIP_OFFSET; 543 break; 544 #endif 545 546 #if STM32MP_UART_PROGRAMMER 547 case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: 548 if (image_id == FW_CONFIG_ID) { 549 stm32cubeprogrammer_uart(); 550 /* FIP loaded at DWL address */ 551 image_block_spec.offset = DWL_BUFFER_BASE; 552 image_block_spec.length = DWL_BUFFER_SIZE; 553 } 554 break; 555 #endif 556 #if STM32MP_USB_PROGRAMMER 557 case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 558 if (image_id == FW_CONFIG_ID) { 559 stm32cubeprogrammer_usb(); 560 /* FIP loaded at DWL address */ 561 image_block_spec.offset = DWL_BUFFER_BASE; 562 image_block_spec.length = DWL_BUFFER_SIZE; 563 } 564 break; 565 #endif 566 567 default: 568 ERROR("FIP Not found\n"); 569 panic(); 570 } 571 572 return 0; 573 } 574 575 /* 576 * Return an IO device handle and specification which can be used to access 577 * an image. Use this to enforce platform load policy. 578 */ 579 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 580 uintptr_t *image_spec) 581 { 582 int rc; 583 const struct plat_io_policy *policy; 584 585 policy = FCONF_GET_PROPERTY(stm32mp, io_policies, image_id); 586 rc = policy->check(policy->image_spec); 587 if (rc == 0) { 588 *image_spec = policy->image_spec; 589 *dev_handle = *(policy->dev_handle); 590 } 591 592 return rc; 593 } 594 595 #if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT 596 /* 597 * In each boot in non-trial mode, we set the BKP register to 598 * FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata. 599 * 600 * As long as the update agent didn't update the "accepted" field in metadata 601 * (i.e. we are in trial mode), we select the new active_index. 602 * To avoid infinite boot loop at trial boot we decrement a BKP register. 603 * If this counter is 0: 604 * - an unexpected TAMPER event raised (that resets the BKP registers to 0) 605 * - a power-off occurs before the update agent was able to update the 606 * "accepted' field 607 * - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode. 608 * we select the previous_active_index. 609 */ 610 #define INVALID_BOOT_IDX 0xFFFFFFFFU 611 612 uint32_t plat_fwu_get_boot_idx(void) 613 { 614 /* 615 * Select boot index and update boot counter only once per boot 616 * even if this function is called several times. 617 */ 618 static uint32_t boot_idx = INVALID_BOOT_IDX; 619 const struct fwu_metadata *data; 620 621 data = fwu_get_metadata(); 622 623 if (boot_idx == INVALID_BOOT_IDX) { 624 boot_idx = data->active_index; 625 if (fwu_is_trial_run_state()) { 626 if (stm32_get_and_dec_fwu_trial_boot_cnt() == 0U) { 627 WARN("Trial FWU fails %u times\n", 628 FWU_MAX_TRIAL_REBOOT); 629 boot_idx = data->previous_active_index; 630 } 631 } else { 632 stm32_set_max_fwu_trial_boot_cnt(); 633 } 634 } 635 636 return boot_idx; 637 } 638 639 static void *stm32_get_image_spec(const uuid_t *img_type_uuid) 640 { 641 unsigned int i; 642 643 for (i = 0U; i < MAX_NUMBER_IDS; i++) { 644 if ((guidcmp(&policies[i].img_type_guid, img_type_uuid)) == 0) { 645 return (void *)policies[i].image_spec; 646 } 647 } 648 649 return NULL; 650 } 651 652 void plat_fwu_set_images_source(const struct fwu_metadata *metadata) 653 { 654 unsigned int i; 655 uint32_t boot_idx; 656 const partition_entry_t *entry; 657 const uuid_t *img_type_uuid, *img_uuid; 658 io_block_spec_t *image_spec; 659 660 boot_idx = plat_fwu_get_boot_idx(); 661 assert(boot_idx < NR_OF_FW_BANKS); 662 663 for (i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) { 664 img_type_uuid = &metadata->img_entry[i].img_type_uuid; 665 image_spec = stm32_get_image_spec(img_type_uuid); 666 if (image_spec == NULL) { 667 ERROR("Unable to get image spec for the image in the metadata\n"); 668 panic(); 669 } 670 671 img_uuid = 672 &metadata->img_entry[i].img_props[boot_idx].img_uuid; 673 674 entry = get_partition_entry_by_uuid(img_uuid); 675 if (entry == NULL) { 676 ERROR("Unable to find the partition with the uuid mentioned in metadata\n"); 677 panic(); 678 } 679 680 image_spec->offset = entry->start; 681 image_spec->length = entry->length; 682 } 683 } 684 685 static int plat_set_image_source(unsigned int image_id, 686 uintptr_t *handle, 687 uintptr_t *image_spec, 688 const char *part_name) 689 { 690 struct plat_io_policy *policy; 691 io_block_spec_t *spec; 692 const partition_entry_t *entry = get_partition_entry(part_name); 693 694 if (entry == NULL) { 695 ERROR("Unable to find the %s partition\n", part_name); 696 return -ENOENT; 697 } 698 699 policy = &policies[image_id]; 700 701 spec = (io_block_spec_t *)policy->image_spec; 702 spec->offset = entry->start; 703 spec->length = entry->length; 704 705 *image_spec = policy->image_spec; 706 *handle = *policy->dev_handle; 707 708 return 0; 709 } 710 711 int plat_fwu_set_metadata_image_source(unsigned int image_id, 712 uintptr_t *handle, 713 uintptr_t *image_spec) 714 { 715 char *part_name; 716 717 assert((image_id == FWU_METADATA_IMAGE_ID) || 718 (image_id == BKUP_FWU_METADATA_IMAGE_ID)); 719 720 partition_init(GPT_IMAGE_ID); 721 722 if (image_id == FWU_METADATA_IMAGE_ID) { 723 part_name = METADATA_PART_1; 724 } else { 725 part_name = METADATA_PART_2; 726 } 727 728 return plat_set_image_source(image_id, handle, image_spec, 729 part_name); 730 } 731 #endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */ 732