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