blob: 66ec29247e3903b5d7a4bc987d714fb70aef1c0c [file] [log] [blame]
Sheetal Tigadoli13680c92019-12-13 10:39:06 +05301/*
2 * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <string.h>
9
10#include <common/debug.h>
11#include <drivers/io/io_driver.h>
12#include <drivers/io/io_fip.h>
13#include <drivers/io/io_memmap.h>
14#include <drivers/io/io_storage.h>
15#include <tools_share/firmware_image_package.h>
16
17#include <cmn_plat_def.h>
18#include <cmn_plat_util.h>
19#include <plat_brcm.h>
20#include <platform_def.h>
21
22/* IO devices */
23static const io_dev_connector_t *fip_dev_con;
24static uintptr_t fip_dev_handle;
25static const io_dev_connector_t *memmap_dev_con;
26static uintptr_t memmap_dev_handle;
27
28static const io_block_spec_t fip_block_spec = {
29 .offset = PLAT_BRCM_FIP_BASE,
30 .length = PLAT_BRCM_FIP_MAX_SIZE
31};
32
33static const io_block_spec_t qspi_fip_block_spec = {
34 .offset = PLAT_BRCM_FIP_QSPI_BASE,
35 .length = PLAT_BRCM_FIP_MAX_SIZE
36};
37
38static const io_block_spec_t nand_fip_block_spec = {
39 .offset = PLAT_BRCM_FIP_NAND_BASE,
40 .length = PLAT_BRCM_FIP_MAX_SIZE
41};
42
43static const io_uuid_spec_t bl2_uuid_spec = {
44 .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
45};
46
47static const io_uuid_spec_t scp_bl2_uuid_spec = {
48 .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
49};
50
51static const io_uuid_spec_t bl31_uuid_spec = {
52 .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
53};
54
55static const io_uuid_spec_t bl32_uuid_spec = {
56 .uuid = UUID_SECURE_PAYLOAD_BL32,
57};
58
59static const io_uuid_spec_t bl32_extra1_uuid_spec = {
60 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
61};
62
63static const io_uuid_spec_t bl32_extra2_uuid_spec = {
64 .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
65};
66
67static const io_uuid_spec_t bl33_uuid_spec = {
68 .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
69};
70
71static const io_uuid_spec_t tb_fw_config_uuid_spec = {
72 .uuid = UUID_TB_FW_CONFIG,
73};
74
75static const io_uuid_spec_t hw_config_uuid_spec = {
76 .uuid = UUID_HW_CONFIG,
77};
78
79static const io_uuid_spec_t soc_fw_config_uuid_spec = {
80 .uuid = UUID_SOC_FW_CONFIG,
81};
82
83static const io_uuid_spec_t tos_fw_config_uuid_spec = {
84 .uuid = UUID_TOS_FW_CONFIG,
85};
86
87static const io_uuid_spec_t nt_fw_config_uuid_spec = {
88 .uuid = UUID_NT_FW_CONFIG,
89};
90
91#if TRUSTED_BOARD_BOOT
92static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
93 .uuid = UUID_TRUSTED_BOOT_FW_CERT,
94};
95
96static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
97 .uuid = UUID_TRUSTED_KEY_CERT,
98};
99
100static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
101 .uuid = UUID_SCP_FW_KEY_CERT,
102};
103
104static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
105 .uuid = UUID_SOC_FW_KEY_CERT,
106};
107
108static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
109 .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
110};
111
112static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
113 .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
114};
115
116static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
117 .uuid = UUID_SCP_FW_CONTENT_CERT,
118};
119
120static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
121 .uuid = UUID_SOC_FW_CONTENT_CERT,
122};
123
124static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
125 .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
126};
127
128static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
129 .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
130};
131#endif /* TRUSTED_BOARD_BOOT */
132
133static int open_fip(const uintptr_t spec);
134static int open_memmap(const uintptr_t spec);
135static int open_qspi(const uintptr_t spec);
136static int open_nand(const uintptr_t spec);
137
138struct plat_io_policy {
139 uintptr_t *dev_handle;
140 uintptr_t image_spec;
141 int (*check)(const uintptr_t spec);
142};
143
144/* By default, BRCM platforms load images from the FIP */
145static const struct plat_io_policy policies[] = {
146 [FIP_IMAGE_ID] = {
147 &memmap_dev_handle,
148 (uintptr_t)&fip_block_spec,
149 open_memmap
150 },
151 [BL2_IMAGE_ID] = {
152 &fip_dev_handle,
153 (uintptr_t)&bl2_uuid_spec,
154 open_fip
155 },
156 [SCP_BL2_IMAGE_ID] = {
157 &fip_dev_handle,
158 (uintptr_t)&scp_bl2_uuid_spec,
159 open_fip
160 },
161 [BL31_IMAGE_ID] = {
162 &fip_dev_handle,
163 (uintptr_t)&bl31_uuid_spec,
164 open_fip
165 },
166 [BL32_IMAGE_ID] = {
167 &fip_dev_handle,
168 (uintptr_t)&bl32_uuid_spec,
169 open_fip
170 },
171 [BL32_EXTRA1_IMAGE_ID] = {
172 &fip_dev_handle,
173 (uintptr_t)&bl32_extra1_uuid_spec,
174 open_fip
175 },
176 [BL32_EXTRA2_IMAGE_ID] = {
177 &fip_dev_handle,
178 (uintptr_t)&bl32_extra2_uuid_spec,
179 open_fip
180 },
181 [BL33_IMAGE_ID] = {
182 &fip_dev_handle,
183 (uintptr_t)&bl33_uuid_spec,
184 open_fip
185 },
186 [TB_FW_CONFIG_ID] = {
187 &fip_dev_handle,
188 (uintptr_t)&tb_fw_config_uuid_spec,
189 open_fip
190 },
191 [HW_CONFIG_ID] = {
192 &fip_dev_handle,
193 (uintptr_t)&hw_config_uuid_spec,
194 open_fip
195 },
196 [SOC_FW_CONFIG_ID] = {
197 &fip_dev_handle,
198 (uintptr_t)&soc_fw_config_uuid_spec,
199 open_fip
200 },
201 [TOS_FW_CONFIG_ID] = {
202 &fip_dev_handle,
203 (uintptr_t)&tos_fw_config_uuid_spec,
204 open_fip
205 },
206 [NT_FW_CONFIG_ID] = {
207 &fip_dev_handle,
208 (uintptr_t)&nt_fw_config_uuid_spec,
209 open_fip
210 },
211#if TRUSTED_BOARD_BOOT
212 [TRUSTED_BOOT_FW_CERT_ID] = {
213 &fip_dev_handle,
214 (uintptr_t)&tb_fw_cert_uuid_spec,
215 open_fip
216 },
217 [TRUSTED_KEY_CERT_ID] = {
218 &fip_dev_handle,
219 (uintptr_t)&trusted_key_cert_uuid_spec,
220 open_fip
221 },
222 [SCP_FW_KEY_CERT_ID] = {
223 &fip_dev_handle,
224 (uintptr_t)&scp_fw_key_cert_uuid_spec,
225 open_fip
226 },
227 [SOC_FW_KEY_CERT_ID] = {
228 &fip_dev_handle,
229 (uintptr_t)&soc_fw_key_cert_uuid_spec,
230 open_fip
231 },
232 [TRUSTED_OS_FW_KEY_CERT_ID] = {
233 &fip_dev_handle,
234 (uintptr_t)&tos_fw_key_cert_uuid_spec,
235 open_fip
236 },
237 [NON_TRUSTED_FW_KEY_CERT_ID] = {
238 &fip_dev_handle,
239 (uintptr_t)&nt_fw_key_cert_uuid_spec,
240 open_fip
241 },
242 [SCP_FW_CONTENT_CERT_ID] = {
243 &fip_dev_handle,
244 (uintptr_t)&scp_fw_cert_uuid_spec,
245 open_fip
246 },
247 [SOC_FW_CONTENT_CERT_ID] = {
248 &fip_dev_handle,
249 (uintptr_t)&soc_fw_cert_uuid_spec,
250 open_fip
251 },
252 [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
253 &fip_dev_handle,
254 (uintptr_t)&tos_fw_cert_uuid_spec,
255 open_fip
256 },
257 [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
258 &fip_dev_handle,
259 (uintptr_t)&nt_fw_cert_uuid_spec,
260 open_fip
261 },
262#endif /* TRUSTED_BOARD_BOOT */
263};
264
265/* By default, BRCM platforms load images from the FIP */
266static const struct plat_io_policy boot_source_policies[] = {
267 [BOOT_SOURCE_QSPI] = {
268 &memmap_dev_handle,
269 (uintptr_t)&qspi_fip_block_spec,
270 open_qspi
271 },
272 [BOOT_SOURCE_NAND] = {
273 &memmap_dev_handle,
274 (uintptr_t)&nand_fip_block_spec,
275 open_nand
276 },
277};
278
279/* Weak definitions may be overridden in specific brcm platform */
280#pragma weak plat_brcm_io_setup
281#pragma weak plat_brcm_process_flags
282
283static int open_fip(const uintptr_t spec)
284{
285 int result;
286 uintptr_t local_image_handle;
287
288 /* See if a Firmware Image Package is available */
289 result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
290 if (result == 0) {
291 result = io_open(fip_dev_handle, spec, &local_image_handle);
292 if (result == 0) {
293 VERBOSE("Using FIP\n");
294 io_close(local_image_handle);
295 }
296 }
297 return result;
298}
299
300
301static int open_memmap(const uintptr_t spec)
302{
303 int result;
304 uintptr_t local_image_handle;
305
306 result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
307 if (result == 0) {
308 result = io_open(memmap_dev_handle, spec, &local_image_handle);
309 if (result == 0) {
310 VERBOSE("Using Memmap\n");
311 io_close(local_image_handle);
312 }
313 }
314 return result;
315}
316
317static int open_qspi(const uintptr_t spec)
318{
319 return open_memmap(spec);
320}
321
322static int open_nand(const uintptr_t spec)
323{
324 return open_memmap(spec);
325}
326
327
328void brcm_io_setup(void)
329{
330 int io_result;
331 uint32_t boot_source;
332
333 io_result = register_io_dev_fip(&fip_dev_con);
334 assert(io_result == 0);
335
336 io_result = register_io_dev_memmap(&memmap_dev_con);
337 assert(io_result == 0);
338
339 /* Open connections to devices and cache the handles */
340 io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
341 &fip_dev_handle);
342 assert(io_result == 0);
343
344 boot_source = boot_source_get();
345 switch (boot_source) {
346 case BOOT_SOURCE_QSPI:
347 case BOOT_SOURCE_NAND:
348 default:
349 io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
350 &memmap_dev_handle);
351 break;
352 }
353 assert(io_result == 0);
354
355 /* Ignore improbable errors in release builds */
356 (void)io_result;
357}
358
359void plat_brcm_io_setup(void)
360{
361 brcm_io_setup();
362}
363
364void plat_brcm_process_flags(uint16_t plat_toc_flags __unused)
365{
366 WARN("%s not implemented\n", __func__);
367}
368
369/*
370 * Return an IO device handle and specification which can be used to access
371 * an image. Use this to enforce platform load policy
372 */
373int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
374 uintptr_t *image_spec)
375{
376 int result;
377 const struct plat_io_policy *policy;
378 uint32_t boot_source;
379 uint16_t lcl_plat_toc_flg;
380
381 assert(image_id < ARRAY_SIZE(policies));
382
383 boot_source = boot_source_get();
384 if (image_id == FIP_IMAGE_ID)
385 policy = &boot_source_policies[boot_source];
386 else
387 policy = &policies[image_id];
388
389 result = policy->check(policy->image_spec);
390 if (result == 0) {
391 *image_spec = policy->image_spec;
392 *dev_handle = *(policy->dev_handle);
393
394 if (image_id == TRUSTED_BOOT_FW_CERT_ID) {
395 /*
396 * Process the header flags to perform
397 * such custom actions as speeding up PLL.
398 * CERT seems to be the first image accessed
399 * by BL1 so this is where we process the flags.
400 */
401 fip_dev_get_plat_toc_flag((io_dev_info_t *)fip_dev_handle,
402 &lcl_plat_toc_flg);
403 plat_brcm_process_flags(lcl_plat_toc_flg);
404 }
405 }
406
407 return result;
408}