blob: ea293131a1136fd44ad08dbcfb370a3fc9a61930 [file] [log] [blame]
Dan Handley9df48042015-03-19 18:58:55 +00001/*
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 */
41static const io_dev_connector_t *fip_dev_con;
42static uintptr_t fip_dev_handle;
43static const io_dev_connector_t *memmap_dev_con;
44static uintptr_t memmap_dev_handle;
45
46static const io_block_spec_t fip_block_spec = {
47 .offset = PLAT_ARM_FIP_BASE,
48 .length = PLAT_ARM_FIP_MAX_SIZE
49};
50
51static const io_file_spec_t bl2_file_spec = {
52 .path = BL2_IMAGE_NAME,
53 .mode = FOPEN_MODE_RB
54};
55
56static const io_file_spec_t bl30_file_spec = {
57 .path = BL30_IMAGE_NAME,
58 .mode = FOPEN_MODE_RB
59};
60
61static const io_file_spec_t bl31_file_spec = {
62 .path = BL31_IMAGE_NAME,
63 .mode = FOPEN_MODE_RB
64};
65
66static const io_file_spec_t bl32_file_spec = {
67 .path = BL32_IMAGE_NAME,
68 .mode = FOPEN_MODE_RB
69};
70
71static 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
77static const io_file_spec_t bl2_cert_file_spec = {
78 .path = BL2_CERT_NAME,
79 .mode = FOPEN_MODE_RB
80};
81
82static const io_file_spec_t trusted_key_cert_file_spec = {
83 .path = TRUSTED_KEY_CERT_NAME,
84 .mode = FOPEN_MODE_RB
85};
86
87static const io_file_spec_t bl30_key_cert_file_spec = {
88 .path = BL30_KEY_CERT_NAME,
89 .mode = FOPEN_MODE_RB
90};
91
92static const io_file_spec_t bl31_key_cert_file_spec = {
93 .path = BL31_KEY_CERT_NAME,
94 .mode = FOPEN_MODE_RB
95};
96
97static const io_file_spec_t bl32_key_cert_file_spec = {
98 .path = BL32_KEY_CERT_NAME,
99 .mode = FOPEN_MODE_RB
100};
101
102static const io_file_spec_t bl33_key_cert_file_spec = {
103 .path = BL33_KEY_CERT_NAME,
104 .mode = FOPEN_MODE_RB
105};
106
107static const io_file_spec_t bl30_cert_file_spec = {
108 .path = BL30_CERT_NAME,
109 .mode = FOPEN_MODE_RB
110};
111
112static const io_file_spec_t bl31_cert_file_spec = {
113 .path = BL31_CERT_NAME,
114 .mode = FOPEN_MODE_RB
115};
116
117static const io_file_spec_t bl32_cert_file_spec = {
118 .path = BL32_CERT_NAME,
119 .mode = FOPEN_MODE_RB
120};
121
122static 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
128static int open_fip(const uintptr_t spec);
129static int open_memmap(const uintptr_t spec);
130
131struct 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
138static 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
232static 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
250static 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
267void 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
290void plat_arm_io_setup(void)
291{
292 arm_io_setup();
293}
294
295int 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 */
305int 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}