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