xref: /rk3399_ARM-atf/plat/hisilicon/hikey960/hikey960_io_storage.c (revision 07217574afcdcd618320c6bcef3bb9887f334537)
12f2abcf4SHaojian Zhuang /*
26971642dSLukas Hanel  * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
32f2abcf4SHaojian Zhuang  *
42f2abcf4SHaojian Zhuang  * SPDX-License-Identifier: BSD-3-Clause
52f2abcf4SHaojian Zhuang  */
62f2abcf4SHaojian Zhuang 
72f2abcf4SHaojian Zhuang #include <assert.h>
82f2abcf4SHaojian Zhuang #include <errno.h>
92f2abcf4SHaojian Zhuang #include <string.h>
1009d40e0eSAntonio Nino Diaz 
1109d40e0eSAntonio Nino Diaz #include <platform_def.h>
1209d40e0eSAntonio Nino Diaz 
1309d40e0eSAntonio Nino Diaz #include <arch_helpers.h>
1409d40e0eSAntonio Nino Diaz #include <common/debug.h>
1509d40e0eSAntonio Nino Diaz #include <drivers/ufs.h>
1609d40e0eSAntonio Nino Diaz #include <drivers/io/io_block.h>
1709d40e0eSAntonio Nino Diaz #include <drivers/io/io_driver.h>
1809d40e0eSAntonio Nino Diaz #include <drivers/io/io_fip.h>
1909d40e0eSAntonio Nino Diaz #include <drivers/io/io_memmap.h>
2009d40e0eSAntonio Nino Diaz #include <drivers/io/io_storage.h>
21c61cf58fSHaojian Zhuang #include <drivers/partition/partition.h>
2209d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
2309d40e0eSAntonio Nino Diaz #include <lib/semihosting.h>
2409d40e0eSAntonio Nino Diaz #include <tools_share/firmware_image_package.h>
252f2abcf4SHaojian Zhuang 
26*c371b83fSArthur Cassegrain #include "hikey960_def.h"
27*c371b83fSArthur Cassegrain #include "hikey960_private.h"
28*c371b83fSArthur Cassegrain 
292f2abcf4SHaojian Zhuang struct plat_io_policy {
302f2abcf4SHaojian Zhuang 	uintptr_t *dev_handle;
312f2abcf4SHaojian Zhuang 	uintptr_t image_spec;
322f2abcf4SHaojian Zhuang 	int (*check)(const uintptr_t spec);
332f2abcf4SHaojian Zhuang };
342f2abcf4SHaojian Zhuang 
352f2abcf4SHaojian Zhuang static const io_dev_connector_t *ufs_dev_con, *fip_dev_con;
362f2abcf4SHaojian Zhuang static uintptr_t ufs_dev_handle, fip_dev_handle;
372f2abcf4SHaojian Zhuang 
382f2abcf4SHaojian Zhuang static int check_ufs(const uintptr_t spec);
392f2abcf4SHaojian Zhuang static int check_fip(const uintptr_t spec);
402f2abcf4SHaojian Zhuang size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size);
412f2abcf4SHaojian Zhuang size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size);
422f2abcf4SHaojian Zhuang 
43c61cf58fSHaojian Zhuang static io_block_spec_t ufs_fip_spec;
44c61cf58fSHaojian Zhuang 
45c61cf58fSHaojian Zhuang static const io_block_spec_t ufs_gpt_spec = {
46c61cf58fSHaojian Zhuang 	.offset		= 0,
47c61cf58fSHaojian Zhuang 	.length		= PLAT_PARTITION_BLOCK_SIZE *
48c61cf58fSHaojian Zhuang 			  (PLAT_PARTITION_MAX_ENTRIES / 4 + 2),
492f2abcf4SHaojian Zhuang };
502f2abcf4SHaojian Zhuang 
51*c371b83fSArthur Cassegrain /* Fastboot serial number stored within first UFS device blocks */
52*c371b83fSArthur Cassegrain static const io_block_spec_t ufs_fastboot_spec = {
53*c371b83fSArthur Cassegrain 	.offset         = UFS_BASE,
54*c371b83fSArthur Cassegrain 	.length         = 1 << 20,
55*c371b83fSArthur Cassegrain };
56*c371b83fSArthur Cassegrain 
572f2abcf4SHaojian Zhuang static const io_block_dev_spec_t ufs_dev_spec = {
582f2abcf4SHaojian Zhuang 	/* It's used as temp buffer in block driver. */
592f2abcf4SHaojian Zhuang 	.buffer		= {
602f2abcf4SHaojian Zhuang 		.offset	= HIKEY960_UFS_DATA_BASE,
612f2abcf4SHaojian Zhuang 		.length	= HIKEY960_UFS_DATA_SIZE,
622f2abcf4SHaojian Zhuang 	},
632f2abcf4SHaojian Zhuang 	.ops		= {
642f2abcf4SHaojian Zhuang 		.read	= ufs_read_lun3_blks,
652f2abcf4SHaojian Zhuang 		.write	= ufs_write_lun3_blks,
662f2abcf4SHaojian Zhuang 	},
672f2abcf4SHaojian Zhuang 	.block_size	= UFS_BLOCK_SIZE,
682f2abcf4SHaojian Zhuang };
692f2abcf4SHaojian Zhuang 
702f2abcf4SHaojian Zhuang static const io_uuid_spec_t scp_bl2_uuid_spec = {
712f2abcf4SHaojian Zhuang 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
722f2abcf4SHaojian Zhuang };
732f2abcf4SHaojian Zhuang 
742f2abcf4SHaojian Zhuang static const io_uuid_spec_t bl31_uuid_spec = {
752f2abcf4SHaojian Zhuang 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
762f2abcf4SHaojian Zhuang };
772f2abcf4SHaojian Zhuang 
785e3325e7SVictor Chong static const io_uuid_spec_t bl32_uuid_spec = {
795e3325e7SVictor Chong 	.uuid = UUID_SECURE_PAYLOAD_BL32,
805e3325e7SVictor Chong };
815e3325e7SVictor Chong 
82b16bb16eSVictor Chong static const io_uuid_spec_t bl32_extra1_uuid_spec = {
83b16bb16eSVictor Chong 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
84b16bb16eSVictor Chong };
85b16bb16eSVictor Chong 
86b16bb16eSVictor Chong static const io_uuid_spec_t bl32_extra2_uuid_spec = {
87b16bb16eSVictor Chong 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
88b16bb16eSVictor Chong };
89b16bb16eSVictor Chong 
906971642dSLukas Hanel #ifdef SPD_spmd
916971642dSLukas Hanel static const io_uuid_spec_t bl32_tos_fw_spec = {
926971642dSLukas Hanel 	.uuid = UUID_TOS_FW_CONFIG,
936971642dSLukas Hanel };
946971642dSLukas Hanel #endif
956971642dSLukas Hanel 
962f2abcf4SHaojian Zhuang static const io_uuid_spec_t bl33_uuid_spec = {
972f2abcf4SHaojian Zhuang 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
982f2abcf4SHaojian Zhuang };
992f2abcf4SHaojian Zhuang 
100745d8a82STeddy Reed #if TRUSTED_BOARD_BOOT
101745d8a82STeddy Reed static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
102745d8a82STeddy Reed 	.uuid = UUID_TRUSTED_KEY_CERT,
103745d8a82STeddy Reed };
104745d8a82STeddy Reed 
105745d8a82STeddy Reed static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
106745d8a82STeddy Reed 	.uuid = UUID_SCP_FW_KEY_CERT,
107745d8a82STeddy Reed };
108745d8a82STeddy Reed 
109745d8a82STeddy Reed static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
110745d8a82STeddy Reed 	.uuid = UUID_SOC_FW_KEY_CERT,
111745d8a82STeddy Reed };
112745d8a82STeddy Reed 
113745d8a82STeddy Reed static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
114745d8a82STeddy Reed 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
115745d8a82STeddy Reed };
116745d8a82STeddy Reed 
117745d8a82STeddy Reed static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
118745d8a82STeddy Reed 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
119745d8a82STeddy Reed };
120745d8a82STeddy Reed 
121745d8a82STeddy Reed static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
122745d8a82STeddy Reed 	.uuid = UUID_SCP_FW_CONTENT_CERT,
123745d8a82STeddy Reed };
124745d8a82STeddy Reed 
125745d8a82STeddy Reed static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
126745d8a82STeddy Reed 	.uuid = UUID_SOC_FW_CONTENT_CERT,
127745d8a82STeddy Reed };
128745d8a82STeddy Reed 
129745d8a82STeddy Reed static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
130745d8a82STeddy Reed 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
131745d8a82STeddy Reed };
132745d8a82STeddy Reed 
133745d8a82STeddy Reed static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
134745d8a82STeddy Reed 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
135745d8a82STeddy Reed };
136745d8a82STeddy Reed #endif /* TRUSTED_BOARD_BOOT */
137745d8a82STeddy Reed 
1382f2abcf4SHaojian Zhuang static const struct plat_io_policy policies[] = {
1392f2abcf4SHaojian Zhuang 	[FIP_IMAGE_ID] = {
1402f2abcf4SHaojian Zhuang 		&ufs_dev_handle,
1412f2abcf4SHaojian Zhuang 		(uintptr_t)&ufs_fip_spec,
1422f2abcf4SHaojian Zhuang 		check_ufs
1432f2abcf4SHaojian Zhuang 	},
1442f2abcf4SHaojian Zhuang 	[SCP_BL2_IMAGE_ID] = {
1452f2abcf4SHaojian Zhuang 		&fip_dev_handle,
1462f2abcf4SHaojian Zhuang 		(uintptr_t)&scp_bl2_uuid_spec,
1472f2abcf4SHaojian Zhuang 		check_fip
1482f2abcf4SHaojian Zhuang 	},
1492f2abcf4SHaojian Zhuang 	[BL31_IMAGE_ID] = {
1502f2abcf4SHaojian Zhuang 		&fip_dev_handle,
1512f2abcf4SHaojian Zhuang 		(uintptr_t)&bl31_uuid_spec,
1522f2abcf4SHaojian Zhuang 		check_fip
1532f2abcf4SHaojian Zhuang 	},
1545e3325e7SVictor Chong 	[BL32_IMAGE_ID] = {
1555e3325e7SVictor Chong 		&fip_dev_handle,
1565e3325e7SVictor Chong 		(uintptr_t)&bl32_uuid_spec,
1575e3325e7SVictor Chong 		check_fip
1585e3325e7SVictor Chong 	},
159b16bb16eSVictor Chong 	[BL32_EXTRA1_IMAGE_ID] = {
160b16bb16eSVictor Chong 		&fip_dev_handle,
161b16bb16eSVictor Chong 		(uintptr_t)&bl32_extra1_uuid_spec,
162b16bb16eSVictor Chong 		check_fip
163b16bb16eSVictor Chong 	},
164b16bb16eSVictor Chong 	[BL32_EXTRA2_IMAGE_ID] = {
165b16bb16eSVictor Chong 		&fip_dev_handle,
166b16bb16eSVictor Chong 		(uintptr_t)&bl32_extra2_uuid_spec,
167b16bb16eSVictor Chong 		check_fip
168b16bb16eSVictor Chong 	},
1696971642dSLukas Hanel 
1706971642dSLukas Hanel #ifdef SPD_spmd
1716971642dSLukas Hanel 	[TOS_FW_CONFIG_ID] = {
1726971642dSLukas Hanel 		&fip_dev_handle,
1736971642dSLukas Hanel 		(uintptr_t)&bl32_tos_fw_spec,
1746971642dSLukas Hanel 		check_fip
1756971642dSLukas Hanel 	},
1766971642dSLukas Hanel #endif
1776971642dSLukas Hanel 
1782f2abcf4SHaojian Zhuang 	[BL33_IMAGE_ID] = {
1792f2abcf4SHaojian Zhuang 		&fip_dev_handle,
1802f2abcf4SHaojian Zhuang 		(uintptr_t)&bl33_uuid_spec,
1812f2abcf4SHaojian Zhuang 		check_fip
182745d8a82STeddy Reed 	},
183745d8a82STeddy Reed #if TRUSTED_BOARD_BOOT
184745d8a82STeddy Reed 	[TRUSTED_KEY_CERT_ID] = {
185745d8a82STeddy Reed 		&fip_dev_handle,
186745d8a82STeddy Reed 		(uintptr_t)&trusted_key_cert_uuid_spec,
187745d8a82STeddy Reed 		check_fip
188745d8a82STeddy Reed 	},
189745d8a82STeddy Reed 	[SCP_FW_KEY_CERT_ID] = {
190745d8a82STeddy Reed 		&fip_dev_handle,
191745d8a82STeddy Reed 		(uintptr_t)&scp_fw_key_cert_uuid_spec,
192745d8a82STeddy Reed 		check_fip
193745d8a82STeddy Reed 	},
194745d8a82STeddy Reed 	[SOC_FW_KEY_CERT_ID] = {
195745d8a82STeddy Reed 		&fip_dev_handle,
196745d8a82STeddy Reed 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
197745d8a82STeddy Reed 		check_fip
198745d8a82STeddy Reed 	},
199745d8a82STeddy Reed 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
200745d8a82STeddy Reed 		&fip_dev_handle,
201745d8a82STeddy Reed 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
202745d8a82STeddy Reed 		check_fip
203745d8a82STeddy Reed 	},
204745d8a82STeddy Reed 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
205745d8a82STeddy Reed 		&fip_dev_handle,
206745d8a82STeddy Reed 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
207745d8a82STeddy Reed 		check_fip
208745d8a82STeddy Reed 	},
209745d8a82STeddy Reed 	[SCP_FW_CONTENT_CERT_ID] = {
210745d8a82STeddy Reed 		&fip_dev_handle,
211745d8a82STeddy Reed 		(uintptr_t)&scp_fw_cert_uuid_spec,
212745d8a82STeddy Reed 		check_fip
213745d8a82STeddy Reed 	},
214745d8a82STeddy Reed 	[SOC_FW_CONTENT_CERT_ID] = {
215745d8a82STeddy Reed 		&fip_dev_handle,
216745d8a82STeddy Reed 		(uintptr_t)&soc_fw_cert_uuid_spec,
217745d8a82STeddy Reed 		check_fip
218745d8a82STeddy Reed 	},
219745d8a82STeddy Reed 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
220745d8a82STeddy Reed 		&fip_dev_handle,
221745d8a82STeddy Reed 		(uintptr_t)&tos_fw_cert_uuid_spec,
222745d8a82STeddy Reed 		check_fip
223745d8a82STeddy Reed 	},
224745d8a82STeddy Reed 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
225745d8a82STeddy Reed 		&fip_dev_handle,
226745d8a82STeddy Reed 		(uintptr_t)&nt_fw_cert_uuid_spec,
227745d8a82STeddy Reed 		check_fip
228745d8a82STeddy Reed 	},
229745d8a82STeddy Reed #endif /* TRUSTED_BOARD_BOOT */
230c61cf58fSHaojian Zhuang 	[GPT_IMAGE_ID] = {
231c61cf58fSHaojian Zhuang 		&ufs_dev_handle,
232c61cf58fSHaojian Zhuang 		(uintptr_t)&ufs_gpt_spec,
233c61cf58fSHaojian Zhuang 		check_ufs
234c61cf58fSHaojian Zhuang 	},
2352f2abcf4SHaojian Zhuang };
2362f2abcf4SHaojian Zhuang 
check_ufs(const uintptr_t spec)2372f2abcf4SHaojian Zhuang static int check_ufs(const uintptr_t spec)
2382f2abcf4SHaojian Zhuang {
2392f2abcf4SHaojian Zhuang 	int result;
2402f2abcf4SHaojian Zhuang 	uintptr_t local_handle;
2412f2abcf4SHaojian Zhuang 
2422f2abcf4SHaojian Zhuang 	result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
2432f2abcf4SHaojian Zhuang 	if (result == 0) {
2442f2abcf4SHaojian Zhuang 		result = io_open(ufs_dev_handle, spec, &local_handle);
2452f2abcf4SHaojian Zhuang 		if (result == 0)
2462f2abcf4SHaojian Zhuang 			io_close(local_handle);
2472f2abcf4SHaojian Zhuang 	}
2482f2abcf4SHaojian Zhuang 	return result;
2492f2abcf4SHaojian Zhuang }
2502f2abcf4SHaojian Zhuang 
check_fip(const uintptr_t spec)2512f2abcf4SHaojian Zhuang static int check_fip(const uintptr_t spec)
2522f2abcf4SHaojian Zhuang {
2532f2abcf4SHaojian Zhuang 	int result;
2542f2abcf4SHaojian Zhuang 	uintptr_t local_image_handle;
2552f2abcf4SHaojian Zhuang 
2562f2abcf4SHaojian Zhuang 	/* See if a Firmware Image Package is available */
2572f2abcf4SHaojian Zhuang 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
2582f2abcf4SHaojian Zhuang 	if (result == 0) {
2592f2abcf4SHaojian Zhuang 		result = io_open(fip_dev_handle, spec, &local_image_handle);
2602f2abcf4SHaojian Zhuang 		if (result == 0) {
2612f2abcf4SHaojian Zhuang 			VERBOSE("Using FIP\n");
2622f2abcf4SHaojian Zhuang 			io_close(local_image_handle);
2632f2abcf4SHaojian Zhuang 		}
2642f2abcf4SHaojian Zhuang 	}
2652f2abcf4SHaojian Zhuang 	return result;
2662f2abcf4SHaojian Zhuang }
2672f2abcf4SHaojian Zhuang 
hikey960_load_serialno(uint64_t * serno)268*c371b83fSArthur Cassegrain int hikey960_load_serialno(uint64_t *serno)
269*c371b83fSArthur Cassegrain {
270*c371b83fSArthur Cassegrain 	int result;
271*c371b83fSArthur Cassegrain 	size_t len = 0;
272*c371b83fSArthur Cassegrain 	uintptr_t local_handle;
273*c371b83fSArthur Cassegrain 	uint64_t buf[HIKEY960_SERIAL_NUMBER_SIZE / sizeof(uint64_t)];
274*c371b83fSArthur Cassegrain 
275*c371b83fSArthur Cassegrain 	if (serno == NULL) {
276*c371b83fSArthur Cassegrain 		return -1;
277*c371b83fSArthur Cassegrain 	}
278*c371b83fSArthur Cassegrain 
279*c371b83fSArthur Cassegrain 	result = io_dev_init(ufs_dev_handle, (uintptr_t)NULL);
280*c371b83fSArthur Cassegrain 	if (result != 0) {
281*c371b83fSArthur Cassegrain 		return result;
282*c371b83fSArthur Cassegrain 	}
283*c371b83fSArthur Cassegrain 
284*c371b83fSArthur Cassegrain 	result = io_open(ufs_dev_handle,
285*c371b83fSArthur Cassegrain 		(uintptr_t)&ufs_fastboot_spec, &local_handle);
286*c371b83fSArthur Cassegrain 	if (result != 0) {
287*c371b83fSArthur Cassegrain 		return result;
288*c371b83fSArthur Cassegrain 	}
289*c371b83fSArthur Cassegrain 
290*c371b83fSArthur Cassegrain 	result = io_seek(local_handle, IO_SEEK_SET,
291*c371b83fSArthur Cassegrain 		HIKEY960_SERIAL_NUMBER_LBA * UFS_BLOCK_SIZE);
292*c371b83fSArthur Cassegrain 	if (result != 0) {
293*c371b83fSArthur Cassegrain 		goto closing;
294*c371b83fSArthur Cassegrain 	}
295*c371b83fSArthur Cassegrain 
296*c371b83fSArthur Cassegrain 	result = io_read(local_handle, (uintptr_t)buf,
297*c371b83fSArthur Cassegrain 		HIKEY960_SERIAL_NUMBER_SIZE, &len);
298*c371b83fSArthur Cassegrain 	if (result != 0) {
299*c371b83fSArthur Cassegrain 		goto closing;
300*c371b83fSArthur Cassegrain 	}
301*c371b83fSArthur Cassegrain 
302*c371b83fSArthur Cassegrain 	if (len != HIKEY960_SERIAL_NUMBER_SIZE) {
303*c371b83fSArthur Cassegrain 		result = -1;
304*c371b83fSArthur Cassegrain 		goto closing;
305*c371b83fSArthur Cassegrain 	}
306*c371b83fSArthur Cassegrain 
307*c371b83fSArthur Cassegrain 	/* UEFI fastboot app stores a 16 bytes blob       */
308*c371b83fSArthur Cassegrain 	/* We extract only relevant 8 bytes serial number */
309*c371b83fSArthur Cassegrain 	*serno = buf[1];
310*c371b83fSArthur Cassegrain 
311*c371b83fSArthur Cassegrain closing:
312*c371b83fSArthur Cassegrain 	io_close(local_handle);
313*c371b83fSArthur Cassegrain 	return result;
314*c371b83fSArthur Cassegrain }
315*c371b83fSArthur Cassegrain 
hikey960_io_setup(void)3162f2abcf4SHaojian Zhuang void hikey960_io_setup(void)
3172f2abcf4SHaojian Zhuang {
3182f2abcf4SHaojian Zhuang 	int result;
3192f2abcf4SHaojian Zhuang 
3202f2abcf4SHaojian Zhuang 	result = register_io_dev_block(&ufs_dev_con);
3212f2abcf4SHaojian Zhuang 	assert(result == 0);
3222f2abcf4SHaojian Zhuang 
3232f2abcf4SHaojian Zhuang 	result = register_io_dev_fip(&fip_dev_con);
3242f2abcf4SHaojian Zhuang 	assert(result == 0);
3252f2abcf4SHaojian Zhuang 
3262f2abcf4SHaojian Zhuang 	result = io_dev_open(ufs_dev_con, (uintptr_t)&ufs_dev_spec,
3272f2abcf4SHaojian Zhuang 			     &ufs_dev_handle);
3282f2abcf4SHaojian Zhuang 	assert(result == 0);
3292f2abcf4SHaojian Zhuang 
3302f2abcf4SHaojian Zhuang 	result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
3312f2abcf4SHaojian Zhuang 	assert(result == 0);
3322f2abcf4SHaojian Zhuang 
3332f2abcf4SHaojian Zhuang 	/* Ignore improbable errors in release builds */
3342f2abcf4SHaojian Zhuang 	(void)result;
3352f2abcf4SHaojian Zhuang }
3362f2abcf4SHaojian Zhuang 
hikey960_set_fip_addr(unsigned int image_id,const char * name)337c61cf58fSHaojian Zhuang int hikey960_set_fip_addr(unsigned int image_id, const char *name)
338c61cf58fSHaojian Zhuang {
339c61cf58fSHaojian Zhuang 	const partition_entry_t *entry;
340c61cf58fSHaojian Zhuang 
341c61cf58fSHaojian Zhuang 	if (ufs_fip_spec.length == 0) {
342c61cf58fSHaojian Zhuang 		partition_init(GPT_IMAGE_ID);
343c61cf58fSHaojian Zhuang 		entry = get_partition_entry(name);
344c61cf58fSHaojian Zhuang 		if (entry == NULL) {
345c61cf58fSHaojian Zhuang 			ERROR("Could NOT find the %s partition!\n", name);
346c61cf58fSHaojian Zhuang 			return -ENOENT;
347c61cf58fSHaojian Zhuang 		}
348c61cf58fSHaojian Zhuang 		ufs_fip_spec.offset = entry->start;
349c61cf58fSHaojian Zhuang 		ufs_fip_spec.length = entry->length;
350c61cf58fSHaojian Zhuang 	}
351c61cf58fSHaojian Zhuang 	return 0;
352c61cf58fSHaojian Zhuang }
353c61cf58fSHaojian Zhuang 
3542f2abcf4SHaojian Zhuang /* Return an IO device handle and specification which can be used to access
3552f2abcf4SHaojian Zhuang  * an image. Use this to enforce platform load policy
3562f2abcf4SHaojian Zhuang  */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)3572f2abcf4SHaojian Zhuang int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
3582f2abcf4SHaojian Zhuang 			  uintptr_t *image_spec)
3592f2abcf4SHaojian Zhuang {
3602f2abcf4SHaojian Zhuang 	int result;
3612f2abcf4SHaojian Zhuang 	const struct plat_io_policy *policy;
3622f2abcf4SHaojian Zhuang 
3632f2abcf4SHaojian Zhuang 	assert(image_id < ARRAY_SIZE(policies));
3642f2abcf4SHaojian Zhuang 
3652f2abcf4SHaojian Zhuang 	policy = &policies[image_id];
3662f2abcf4SHaojian Zhuang 	result = policy->check(policy->image_spec);
3672f2abcf4SHaojian Zhuang 	assert(result == 0);
3682f2abcf4SHaojian Zhuang 
3692f2abcf4SHaojian Zhuang 	*image_spec = policy->image_spec;
3702f2abcf4SHaojian Zhuang 	*dev_handle = *(policy->dev_handle);
3712f2abcf4SHaojian Zhuang 
3722f2abcf4SHaojian Zhuang 	return result;
3732f2abcf4SHaojian Zhuang }
3742f2abcf4SHaojian Zhuang 
ufs_read_lun3_blks(int lba,uintptr_t buf,size_t size)3752f2abcf4SHaojian Zhuang size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size)
3762f2abcf4SHaojian Zhuang {
3772f2abcf4SHaojian Zhuang 	return ufs_read_blocks(3, lba, buf, size);
3782f2abcf4SHaojian Zhuang }
3792f2abcf4SHaojian Zhuang 
ufs_write_lun3_blks(int lba,const uintptr_t buf,size_t size)3802f2abcf4SHaojian Zhuang size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size)
3812f2abcf4SHaojian Zhuang {
3822f2abcf4SHaojian Zhuang 	return ufs_write_blocks(3, lba, buf, size);
3832f2abcf4SHaojian Zhuang }
384