xref: /rk3399_ARM-atf/plat/st/common/bl2_io_storage.c (revision 1631f9c75c6e9667a320c8daf6a05bb49b80826e)
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_fip.h>
18 #include <drivers/io/io_memmap.h>
19 #include <drivers/io/io_mtd.h>
20 #include <drivers/io/io_storage.h>
21 #include <drivers/mmc.h>
22 #include <drivers/partition/efi.h>
23 #include <drivers/partition/partition.h>
24 #include <drivers/raw_nand.h>
25 #include <drivers/spi_nand.h>
26 #include <drivers/spi_nor.h>
27 #include <drivers/st/io_mmc.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 
51 #if STM32MP_SDMMC || STM32MP_EMMC
52 static struct mmc_device_info mmc_info;
53 
54 static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
55 
56 static io_block_dev_spec_t mmc_block_dev_spec = {
57 	/* It's used as temp buffer in block driver */
58 	.buffer = {
59 		.offset = (size_t)&block_buffer,
60 		.length = MMC_BLOCK_SIZE,
61 	},
62 	.ops = {
63 		.read = mmc_read_blocks,
64 		.write = NULL,
65 	},
66 	.block_size = MMC_BLOCK_SIZE,
67 };
68 
69 static const io_dev_connector_t *mmc_dev_con;
70 #endif /* STM32MP_SDMMC || STM32MP_EMMC */
71 
72 #if STM32MP_SPI_NOR
73 static io_mtd_dev_spec_t spi_nor_dev_spec = {
74 	.ops = {
75 		.init = spi_nor_init,
76 		.read = spi_nor_read,
77 	},
78 };
79 #endif
80 
81 #if STM32MP_RAW_NAND
82 static io_mtd_dev_spec_t nand_dev_spec = {
83 	.ops = {
84 		.init = nand_raw_init,
85 		.read = nand_read,
86 		.seek = nand_seek_bb
87 	},
88 };
89 
90 static const io_dev_connector_t *nand_dev_con;
91 #endif
92 
93 #if STM32MP_SPI_NAND
94 static io_mtd_dev_spec_t spi_nand_dev_spec = {
95 	.ops = {
96 		.init = spi_nand_init,
97 		.read = nand_read,
98 		.seek = nand_seek_bb
99 	},
100 };
101 #endif
102 
103 #if STM32MP_SPI_NAND || STM32MP_SPI_NOR
104 static const io_dev_connector_t *spi_dev_con;
105 #endif
106 
107 #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
108 static const io_dev_connector_t *memmap_dev_con;
109 #endif
110 
111 io_block_spec_t image_block_spec = {
112 	.offset = 0U,
113 	.length = 0U,
114 };
115 
116 int open_fip(const uintptr_t spec)
117 {
118 	return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
119 }
120 
121 int open_storage(const uintptr_t spec)
122 {
123 	return io_dev_init(storage_dev_handle, 0);
124 }
125 
126 #if STM32MP_EMMC_BOOT
127 static uint32_t get_boot_part_fip_header(void)
128 {
129 	io_block_spec_t emmc_boot_fip_block_spec = {
130 		.offset = STM32MP_EMMC_BOOT_FIP_OFFSET,
131 		.length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */
132 	};
133 	uint32_t magic = 0U;
134 	int io_result;
135 	size_t bytes_read;
136 	uintptr_t fip_hdr_handle;
137 
138 	io_result = io_open(storage_dev_handle, (uintptr_t)&emmc_boot_fip_block_spec,
139 			    &fip_hdr_handle);
140 	assert(io_result == 0);
141 
142 	io_result = io_read(fip_hdr_handle, (uintptr_t)&magic, sizeof(magic),
143 			    &bytes_read);
144 	if ((io_result != 0) || (bytes_read != sizeof(magic))) {
145 		panic();
146 	}
147 
148 	io_close(fip_hdr_handle);
149 
150 	VERBOSE("%s: eMMC boot magic at offset 256K: %08x\n",
151 		__func__, magic);
152 
153 	return magic;
154 }
155 #endif
156 
157 static void print_boot_device(boot_api_context_t *boot_context)
158 {
159 	switch (boot_context->boot_interface_selected) {
160 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
161 		INFO("Using SDMMC\n");
162 		break;
163 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
164 		INFO("Using EMMC\n");
165 		break;
166 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
167 		INFO("Using QSPI NOR\n");
168 		break;
169 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
170 		INFO("Using FMC NAND\n");
171 		break;
172 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
173 		INFO("Using SPI NAND\n");
174 		break;
175 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART:
176 		INFO("Using UART\n");
177 		break;
178 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB:
179 		INFO("Using USB\n");
180 		break;
181 	default:
182 		ERROR("Boot interface %u not found\n",
183 		      boot_context->boot_interface_selected);
184 		panic();
185 		break;
186 	}
187 
188 	if (boot_context->boot_interface_instance != 0U) {
189 		INFO("  Instance %d\n", boot_context->boot_interface_instance);
190 	}
191 }
192 
193 #if STM32MP_SDMMC || STM32MP_EMMC
194 static void boot_mmc(enum mmc_device_type mmc_dev_type,
195 		     uint16_t boot_interface_instance)
196 {
197 	int io_result __unused;
198 	struct stm32_sdmmc2_params params;
199 
200 	zeromem(&params, sizeof(struct stm32_sdmmc2_params));
201 
202 	mmc_info.mmc_dev_type = mmc_dev_type;
203 
204 	switch (boot_interface_instance) {
205 	case 1:
206 		params.reg_base = STM32MP_SDMMC1_BASE;
207 		break;
208 	case 2:
209 		params.reg_base = STM32MP_SDMMC2_BASE;
210 		break;
211 	case 3:
212 		params.reg_base = STM32MP_SDMMC3_BASE;
213 		break;
214 	default:
215 		WARN("SDMMC instance not found, using default\n");
216 		if (mmc_dev_type == MMC_IS_SD) {
217 			params.reg_base = STM32MP_SDMMC1_BASE;
218 		} else {
219 			params.reg_base = STM32MP_SDMMC2_BASE;
220 		}
221 		break;
222 	}
223 
224 	params.device_info = &mmc_info;
225 	if (stm32_sdmmc2_mmc_init(&params) != 0) {
226 		ERROR("SDMMC%u init failed\n", boot_interface_instance);
227 		panic();
228 	}
229 
230 	/* Open MMC as a block device to read FIP */
231 	io_result = register_io_dev_block(&mmc_dev_con);
232 	if (io_result != 0) {
233 		panic();
234 	}
235 
236 	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec,
237 				&storage_dev_handle);
238 	assert(io_result == 0);
239 
240 #if STM32MP_EMMC_BOOT
241 	if (mmc_dev_type == MMC_IS_EMMC) {
242 		io_result = mmc_part_switch_current_boot();
243 		assert(io_result == 0);
244 
245 		if (get_boot_part_fip_header() != TOC_HEADER_NAME) {
246 			WARN("%s: Can't find FIP header on eMMC boot partition. Trying GPT\n",
247 			     __func__);
248 			io_result = mmc_part_switch_user();
249 			assert(io_result == 0);
250 			return;
251 		}
252 
253 		VERBOSE("%s: FIP header found on eMMC boot partition\n",
254 			__func__);
255 		image_block_spec.offset = STM32MP_EMMC_BOOT_FIP_OFFSET;
256 	}
257 #endif
258 }
259 #endif /* STM32MP_SDMMC || STM32MP_EMMC */
260 
261 #if STM32MP_SPI_NOR
262 static void boot_spi_nor(boot_api_context_t *boot_context)
263 {
264 	int io_result __unused;
265 
266 	io_result = stm32_qspi_init();
267 	assert(io_result == 0);
268 
269 	io_result = register_io_dev_mtd(&spi_dev_con);
270 	assert(io_result == 0);
271 
272 	/* Open connections to device */
273 	io_result = io_dev_open(spi_dev_con,
274 				(uintptr_t)&spi_nor_dev_spec,
275 				&storage_dev_handle);
276 	assert(io_result == 0);
277 }
278 #endif /* STM32MP_SPI_NOR */
279 
280 #if STM32MP_RAW_NAND
281 static void boot_fmc2_nand(boot_api_context_t *boot_context)
282 {
283 	int io_result __unused;
284 
285 	io_result = stm32_fmc2_init();
286 	assert(io_result == 0);
287 
288 	/* Register the IO device on this platform */
289 	io_result = register_io_dev_mtd(&nand_dev_con);
290 	assert(io_result == 0);
291 
292 	/* Open connections to device */
293 	io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
294 				&storage_dev_handle);
295 	assert(io_result == 0);
296 }
297 #endif /* STM32MP_RAW_NAND */
298 
299 #if STM32MP_SPI_NAND
300 static void boot_spi_nand(boot_api_context_t *boot_context)
301 {
302 	int io_result __unused;
303 
304 	io_result = stm32_qspi_init();
305 	assert(io_result == 0);
306 
307 	io_result = register_io_dev_mtd(&spi_dev_con);
308 	assert(io_result == 0);
309 
310 	/* Open connections to device */
311 	io_result = io_dev_open(spi_dev_con,
312 				(uintptr_t)&spi_nand_dev_spec,
313 				&storage_dev_handle);
314 	assert(io_result == 0);
315 }
316 #endif /* STM32MP_SPI_NAND */
317 
318 #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
319 static void mmap_io_setup(void)
320 {
321 	int io_result __unused;
322 
323 	io_result = register_io_dev_memmap(&memmap_dev_con);
324 	assert(io_result == 0);
325 
326 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
327 				&storage_dev_handle);
328 	assert(io_result == 0);
329 }
330 
331 #if STM32MP_UART_PROGRAMMER
332 static void stm32cubeprogrammer_uart(void)
333 {
334 	int ret __unused;
335 	boot_api_context_t *boot_context =
336 		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
337 	uintptr_t uart_base;
338 
339 	uart_base = get_uart_address(boot_context->boot_interface_instance);
340 	ret = stm32cubeprog_uart_load(uart_base, DWL_BUFFER_BASE, DWL_BUFFER_SIZE);
341 	assert(ret == 0);
342 }
343 #endif
344 
345 #if STM32MP_USB_PROGRAMMER
346 static void stm32cubeprogrammer_usb(void)
347 {
348 	int ret __unused;
349 	struct usb_handle *pdev;
350 
351 	/* Init USB on platform */
352 	pdev = usb_dfu_plat_init();
353 
354 	ret = stm32cubeprog_usb_load(pdev, DWL_BUFFER_BASE, DWL_BUFFER_SIZE);
355 	assert(ret == 0);
356 }
357 #endif
358 #endif /* STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER */
359 
360 
361 void stm32mp_io_setup(void)
362 {
363 	int io_result __unused;
364 	boot_api_context_t *boot_context =
365 		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
366 
367 	print_boot_device(boot_context);
368 
369 	if ((boot_context->boot_partition_used_toboot == 1U) ||
370 	    (boot_context->boot_partition_used_toboot == 2U)) {
371 		INFO("Boot used partition fsbl%u\n",
372 		     boot_context->boot_partition_used_toboot);
373 	}
374 
375 	io_result = register_io_dev_fip(&fip_dev_con);
376 	assert(io_result == 0);
377 
378 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
379 				&fip_dev_handle);
380 
381 	switch (boot_context->boot_interface_selected) {
382 #if STM32MP_SDMMC
383 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
384 		dmbsy();
385 		boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
386 		break;
387 #endif
388 #if STM32MP_EMMC
389 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
390 		dmbsy();
391 		boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
392 		break;
393 #endif
394 #if STM32MP_SPI_NOR
395 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
396 		dmbsy();
397 		boot_spi_nor(boot_context);
398 		break;
399 #endif
400 #if STM32MP_RAW_NAND
401 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
402 		dmbsy();
403 		boot_fmc2_nand(boot_context);
404 		break;
405 #endif
406 #if STM32MP_SPI_NAND
407 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
408 		dmbsy();
409 		boot_spi_nand(boot_context);
410 		break;
411 #endif
412 #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER
413 #if STM32MP_UART_PROGRAMMER
414 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART:
415 #endif
416 #if STM32MP_USB_PROGRAMMER
417 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB:
418 #endif
419 		dmbsy();
420 		mmap_io_setup();
421 		break;
422 #endif
423 
424 	default:
425 		ERROR("Boot interface %d not supported\n",
426 		      boot_context->boot_interface_selected);
427 		panic();
428 		break;
429 	}
430 }
431 
432 int bl2_plat_handle_pre_image_load(unsigned int image_id)
433 {
434 	static bool gpt_init_done __unused;
435 	uint16_t boot_itf = stm32mp_get_boot_itf_selected();
436 
437 	switch (boot_itf) {
438 #if STM32MP_SDMMC || STM32MP_EMMC
439 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
440 #if STM32MP_EMMC_BOOT
441 		if (image_block_spec.offset == STM32MP_EMMC_BOOT_FIP_OFFSET) {
442 			break;
443 		}
444 #endif
445 		/* fallthrough */
446 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
447 		if (!gpt_init_done) {
448 /*
449  * With FWU Multi Bank feature enabled, the selection of
450  * the image to boot will be done by fwu_init calling the
451  * platform hook, plat_fwu_set_images_source.
452  */
453 #if !PSA_FWU_SUPPORT
454 			const partition_entry_t *entry;
455 			const struct efi_guid img_type_guid = STM32MP_FIP_GUID;
456 			uuid_t img_type_uuid;
457 
458 			guidcpy(&img_type_uuid, &img_type_guid);
459 			partition_init(GPT_IMAGE_ID);
460 			entry = get_partition_entry_by_type(&img_type_uuid);
461 			if (entry == NULL) {
462 				entry = get_partition_entry(FIP_IMAGE_NAME);
463 				if (entry == NULL) {
464 					ERROR("Could NOT find the %s partition!\n",
465 					      FIP_IMAGE_NAME);
466 
467 					return -ENOENT;
468 				}
469 			}
470 
471 			image_block_spec.offset = entry->start;
472 			image_block_spec.length = entry->length;
473 #endif
474 			gpt_init_done = true;
475 		} else {
476 			bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
477 			assert(bl_mem_params != NULL);
478 
479 			mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base;
480 			mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size;
481 		}
482 
483 		break;
484 #endif
485 
486 #if STM32MP_RAW_NAND || STM32MP_SPI_NAND
487 #if STM32MP_RAW_NAND
488 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
489 #endif
490 #if STM32MP_SPI_NAND
491 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
492 #endif
493 		image_block_spec.offset = STM32MP_NAND_FIP_OFFSET;
494 		break;
495 #endif
496 
497 #if STM32MP_SPI_NOR
498 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
499 		image_block_spec.offset = STM32MP_NOR_FIP_OFFSET;
500 		break;
501 #endif
502 
503 #if STM32MP_UART_PROGRAMMER
504 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART:
505 		if (image_id == FW_CONFIG_ID) {
506 			stm32cubeprogrammer_uart();
507 			/* FIP loaded at DWL address */
508 			image_block_spec.offset = DWL_BUFFER_BASE;
509 			image_block_spec.length = DWL_BUFFER_SIZE;
510 		}
511 		break;
512 #endif
513 #if STM32MP_USB_PROGRAMMER
514 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB:
515 		if (image_id == FW_CONFIG_ID) {
516 			stm32cubeprogrammer_usb();
517 			/* FIP loaded at DWL address */
518 			image_block_spec.offset = DWL_BUFFER_BASE;
519 			image_block_spec.length = DWL_BUFFER_SIZE;
520 		}
521 		break;
522 #endif
523 
524 	default:
525 		ERROR("FIP Not found\n");
526 		panic();
527 	}
528 
529 	return 0;
530 }
531 
532 /*
533  * Return an IO device handle and specification which can be used to access
534  * an image. Use this to enforce platform load policy.
535  */
536 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
537 			  uintptr_t *image_spec)
538 {
539 	int rc;
540 	const struct plat_io_policy *policy;
541 
542 	policy = FCONF_GET_PROPERTY(stm32mp, io_policies, image_id);
543 	rc = policy->check(policy->image_spec);
544 	if (rc == 0) {
545 		*image_spec = policy->image_spec;
546 		*dev_handle = *(policy->dev_handle);
547 	}
548 
549 	return rc;
550 }
551 
552 #if (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT
553 /*
554  * In each boot in non-trial mode, we set the BKP register to
555  * FWU_MAX_TRIAL_REBOOT, and return the active_index from metadata.
556  *
557  * As long as the update agent didn't update the "accepted" field in metadata
558  * (i.e. we are in trial mode), we select the new active_index.
559  * To avoid infinite boot loop at trial boot we decrement a BKP register.
560  * If this counter is 0:
561  *     - an unexpected TAMPER event raised (that resets the BKP registers to 0)
562  *     - a power-off occurs before the update agent was able to update the
563  *       "accepted' field
564  *     - we already boot FWU_MAX_TRIAL_REBOOT times in trial mode.
565  * we select the previous_active_index.
566  */
567 #define INVALID_BOOT_IDX		0xFFFFFFFF
568 
569 uint32_t plat_fwu_get_boot_idx(void)
570 {
571 	/*
572 	 * Select boot index and update boot counter only once per boot
573 	 * even if this function is called several times.
574 	 */
575 	static uint32_t boot_idx = INVALID_BOOT_IDX;
576 	const struct fwu_metadata *data;
577 
578 	data = fwu_get_metadata();
579 
580 	if (boot_idx == INVALID_BOOT_IDX) {
581 		boot_idx = data->active_index;
582 		if (fwu_is_trial_run_state()) {
583 			if (stm32_get_and_dec_fwu_trial_boot_cnt() == 0U) {
584 				WARN("Trial FWU fails %u times\n",
585 				     FWU_MAX_TRIAL_REBOOT);
586 				boot_idx = data->previous_active_index;
587 			}
588 		} else {
589 			stm32_set_max_fwu_trial_boot_cnt();
590 		}
591 	}
592 
593 	return boot_idx;
594 }
595 
596 static void *stm32_get_image_spec(const uuid_t *img_type_uuid)
597 {
598 	unsigned int i;
599 
600 	for (i = 0U; i < MAX_NUMBER_IDS; i++) {
601 		if ((guidcmp(&policies[i].img_type_guid, img_type_uuid)) == 0) {
602 			return (void *)policies[i].image_spec;
603 		}
604 	}
605 
606 	return NULL;
607 }
608 
609 void plat_fwu_set_images_source(const struct fwu_metadata *metadata)
610 {
611 	unsigned int i;
612 	uint32_t boot_idx;
613 	const partition_entry_t *entry;
614 	const uuid_t *img_type_uuid, *img_uuid;
615 	io_block_spec_t *image_spec;
616 
617 	boot_idx = plat_fwu_get_boot_idx();
618 	assert(boot_idx < NR_OF_FW_BANKS);
619 
620 	for (i = 0U; i < NR_OF_IMAGES_IN_FW_BANK; i++) {
621 		img_type_uuid = &metadata->img_entry[i].img_type_uuid;
622 		image_spec = stm32_get_image_spec(img_type_uuid);
623 		if (image_spec == NULL) {
624 			ERROR("Unable to get image spec for the image in the metadata\n");
625 			panic();
626 		}
627 
628 		img_uuid =
629 			&metadata->img_entry[i].img_props[boot_idx].img_uuid;
630 
631 		entry = get_partition_entry_by_uuid(img_uuid);
632 		if (entry == NULL) {
633 			ERROR("Unable to find the partition with the uuid mentioned in metadata\n");
634 			panic();
635 		}
636 
637 		image_spec->offset = entry->start;
638 		image_spec->length = entry->length;
639 	}
640 }
641 
642 static int plat_set_image_source(unsigned int image_id,
643 				 uintptr_t *handle,
644 				 uintptr_t *image_spec,
645 				 const char *part_name)
646 {
647 	struct plat_io_policy *policy;
648 	io_block_spec_t *spec;
649 	const partition_entry_t *entry = get_partition_entry(part_name);
650 
651 	if (entry == NULL) {
652 		ERROR("Unable to find the %s partition\n", part_name);
653 		return -ENOENT;
654 	}
655 
656 	policy = &policies[image_id];
657 
658 	spec = (io_block_spec_t *)policy->image_spec;
659 	spec->offset = entry->start;
660 	spec->length = entry->length;
661 
662 	*image_spec = policy->image_spec;
663 	*handle = *policy->dev_handle;
664 
665 	return 0;
666 }
667 
668 int plat_fwu_set_metadata_image_source(unsigned int image_id,
669 				       uintptr_t *handle,
670 				       uintptr_t *image_spec)
671 {
672 	char *part_name;
673 
674 	assert((image_id == FWU_METADATA_IMAGE_ID) ||
675 	       (image_id == BKUP_FWU_METADATA_IMAGE_ID));
676 
677 	partition_init(GPT_IMAGE_ID);
678 
679 	if (image_id == FWU_METADATA_IMAGE_ID) {
680 		part_name = METADATA_PART_1;
681 	} else {
682 		part_name = METADATA_PART_2;
683 	}
684 
685 	return plat_set_image_source(image_id, handle, image_spec,
686 				     part_name);
687 }
688 #endif /* (STM32MP_SDMMC || STM32MP_EMMC) && PSA_FWU_SUPPORT */
689