blob: ed1f6faed27a93fae7b4c1efa7307b1e9cafb0b3 [file] [log] [blame]
Masahiro Yamada574388c2016-09-03 11:37:40 +09001/*
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
Masahiro Yamadadb72b0c2018-02-02 15:55:13 +090021#define UNIPHIER_ROM_REGION_BASE 0x00000000ULL
22#define UNIPHIER_ROM_REGION_SIZE 0x10000000ULL
Masahiro Yamada574388c2016-09-03 11:37:40 +090023
Masahiro Yamadadb72b0c2018-02-02 15:55:13 +090024#define UNIPHIER_OCM_REGION_BASE 0x30000000ULL
25#define UNIPHIER_OCM_REGION_SIZE 0x00040000ULL
Masahiro Yamada8f642922018-01-30 19:30:39 +090026
Masahiro Yamada574388c2016-09-03 11:37:40 +090027static const io_dev_connector_t *uniphier_fip_dev_con;
28static uintptr_t uniphier_fip_dev_handle;
29
30static const io_dev_connector_t *uniphier_backend_dev_con;
31static uintptr_t uniphier_backend_dev_handle;
32
33static io_block_spec_t uniphier_fip_spec = {
34 /* .offset will be set by the io_setup func */
35 .length = 0x00200000,
36};
37
38static const io_uuid_spec_t uniphier_bl2_spec = {
39 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
40};
41
42static const io_uuid_spec_t uniphier_scp_spec = {
43 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
44};
45
46static const io_uuid_spec_t uniphier_bl31_spec = {
47 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
48};
49
50static const io_uuid_spec_t uniphier_bl32_spec = {
51 .uuid = UUID_SECURE_PAYLOAD_BL32,
52};
53
54static const io_uuid_spec_t uniphier_bl33_spec = {
55 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
56};
57
58#if TRUSTED_BOARD_BOOT
59static const io_uuid_spec_t uniphier_tb_fw_cert_spec = {
60 .uuid = UUID_TRUSTED_BOOT_FW_CERT,
61};
62
63static const io_uuid_spec_t uniphier_trusted_key_cert_spec = {
64 .uuid = UUID_TRUSTED_KEY_CERT,
65};
66
67static const io_uuid_spec_t uniphier_scp_fw_key_cert_spec = {
68 .uuid = UUID_SCP_FW_KEY_CERT,
69};
70
71static const io_uuid_spec_t uniphier_soc_fw_key_cert_spec = {
72 .uuid = UUID_SOC_FW_KEY_CERT,
73};
74
75static const io_uuid_spec_t uniphier_tos_fw_key_cert_spec = {
76 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
77};
78
79static const io_uuid_spec_t uniphier_nt_fw_key_cert_spec = {
80 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
81};
82
83static const io_uuid_spec_t uniphier_scp_fw_cert_spec = {
84 .uuid = UUID_SCP_FW_CONTENT_CERT,
85};
86
87static const io_uuid_spec_t uniphier_soc_fw_cert_spec = {
88 .uuid = UUID_SOC_FW_CONTENT_CERT,
89};
90
91static const io_uuid_spec_t uniphier_tos_fw_cert_spec = {
92 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
93};
94
95static 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
100struct uniphier_io_policy {
101 uintptr_t *dev_handle;
102 uintptr_t image_spec;
103 uintptr_t init_params;
104};
105
106static 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
190static 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
204static 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
224static 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
235static 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
247static 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
259static int uniphier_io_nor_setup(unsigned int soc_id)
260{
261 return uniphier_io_memmap_setup(0x70000);
262}
263
264static 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
Masahiro Yamada8f642922018-01-30 19:30:39 +0900277 /*
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
Masahiro Yamada574388c2016-09-03 11:37:40 +0900289 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
296static 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
303int 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
325int 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}
338
339int uniphier_check_image(unsigned int image_id)
340{
341 uintptr_t dev_handle, image_spec, image_handle;
342 int ret;
343
344 ret = plat_get_image_source(image_id, &dev_handle, &image_spec);
345 if (ret)
346 return ret;
347
348 ret = io_open(dev_handle, image_spec, &image_handle);
349 if (ret)
350 return ret;
351
352 io_close(image_handle);
353
354 return 0;
355}