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