1 /*
2  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 #include <firmware_image_package.h>
10 #include <io/io_block.h>
11 #include <io/io_driver.h>
12 #include <io/io_fip.h>
13 #include <io/io_memmap.h>
14 #include <platform_def.h>
15 #include <types.h>
16 #include <utils_def.h>
17 #include <xlat_tables_v2.h>
18 
19 #include "uniphier.h"
20 
21 #define UNIPHIER_ROM_REGION_BASE	0x00000000
22 #define UNIPHIER_ROM_REGION_SIZE	0x10000000
23 
24 static const io_dev_connector_t *uniphier_fip_dev_con;
25 static uintptr_t uniphier_fip_dev_handle;
26 
27 static const io_dev_connector_t *uniphier_backend_dev_con;
28 static uintptr_t uniphier_backend_dev_handle;
29 
30 static io_block_spec_t uniphier_fip_spec = {
31 	/* .offset will be set by the io_setup func */
32 	.length = 0x00200000,
33 };
34 
35 static const io_uuid_spec_t uniphier_bl2_spec = {
36 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
37 };
38 
39 static const io_uuid_spec_t uniphier_scp_spec = {
40 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
41 };
42 
43 static const io_uuid_spec_t uniphier_bl31_spec = {
44 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
45 };
46 
47 static const io_uuid_spec_t uniphier_bl32_spec = {
48 	.uuid = UUID_SECURE_PAYLOAD_BL32,
49 };
50 
51 static const io_uuid_spec_t uniphier_bl33_spec = {
52 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
53 };
54 
55 #if TRUSTED_BOARD_BOOT
56 static const io_uuid_spec_t uniphier_tb_fw_cert_spec = {
57 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
58 };
59 
60 static const io_uuid_spec_t uniphier_trusted_key_cert_spec = {
61 	.uuid = UUID_TRUSTED_KEY_CERT,
62 };
63 
64 static const io_uuid_spec_t uniphier_scp_fw_key_cert_spec = {
65 	.uuid = UUID_SCP_FW_KEY_CERT,
66 };
67 
68 static const io_uuid_spec_t uniphier_soc_fw_key_cert_spec = {
69 	.uuid = UUID_SOC_FW_KEY_CERT,
70 };
71 
72 static const io_uuid_spec_t uniphier_tos_fw_key_cert_spec = {
73 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
74 };
75 
76 static const io_uuid_spec_t uniphier_nt_fw_key_cert_spec = {
77 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
78 };
79 
80 static const io_uuid_spec_t uniphier_scp_fw_cert_spec = {
81 	.uuid = UUID_SCP_FW_CONTENT_CERT,
82 };
83 
84 static const io_uuid_spec_t uniphier_soc_fw_cert_spec = {
85 	.uuid = UUID_SOC_FW_CONTENT_CERT,
86 };
87 
88 static const io_uuid_spec_t uniphier_tos_fw_cert_spec = {
89 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
90 };
91 
92 static const io_uuid_spec_t uniphier_nt_fw_cert_spec = {
93 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
94 };
95 #endif /* TRUSTED_BOARD_BOOT */
96 
97 struct uniphier_io_policy {
98 	uintptr_t *dev_handle;
99 	uintptr_t image_spec;
100 	uintptr_t init_params;
101 };
102 
103 static const struct uniphier_io_policy uniphier_io_policies[] = {
104 	[FIP_IMAGE_ID] = {
105 		.dev_handle = &uniphier_backend_dev_handle,
106 		.image_spec = (uintptr_t)&uniphier_fip_spec,
107 	},
108 	[BL2_IMAGE_ID] = {
109 		.dev_handle = &uniphier_fip_dev_handle,
110 		.image_spec = (uintptr_t)&uniphier_bl2_spec,
111 		.init_params = FIP_IMAGE_ID,
112 	},
113 	[SCP_BL2_IMAGE_ID] = {
114 		.dev_handle = &uniphier_fip_dev_handle,
115 		.image_spec = (uintptr_t)&uniphier_scp_spec,
116 		.init_params = FIP_IMAGE_ID,
117 	},
118 	[BL31_IMAGE_ID] = {
119 		.dev_handle = &uniphier_fip_dev_handle,
120 		.image_spec = (uintptr_t)&uniphier_bl31_spec,
121 		.init_params = FIP_IMAGE_ID,
122 	},
123 	[BL32_IMAGE_ID] = {
124 		.dev_handle = &uniphier_fip_dev_handle,
125 		.image_spec = (uintptr_t)&uniphier_bl32_spec,
126 		.init_params = FIP_IMAGE_ID,
127 	},
128 	[BL33_IMAGE_ID] = {
129 		.dev_handle = &uniphier_fip_dev_handle,
130 		.image_spec = (uintptr_t)&uniphier_bl33_spec,
131 		.init_params = FIP_IMAGE_ID,
132 	},
133 #if TRUSTED_BOARD_BOOT
134 	[TRUSTED_BOOT_FW_CERT_ID] = {
135 		.dev_handle = &uniphier_fip_dev_handle,
136 		.image_spec = (uintptr_t)&uniphier_tb_fw_cert_spec,
137 		.init_params = FIP_IMAGE_ID,
138 	},
139 	[TRUSTED_KEY_CERT_ID] = {
140 		.dev_handle = &uniphier_fip_dev_handle,
141 		.image_spec = (uintptr_t)&uniphier_trusted_key_cert_spec,
142 		.init_params = FIP_IMAGE_ID,
143 	},
144 	[SCP_FW_KEY_CERT_ID] = {
145 		.dev_handle = &uniphier_fip_dev_handle,
146 		.image_spec = (uintptr_t)&uniphier_scp_fw_key_cert_spec,
147 		.init_params = FIP_IMAGE_ID,
148 	},
149 	[SOC_FW_KEY_CERT_ID] = {
150 		.dev_handle = &uniphier_fip_dev_handle,
151 		.image_spec = (uintptr_t)&uniphier_soc_fw_key_cert_spec,
152 		.init_params = FIP_IMAGE_ID,
153 	},
154 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
155 		.dev_handle = &uniphier_fip_dev_handle,
156 		.image_spec = (uintptr_t)&uniphier_tos_fw_key_cert_spec,
157 		.init_params = FIP_IMAGE_ID,
158 	},
159 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
160 		.dev_handle = &uniphier_fip_dev_handle,
161 		.image_spec = (uintptr_t)&uniphier_nt_fw_key_cert_spec,
162 		.init_params = FIP_IMAGE_ID,
163 	},
164 	[SCP_FW_CONTENT_CERT_ID] = {
165 		.dev_handle = &uniphier_fip_dev_handle,
166 		.image_spec = (uintptr_t)&uniphier_scp_fw_cert_spec,
167 		.init_params = FIP_IMAGE_ID,
168 	},
169 	[SOC_FW_CONTENT_CERT_ID] = {
170 		.dev_handle = &uniphier_fip_dev_handle,
171 		.image_spec = (uintptr_t)&uniphier_soc_fw_cert_spec,
172 		.init_params = FIP_IMAGE_ID,
173 	},
174 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
175 		.dev_handle = &uniphier_fip_dev_handle,
176 		.image_spec = (uintptr_t)&uniphier_tos_fw_cert_spec,
177 		.init_params = FIP_IMAGE_ID,
178 	},
179 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
180 		.dev_handle = &uniphier_fip_dev_handle,
181 		.image_spec = (uintptr_t)&uniphier_nt_fw_cert_spec,
182 		.init_params = FIP_IMAGE_ID,
183 	},
184 #endif
185 };
186 
uniphier_io_block_setup(size_t fip_offset,uintptr_t block_dev_spec)187 static int uniphier_io_block_setup(size_t fip_offset, uintptr_t block_dev_spec)
188 {
189 	int ret;
190 
191 	uniphier_fip_spec.offset = fip_offset;
192 
193 	ret = register_io_dev_block(&uniphier_backend_dev_con);
194 	if (ret)
195 		return ret;
196 
197 	return io_dev_open(uniphier_backend_dev_con, block_dev_spec,
198 			   &uniphier_backend_dev_handle);
199 }
200 
uniphier_io_memmap_setup(size_t fip_offset)201 static int uniphier_io_memmap_setup(size_t fip_offset)
202 {
203 	int ret;
204 
205 	uniphier_fip_spec.offset = fip_offset;
206 
207 	ret = mmap_add_dynamic_region(fip_offset, fip_offset,
208 				      uniphier_fip_spec.length,
209 				      MT_RO_DATA | MT_SECURE);
210 	if (ret)
211 		return ret;
212 
213 	ret = register_io_dev_memmap(&uniphier_backend_dev_con);
214 	if (ret)
215 		return ret;
216 
217 	return io_dev_open(uniphier_backend_dev_con, 0,
218 			   &uniphier_backend_dev_handle);
219 }
220 
uniphier_io_fip_setup(void)221 static int uniphier_io_fip_setup(void)
222 {
223 	int ret;
224 
225 	ret = register_io_dev_fip(&uniphier_fip_dev_con);
226 	if (ret)
227 		return ret;
228 
229 	return io_dev_open(uniphier_fip_dev_con, 0, &uniphier_fip_dev_handle);
230 }
231 
uniphier_io_emmc_setup(unsigned int soc_id)232 static int uniphier_io_emmc_setup(unsigned int soc_id)
233 {
234 	uintptr_t block_dev_spec;
235 	int ret;
236 
237 	ret = uniphier_emmc_init(&block_dev_spec);
238 	if (ret)
239 		return ret;
240 
241 	return uniphier_io_block_setup(0x20000, block_dev_spec);
242 }
243 
uniphier_io_nand_setup(unsigned int soc_id)244 static int uniphier_io_nand_setup(unsigned int soc_id)
245 {
246 	uintptr_t block_dev_spec;
247 	int ret;
248 
249 	ret = uniphier_nand_init(&block_dev_spec);
250 	if (ret)
251 		return ret;
252 
253 	return uniphier_io_block_setup(0x20000, block_dev_spec);
254 }
255 
uniphier_io_nor_setup(unsigned int soc_id)256 static int uniphier_io_nor_setup(unsigned int soc_id)
257 {
258 	return uniphier_io_memmap_setup(0x70000);
259 }
260 
uniphier_io_usb_setup(unsigned int soc_id)261 static int uniphier_io_usb_setup(unsigned int soc_id)
262 {
263 	uintptr_t block_dev_spec;
264 	int ret;
265 
266 	/* use ROM API for loading images from USB storage */
267 	ret = mmap_add_dynamic_region(UNIPHIER_ROM_REGION_BASE,
268 				      UNIPHIER_ROM_REGION_BASE,
269 				      UNIPHIER_ROM_REGION_SIZE,
270 				      MT_CODE | MT_SECURE);
271 	if (ret)
272 		return ret;
273 
274 	ret = uniphier_usb_init(soc_id, &block_dev_spec);
275 	if (ret)
276 		return ret;
277 
278 	return uniphier_io_block_setup(0x20000, block_dev_spec);
279 }
280 
281 static int (* const uniphier_io_setup_table[])(unsigned int) = {
282 	[UNIPHIER_BOOT_DEVICE_EMMC] = uniphier_io_emmc_setup,
283 	[UNIPHIER_BOOT_DEVICE_NAND] = uniphier_io_nand_setup,
284 	[UNIPHIER_BOOT_DEVICE_NOR] = uniphier_io_nor_setup,
285 	[UNIPHIER_BOOT_DEVICE_USB] = uniphier_io_usb_setup,
286 };
287 
uniphier_io_setup(unsigned int soc_id)288 int uniphier_io_setup(unsigned int soc_id)
289 {
290 	int (*io_setup)(unsigned int soc_id);
291 	unsigned int boot_dev;
292 	int ret;
293 
294 	boot_dev = uniphier_get_boot_device(soc_id);
295 	if (boot_dev == UNIPHIER_BOOT_DEVICE_RSV)
296 		return -EINVAL;
297 
298 	io_setup = uniphier_io_setup_table[boot_dev];
299 	ret = io_setup(soc_id);
300 	if (ret)
301 		return ret;
302 
303 	ret = uniphier_io_fip_setup();
304 	if (ret)
305 		return ret;
306 
307 	return 0;
308 }
309 
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)310 int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
311 			  uintptr_t *image_spec)
312 {
313 	uintptr_t init_params;
314 
315 	assert(image_id < ARRAY_SIZE(uniphier_io_policies));
316 
317 	*dev_handle = *(uniphier_io_policies[image_id].dev_handle);
318 	*image_spec = uniphier_io_policies[image_id].image_spec;
319 	init_params = uniphier_io_policies[image_id].init_params;
320 
321 	return io_dev_init(*dev_handle, init_params);
322 }
323 
uniphier_check_image(unsigned int image_id)324 int uniphier_check_image(unsigned int image_id)
325 {
326 	uintptr_t dev_handle, image_spec, image_handle;
327 	int ret;
328 
329 	ret = plat_get_image_source(image_id, &dev_handle, &image_spec);
330 	if (ret)
331 		return ret;
332 
333 	ret = io_open(dev_handle, image_spec, &image_handle);
334 	if (ret)
335 		return ret;
336 
337 	io_close(image_handle);
338 
339 	return 0;
340 }
341