From 23ff9baa7e01eac3a451f2e8ed768c9b90d3567a Mon Sep 17 00:00:00 2001 From: Vikram Kanigiri Date: Tue, 13 May 2014 14:42:08 +0100 Subject: Introduce macros to manipulate the SPSR This patch introduces macros (SPSR_64 and SPSR_32) to create a SPSR for both aarch32 and aarch64 execution states. These macros allow the user to set fields in the SPSR depending upon its format. The make_spsr() function which did not allow manipulation of all the fields in the aarch32 SPSR has been replaced by these new macros. Change-Id: I9425dda0923e8d5f03d03ddb8fa0e28392c4c61e --- common/bl_common.c | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'common/bl_common.c') diff --git a/common/bl_common.c b/common/bl_common.c index 86b0cc5c..037d0ff2 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -122,20 +122,6 @@ void __dead2 change_el(el_change_info_t *info) raise_el(&info->args); } -/* TODO: add a parameter for DAIF. not needed right now */ -unsigned long make_spsr(unsigned long target_el, - unsigned long target_sp, - unsigned long target_rw) -{ - unsigned long spsr; - - /* Disable all exceptions & setup the EL */ - spsr = (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT) - << PSR_DAIF_SHIFT; - spsr |= PSR_MODE(target_rw, target_el, target_sp); - - return spsr; -} /******************************************************************************* * The next two functions are the weak definitions. Platform specific -- cgit From 29fb905d5f36a415a170a4bffeadf13b5f084345 Mon Sep 17 00:00:00 2001 From: Vikram Kanigiri Date: Thu, 15 May 2014 18:27:15 +0100 Subject: Rework handover interface between BL stages This patch reworks the handover interface from: BL1 to BL2 and BL2 to BL3-1. It removes the raise_el(), change_el(), drop_el() and run_image() functions as they catered for code paths that were never exercised. BL1 calls bl1_run_bl2() to jump into BL2 instead of doing the same by calling run_image(). Similarly, BL2 issues the SMC to transfer execution to BL3-1 through BL1 directly. Only x0 and x1 are used to pass arguments to BL31. These arguments and parameters for running BL3-1 are passed through a reference to a 'el_change_info_t' structure. They were being passed value in general purpose registers earlier. Change-Id: Id4fd019a19a9595de063766d4a66295a2c9307e1 --- common/bl_common.c | 90 ------------------------------------------------------ 1 file changed, 90 deletions(-) (limited to 'common/bl_common.c') diff --git a/common/bl_common.c b/common/bl_common.c index 037d0ff2..4144ae50 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -71,57 +71,6 @@ void change_security_state(unsigned int target_security_state) write_scr(scr); } -void __dead2 drop_el(aapcs64_params_t *args, - unsigned long spsr, - unsigned long entrypoint) -{ - write_spsr_el3(spsr); - write_elr_el3(entrypoint); - eret(args->arg0, - args->arg1, - args->arg2, - args->arg3, - args->arg4, - args->arg5, - args->arg6, - args->arg7); -} - -void __dead2 raise_el(aapcs64_params_t *args) -{ - smc(args->arg0, - args->arg1, - args->arg2, - args->arg3, - args->arg4, - args->arg5, - args->arg6, - args->arg7); -} - -/* - * TODO: If we are not EL3 then currently we only issue an SMC. - * Add support for dropping into EL0 etc. Consider adding support - * for switching from S-EL1 to S-EL0/1 etc. - */ -void __dead2 change_el(el_change_info_t *info) -{ - if (IS_IN_EL3()) { - /* - * We can go anywhere from EL3. So find where. - * TODO: Lots to do if we are going non-secure. - * Flip the NS bit. Restore NS registers etc. - * Just doing the bare minimal for now. - */ - - if (info->security_state == NON_SECURE) - change_security_state(info->security_state); - - drop_el(&info->args, info->spsr, info->entrypoint); - } else - raise_el(&info->args); -} - /******************************************************************************* * The next two functions are the weak definitions. Platform specific @@ -521,42 +470,3 @@ exit: fail: image_base = 0; goto exit; } - -/******************************************************************************* - * Run a loaded image from the given entry point. This could result in either - * dropping into a lower exception level or jumping to a higher exception level. - * The only way of doing the latter is through an SMC. In either case, setup the - * parameters for the EL change request correctly. - ******************************************************************************/ -void __dead2 run_image(unsigned long entrypoint, - unsigned long spsr, - unsigned long target_security_state, - void *first_arg, - void *second_arg) -{ - el_change_info_t run_image_info; - - /* Tell next EL what we want done */ - run_image_info.args.arg0 = RUN_IMAGE; - run_image_info.entrypoint = entrypoint; - run_image_info.spsr = spsr; - run_image_info.security_state = target_security_state; - - /* - * If we are EL3 then only an eret can take us to the desired - * exception level. Else for the time being assume that we have - * to jump to a higher EL and issue an SMC. Contents of argY - * will go into the general purpose register xY e.g. arg0->x0 - */ - if (IS_IN_EL3()) { - run_image_info.args.arg1 = (unsigned long) first_arg; - run_image_info.args.arg2 = (unsigned long) second_arg; - } else { - run_image_info.args.arg1 = entrypoint; - run_image_info.args.arg2 = spsr; - run_image_info.args.arg3 = (unsigned long) first_arg; - run_image_info.args.arg4 = (unsigned long) second_arg; - } - - change_el(&run_image_info); -} -- cgit From 4112bfa0c223eda73af1cfe57ca7dc926f767dd8 Mon Sep 17 00:00:00 2001 From: Vikram Kanigiri Date: Tue, 15 Apr 2014 18:08:08 +0100 Subject: Populate BL31 input parameters as per new spec This patch is based on spec published at https://github.com/ARM-software/tf-issues/issues/133 It rearranges the bl31_args struct into bl31_params and bl31_plat_params which provide the information needed for Trusted firmware and platform specific data via x0 and x1 On the FVP platform BL3-1 params and BL3-1 plat params and its constituents are stored at the start of TZDRAM. The information about memory availability and size for BL3-1, BL3-2 and BL3-3 is moved into platform specific data. Change-Id: I8b32057a3d0dd3968ea26c2541a0714177820da9 --- common/bl_common.c | 53 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 21 deletions(-) (limited to 'common/bl_common.c') diff --git a/common/bl_common.c b/common/bl_common.c index 4144ae50..a2fa2d6b 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -35,6 +35,7 @@ #include #include #include +#include #include unsigned long page_align(unsigned long value, unsigned dir) @@ -229,12 +230,15 @@ unsigned long image_size(const char *image_name) * Generic function to load an image into the trusted RAM, * given a name, extents of free memory & whether the image should be loaded at * the bottom or top of the free memory. It updates the memory layout if the - * load is successful. + * load is successful. It also updates the image information and the entry point + * information in the params passed ******************************************************************************/ -unsigned long load_image(meminfo_t *mem_layout, +int load_image(meminfo_t *mem_layout, const char *image_name, unsigned int load_type, - unsigned long fixed_addr) + unsigned long fixed_addr, + image_info_t *image_data, + entry_point_info_t *entry_point_info) { uintptr_t dev_handle; uintptr_t image_handle; @@ -248,13 +252,14 @@ unsigned long load_image(meminfo_t *mem_layout, assert(mem_layout != NULL); assert(image_name != NULL); + assert(image_data->h.version >= VERSION_1); /* Obtain a reference to the image by querying the platform layer */ io_result = plat_get_image_source(image_name, &dev_handle, &image_spec); if (io_result != IO_SUCCESS) { WARN("Failed to obtain reference to image '%s' (%i)\n", image_name, io_result); - return 0; + return io_result; } /* Attempt to access the image */ @@ -262,7 +267,7 @@ unsigned long load_image(meminfo_t *mem_layout, if (io_result != IO_SUCCESS) { WARN("Failed to access image '%s' (%i)\n", image_name, io_result); - return 0; + return io_result; } /* Find the size of the image */ @@ -270,7 +275,7 @@ unsigned long load_image(meminfo_t *mem_layout, if ((io_result != IO_SUCCESS) || (image_size == 0)) { WARN("Failed to determine the size of the image '%s' file (%i)\n", image_name, io_result); - goto fail; + goto exit; } /* See if we have enough space */ @@ -278,7 +283,7 @@ unsigned long load_image(meminfo_t *mem_layout, WARN("Cannot load '%s' file: Not enough space.\n", image_name); dump_load_info(0, image_size, mem_layout); - goto fail; + goto exit; } switch (load_type) { @@ -297,7 +302,8 @@ unsigned long load_image(meminfo_t *mem_layout, WARN("Cannot load '%s' file: Not enough space.\n", image_name); dump_load_info(image_base, image_size, mem_layout); - goto fail; + io_result = -ENOMEM; + goto exit; } /* Calculate the amount of extra memory used due to alignment */ @@ -315,10 +321,11 @@ unsigned long load_image(meminfo_t *mem_layout, /* Page align base address and check whether the image still fits */ if (image_base + image_size > mem_layout->free_base + mem_layout->free_size) { - WARN("Cannot load '%s' file: Not enough space.\n", - image_name); - dump_load_info(image_base, image_size, mem_layout); - goto fail; + WARN("Cannot load '%s' file: Not enough space.\n", + image_name); + dump_load_info(image_base, image_size, mem_layout); + io_result = -ENOMEM; + goto exit; } /* Calculate the amount of extra memory used due to alignment */ @@ -383,14 +390,16 @@ unsigned long load_image(meminfo_t *mem_layout, WARN("Cannot load '%s' file: Not enough space.\n", image_name); dump_load_info(image_base, image_size, mem_layout); - goto fail; + io_result = -ENOMEM; + goto exit; } /* Check whether the fixed load address is page-aligned. */ if (!is_page_aligned(image_base)) { WARN("Cannot load '%s' file at unaligned address 0x%lx\n", image_name, fixed_addr); - goto fail; + io_result = -ENOMEM; + goto exit; } /* @@ -440,9 +449,14 @@ unsigned long load_image(meminfo_t *mem_layout, io_result = io_read(image_handle, image_base, image_size, &bytes_read); if ((io_result != IO_SUCCESS) || (bytes_read < image_size)) { WARN("Failed to load '%s' file (%i)\n", image_name, io_result); - goto fail; + goto exit; } + image_data->image_base = image_base; + image_data->image_size = image_size; + + entry_point_info->pc = image_base; + /* * File has been successfully loaded. Update the free memory * data structure & flush the contents of the TZRAM so that @@ -458,15 +472,12 @@ unsigned long load_image(meminfo_t *mem_layout, mem_layout->free_base += offset + image_size; exit: - io_result = io_close(image_handle); + io_close(image_handle); /* Ignore improbable/unrecoverable error in 'close' */ /* TODO: Consider maintaining open device connection from this bootloader stage */ - io_result = io_dev_close(dev_handle); + io_dev_close(dev_handle); /* Ignore improbable/unrecoverable error in 'dev_close' */ - return image_base; - -fail: image_base = 0; - goto exit; + return io_result; } -- cgit From 6871c5d3a227cb95008a25e90e358ec0ac615222 Mon Sep 17 00:00:00 2001 From: Vikram Kanigiri Date: Fri, 16 May 2014 18:48:12 +0100 Subject: Rework memory information passing to BL3-x images The issues addressed in this patch are: 1. Remove meminfo_t from the common interfaces in BL3-x, expecting that platform code will find a suitable mechanism to determine the memory extents in these images and provide it to the BL3-x images. 2. Remove meminfo_t and bl31_plat_params_t from all FVP BL3-x code as the images use link-time information to determine memory extents. meminfo_t is still used by common interface in BL1/BL2 for loading images Change-Id: I4e825ebf6f515b59d84dc2bdddf6edbf15e2d60f --- common/bl_common.c | 61 ++---------------------------------------------------- 1 file changed, 2 insertions(+), 59 deletions(-) (limited to 'common/bl_common.c') diff --git a/common/bl_common.c b/common/bl_common.c index a2fa2d6b..911ad4c1 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -74,67 +74,10 @@ void change_security_state(unsigned int target_security_state) /******************************************************************************* - * The next two functions are the weak definitions. Platform specific - * code can override them if it wishes to. + * The next function is a weak definition. Platform specific + * code can override it if it wishes to. ******************************************************************************/ -/******************************************************************************* - * Function that takes a memory layout into which BL31 has been either top or - * bottom loaded. Using this information, it populates bl31_mem_layout to tell - * BL31 how much memory it has access to and how much is available for use. It - * does not need the address where BL31 has been loaded as BL31 will reclaim - * all the memory used by BL2. - * TODO: Revisit if this and init_bl2_mem_layout can be replaced by a single - * routine. - ******************************************************************************/ -void init_bl31_mem_layout(const meminfo_t *bl2_mem_layout, - meminfo_t *bl31_mem_layout, - unsigned int load_type) -{ - if (load_type == BOT_LOAD) { - /* - * ------------ ^ - * | BL2 | | - * |----------| ^ | BL2 - * | | | BL2 free | total - * | | | size | size - * |----------| BL2 free base v | - * | BL31 | | - * ------------ BL2 total base v - */ - unsigned long bl31_size; - - bl31_mem_layout->free_base = bl2_mem_layout->free_base; - - bl31_size = bl2_mem_layout->free_base - bl2_mem_layout->total_base; - bl31_mem_layout->free_size = bl2_mem_layout->total_size - bl31_size; - } else { - /* - * ------------ ^ - * | BL31 | | - * |----------| ^ | BL2 - * | | | BL2 free | total - * | | | size | size - * |----------| BL2 free base v | - * | BL2 | | - * ------------ BL2 total base v - */ - unsigned long bl2_size; - - bl31_mem_layout->free_base = bl2_mem_layout->total_base; - - bl2_size = bl2_mem_layout->free_base - bl2_mem_layout->total_base; - bl31_mem_layout->free_size = bl2_mem_layout->free_size + bl2_size; - } - - bl31_mem_layout->total_base = bl2_mem_layout->total_base; - bl31_mem_layout->total_size = bl2_mem_layout->total_size; - bl31_mem_layout->attr = load_type; - - flush_dcache_range((unsigned long) bl31_mem_layout, sizeof(meminfo_t)); - return; -} - /******************************************************************************* * Function that takes a memory layout into which BL2 has been either top or * bottom loaded along with the address where BL2 has been loaded in it. Using -- cgit