xref: /rk3399_ARM-atf/plat/arm/common/arm_io_storage.c (revision b4315306ada18bac1c74f34db717d22fd5ff3003)
1*b4315306SDan Handley /*
2*b4315306SDan Handley  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3*b4315306SDan Handley  *
4*b4315306SDan Handley  * Redistribution and use in source and binary forms, with or without
5*b4315306SDan Handley  * modification, are permitted provided that the following conditions are met:
6*b4315306SDan Handley  *
7*b4315306SDan Handley  * Redistributions of source code must retain the above copyright notice, this
8*b4315306SDan Handley  * list of conditions and the following disclaimer.
9*b4315306SDan Handley  *
10*b4315306SDan Handley  * Redistributions in binary form must reproduce the above copyright notice,
11*b4315306SDan Handley  * this list of conditions and the following disclaimer in the documentation
12*b4315306SDan Handley  * and/or other materials provided with the distribution.
13*b4315306SDan Handley  *
14*b4315306SDan Handley  * Neither the name of ARM nor the names of its contributors may be used
15*b4315306SDan Handley  * to endorse or promote products derived from this software without specific
16*b4315306SDan Handley  * prior written permission.
17*b4315306SDan Handley  *
18*b4315306SDan Handley  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19*b4315306SDan Handley  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*b4315306SDan Handley  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*b4315306SDan Handley  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22*b4315306SDan Handley  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*b4315306SDan Handley  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*b4315306SDan Handley  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*b4315306SDan Handley  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*b4315306SDan Handley  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*b4315306SDan Handley  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*b4315306SDan Handley  * POSSIBILITY OF SUCH DAMAGE.
29*b4315306SDan Handley  */
30*b4315306SDan Handley #include <assert.h>
31*b4315306SDan Handley #include <debug.h>
32*b4315306SDan Handley #include <io_driver.h>
33*b4315306SDan Handley #include <io_fip.h>
34*b4315306SDan Handley #include <io_memmap.h>
35*b4315306SDan Handley #include <io_storage.h>
36*b4315306SDan Handley #include <platform_def.h>
37*b4315306SDan Handley #include <semihosting.h>	/* For FOPEN_MODE_... */
38*b4315306SDan Handley #include <string.h>
39*b4315306SDan Handley 
40*b4315306SDan Handley /* IO devices */
41*b4315306SDan Handley static const io_dev_connector_t *fip_dev_con;
42*b4315306SDan Handley static uintptr_t fip_dev_handle;
43*b4315306SDan Handley static const io_dev_connector_t *memmap_dev_con;
44*b4315306SDan Handley static uintptr_t memmap_dev_handle;
45*b4315306SDan Handley 
46*b4315306SDan Handley static const io_block_spec_t fip_block_spec = {
47*b4315306SDan Handley 	.offset = PLAT_ARM_FIP_BASE,
48*b4315306SDan Handley 	.length = PLAT_ARM_FIP_MAX_SIZE
49*b4315306SDan Handley };
50*b4315306SDan Handley 
51*b4315306SDan Handley static const io_file_spec_t bl2_file_spec = {
52*b4315306SDan Handley 	.path = BL2_IMAGE_NAME,
53*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
54*b4315306SDan Handley };
55*b4315306SDan Handley 
56*b4315306SDan Handley static const io_file_spec_t bl30_file_spec = {
57*b4315306SDan Handley 	.path = BL30_IMAGE_NAME,
58*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
59*b4315306SDan Handley };
60*b4315306SDan Handley 
61*b4315306SDan Handley static const io_file_spec_t bl31_file_spec = {
62*b4315306SDan Handley 	.path = BL31_IMAGE_NAME,
63*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
64*b4315306SDan Handley };
65*b4315306SDan Handley 
66*b4315306SDan Handley static const io_file_spec_t bl32_file_spec = {
67*b4315306SDan Handley 	.path = BL32_IMAGE_NAME,
68*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
69*b4315306SDan Handley };
70*b4315306SDan Handley 
71*b4315306SDan Handley static const io_file_spec_t bl33_file_spec = {
72*b4315306SDan Handley 	.path = BL33_IMAGE_NAME,
73*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
74*b4315306SDan Handley };
75*b4315306SDan Handley 
76*b4315306SDan Handley #if TRUSTED_BOARD_BOOT
77*b4315306SDan Handley static const io_file_spec_t bl2_cert_file_spec = {
78*b4315306SDan Handley 	.path = BL2_CERT_NAME,
79*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
80*b4315306SDan Handley };
81*b4315306SDan Handley 
82*b4315306SDan Handley static const io_file_spec_t trusted_key_cert_file_spec = {
83*b4315306SDan Handley 	.path = TRUSTED_KEY_CERT_NAME,
84*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
85*b4315306SDan Handley };
86*b4315306SDan Handley 
87*b4315306SDan Handley static const io_file_spec_t bl30_key_cert_file_spec = {
88*b4315306SDan Handley 	.path = BL30_KEY_CERT_NAME,
89*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
90*b4315306SDan Handley };
91*b4315306SDan Handley 
92*b4315306SDan Handley static const io_file_spec_t bl31_key_cert_file_spec = {
93*b4315306SDan Handley 	.path = BL31_KEY_CERT_NAME,
94*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
95*b4315306SDan Handley };
96*b4315306SDan Handley 
97*b4315306SDan Handley static const io_file_spec_t bl32_key_cert_file_spec = {
98*b4315306SDan Handley 	.path = BL32_KEY_CERT_NAME,
99*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
100*b4315306SDan Handley };
101*b4315306SDan Handley 
102*b4315306SDan Handley static const io_file_spec_t bl33_key_cert_file_spec = {
103*b4315306SDan Handley 	.path = BL33_KEY_CERT_NAME,
104*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
105*b4315306SDan Handley };
106*b4315306SDan Handley 
107*b4315306SDan Handley static const io_file_spec_t bl30_cert_file_spec = {
108*b4315306SDan Handley 	.path = BL30_CERT_NAME,
109*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
110*b4315306SDan Handley };
111*b4315306SDan Handley 
112*b4315306SDan Handley static const io_file_spec_t bl31_cert_file_spec = {
113*b4315306SDan Handley 	.path = BL31_CERT_NAME,
114*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
115*b4315306SDan Handley };
116*b4315306SDan Handley 
117*b4315306SDan Handley static const io_file_spec_t bl32_cert_file_spec = {
118*b4315306SDan Handley 	.path = BL32_CERT_NAME,
119*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
120*b4315306SDan Handley };
121*b4315306SDan Handley 
122*b4315306SDan Handley static const io_file_spec_t bl33_cert_file_spec = {
123*b4315306SDan Handley 	.path = BL33_CERT_NAME,
124*b4315306SDan Handley 	.mode = FOPEN_MODE_RB
125*b4315306SDan Handley };
126*b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */
127*b4315306SDan Handley 
128*b4315306SDan Handley static int open_fip(const uintptr_t spec);
129*b4315306SDan Handley static int open_memmap(const uintptr_t spec);
130*b4315306SDan Handley 
131*b4315306SDan Handley struct plat_io_policy {
132*b4315306SDan Handley 	const char *image_name;
133*b4315306SDan Handley 	uintptr_t *dev_handle;
134*b4315306SDan Handley 	uintptr_t image_spec;
135*b4315306SDan Handley 	int (*check)(const uintptr_t spec);
136*b4315306SDan Handley };
137*b4315306SDan Handley 
138*b4315306SDan Handley static const struct plat_io_policy policies[] = {
139*b4315306SDan Handley 	{
140*b4315306SDan Handley 		FIP_IMAGE_NAME,
141*b4315306SDan Handley 		&memmap_dev_handle,
142*b4315306SDan Handley 		(uintptr_t)&fip_block_spec,
143*b4315306SDan Handley 		open_memmap
144*b4315306SDan Handley 	}, {
145*b4315306SDan Handley 		BL2_IMAGE_NAME,
146*b4315306SDan Handley 		&fip_dev_handle,
147*b4315306SDan Handley 		(uintptr_t)&bl2_file_spec,
148*b4315306SDan Handley 		open_fip
149*b4315306SDan Handley 	}, {
150*b4315306SDan Handley 		BL30_IMAGE_NAME,
151*b4315306SDan Handley 		&fip_dev_handle,
152*b4315306SDan Handley 		(uintptr_t)&bl30_file_spec,
153*b4315306SDan Handley 		open_fip
154*b4315306SDan Handley 	}, {
155*b4315306SDan Handley 		BL31_IMAGE_NAME,
156*b4315306SDan Handley 		&fip_dev_handle,
157*b4315306SDan Handley 		(uintptr_t)&bl31_file_spec,
158*b4315306SDan Handley 		open_fip
159*b4315306SDan Handley 	}, {
160*b4315306SDan Handley 		BL32_IMAGE_NAME,
161*b4315306SDan Handley 		&fip_dev_handle,
162*b4315306SDan Handley 		(uintptr_t)&bl32_file_spec,
163*b4315306SDan Handley 		open_fip
164*b4315306SDan Handley 	}, {
165*b4315306SDan Handley 		BL33_IMAGE_NAME,
166*b4315306SDan Handley 		&fip_dev_handle,
167*b4315306SDan Handley 		(uintptr_t)&bl33_file_spec,
168*b4315306SDan Handley 		open_fip
169*b4315306SDan Handley 	}, {
170*b4315306SDan Handley #if TRUSTED_BOARD_BOOT
171*b4315306SDan Handley 		BL2_CERT_NAME,
172*b4315306SDan Handley 		&fip_dev_handle,
173*b4315306SDan Handley 		(uintptr_t)&bl2_cert_file_spec,
174*b4315306SDan Handley 		open_fip
175*b4315306SDan Handley 	}, {
176*b4315306SDan Handley 		TRUSTED_KEY_CERT_NAME,
177*b4315306SDan Handley 		&fip_dev_handle,
178*b4315306SDan Handley 		(uintptr_t)&trusted_key_cert_file_spec,
179*b4315306SDan Handley 		open_fip
180*b4315306SDan Handley 	}, {
181*b4315306SDan Handley 		BL30_KEY_CERT_NAME,
182*b4315306SDan Handley 		&fip_dev_handle,
183*b4315306SDan Handley 		(uintptr_t)&bl30_key_cert_file_spec,
184*b4315306SDan Handley 		open_fip
185*b4315306SDan Handley 	}, {
186*b4315306SDan Handley 		BL31_KEY_CERT_NAME,
187*b4315306SDan Handley 		&fip_dev_handle,
188*b4315306SDan Handley 		(uintptr_t)&bl31_key_cert_file_spec,
189*b4315306SDan Handley 		open_fip
190*b4315306SDan Handley 	}, {
191*b4315306SDan Handley 		BL32_KEY_CERT_NAME,
192*b4315306SDan Handley 		&fip_dev_handle,
193*b4315306SDan Handley 		(uintptr_t)&bl32_key_cert_file_spec,
194*b4315306SDan Handley 		open_fip
195*b4315306SDan Handley 	}, {
196*b4315306SDan Handley 		BL33_KEY_CERT_NAME,
197*b4315306SDan Handley 		&fip_dev_handle,
198*b4315306SDan Handley 		(uintptr_t)&bl33_key_cert_file_spec,
199*b4315306SDan Handley 		open_fip
200*b4315306SDan Handley 	}, {
201*b4315306SDan Handley 		BL30_CERT_NAME,
202*b4315306SDan Handley 		&fip_dev_handle,
203*b4315306SDan Handley 		(uintptr_t)&bl30_cert_file_spec,
204*b4315306SDan Handley 		open_fip
205*b4315306SDan Handley 	}, {
206*b4315306SDan Handley 		BL31_CERT_NAME,
207*b4315306SDan Handley 		&fip_dev_handle,
208*b4315306SDan Handley 		(uintptr_t)&bl31_cert_file_spec,
209*b4315306SDan Handley 		open_fip
210*b4315306SDan Handley 	}, {
211*b4315306SDan Handley 		BL32_CERT_NAME,
212*b4315306SDan Handley 		&fip_dev_handle,
213*b4315306SDan Handley 		(uintptr_t)&bl32_cert_file_spec,
214*b4315306SDan Handley 		open_fip
215*b4315306SDan Handley 	}, {
216*b4315306SDan Handley 		BL33_CERT_NAME,
217*b4315306SDan Handley 		&fip_dev_handle,
218*b4315306SDan Handley 		(uintptr_t)&bl33_cert_file_spec,
219*b4315306SDan Handley 		open_fip
220*b4315306SDan Handley 	}, {
221*b4315306SDan Handley #endif /* TRUSTED_BOARD_BOOT */
222*b4315306SDan Handley 		0, 0, 0
223*b4315306SDan Handley 	}
224*b4315306SDan Handley };
225*b4315306SDan Handley 
226*b4315306SDan Handley 
227*b4315306SDan Handley /* Weak definitions may be overridden in specific ARM standard platform */
228*b4315306SDan Handley #pragma weak plat_arm_io_setup
229*b4315306SDan Handley #pragma weak plat_arm_get_alt_image_source
230*b4315306SDan Handley 
231*b4315306SDan Handley 
232*b4315306SDan Handley static int open_fip(const uintptr_t spec)
233*b4315306SDan Handley {
234*b4315306SDan Handley 	int result;
235*b4315306SDan Handley 	uintptr_t local_image_handle;
236*b4315306SDan Handley 
237*b4315306SDan Handley 	/* See if a Firmware Image Package is available */
238*b4315306SDan Handley 	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME);
239*b4315306SDan Handley 	if (result == IO_SUCCESS) {
240*b4315306SDan Handley 		result = io_open(fip_dev_handle, spec, &local_image_handle);
241*b4315306SDan Handley 		if (result == IO_SUCCESS) {
242*b4315306SDan Handley 			VERBOSE("Using FIP\n");
243*b4315306SDan Handley 			io_close(local_image_handle);
244*b4315306SDan Handley 		}
245*b4315306SDan Handley 	}
246*b4315306SDan Handley 	return result;
247*b4315306SDan Handley }
248*b4315306SDan Handley 
249*b4315306SDan Handley 
250*b4315306SDan Handley static int open_memmap(const uintptr_t spec)
251*b4315306SDan Handley {
252*b4315306SDan Handley 	int result;
253*b4315306SDan Handley 	uintptr_t local_image_handle;
254*b4315306SDan Handley 
255*b4315306SDan Handley 	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
256*b4315306SDan Handley 	if (result == IO_SUCCESS) {
257*b4315306SDan Handley 		result = io_open(memmap_dev_handle, spec, &local_image_handle);
258*b4315306SDan Handley 		if (result == IO_SUCCESS) {
259*b4315306SDan Handley 			VERBOSE("Using Memmap\n");
260*b4315306SDan Handley 			io_close(local_image_handle);
261*b4315306SDan Handley 		}
262*b4315306SDan Handley 	}
263*b4315306SDan Handley 	return result;
264*b4315306SDan Handley }
265*b4315306SDan Handley 
266*b4315306SDan Handley 
267*b4315306SDan Handley void arm_io_setup(void)
268*b4315306SDan Handley {
269*b4315306SDan Handley 	int io_result;
270*b4315306SDan Handley 
271*b4315306SDan Handley 	io_result = register_io_dev_fip(&fip_dev_con);
272*b4315306SDan Handley 	assert(io_result == IO_SUCCESS);
273*b4315306SDan Handley 
274*b4315306SDan Handley 	io_result = register_io_dev_memmap(&memmap_dev_con);
275*b4315306SDan Handley 	assert(io_result == IO_SUCCESS);
276*b4315306SDan Handley 
277*b4315306SDan Handley 	/* Open connections to devices and cache the handles */
278*b4315306SDan Handley 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
279*b4315306SDan Handley 				&fip_dev_handle);
280*b4315306SDan Handley 	assert(io_result == IO_SUCCESS);
281*b4315306SDan Handley 
282*b4315306SDan Handley 	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
283*b4315306SDan Handley 				&memmap_dev_handle);
284*b4315306SDan Handley 	assert(io_result == IO_SUCCESS);
285*b4315306SDan Handley 
286*b4315306SDan Handley 	/* Ignore improbable errors in release builds */
287*b4315306SDan Handley 	(void)io_result;
288*b4315306SDan Handley }
289*b4315306SDan Handley 
290*b4315306SDan Handley void plat_arm_io_setup(void)
291*b4315306SDan Handley {
292*b4315306SDan Handley 	arm_io_setup();
293*b4315306SDan Handley }
294*b4315306SDan Handley 
295*b4315306SDan Handley int plat_arm_get_alt_image_source(
296*b4315306SDan Handley 	const uintptr_t image_spec __attribute__((unused)),
297*b4315306SDan Handley 	uintptr_t *dev_handle __attribute__((unused)))
298*b4315306SDan Handley {
299*b4315306SDan Handley 	/* By default do not try an alternative */
300*b4315306SDan Handley 	return IO_FAIL;
301*b4315306SDan Handley }
302*b4315306SDan Handley 
303*b4315306SDan Handley /* Return an IO device handle and specification which can be used to access
304*b4315306SDan Handley  * an image. Use this to enforce platform load policy */
305*b4315306SDan Handley int plat_get_image_source(const char *image_name, uintptr_t *dev_handle,
306*b4315306SDan Handley 			  uintptr_t *image_spec)
307*b4315306SDan Handley {
308*b4315306SDan Handley 	int result = IO_FAIL;
309*b4315306SDan Handley 	const struct plat_io_policy *policy;
310*b4315306SDan Handley 
311*b4315306SDan Handley 	if ((image_name != NULL) && (dev_handle != NULL) &&
312*b4315306SDan Handley 	    (image_spec != NULL)) {
313*b4315306SDan Handley 		policy = policies;
314*b4315306SDan Handley 		while (policy->image_name != NULL) {
315*b4315306SDan Handley 			if (strcmp(policy->image_name, image_name) == 0) {
316*b4315306SDan Handley 				result = policy->check(policy->image_spec);
317*b4315306SDan Handley 				if (result == IO_SUCCESS) {
318*b4315306SDan Handley 					*image_spec = policy->image_spec;
319*b4315306SDan Handley 					*dev_handle = *(policy->dev_handle);
320*b4315306SDan Handley 					break;
321*b4315306SDan Handley 				}
322*b4315306SDan Handley 				VERBOSE("Trying alternative IO\n");
323*b4315306SDan Handley 				result = plat_arm_get_alt_image_source(
324*b4315306SDan Handley 						policy->image_spec,
325*b4315306SDan Handley 						dev_handle);
326*b4315306SDan Handley 				if (result == IO_SUCCESS) {
327*b4315306SDan Handley 					*image_spec = policy->image_spec;
328*b4315306SDan Handley 					break;
329*b4315306SDan Handley 				}
330*b4315306SDan Handley 			}
331*b4315306SDan Handley 			policy++;
332*b4315306SDan Handley 		}
333*b4315306SDan Handley 	} else {
334*b4315306SDan Handley 		result = IO_FAIL;
335*b4315306SDan Handley 	}
336*b4315306SDan Handley 	return result;
337*b4315306SDan Handley }
338