blob: ee0eb963216923a2be482bd8dd52619869a13a55 [file] [log] [blame]
Yatharth Kochar51f76f62016-09-12 16:10:33 +01001/*
2 * Copyright (c) 2016, 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
31#include <arch.h>
32#include <arch_helpers.h>
33#include <assert.h>
34#include <auth_mod.h>
35#include <bl_common.h>
36#include <debug.h>
37#include <errno.h>
38#include <platform.h>
39#include <platform_def.h>
40#include <stdint.h>
41
42/*
43 * Check for platforms that use obsolete image terminology
44 */
45#ifdef BL30_BASE
46# error "BL30_BASE platform define no longer used - please use SCP_BL2_BASE"
47#endif
48
49/*******************************************************************************
50 * Load the SCP_BL2 image if there's one.
51 * If a platform does not want to attempt to load SCP_BL2 image it must leave
52 * SCP_BL2_BASE undefined.
53 * Return 0 on success or if there's no SCP_BL2 image to load, a negative error
54 * code otherwise.
55 ******************************************************************************/
56static int load_scp_bl2(void)
57{
58 int e = 0;
59#ifdef SCP_BL2_BASE
60 meminfo_t scp_bl2_mem_info;
61 image_info_t scp_bl2_image_info;
62
63 /*
64 * It is up to the platform to specify where SCP_BL2 should be loaded if
65 * it exists. It could create space in the secure sram or point to a
66 * completely different memory.
67 *
68 * The entry point information is not relevant in this case as the AP
69 * won't execute the SCP_BL2 image.
70 */
71 INFO("BL2: Loading SCP_BL2\n");
72 bl2_plat_get_scp_bl2_meminfo(&scp_bl2_mem_info);
73 scp_bl2_image_info.h.version = VERSION_1;
74 e = load_auth_image(&scp_bl2_mem_info,
75 SCP_BL2_IMAGE_ID,
76 SCP_BL2_BASE,
77 &scp_bl2_image_info,
78 NULL);
79
80 if (e == 0) {
81 /* The subsequent handling of SCP_BL2 is platform specific */
82 e = bl2_plat_handle_scp_bl2(&scp_bl2_image_info);
83 if (e) {
84 ERROR("Failure in platform-specific handling of SCP_BL2 image.\n");
85 }
86 }
87#endif /* SCP_BL2_BASE */
88
89 return e;
90}
91
92#ifndef EL3_PAYLOAD_BASE
93/*******************************************************************************
94 * Load the BL31 image.
95 * The bl2_to_bl31_params and bl31_ep_info params will be updated with the
96 * relevant BL31 information.
97 * Return 0 on success, a negative error code otherwise.
98 ******************************************************************************/
99static int load_bl31(bl31_params_t *bl2_to_bl31_params,
100 entry_point_info_t *bl31_ep_info)
101{
102 meminfo_t *bl2_tzram_layout;
103 int e;
104
105 INFO("BL2: Loading BL31\n");
106 assert(bl2_to_bl31_params != NULL);
107 assert(bl31_ep_info != NULL);
108
109 /* Find out how much free trusted ram remains after BL2 load */
110 bl2_tzram_layout = bl2_plat_sec_mem_layout();
111
112 /* Set the X0 parameter to BL31 */
113 bl31_ep_info->args.arg0 = (unsigned long)bl2_to_bl31_params;
114
115 /* Load the BL31 image */
116 e = load_auth_image(bl2_tzram_layout,
117 BL31_IMAGE_ID,
118 BL31_BASE,
119 bl2_to_bl31_params->bl31_image_info,
120 bl31_ep_info);
121
122 if (e == 0) {
123 bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info,
124 bl31_ep_info);
125 }
126
127 return e;
128}
129
130/*******************************************************************************
131 * Load the BL32 image if there's one.
132 * The bl2_to_bl31_params param will be updated with the relevant BL32
133 * information.
134 * If a platform does not want to attempt to load BL32 image it must leave
135 * BL32_BASE undefined.
136 * Return 0 on success or if there's no BL32 image to load, a negative error
137 * code otherwise.
138 ******************************************************************************/
139static int load_bl32(bl31_params_t *bl2_to_bl31_params)
140{
141 int e = 0;
142#ifdef BL32_BASE
143 meminfo_t bl32_mem_info;
144
145 INFO("BL2: Loading BL32\n");
146 assert(bl2_to_bl31_params != NULL);
147
148 /*
149 * It is up to the platform to specify where BL32 should be loaded if
150 * it exists. It could create space in the secure sram or point to a
151 * completely different memory.
152 */
153 bl2_plat_get_bl32_meminfo(&bl32_mem_info);
154 e = load_auth_image(&bl32_mem_info,
155 BL32_IMAGE_ID,
156 BL32_BASE,
157 bl2_to_bl31_params->bl32_image_info,
158 bl2_to_bl31_params->bl32_ep_info);
159
160 if (e == 0) {
161 bl2_plat_set_bl32_ep_info(
162 bl2_to_bl31_params->bl32_image_info,
163 bl2_to_bl31_params->bl32_ep_info);
164 }
165#endif /* BL32_BASE */
166
167 return e;
168}
169
170#ifndef PRELOADED_BL33_BASE
171/*******************************************************************************
172 * Load the BL33 image.
173 * The bl2_to_bl31_params param will be updated with the relevant BL33
174 * information.
175 * Return 0 on success, a negative error code otherwise.
176 ******************************************************************************/
177static int load_bl33(bl31_params_t *bl2_to_bl31_params)
178{
179 meminfo_t bl33_mem_info;
180 int e;
181
182 INFO("BL2: Loading BL33\n");
183 assert(bl2_to_bl31_params != NULL);
184
185 bl2_plat_get_bl33_meminfo(&bl33_mem_info);
186
187 /* Load the BL33 image in non-secure memory provided by the platform */
188 e = load_auth_image(&bl33_mem_info,
189 BL33_IMAGE_ID,
190 plat_get_ns_image_entrypoint(),
191 bl2_to_bl31_params->bl33_image_info,
192 bl2_to_bl31_params->bl33_ep_info);
193
194 if (e == 0) {
195 bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info,
196 bl2_to_bl31_params->bl33_ep_info);
197 }
198
199 return e;
200}
201#endif /* PRELOADED_BL33_BASE */
202
203#endif /* EL3_PAYLOAD_BASE */
204
205/*******************************************************************************
206 * This function loads SCP_BL2/BL3x images and returns the ep_info for
207 * the next executable image.
208 ******************************************************************************/
209entry_point_info_t *bl2_load_images(void)
210{
211 bl31_params_t *bl2_to_bl31_params;
212 entry_point_info_t *bl31_ep_info;
213 int e;
214
215 e = load_scp_bl2();
216 if (e) {
217 ERROR("Failed to load SCP_BL2 (%i)\n", e);
218 plat_error_handler(e);
219 }
220
221 /* Perform platform setup in BL2 after loading SCP_BL2 */
222 bl2_platform_setup();
223
224 /*
225 * Get a pointer to the memory the platform has set aside to pass
226 * information to BL31.
227 */
228 bl2_to_bl31_params = bl2_plat_get_bl31_params();
229 bl31_ep_info = bl2_plat_get_bl31_ep_info();
230
231#ifdef EL3_PAYLOAD_BASE
232 /*
233 * In the case of an EL3 payload, we don't need to load any further
234 * images. Just update the BL31 entrypoint info structure to make BL1
235 * jump to the EL3 payload.
236 * The pointer to the memory the platform has set aside to pass
237 * information to BL31 in the normal boot flow is reused here, even
238 * though only a fraction of the information contained in the
239 * bl31_params_t structure makes sense in the context of EL3 payloads.
240 * This will be refined in the future.
241 */
242 INFO("BL2: Populating the entrypoint info for the EL3 payload\n");
243 bl31_ep_info->pc = EL3_PAYLOAD_BASE;
244 bl31_ep_info->args.arg0 = (unsigned long) bl2_to_bl31_params;
245 bl2_plat_set_bl31_ep_info(NULL, bl31_ep_info);
246#else
247 e = load_bl31(bl2_to_bl31_params, bl31_ep_info);
248 if (e) {
249 ERROR("Failed to load BL31 (%i)\n", e);
250 plat_error_handler(e);
251 }
252
253 e = load_bl32(bl2_to_bl31_params);
254 if (e) {
255 if (e == -EAUTH) {
256 ERROR("Failed to authenticate BL32\n");
257 plat_error_handler(e);
258 } else {
259 WARN("Failed to load BL32 (%i)\n", e);
260 }
261 }
262
263#ifdef PRELOADED_BL33_BASE
264 /*
265 * In this case, don't load the BL33 image as it's already loaded in
266 * memory. Update BL33 entrypoint information.
267 */
268 INFO("BL2: Populating the entrypoint info for the preloaded BL33\n");
269 bl2_to_bl31_params->bl33_ep_info->pc = PRELOADED_BL33_BASE;
270 bl2_plat_set_bl33_ep_info(NULL, bl2_to_bl31_params->bl33_ep_info);
271#else
272 e = load_bl33(bl2_to_bl31_params);
273 if (e) {
274 ERROR("Failed to load BL33 (%i)\n", e);
275 plat_error_handler(e);
276 }
277#endif /* PRELOADED_BL33_BASE */
278
279#endif /* EL3_PAYLOAD_BASE */
280
281 /* Flush the params to be passed to memory */
282 bl2_plat_flush_bl31_params();
283
284 return bl31_ep_info;
285}