blob: b9a30d88ea72e67922d89f25b7ba37f319f97e6b [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
Jens Wiklandere22b91e2018-09-04 14:07:19 +0200120void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
121 u_register_t arg2, u_register_t arg3)
Jens Wiklander52c798e2015-12-07 14:37:10 +0100122{
Jens Wiklandere22b91e2018-09-04 14:07:19 +0200123 meminfo_t *mem_layout = (void *)arg1;
124
Jens Wiklander52c798e2015-12-07 14:37:10 +0100125 /* Initialize the console to provide early debug support */
Michalis Pappascca6cb72018-03-04 15:43:38 +0800126 qemu_console_init();
Jens Wiklander52c798e2015-12-07 14:37:10 +0100127
128 /* Setup the BL2 memory layout */
129 bl2_tzram_layout = *mem_layout;
130
131 plat_qemu_io_setup();
132}
133
134static void security_setup(void)
135{
136 /*
137 * This is where a TrustZone address space controller and other
138 * security related peripherals, would be configured.
139 */
140}
141
142static void update_dt(void)
143{
144 int ret;
145 void *fdt = (void *)(uintptr_t)PLAT_QEMU_DT_BASE;
146
147 ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE);
148 if (ret < 0) {
149 ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret);
150 return;
151 }
152
153 if (dt_add_psci_node(fdt)) {
154 ERROR("Failed to add PSCI Device Tree node\n");
155 return;
156 }
157
158 if (dt_add_psci_cpu_enable_methods(fdt)) {
159 ERROR("Failed to add PSCI cpu enable methods in Device Tree\n");
160 return;
161 }
162
163 ret = fdt_pack(fdt);
164 if (ret < 0)
165 ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
166}
167
168void bl2_platform_setup(void)
169{
170 security_setup();
171 update_dt();
172
173 /* TODO Initialize timer */
174}
175
Etienne Carriere911de8c2018-02-02 13:23:22 +0100176#ifdef AARCH32
177#define QEMU_CONFIGURE_BL2_MMU(...) qemu_configure_mmu_secure(__VA_ARGS__)
178#else
179#define QEMU_CONFIGURE_BL2_MMU(...) qemu_configure_mmu_el1(__VA_ARGS__)
180#endif
181
Jens Wiklander52c798e2015-12-07 14:37:10 +0100182void bl2_plat_arch_setup(void)
183{
Etienne Carriere911de8c2018-02-02 13:23:22 +0100184 QEMU_CONFIGURE_BL2_MMU(bl2_tzram_layout.total_base,
Jens Wiklander52c798e2015-12-07 14:37:10 +0100185 bl2_tzram_layout.total_size,
Michalis Pappasba861122018-02-28 14:36:03 +0800186 BL_CODE_BASE, BL_CODE_END,
187 BL_RO_DATA_BASE, BL_RO_DATA_END,
Masahiro Yamada0fac5af2016-12-28 16:11:41 +0900188 BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
Jens Wiklander52c798e2015-12-07 14:37:10 +0100189}
190
191/*******************************************************************************
192 * Gets SPSR for BL32 entry
193 ******************************************************************************/
194static uint32_t qemu_get_spsr_for_bl32_entry(void)
195{
Etienne Carriere911de8c2018-02-02 13:23:22 +0100196#ifdef AARCH64
Jens Wiklander52c798e2015-12-07 14:37:10 +0100197 /*
198 * The Secure Payload Dispatcher service is responsible for
199 * setting the SPSR prior to entry into the BL3-2 image.
200 */
201 return 0;
Etienne Carriere911de8c2018-02-02 13:23:22 +0100202#else
203 return SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE,
204 DISABLE_ALL_EXCEPTIONS);
205#endif
Jens Wiklander52c798e2015-12-07 14:37:10 +0100206}
207
208/*******************************************************************************
209 * Gets SPSR for BL33 entry
210 ******************************************************************************/
211static uint32_t qemu_get_spsr_for_bl33_entry(void)
212{
Jens Wiklander52c798e2015-12-07 14:37:10 +0100213 uint32_t spsr;
Etienne Carriere911de8c2018-02-02 13:23:22 +0100214#ifdef AARCH64
215 unsigned int mode;
Jens Wiklander52c798e2015-12-07 14:37:10 +0100216
217 /* Figure out what mode we enter the non-secure world in */
Jeenu Viswambharan2a9b8822017-02-21 14:40:44 +0000218 mode = EL_IMPLEMENTED(2) ? MODE_EL2 : MODE_EL1;
Jens Wiklander52c798e2015-12-07 14:37:10 +0100219
220 /*
221 * TODO: Consider the possibility of specifying the SPSR in
222 * the FIP ToC and allowing the platform to have a say as
223 * well.
224 */
225 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
Etienne Carriere911de8c2018-02-02 13:23:22 +0100226#else
227 spsr = SPSR_MODE32(MODE32_svc,
228 plat_get_ns_image_entrypoint() & 0x1,
229 SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
230#endif
Jens Wiklander52c798e2015-12-07 14:37:10 +0100231 return spsr;
232}
233
Fu Weic2f78442017-05-27 21:21:42 +0800234#if LOAD_IMAGE_V2
235static int qemu_bl2_handle_post_image_load(unsigned int image_id)
236{
237 int err = 0;
238 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
Etienne Carriere911de8c2018-02-02 13:23:22 +0100239#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE)
Jens Wiklander0acbaaa2017-08-24 13:16:26 +0200240 bl_mem_params_node_t *pager_mem_params = NULL;
241 bl_mem_params_node_t *paged_mem_params = NULL;
242#endif
Fu Weic2f78442017-05-27 21:21:42 +0800243
244 assert(bl_mem_params);
245
246 switch (image_id) {
Fu Weic2f78442017-05-27 21:21:42 +0800247 case BL32_IMAGE_ID:
Etienne Carriere911de8c2018-02-02 13:23:22 +0100248#if defined(SPD_opteed) || defined(AARCH32_SP_OPTEE)
Jens Wiklander0acbaaa2017-08-24 13:16:26 +0200249 pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
250 assert(pager_mem_params);
251
252 paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
253 assert(paged_mem_params);
254
255 err = parse_optee_header(&bl_mem_params->ep_info,
256 &pager_mem_params->image_info,
257 &paged_mem_params->image_info);
258 if (err != 0) {
259 WARN("OPTEE header parse error.\n");
260 }
261
Etienne Carriere911de8c2018-02-02 13:23:22 +0100262#if defined(SPD_opteed)
Jens Wiklander0acbaaa2017-08-24 13:16:26 +0200263 /*
264 * OP-TEE expect to receive DTB address in x2.
265 * This will be copied into x2 by dispatcher.
266 */
267 bl_mem_params->ep_info.args.arg3 = PLAT_QEMU_DT_BASE;
Etienne Carriere911de8c2018-02-02 13:23:22 +0100268#else /* case AARCH32_SP_OPTEE */
269 bl_mem_params->ep_info.args.arg0 =
270 bl_mem_params->ep_info.args.arg1;
271 bl_mem_params->ep_info.args.arg1 = 0;
272 bl_mem_params->ep_info.args.arg2 = PLAT_QEMU_DT_BASE;
273 bl_mem_params->ep_info.args.arg3 = 0;
274#endif
Jens Wiklander0acbaaa2017-08-24 13:16:26 +0200275#endif
Fu Weic2f78442017-05-27 21:21:42 +0800276 bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
277 break;
Etienne Carriere911de8c2018-02-02 13:23:22 +0100278
Fu Weic2f78442017-05-27 21:21:42 +0800279 case BL33_IMAGE_ID:
Etienne Carriere911de8c2018-02-02 13:23:22 +0100280#ifdef AARCH32_SP_OPTEE
281 /* AArch32 only core: OP-TEE expects NSec EP in register LR */
282 pager_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
283 assert(pager_mem_params);
284 pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
285#endif
286
Fu Weic2f78442017-05-27 21:21:42 +0800287 /* BL33 expects to receive the primary CPU MPID (through r0) */
288 bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
289 bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
290 break;
Jonathan Wrightff957ed2018-03-14 15:24:00 +0000291 default:
292 /* Do nothing in default case */
293 break;
Fu Weic2f78442017-05-27 21:21:42 +0800294 }
295
296 return err;
297}
298
299/*******************************************************************************
300 * This function can be used by the platforms to update/use image
301 * information for given `image_id`.
302 ******************************************************************************/
303int bl2_plat_handle_post_image_load(unsigned int image_id)
304{
305 return qemu_bl2_handle_post_image_load(image_id);
306}
307
308#else /* LOAD_IMAGE_V2 */
309
Jens Wiklander52c798e2015-12-07 14:37:10 +0100310/*******************************************************************************
311 * Before calling this function BL3-1 is loaded in memory and its entrypoint
312 * is set by load_image. This is a placeholder for the platform to change
313 * the entrypoint of BL3-1 and set SPSR and security state.
314 * On ARM standard platforms we only set the security state of the entrypoint
315 ******************************************************************************/
316void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
317 entry_point_info_t *bl31_ep_info)
318{
319 SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
320 bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
321 DISABLE_ALL_EXCEPTIONS);
322}
323
324/*******************************************************************************
325 * Before calling this function BL3-2 is loaded in memory and its entrypoint
326 * is set by load_image. This is a placeholder for the platform to change
327 * the entrypoint of BL3-2 and set SPSR and security state.
328 * On ARM standard platforms we only set the security state of the entrypoint
329 ******************************************************************************/
330void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
331 entry_point_info_t *bl32_ep_info)
332{
333 SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
334 bl32_ep_info->spsr = qemu_get_spsr_for_bl32_entry();
335}
336
337/*******************************************************************************
338 * Before calling this function BL3-3 is loaded in memory and its entrypoint
339 * is set by load_image. This is a placeholder for the platform to change
340 * the entrypoint of BL3-3 and set SPSR and security state.
341 * On ARM standard platforms we only set the security state of the entrypoint
342 ******************************************************************************/
343void bl2_plat_set_bl33_ep_info(image_info_t *image,
344 entry_point_info_t *bl33_ep_info)
345{
346
347 SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
348 bl33_ep_info->spsr = qemu_get_spsr_for_bl33_entry();
349}
350
351/*******************************************************************************
352 * Populate the extents of memory available for loading BL32
353 ******************************************************************************/
354void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
355{
356 /*
357 * Populate the extents of memory available for loading BL32.
358 */
359 bl32_meminfo->total_base = BL32_BASE;
360 bl32_meminfo->free_base = BL32_BASE;
361 bl32_meminfo->total_size = (BL32_MEM_BASE + BL32_MEM_SIZE) - BL32_BASE;
362 bl32_meminfo->free_size = (BL32_MEM_BASE + BL32_MEM_SIZE) - BL32_BASE;
363}
364
365/*******************************************************************************
366 * Populate the extents of memory available for loading BL33
367 ******************************************************************************/
368void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
369{
370 bl33_meminfo->total_base = NS_DRAM0_BASE;
371 bl33_meminfo->total_size = NS_DRAM0_SIZE;
372 bl33_meminfo->free_base = NS_DRAM0_BASE;
373 bl33_meminfo->free_size = NS_DRAM0_SIZE;
374}
Fu Weic2f78442017-05-27 21:21:42 +0800375#endif /* !LOAD_IMAGE_V2 */
Jens Wiklander52c798e2015-12-07 14:37:10 +0100376
Etienne Carriere911de8c2018-02-02 13:23:22 +0100377uintptr_t plat_get_ns_image_entrypoint(void)
Jens Wiklander52c798e2015-12-07 14:37:10 +0100378{
379 return NS_IMAGE_OFFSET;
380}