Home | History | Annotate | Download | only in qemu
      1 /*
      2  * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 #include <arch_helpers.h>
      7 #include <assert.h>
      8 #include <bl_common.h>
      9 #include <console.h>
     10 #include <debug.h>
     11 #include <desc_image_load.h>
     12 #ifdef SPD_opteed
     13 #include <optee_utils.h>
     14 #endif
     15 #include <libfdt.h>
     16 #include <platform_def.h>
     17 #include <string.h>
     18 #include <utils.h>
     19 #include "qemu_private.h"
     20 
     21 /*
     22  * The next 2 constants identify the extents of the code & RO data region.
     23  * These addresses are used by the MMU setup code and therefore they must be
     24  * page-aligned.  It is the responsibility of the linker script to ensure that
     25  * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
     26  */
     27 #define BL2_RO_BASE (unsigned long)(&__RO_START__)
     28 #define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
     29 
     30 /* Data structure which holds the extents of the trusted SRAM for BL2 */
     31 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
     32 
     33 #if !LOAD_IMAGE_V2
     34 /*******************************************************************************
     35  * This structure represents the superset of information that is passed to
     36  * BL3-1, e.g. while passing control to it from BL2, bl31_params
     37  * and other platform specific params
     38  ******************************************************************************/
     39 typedef struct bl2_to_bl31_params_mem {
     40 	bl31_params_t bl31_params;
     41 	image_info_t bl31_image_info;
     42 	image_info_t bl32_image_info;
     43 	image_info_t bl33_image_info;
     44 	entry_point_info_t bl33_ep_info;
     45 	entry_point_info_t bl32_ep_info;
     46 	entry_point_info_t bl31_ep_info;
     47 } bl2_to_bl31_params_mem_t;
     48 
     49 
     50 static bl2_to_bl31_params_mem_t bl31_params_mem;
     51 
     52 
     53 meminfo_t *bl2_plat_sec_mem_layout(void)
     54 {
     55 	return &bl2_tzram_layout;
     56 }
     57 
     58 /*******************************************************************************
     59  * This function assigns a pointer to the memory that the platform has kept
     60  * aside to pass platform specific and trusted firmware related information
     61  * to BL31. This memory is allocated by allocating memory to
     62  * bl2_to_bl31_params_mem_t structure which is a superset of all the
     63  * structure whose information is passed to BL31
     64  * NOTE: This function should be called only once and should be done
     65  * before generating params to BL31
     66  ******************************************************************************/
     67 bl31_params_t *bl2_plat_get_bl31_params(void)
     68 {
     69 	bl31_params_t *bl2_to_bl31_params;
     70 
     71 	/*
     72 	 * Initialise the memory for all the arguments that needs to
     73 	 * be passed to BL3-1
     74 	 */
     75 	zeromem(&bl31_params_mem, sizeof(bl2_to_bl31_params_mem_t));
     76 
     77 	/* Assign memory for TF related information */
     78 	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
     79 	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
     80 
     81 	/* Fill BL3-1 related information */
     82 	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
     83 	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
     84 		VERSION_1, 0);
     85 
     86 	/* Fill BL3-2 related information */
     87 	bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
     88 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
     89 		VERSION_1, 0);
     90 	bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
     91 	SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
     92 		VERSION_1, 0);
     93 
     94 	/* Fill BL3-3 related information */
     95 	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
     96 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
     97 		PARAM_EP, VERSION_1, 0);
     98 
     99 	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
    100 	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
    101 
    102 	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
    103 	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
    104 		VERSION_1, 0);
    105 
    106 	return bl2_to_bl31_params;
    107 }
    108 
    109 /* Flush the TF params and the TF plat params */
    110 void bl2_plat_flush_bl31_params(void)
    111 {
    112 	flush_dcache_range((unsigned long)&bl31_params_mem,
    113 			sizeof(bl2_to_bl31_params_mem_t));
    114 }
    115 
    116 /*******************************************************************************
    117  * This function returns a pointer to the shared memory that the platform
    118  * has kept to point to entry point information of BL31 to BL2
    119  ******************************************************************************/
    120 struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
    121 {
    122 #if DEBUG
    123 	bl31_params_mem.bl31_ep_info.args.arg1 = QEMU_BL31_PLAT_PARAM_VAL;
    124 #endif
    125 
    126 	return &bl31_params_mem.bl31_ep_info;
    127 }
    128 #endif /* !LOAD_IMAGE_V2 */
    129 
    130 
    131 
    132 void bl2_early_platform_setup(meminfo_t *mem_layout)
    133 {
    134 	/* Initialize the console to provide early debug support */
    135 	console_init(PLAT_QEMU_BOOT_UART_BASE, PLAT_QEMU_BOOT_UART_CLK_IN_HZ,
    136 			PLAT_QEMU_CONSOLE_BAUDRATE);
    137 
    138 	/* Setup the BL2 memory layout */
    139 	bl2_tzram_layout = *mem_layout;
    140 
    141 	plat_qemu_io_setup();
    142 }
    143 
    144 static void security_setup(void)
    145 {
    146 	/*
    147 	 * This is where a TrustZone address space controller and other
    148 	 * security related peripherals, would be configured.
    149 	 */
    150 }
    151 
    152 static void update_dt(void)
    153 {
    154 	int ret;
    155 	void *fdt = (void *)(uintptr_t)PLAT_QEMU_DT_BASE;
    156 
    157 	ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE);
    158 	if (ret < 0) {
    159 		ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret);
    160 		return;
    161 	}
    162 
    163 	if (dt_add_psci_node(fdt)) {
    164 		ERROR("Failed to add PSCI Device Tree node\n");
    165 		return;
    166 	}
    167 
    168 	if (dt_add_psci_cpu_enable_methods(fdt)) {
    169 		ERROR("Failed to add PSCI cpu enable methods in Device Tree\n");
    170 		return;
    171 	}
    172 
    173 	ret = fdt_pack(fdt);
    174 	if (ret < 0)
    175 		ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
    176 }
    177 
    178 void bl2_platform_setup(void)
    179 {
    180 	security_setup();
    181 	update_dt();
    182 
    183 	/* TODO Initialize timer */
    184 }
    185 
    186 void bl2_plat_arch_setup(void)
    187 {
    188 	qemu_configure_mmu_el1(bl2_tzram_layout.total_base,
    189 			      bl2_tzram_layout.total_size,
    190 			      BL2_RO_BASE, BL2_RO_LIMIT,
    191 			      BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
    192 }
    193 
    194 /*******************************************************************************
    195  * Gets SPSR for BL32 entry
    196  ******************************************************************************/
    197 static uint32_t qemu_get_spsr_for_bl32_entry(void)
    198 {
    199 	/*
    200 	 * The Secure Payload Dispatcher service is responsible for
    201 	 * setting the SPSR prior to entry into the BL3-2 image.
    202 	 */
    203 	return 0;
    204 }
    205 
    206 /*******************************************************************************
    207  * Gets SPSR for BL33 entry
    208  ******************************************************************************/
    209 static uint32_t qemu_get_spsr_for_bl33_entry(void)
    210 {
    211 	unsigned int mode;
    212 	uint32_t spsr;
    213 
    214 	/* Figure out what mode we enter the non-secure world in */
    215 	mode = EL_IMPLEMENTED(2) ? MODE_EL2 : MODE_EL1;
    216 
    217 	/*
    218 	 * TODO: Consider the possibility of specifying the SPSR in
    219 	 * the FIP ToC and allowing the platform to have a say as
    220 	 * well.
    221 	 */
    222 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
    223 	return spsr;
    224 }
    225 
    226 #if LOAD_IMAGE_V2
    227 static int qemu_bl2_handle_post_image_load(unsigned int image_id)
    228 {
    229 	int err = 0;
    230 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
    231 #ifdef SPD_opteed
    232 	bl_mem_params_node_t *pager_mem_params = NULL;
    233 	bl_mem_params_node_t *paged_mem_params = NULL;
    234 #endif
    235 
    236 	assert(bl_mem_params);
    237 
    238 	switch (image_id) {
    239 # ifdef AARCH64
    240 	case BL32_IMAGE_ID:
    241 #ifdef SPD_opteed
    242 		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
    243 		assert(pager_mem_params);
    244 
    245 		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
    246 		assert(paged_mem_params);
    247 
    248 		err = parse_optee_header(&bl_mem_params->ep_info,
    249 					 &pager_mem_params->image_info,
    250 					 &paged_mem_params->image_info);
    251 		if (err != 0) {
    252 			WARN("OPTEE header parse error.\n");
    253 		}
    254 
    255 		/*
    256 		 * OP-TEE expect to receive DTB address in x2.
    257 		 * This will be copied into x2 by dispatcher.
    258 		 */
    259 		bl_mem_params->ep_info.args.arg3 = PLAT_QEMU_DT_BASE;
    260 #endif
    261 		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl32_entry();
    262 		break;
    263 # endif
    264 	case BL33_IMAGE_ID:
    265 		/* BL33 expects to receive the primary CPU MPID (through r0) */
    266 		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
    267 		bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
    268 		break;
    269 	}
    270 
    271 	return err;
    272 }
    273 
    274 /*******************************************************************************
    275  * This function can be used by the platforms to update/use image
    276  * information for given `image_id`.
    277  ******************************************************************************/
    278 int bl2_plat_handle_post_image_load(unsigned int image_id)
    279 {
    280 	return qemu_bl2_handle_post_image_load(image_id);
    281 }
    282 
    283 #else /* LOAD_IMAGE_V2 */
    284 
    285 /*******************************************************************************
    286  * Before calling this function BL3-1 is loaded in memory and its entrypoint
    287  * is set by load_image. This is a placeholder for the platform to change
    288  * the entrypoint of BL3-1 and set SPSR and security state.
    289  * On ARM standard platforms we only set the security state of the entrypoint
    290  ******************************************************************************/
    291 void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
    292 					entry_point_info_t *bl31_ep_info)
    293 {
    294 	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
    295 	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
    296 					DISABLE_ALL_EXCEPTIONS);
    297 }
    298 
    299 /*******************************************************************************
    300  * Before calling this function BL3-2 is loaded in memory and its entrypoint
    301  * is set by load_image. This is a placeholder for the platform to change
    302  * the entrypoint of BL3-2 and set SPSR and security state.
    303  * On ARM standard platforms we only set the security state of the entrypoint
    304  ******************************************************************************/
    305 void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
    306 					entry_point_info_t *bl32_ep_info)
    307 {
    308 	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
    309 	bl32_ep_info->spsr = qemu_get_spsr_for_bl32_entry();
    310 }
    311 
    312 /*******************************************************************************
    313  * Before calling this function BL3-3 is loaded in memory and its entrypoint
    314  * is set by load_image. This is a placeholder for the platform to change
    315  * the entrypoint of BL3-3 and set SPSR and security state.
    316  * On ARM standard platforms we only set the security state of the entrypoint
    317  ******************************************************************************/
    318 void bl2_plat_set_bl33_ep_info(image_info_t *image,
    319 					entry_point_info_t *bl33_ep_info)
    320 {
    321 
    322 	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
    323 	bl33_ep_info->spsr = qemu_get_spsr_for_bl33_entry();
    324 }
    325 
    326 /*******************************************************************************
    327  * Populate the extents of memory available for loading BL32
    328  ******************************************************************************/
    329 void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
    330 {
    331 	/*
    332 	 * Populate the extents of memory available for loading BL32.
    333 	 */
    334 	bl32_meminfo->total_base = BL32_BASE;
    335 	bl32_meminfo->free_base = BL32_BASE;
    336 	bl32_meminfo->total_size = (BL32_MEM_BASE + BL32_MEM_SIZE) - BL32_BASE;
    337 	bl32_meminfo->free_size = (BL32_MEM_BASE + BL32_MEM_SIZE) - BL32_BASE;
    338 }
    339 
    340 /*******************************************************************************
    341  * Populate the extents of memory available for loading BL33
    342  ******************************************************************************/
    343 void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
    344 {
    345 	bl33_meminfo->total_base = NS_DRAM0_BASE;
    346 	bl33_meminfo->total_size = NS_DRAM0_SIZE;
    347 	bl33_meminfo->free_base = NS_DRAM0_BASE;
    348 	bl33_meminfo->free_size = NS_DRAM0_SIZE;
    349 }
    350 #endif /* !LOAD_IMAGE_V2 */
    351 
    352 unsigned long plat_get_ns_image_entrypoint(void)
    353 {
    354 	return NS_IMAGE_OFFSET;
    355 }
    356