1 /*
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 */
23 static const io_dev_connector_t *fip_dev_con;
24 static uintptr_t fip_dev_handle;
25 static const io_dev_connector_t *memmap_dev_con;
26 static uintptr_t memmap_dev_handle;
27 
28 static const io_block_spec_t fip_block_spec = {
29 	.offset = PLAT_BRCM_FIP_BASE,
30 	.length = PLAT_BRCM_FIP_MAX_SIZE
31 };
32 
33 static 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 
38 static 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 
43 static const io_uuid_spec_t bl2_uuid_spec = {
44 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
45 };
46 
47 static const io_uuid_spec_t scp_bl2_uuid_spec = {
48 	.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
49 };
50 
51 static const io_uuid_spec_t bl31_uuid_spec = {
52 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
53 };
54 
55 static const io_uuid_spec_t bl32_uuid_spec = {
56 	.uuid = UUID_SECURE_PAYLOAD_BL32,
57 };
58 
59 static const io_uuid_spec_t bl32_extra1_uuid_spec = {
60 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
61 };
62 
63 static const io_uuid_spec_t bl32_extra2_uuid_spec = {
64 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
65 };
66 
67 static const io_uuid_spec_t bl33_uuid_spec = {
68 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
69 };
70 
71 static const io_uuid_spec_t tb_fw_config_uuid_spec = {
72 	.uuid = UUID_TB_FW_CONFIG,
73 };
74 
75 static const io_uuid_spec_t hw_config_uuid_spec = {
76 	.uuid = UUID_HW_CONFIG,
77 };
78 
79 static const io_uuid_spec_t soc_fw_config_uuid_spec = {
80 	.uuid = UUID_SOC_FW_CONFIG,
81 };
82 
83 static const io_uuid_spec_t tos_fw_config_uuid_spec = {
84 	.uuid = UUID_TOS_FW_CONFIG,
85 };
86 
87 static const io_uuid_spec_t nt_fw_config_uuid_spec = {
88 	.uuid = UUID_NT_FW_CONFIG,
89 };
90 
91 #if TRUSTED_BOARD_BOOT
92 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
93 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
94 };
95 
96 static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
97 	.uuid = UUID_TRUSTED_KEY_CERT,
98 };
99 
100 static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
101 	.uuid = UUID_SCP_FW_KEY_CERT,
102 };
103 
104 static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
105 	.uuid = UUID_SOC_FW_KEY_CERT,
106 };
107 
108 static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
109 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
110 };
111 
112 static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
113 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
114 };
115 
116 static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
117 	.uuid = UUID_SCP_FW_CONTENT_CERT,
118 };
119 
120 static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
121 	.uuid = UUID_SOC_FW_CONTENT_CERT,
122 };
123 
124 static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
125 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
126 };
127 
128 static 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 
133 static int open_fip(const uintptr_t spec);
134 static int open_memmap(const uintptr_t spec);
135 static int open_qspi(const uintptr_t spec);
136 static int open_nand(const uintptr_t spec);
137 
138 struct 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 */
145 static 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 */
266 static 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 
open_fip(const uintptr_t spec)283 static 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 
open_memmap(const uintptr_t spec)301 static 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 
open_qspi(const uintptr_t spec)317 static int open_qspi(const uintptr_t spec)
318 {
319 	return open_memmap(spec);
320 }
321 
open_nand(const uintptr_t spec)322 static int open_nand(const uintptr_t spec)
323 {
324 	return open_memmap(spec);
325 }
326 
327 
brcm_io_setup(void)328 void 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 
plat_brcm_io_setup(void)359 void plat_brcm_io_setup(void)
360 {
361 	brcm_io_setup();
362 }
363 
plat_brcm_process_flags(uint16_t plat_toc_flags __unused)364 void 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  */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)373 int 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 }
409