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