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