blob: 997c85d7adc16afb3a053f23509a85cea5949a59 [file] [log] [blame]
Jens Wiklander52c798e2015-12-07 14:37:10 +01001/*
Douglas Raillarda8954fc2017-01-26 15:54:44 +00002 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
Jens Wiklander52c798e2015-12-07 14:37:10 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Jens Wiklander52c798e2015-12-07 14:37:10 +01005 */
6#include <arch_helpers.h>
Fu Weic2f78442017-05-27 21:21:42 +08007#include <assert.h>
Jens Wiklander52c798e2015-12-07 14:37:10 +01008#include <bl_common.h>
Jens Wiklander52c798e2015-12-07 14:37:10 +01009#include <debug.h>
Fu Weic2f78442017-05-27 21:21:42 +080010#include <desc_image_load.h>
Jens Wiklander0acbaaa2017-08-24 13:16:26 +020011#include <optee_utils.h>
Jens Wiklander52c798e2015-12-07 14:37:10 +010012#include <libfdt.h>
Etienne Carriere911de8c2018-02-02 13:23:22 +010013#include <platform.h>
Jens Wiklander52c798e2015-12-07 14:37:10 +010014#include <platform_def.h>
Jens Wiklander52c798e2015-12-07 14:37:10 +010015#include <string.h>
Douglas Raillarda8954fc2017-01-26 15:54:44 +000016#include <utils.h>
Isla Mitchelle3631462017-07-14 10:46:32 +010017#include "qemu_private.h"
Jens Wiklander52c798e2015-12-07 14:37:10 +010018
Jens Wiklander52c798e2015-12-07 14:37:10 +010019
Fu Weic2f78442017-05-27 21:21:42 +080020/* Data structure which holds the extents of the trusted SRAM for BL2 */
21static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
22
23#if !LOAD_IMAGE_V2
Jens Wiklander52c798e2015-12-07 14:37:10 +010024/*******************************************************************************
25 * This structure represents the superset of information that is passed to
26 * BL3-1, e.g. while passing control to it from BL2, bl31_params
27 * and other platform specific params
28 ******************************************************************************/
29typedef struct bl2_to_bl31_params_mem {
30 bl31_params_t bl31_params;
31 image_info_t bl31_image_info;
32 image_info_t bl32_image_info;
33 image_info_t bl33_image_info;
34 entry_point_info_t bl33_ep_info;
35 entry_point_info_t bl32_ep_info;
36 entry_point_info_t bl31_ep_info;
37} bl2_to_bl31_params_mem_t;
38
39
40static bl2_to_bl31_params_mem_t bl31_params_mem;
41
Jens Wiklander52c798e2015-12-07 14:37:10 +010042
43meminfo_t *bl2_plat_sec_mem_layout(void)
44{
45 return &bl2_tzram_layout;
46}
47
48/*******************************************************************************
49 * This function assigns a pointer to the memory that the platform has kept
50 * aside to pass platform specific and trusted firmware related information
51 * to BL31. This memory is allocated by allocating memory to
52 * bl2_to_bl31_params_mem_t structure which is a superset of all the
53 * structure whose information is passed to BL31
54 * NOTE: This function should be called only once and should be done
55 * before generating params to BL31
56 ******************************************************************************/
57bl31_params_t *bl2_plat_get_bl31_params(void)
58{
59 bl31_params_t *bl2_to_bl31_params;
60
61 /*
62 * Initialise the memory for all the arguments that needs to
63 * be passed to BL3-1
64 */
Douglas Raillarda8954fc2017-01-26 15:54:44 +000065 zeromem(&bl31_params_mem, sizeof(bl2_to_bl31_params_mem_t));
Jens Wiklander52c798e2015-12-07 14:37:10 +010066
67 /* Assign memory for TF related information */
68 bl2_to_bl31_params = &bl31_params_mem.bl31_params;
69 SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
70
71 /* Fill BL3-1 related information */
72 bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
73 SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
74 VERSION_1, 0);
75
76 /* Fill BL3-2 related information */
77 bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
78 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
79 VERSION_1, 0);
80 bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
81 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
82 VERSION_1, 0);
83
84 /* Fill BL3-3 related information */
85 bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
86 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
87 PARAM_EP, VERSION_1, 0);
88
89 /* BL3-3 expects to receive the primary CPU MPID (through x0) */
90 bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
91
92 bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
93 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
94 VERSION_1, 0);
95
96 return bl2_to_bl31_params;
97}
98
99/* Flush the TF params and the TF plat params */
100void bl2_plat_flush_bl31_params(void)
101{
102 flush_dcache_range((unsigned long)&bl31_params_mem,
103 sizeof(bl2_to_bl31_params_mem_t));
104}
105
106/*******************************************************************************
107 * This function returns a pointer to the shared memory that the platform
108 * has kept to point to entry point information of BL31 to BL2
109 ******************************************************************************/
110struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
111{
112#if DEBUG
113 bl31_params_mem.bl31_ep_info.args.arg1 = QEMU_BL31_PLAT_PARAM_VAL;
114#endif
115
116 return &bl31_params_mem.bl31_ep_info;
117}
Fu Weic2f78442017-05-27 21:21:42 +0800118#endif /* !LOAD_IMAGE_V2 */
Jens Wiklander52c798e2015-12-07 14:37:10 +0100119
120
121
122void bl2_early_platform_setup(meminfo_t *mem_layout)
123{
124 /* Initialize the console to provide early debug support */
Michalis Pappascca6cb72018-03-04 15:43:38 +0800125 qemu_console_init();
Jens Wiklander52c798e2015-12-07 14:37:10 +0100126
127 /* Setup the BL2 memory layout */
128 bl2_tzram_layout = *mem_layout;
129
130 plat_qemu_io_setup();
131}
132
133static void security_setup(void)
134{
135 /*
136 * This is where a TrustZone address space controller and other
137 * security related peripherals, would be configured.
138 */
139}
140
141static void update_dt(void)
142{
143 int ret;
144 void *fdt = (void *)(uintptr_t)PLAT_QEMU_DT_BASE;
145
146 ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE);
147 if (ret < 0) {
148 ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret);
149 return;
150 }
151
152 if (dt_add_psci_node(fdt)) {
153 ERROR("Failed to add PSCI Device Tree node\n");
154 return;
155 }
156
157 if (dt_add_psci_cpu_enable_methods(fdt)) {
158 ERROR("Failed to add PSCI cpu enable methods in Device Tree\n");
159 return;
160 }
161
162 ret = fdt_pack(fdt);
163 if (ret < 0)
164 ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
165}
166
167void bl2_platform_setup(void)
168{
169 security_setup();
170 update_dt();
171
172 /* TODO Initialize timer */
173}
174
Etienne Carriere911de8c2018-02-02 13:23:22 +0100175#ifdef AARCH32
176#define QEMU_CONFIGURE_BL2_MMU(...) qemu_configure_mmu_secure(__VA_ARGS__)
177#else
178#define QEMU_CONFIGURE_BL2_MMU(...) qemu_configure_mmu_el1(__VA_ARGS__)
179#endif
180
Jens Wiklander52c798e2015-12-07 14:37:10 +0100181void bl2_plat_arch_setup(void)
182{
Etienne Carriere911de8c2018-02-02 13:23:22 +0100183 QEMU_CONFIGURE_BL2_MMU(bl2_tzram_layout.total_base,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100184 bl2_tzram_layout.total_size,
Michalis Pappasba861122018-02-28 14:36:03 +0800185 BL_CODE_BASE, BL_CODE_END,
186 BL_RO_DATA_BASE, BL_RO_DATA_END,
Masahiro Yamada0fac5af2016-12-28 16:11:41 +0900187 BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
Jens Wiklander52c798e2015-12-07 14:37:10 +0100188}
189
190/*******************************************************************************
191 * Gets SPSR for BL32 entry
192 ******************************************************************************/
193static uint32_t qemu_get_spsr_for_bl32_entry(void)
194{
Etienne Carriere911de8c2018-02-02 13:23:22 +0100195#ifdef AARCH64
Jens Wiklander52c798e2015-12-07 14:37:10 +0100196 /*
197 * The Secure Payload Dispatcher service is responsible for
198 * setting the SPSR prior to entry into the BL3-2 image.
199 */
200 return 0;
Etienne Carriere911de8c2018-02-02 13:23:22 +0100201#else
202 return SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE,
203 DISABLE_ALL_EXCEPTIONS);
204#endif
Jens Wiklander52c798e2015-12-07 14:37:10 +0100205}
206
207/*******************************************************************************
208 * Gets SPSR for BL33 entry
209 ******************************************************************************/
210static uint32_t qemu_get_spsr_for_bl33_entry(void)
211{
Jens Wiklander52c798e2015-12-07 14:37:10 +0100212 uint32_t spsr;
Etienne Carriere911de8c2018-02-02 13:23:22 +0100213#ifdef AARCH64
214 unsigned int mode;
Jens Wiklander52c798e2015-12-07 14:37:10 +0100215
216 /* Figure out what mode we enter the non-secure world in */
Jeenu Viswambharan2a9b8822017-02-21 14:40:44 +0000217 mode = EL_IMPLEMENTED(2) ? MODE_EL2 : MODE_EL1;
Jens Wiklander52c798e2015-12-07 14:37:10 +0100218
219 /*
220 * TODO: Consider the possibility of specifying the SPSR in
221 * the FIP ToC and allowing the platform to have a say as
222 * well.
223 */
224 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
Etienne Carriere911de8c2018-02-02 13:23:22 +0100225#else
226 spsr = SPSR_MODE32(MODE32_svc,
227 plat_get_ns_image_entrypoint() & 0x1,
228 SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
229#endif
Jens Wiklander52c798e2015-12-07 14:37:10 +0100230 return spsr;
231}
232
Fu Weic2f78442017-05-27 21:21:42 +0800233#if LOAD_IMAGE_V2
234static int qemu_bl2_handle_post_image_load(unsigned int image_id)
235{
236 int err = 0;
237 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
Etienne Carriere911de8c2018-02-02 13:23:22 +0100238#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE)
Jens Wiklander0acbaaa2017-08-24 13:16:26 +0200239 bl_mem_params_node_t *pager_mem_params = NULL;
240 bl_mem_params_node_t *paged_mem_params = NULL;
241#endif
Fu Weic2f78442017-05-27 21:21:42 +0800242
243 assert(bl_mem_params);
244
245 switch (image_id) {
Fu Weic2f78442017-05-27 21:21:42 +0800246 case BL32_IMAGE_ID:
Etienne Carriere911de8c2018-02-02 13:23:22 +0100247#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE)
Jens Wiklander0acbaaa2017-08-24 13:16:26 +0200248 pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
249 assert(pager_mem_params);
250
251 paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
252 assert(paged_mem_params);
253
254 err = parse_optee_header(&bl_mem_params->ep_info,
255 &pager_mem_params->image_info,
256 &paged_mem_params->image_info);
257 if (err != 0) {
258 WARN("OPTEE header parse error.\n");
259 }
260
Etienne Carriere911de8c2018-02-02 13:23:22 +0100261#if defined(SPD_opteed)
Jens Wiklander0acbaaa2017-08-24 13:16:26 +0200262 /*
263 * OP-TEE expect to receive DTB address in x2.
264 * This will be copied into x2 by dispatcher.
265 */
266 bl_mem_params->ep_info.args.arg3 = PLAT_QEMU_DT_BASE;
Etienne Carriere911de8c2018-02-02 13:23:22 +0100267#else /* case AARCH32_SP_OPTEE */
268 bl_mem_params->ep_info.args.arg0 =
269 bl_mem_params->ep_info.args.arg1;
270 bl_mem_params->ep_info.args.arg1 = 0;
271 bl_mem_params->ep_info.args.arg2 = PLAT_QEMU_DT_BASE;
272 bl_mem_params->ep_info.args.arg3 = 0;
273#endif
Jens Wiklander0acbaaa2017-08-24 13:16:26 +0200274#endif
Fu Weic2f78442017-05-27 21:21:42 +0800275 bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
276 break;
Etienne Carriere911de8c2018-02-02 13:23:22 +0100277
Fu Weic2f78442017-05-27 21:21:42 +0800278 case BL33_IMAGE_ID:
Etienne Carriere911de8c2018-02-02 13:23:22 +0100279#ifdef AARCH32_SP_OPTEE
280 /* AArch32 only core: OP-TEE expects NSec EP in register LR */
281 pager_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
282 assert(pager_mem_params);
283 pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
284#endif
285
Fu Weic2f78442017-05-27 21:21:42 +0800286 /* BL33 expects to receive the primary CPU MPID (through r0) */
287 bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
288 bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
289 break;
Jonathan Wrightff957ed2018-03-14 15:24:00 +0000290 default:
291 /* Do nothing in default case */
292 break;
Fu Weic2f78442017-05-27 21:21:42 +0800293 }
294
295 return err;
296}
297
298/*******************************************************************************
299 * This function can be used by the platforms to update/use image
300 * information for given `image_id`.
301 ******************************************************************************/
302int bl2_plat_handle_post_image_load(unsigned int image_id)
303{
304 return qemu_bl2_handle_post_image_load(image_id);
305}
306
307#else /* LOAD_IMAGE_V2 */
308
Jens Wiklander52c798e2015-12-07 14:37:10 +0100309/*******************************************************************************
310 * Before calling this function BL3-1 is loaded in memory and its entrypoint
311 * is set by load_image. This is a placeholder for the platform to change
312 * the entrypoint of BL3-1 and set SPSR and security state.
313 * On ARM standard platforms we only set the security state of the entrypoint
314 ******************************************************************************/
315void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
316 entry_point_info_t *bl31_ep_info)
317{
318 SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
319 bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
320 DISABLE_ALL_EXCEPTIONS);
321}
322
323/*******************************************************************************
324 * Before calling this function BL3-2 is loaded in memory and its entrypoint
325 * is set by load_image. This is a placeholder for the platform to change
326 * the entrypoint of BL3-2 and set SPSR and security state.
327 * On ARM standard platforms we only set the security state of the entrypoint
328 ******************************************************************************/
329void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
330 entry_point_info_t *bl32_ep_info)
331{
332 SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
333 bl32_ep_info->spsr = qemu_get_spsr_for_bl32_entry();
334}
335
336/*******************************************************************************
337 * Before calling this function BL3-3 is loaded in memory and its entrypoint
338 * is set by load_image. This is a placeholder for the platform to change
339 * the entrypoint of BL3-3 and set SPSR and security state.
340 * On ARM standard platforms we only set the security state of the entrypoint
341 ******************************************************************************/
342void bl2_plat_set_bl33_ep_info(image_info_t *image,
343 entry_point_info_t *bl33_ep_info)
344{
345
346 SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
347 bl33_ep_info->spsr = qemu_get_spsr_for_bl33_entry();
348}
349
350/*******************************************************************************
351 * Populate the extents of memory available for loading BL32
352 ******************************************************************************/
353void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
354{
355 /*
356 * Populate the extents of memory available for loading BL32.
357 */
358 bl32_meminfo->total_base = BL32_BASE;
359 bl32_meminfo->free_base = BL32_BASE;
360 bl32_meminfo->total_size = (BL32_MEM_BASE + BL32_MEM_SIZE) - BL32_BASE;
361 bl32_meminfo->free_size = (BL32_MEM_BASE + BL32_MEM_SIZE) - BL32_BASE;
362}
363
364/*******************************************************************************
365 * Populate the extents of memory available for loading BL33
366 ******************************************************************************/
367void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
368{
369 bl33_meminfo->total_base = NS_DRAM0_BASE;
370 bl33_meminfo->total_size = NS_DRAM0_SIZE;
371 bl33_meminfo->free_base = NS_DRAM0_BASE;
372 bl33_meminfo->free_size = NS_DRAM0_SIZE;
373}
Fu Weic2f78442017-05-27 21:21:42 +0800374#endif /* !LOAD_IMAGE_V2 */
Jens Wiklander52c798e2015-12-07 14:37:10 +0100375
Etienne Carriere911de8c2018-02-02 13:23:22 +0100376uintptr_t plat_get_ns_image_entrypoint(void)
Jens Wiklander52c798e2015-12-07 14:37:10 +0100377{
378 return NS_IMAGE_OFFSET;
379}