xref: /rk3399_ARM-atf/plat/rpi/common/rpi3_io_storage.c (revision ed01e0c407a1794faf8ff8173183a50419bbd2ae)
1*4f2b9848SAndre Przywara /*
2*4f2b9848SAndre Przywara  * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
3*4f2b9848SAndre Przywara  *
4*4f2b9848SAndre Przywara  * SPDX-License-Identifier: BSD-3-Clause
5*4f2b9848SAndre Przywara  */
6*4f2b9848SAndre Przywara 
7*4f2b9848SAndre Przywara #include <assert.h>
8*4f2b9848SAndre Przywara #include <string.h>
9*4f2b9848SAndre Przywara 
10*4f2b9848SAndre Przywara #include <platform_def.h>
11*4f2b9848SAndre Przywara 
12*4f2b9848SAndre Przywara #include <common/bl_common.h>
13*4f2b9848SAndre Przywara #include <common/debug.h>
14*4f2b9848SAndre Przywara #include <drivers/io/io_driver.h>
15*4f2b9848SAndre Przywara #include <drivers/io/io_fip.h>
16*4f2b9848SAndre Przywara #include <drivers/io/io_memmap.h>
17*4f2b9848SAndre Przywara #include <tools_share/firmware_image_package.h>
18*4f2b9848SAndre Przywara 
19*4f2b9848SAndre Przywara /* Semihosting filenames */
20*4f2b9848SAndre Przywara #define BL2_IMAGE_NAME			"bl2.bin"
21*4f2b9848SAndre Przywara #define BL31_IMAGE_NAME			"bl31.bin"
22*4f2b9848SAndre Przywara #define BL32_IMAGE_NAME			"bl32.bin"
23*4f2b9848SAndre Przywara #define BL33_IMAGE_NAME			"bl33.bin"
24*4f2b9848SAndre Przywara 
25*4f2b9848SAndre Przywara #if TRUSTED_BOARD_BOOT
26*4f2b9848SAndre Przywara #define TRUSTED_BOOT_FW_CERT_NAME	"tb_fw.crt"
27*4f2b9848SAndre Przywara #define TRUSTED_KEY_CERT_NAME		"trusted_key.crt"
28*4f2b9848SAndre Przywara #define SOC_FW_KEY_CERT_NAME		"soc_fw_key.crt"
29*4f2b9848SAndre Przywara #define TOS_FW_KEY_CERT_NAME		"tos_fw_key.crt"
30*4f2b9848SAndre Przywara #define NT_FW_KEY_CERT_NAME		"nt_fw_key.crt"
31*4f2b9848SAndre Przywara #define SOC_FW_CONTENT_CERT_NAME	"soc_fw_content.crt"
32*4f2b9848SAndre Przywara #define TOS_FW_CONTENT_CERT_NAME	"tos_fw_content.crt"
33*4f2b9848SAndre Przywara #define NT_FW_CONTENT_CERT_NAME		"nt_fw_content.crt"
34*4f2b9848SAndre Przywara #endif /* TRUSTED_BOARD_BOOT */
35*4f2b9848SAndre Przywara 
36*4f2b9848SAndre Przywara /* IO devices */
37*4f2b9848SAndre Przywara static const io_dev_connector_t *fip_dev_con;
38*4f2b9848SAndre Przywara static uintptr_t fip_dev_handle;
39*4f2b9848SAndre Przywara static const io_dev_connector_t *memmap_dev_con;
40*4f2b9848SAndre Przywara static uintptr_t memmap_dev_handle;
41*4f2b9848SAndre Przywara 
42*4f2b9848SAndre Przywara static const io_block_spec_t fip_block_spec = {
43*4f2b9848SAndre Przywara 	.offset = PLAT_RPI3_FIP_BASE,
44*4f2b9848SAndre Przywara 	.length = PLAT_RPI3_FIP_MAX_SIZE
45*4f2b9848SAndre Przywara };
46*4f2b9848SAndre Przywara 
47*4f2b9848SAndre Przywara static const io_uuid_spec_t bl2_uuid_spec = {
48*4f2b9848SAndre Przywara 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
49*4f2b9848SAndre Przywara };
50*4f2b9848SAndre Przywara 
51*4f2b9848SAndre Przywara static const io_uuid_spec_t bl31_uuid_spec = {
52*4f2b9848SAndre Przywara 	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
53*4f2b9848SAndre Przywara };
54*4f2b9848SAndre Przywara 
55*4f2b9848SAndre Przywara static const io_uuid_spec_t bl32_uuid_spec = {
56*4f2b9848SAndre Przywara 	.uuid = UUID_SECURE_PAYLOAD_BL32,
57*4f2b9848SAndre Przywara };
58*4f2b9848SAndre Przywara 
59*4f2b9848SAndre Przywara static const io_uuid_spec_t bl32_extra1_uuid_spec = {
60*4f2b9848SAndre Przywara 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
61*4f2b9848SAndre Przywara };
62*4f2b9848SAndre Przywara 
63*4f2b9848SAndre Przywara static const io_uuid_spec_t bl32_extra2_uuid_spec = {
64*4f2b9848SAndre Przywara 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
65*4f2b9848SAndre Przywara };
66*4f2b9848SAndre Przywara 
67*4f2b9848SAndre Przywara static const io_uuid_spec_t bl33_uuid_spec = {
68*4f2b9848SAndre Przywara 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
69*4f2b9848SAndre Przywara };
70*4f2b9848SAndre Przywara 
71*4f2b9848SAndre Przywara #if TRUSTED_BOARD_BOOT
72*4f2b9848SAndre Przywara static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
73*4f2b9848SAndre Przywara 	.uuid = UUID_TRUSTED_BOOT_FW_CERT,
74*4f2b9848SAndre Przywara };
75*4f2b9848SAndre Przywara 
76*4f2b9848SAndre Przywara static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
77*4f2b9848SAndre Przywara 	.uuid = UUID_TRUSTED_KEY_CERT,
78*4f2b9848SAndre Przywara };
79*4f2b9848SAndre Przywara 
80*4f2b9848SAndre Przywara static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
81*4f2b9848SAndre Przywara 	.uuid = UUID_SOC_FW_KEY_CERT,
82*4f2b9848SAndre Przywara };
83*4f2b9848SAndre Przywara 
84*4f2b9848SAndre Przywara static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
85*4f2b9848SAndre Przywara 	.uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
86*4f2b9848SAndre Przywara };
87*4f2b9848SAndre Przywara 
88*4f2b9848SAndre Przywara static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
89*4f2b9848SAndre Przywara 	.uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
90*4f2b9848SAndre Przywara };
91*4f2b9848SAndre Przywara 
92*4f2b9848SAndre Przywara static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
93*4f2b9848SAndre Przywara 	.uuid = UUID_SOC_FW_CONTENT_CERT,
94*4f2b9848SAndre Przywara };
95*4f2b9848SAndre Przywara 
96*4f2b9848SAndre Przywara static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
97*4f2b9848SAndre Przywara 	.uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
98*4f2b9848SAndre Przywara };
99*4f2b9848SAndre Przywara 
100*4f2b9848SAndre Przywara static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
101*4f2b9848SAndre Przywara 	.uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
102*4f2b9848SAndre Przywara };
103*4f2b9848SAndre Przywara #endif /* TRUSTED_BOARD_BOOT */
104*4f2b9848SAndre Przywara 
105*4f2b9848SAndre Przywara static int open_fip(const uintptr_t spec);
106*4f2b9848SAndre Przywara static int open_memmap(const uintptr_t spec);
107*4f2b9848SAndre Przywara 
108*4f2b9848SAndre Przywara struct plat_io_policy {
109*4f2b9848SAndre Przywara 	uintptr_t *dev_handle;
110*4f2b9848SAndre Przywara 	uintptr_t image_spec;
111*4f2b9848SAndre Przywara 	int (*check)(const uintptr_t spec);
112*4f2b9848SAndre Przywara };
113*4f2b9848SAndre Przywara 
114*4f2b9848SAndre Przywara /* By default, load images from the FIP */
115*4f2b9848SAndre Przywara static const struct plat_io_policy policies[] = {
116*4f2b9848SAndre Przywara 	[FIP_IMAGE_ID] = {
117*4f2b9848SAndre Przywara 		&memmap_dev_handle,
118*4f2b9848SAndre Przywara 		(uintptr_t)&fip_block_spec,
119*4f2b9848SAndre Przywara 		open_memmap
120*4f2b9848SAndre Przywara 	},
121*4f2b9848SAndre Przywara 	[BL2_IMAGE_ID] = {
122*4f2b9848SAndre Przywara 		&fip_dev_handle,
123*4f2b9848SAndre Przywara 		(uintptr_t)&bl2_uuid_spec,
124*4f2b9848SAndre Przywara 		open_fip
125*4f2b9848SAndre Przywara 	},
126*4f2b9848SAndre Przywara 	[BL31_IMAGE_ID] = {
127*4f2b9848SAndre Przywara 		&fip_dev_handle,
128*4f2b9848SAndre Przywara 		(uintptr_t)&bl31_uuid_spec,
129*4f2b9848SAndre Przywara 		open_fip
130*4f2b9848SAndre Przywara 	},
131*4f2b9848SAndre Przywara 	[BL32_IMAGE_ID] = {
132*4f2b9848SAndre Przywara 		&fip_dev_handle,
133*4f2b9848SAndre Przywara 		(uintptr_t)&bl32_uuid_spec,
134*4f2b9848SAndre Przywara 		open_fip
135*4f2b9848SAndre Przywara 	},
136*4f2b9848SAndre Przywara 	[BL32_EXTRA1_IMAGE_ID] = {
137*4f2b9848SAndre Przywara 		&fip_dev_handle,
138*4f2b9848SAndre Przywara 		(uintptr_t)&bl32_extra1_uuid_spec,
139*4f2b9848SAndre Przywara 		open_fip
140*4f2b9848SAndre Przywara 	},
141*4f2b9848SAndre Przywara 	[BL32_EXTRA2_IMAGE_ID] = {
142*4f2b9848SAndre Przywara 		&fip_dev_handle,
143*4f2b9848SAndre Przywara 		(uintptr_t)&bl32_extra2_uuid_spec,
144*4f2b9848SAndre Przywara 		open_fip
145*4f2b9848SAndre Przywara 	},
146*4f2b9848SAndre Przywara 	[BL33_IMAGE_ID] = {
147*4f2b9848SAndre Przywara 		&fip_dev_handle,
148*4f2b9848SAndre Przywara 		(uintptr_t)&bl33_uuid_spec,
149*4f2b9848SAndre Przywara 		open_fip
150*4f2b9848SAndre Przywara 	},
151*4f2b9848SAndre Przywara #if TRUSTED_BOARD_BOOT
152*4f2b9848SAndre Przywara 	[TRUSTED_BOOT_FW_CERT_ID] = {
153*4f2b9848SAndre Przywara 		&fip_dev_handle,
154*4f2b9848SAndre Przywara 		(uintptr_t)&tb_fw_cert_uuid_spec,
155*4f2b9848SAndre Przywara 		open_fip
156*4f2b9848SAndre Przywara 	},
157*4f2b9848SAndre Przywara 	[TRUSTED_KEY_CERT_ID] = {
158*4f2b9848SAndre Przywara 		&fip_dev_handle,
159*4f2b9848SAndre Przywara 		(uintptr_t)&trusted_key_cert_uuid_spec,
160*4f2b9848SAndre Przywara 		open_fip
161*4f2b9848SAndre Przywara 	},
162*4f2b9848SAndre Przywara 	[SOC_FW_KEY_CERT_ID] = {
163*4f2b9848SAndre Przywara 		&fip_dev_handle,
164*4f2b9848SAndre Przywara 		(uintptr_t)&soc_fw_key_cert_uuid_spec,
165*4f2b9848SAndre Przywara 		open_fip
166*4f2b9848SAndre Przywara 	},
167*4f2b9848SAndre Przywara 	[TRUSTED_OS_FW_KEY_CERT_ID] = {
168*4f2b9848SAndre Przywara 		&fip_dev_handle,
169*4f2b9848SAndre Przywara 		(uintptr_t)&tos_fw_key_cert_uuid_spec,
170*4f2b9848SAndre Przywara 		open_fip
171*4f2b9848SAndre Przywara 	},
172*4f2b9848SAndre Przywara 	[NON_TRUSTED_FW_KEY_CERT_ID] = {
173*4f2b9848SAndre Przywara 		&fip_dev_handle,
174*4f2b9848SAndre Przywara 		(uintptr_t)&nt_fw_key_cert_uuid_spec,
175*4f2b9848SAndre Przywara 		open_fip
176*4f2b9848SAndre Przywara 	},
177*4f2b9848SAndre Przywara 	[SOC_FW_CONTENT_CERT_ID] = {
178*4f2b9848SAndre Przywara 		&fip_dev_handle,
179*4f2b9848SAndre Przywara 		(uintptr_t)&soc_fw_cert_uuid_spec,
180*4f2b9848SAndre Przywara 		open_fip
181*4f2b9848SAndre Przywara 	},
182*4f2b9848SAndre Przywara 	[TRUSTED_OS_FW_CONTENT_CERT_ID] = {
183*4f2b9848SAndre Przywara 		&fip_dev_handle,
184*4f2b9848SAndre Przywara 		(uintptr_t)&tos_fw_cert_uuid_spec,
185*4f2b9848SAndre Przywara 		open_fip
186*4f2b9848SAndre Przywara 	},
187*4f2b9848SAndre Przywara 	[NON_TRUSTED_FW_CONTENT_CERT_ID] = {
188*4f2b9848SAndre Przywara 		&fip_dev_handle,
189*4f2b9848SAndre Przywara 		(uintptr_t)&nt_fw_cert_uuid_spec,
190*4f2b9848SAndre Przywara 		open_fip
191*4f2b9848SAndre Przywara 	},
192*4f2b9848SAndre Przywara #endif /* TRUSTED_BOARD_BOOT */
193*4f2b9848SAndre Przywara };
194*4f2b9848SAndre Przywara 
open_fip(const uintptr_t spec)195*4f2b9848SAndre Przywara static int open_fip(const uintptr_t spec)
196*4f2b9848SAndre Przywara {
197*4f2b9848SAndre Przywara 	int result;
198*4f2b9848SAndre Przywara 	uintptr_t local_image_handle;
199*4f2b9848SAndre Przywara 
200*4f2b9848SAndre Przywara 	/* See if a Firmware Image Package is available */
201*4f2b9848SAndre Przywara 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
202*4f2b9848SAndre Przywara 	if (result == 0) {
203*4f2b9848SAndre Przywara 		result = io_open(fip_dev_handle, spec, &local_image_handle);
204*4f2b9848SAndre Przywara 		if (result == 0) {
205*4f2b9848SAndre Przywara 			VERBOSE("Using FIP\n");
206*4f2b9848SAndre Przywara 			io_close(local_image_handle);
207*4f2b9848SAndre Przywara 		}
208*4f2b9848SAndre Przywara 	}
209*4f2b9848SAndre Przywara 	return result;
210*4f2b9848SAndre Przywara }
211*4f2b9848SAndre Przywara 
open_memmap(const uintptr_t spec)212*4f2b9848SAndre Przywara static int open_memmap(const uintptr_t spec)
213*4f2b9848SAndre Przywara {
214*4f2b9848SAndre Przywara 	int result;
215*4f2b9848SAndre Przywara 	uintptr_t local_image_handle;
216*4f2b9848SAndre Przywara 
217*4f2b9848SAndre Przywara 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
218*4f2b9848SAndre Przywara 	if (result == 0) {
219*4f2b9848SAndre Przywara 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
220*4f2b9848SAndre Przywara 		if (result == 0) {
221*4f2b9848SAndre Przywara 			VERBOSE("Using Memmap\n");
222*4f2b9848SAndre Przywara 			io_close(local_image_handle);
223*4f2b9848SAndre Przywara 		}
224*4f2b9848SAndre Przywara 	}
225*4f2b9848SAndre Przywara 	return result;
226*4f2b9848SAndre Przywara }
227*4f2b9848SAndre Przywara 
plat_rpi3_io_setup(void)228*4f2b9848SAndre Przywara void plat_rpi3_io_setup(void)
229*4f2b9848SAndre Przywara {
230*4f2b9848SAndre Przywara 	int io_result;
231*4f2b9848SAndre Przywara 
232*4f2b9848SAndre Przywara 	io_result = register_io_dev_fip(&fip_dev_con);
233*4f2b9848SAndre Przywara 	assert(io_result == 0);
234*4f2b9848SAndre Przywara 
235*4f2b9848SAndre Przywara 	io_result = register_io_dev_memmap(&memmap_dev_con);
236*4f2b9848SAndre Przywara 	assert(io_result == 0);
237*4f2b9848SAndre Przywara 
238*4f2b9848SAndre Przywara 	/* Open connections to devices and cache the handles */
239*4f2b9848SAndre Przywara 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
240*4f2b9848SAndre Przywara 				&fip_dev_handle);
241*4f2b9848SAndre Przywara 	assert(io_result == 0);
242*4f2b9848SAndre Przywara 
243*4f2b9848SAndre Przywara 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
244*4f2b9848SAndre Przywara 				&memmap_dev_handle);
245*4f2b9848SAndre Przywara 	assert(io_result == 0);
246*4f2b9848SAndre Przywara 
247*4f2b9848SAndre Przywara 	/* Ignore improbable errors in release builds */
248*4f2b9848SAndre Przywara 	(void)io_result;
249*4f2b9848SAndre Przywara }
250*4f2b9848SAndre Przywara 
251*4f2b9848SAndre Przywara /*
252*4f2b9848SAndre Przywara  * Return an IO device handle and specification which can be used to access
253*4f2b9848SAndre Przywara  * an image. Use this to enforce platform load policy
254*4f2b9848SAndre Przywara  */
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)255*4f2b9848SAndre Przywara int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
256*4f2b9848SAndre Przywara 			  uintptr_t *image_spec)
257*4f2b9848SAndre Przywara {
258*4f2b9848SAndre Przywara 	int result;
259*4f2b9848SAndre Przywara 	const struct plat_io_policy *policy;
260*4f2b9848SAndre Przywara 
261*4f2b9848SAndre Przywara 	assert(image_id < ARRAY_SIZE(policies));
262*4f2b9848SAndre Przywara 
263*4f2b9848SAndre Przywara 	policy = &policies[image_id];
264*4f2b9848SAndre Przywara 	result = policy->check(policy->image_spec);
265*4f2b9848SAndre Przywara 	if (result == 0) {
266*4f2b9848SAndre Przywara 		*image_spec = policy->image_spec;
267*4f2b9848SAndre Przywara 		*dev_handle = *(policy->dev_handle);
268*4f2b9848SAndre Przywara 	}
269*4f2b9848SAndre Przywara 
270*4f2b9848SAndre Przywara 	return result;
271*4f2b9848SAndre Przywara }
272