From: Achin Gupta Date: Wed, 19 Feb 2014 17:18:23 +0000 (+0000) Subject: Rework BL2 to BL3-1 hand over interface X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=e4d084ea9629703166e59d116d4aefbd6f2be531;p=project%2Fbcm63xx%2Fatf.git Rework BL2 to BL3-1 hand over interface This patch reworks BL2 to BL3-1 hand over interface by introducing a composite structure (bl31_args) that holds the superset of information that needs to be passed from BL2 to BL3-1. - The extents of secure memory available to BL3-1 - The extents of memory available to BL3-2 (not yet implemented) and BL3-3 - Information to execute BL3-2 (not yet implemented) and BL3-3 images This patch also introduces a new platform API (bl2_get_bl31_args_ptr) that needs to be implemented by the platform code to export reference to bl31_args structure which has been allocated in platform-defined memory. The platform will initialize the extents of memory available to BL3-3 during early platform setup in bl31_args structure. This obviates the need for bl2_get_ns_mem_layout platform API. BL2 calls the bl2_get_bl31_args_ptr function to get a reference to bl31_args structure. It uses the 'bl33_meminfo' field of this structure to load the BL3-3 image. It sets the entry point information for the BL3-3 image in the 'bl33_image_info' field of this structure. The reference to this structure is passed to the BL3-1 image. Also fixes issue ARM-software/tf-issues#25 Change-Id: Ic36426196dd5ebf89e60ff42643bed01b3500517 --- diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S index ac52e529..7a00a3fb 100644 --- a/bl1/bl1.ld.S +++ b/bl1/bl1.ld.S @@ -116,5 +116,5 @@ SECTIONS __COHERENT_RAM_UNALIGNED_SIZE__ = __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__; - ASSERT(. <= BL31_BASE, "BL31 image overlaps BL1 image.") + ASSERT(. <= BL31_BASE, "BL1 image overlaps BL31 image.") } diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c index 06ab4e59..b3adc251 100644 --- a/bl1/bl1_main.c +++ b/bl1/bl1_main.c @@ -104,7 +104,11 @@ void bl1_main(void) printf("BL2 memory layout address = 0x%llx \n\r", (unsigned long long) bl2_tzram_layout); #endif - run_image(bl2_base, spsr, SECURE, bl2_tzram_layout, 0); + run_image(bl2_base, + spsr, + SECURE, + (void *) bl2_tzram_layout, + NULL); } /* diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index 4745881e..a3e0cdfd 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -48,9 +48,7 @@ void bl2_main(void) { meminfo *bl2_tzram_layout; - meminfo *bl31_tzram_layout; - meminfo *bl33_ns_layout; - el_change_info *ns_image_info; + bl31_args *bl2_to_bl31_args; unsigned long bl31_base, bl33_base, el_status; unsigned int bl2_load, bl31_load, mode; @@ -60,7 +58,7 @@ void bl2_main(void) /* Perform platform setup in BL1 */ bl2_platform_setup(); -#if defined (__GNUC__) +#if defined(__GNUC__) printf("BL2 Built : %s, %s\n\r", __TIME__, __DATE__); #endif @@ -80,19 +78,30 @@ void bl2_main(void) bl31_load, BL31_BASE); /* Assert if it has not been possible to load BL31 */ - assert(bl31_base != 0); + if (bl31_base == 0) { + ERROR("Failed to load BL3-1.\n"); + panic(); + } + + /* + * Get a pointer to the memory the platform has set aside to pass + * information to BL31. + */ + bl2_to_bl31_args = bl2_get_bl31_args_ptr(); /* * Create a new layout of memory for BL31 as seen by BL2. This * will gobble up all the BL2 memory. */ - bl31_tzram_layout = (meminfo *) get_el_change_mem_ptr(); - init_bl31_mem_layout(bl2_tzram_layout, bl31_tzram_layout, bl31_load); - - /* Find out where the BL3-3 normal world firmware should go. */ - bl33_ns_layout = bl2_get_ns_mem_layout(); - bl33_base = load_image(bl33_ns_layout, BL33_IMAGE_NAME, - BOT_LOAD, plat_get_ns_image_entrypoint()); + init_bl31_mem_layout(bl2_tzram_layout, + &bl2_to_bl31_args->bl31_meminfo, + bl31_load); + + /* Load the BL33 image in non-secure memory provided by the platform */ + bl33_base = load_image(&bl2_to_bl31_args->bl33_meminfo, + BL33_IMAGE_NAME, + BOT_LOAD, + plat_get_ns_image_entrypoint()); /* Halt if failed to load normal world firmware. */ if (bl33_base == 0) { ERROR("Failed to load BL3-3.\n"); @@ -101,11 +110,9 @@ void bl2_main(void) /* * BL2 also needs to tell BL31 where the non-trusted software image - * has been loaded. Place this info right after the BL31 memory layout + * is located. */ - ns_image_info = (el_change_info *) ((unsigned char *) bl31_tzram_layout - + sizeof(meminfo)); - ns_image_info->entrypoint = bl33_base; + bl2_to_bl31_args->bl33_image_info.entrypoint = bl33_base; /* Figure out what mode we enter the non-secure world in */ el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT; @@ -116,22 +123,27 @@ void bl2_main(void) else mode = MODE_EL1; - ns_image_info->spsr = make_spsr(mode, MODE_SP_ELX, MODE_RW_64); - ns_image_info->security_state = NON_SECURE; - flush_dcache_range((unsigned long) ns_image_info, - sizeof(el_change_info)); + /* + * TODO: Consider the possibility of specifying the SPSR in + * the FIP ToC and allowing the platform to have a say as + * well. + */ + bl2_to_bl31_args->bl33_image_info.spsr = + make_spsr(mode, MODE_SP_ELX, MODE_RW_64); + bl2_to_bl31_args->bl33_image_info.security_state = NON_SECURE; + + /* Flush the entire BL31 args buffer */ + flush_dcache_range((unsigned long) bl2_to_bl31_args, + sizeof(*bl2_to_bl31_args)); /* * Run BL31 via an SMC to BL1. Information on how to pass control to - * the non-trusted software image will be passed to BL31 in x2. + * the BL32 (if present) and BL33 software images will be passed to + * BL31 as an argument. */ - if (bl31_base) - run_image(bl31_base, - make_spsr(MODE_EL3, MODE_SP_ELX, MODE_RW_64), - SECURE, - bl31_tzram_layout, - (void *) ns_image_info); - - /* There is no valid reason for run_image() to return */ - assert(0); + run_image(bl31_base, + make_spsr(MODE_EL3, MODE_SP_ELX, MODE_RW_64), + SECURE, + (void *) bl2_to_bl31_args, + NULL); } diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S index 1b8488d6..c72b3633 100644 --- a/bl31/aarch64/bl31_entrypoint.S +++ b/bl31/aarch64/bl31_entrypoint.S @@ -47,11 +47,10 @@ bl31_entrypoint: ; .type bl31_entrypoint, %function /* --------------------------------------------- - * BL2 has populated x0,x3,x4 with the opcode - * indicating BL31 should be run, memory layout - * of the trusted SRAM available to BL31 and - * information about running the non-trusted - * software already loaded by BL2. + * BL2 has populated x0 with the opcode + * indicating BL31 should be run, x3 with + * a pointer to a 'bl31_args' structure & x4 + * with any other optional information * --------------------------------------------- */ diff --git a/common/bl_common.c b/common/bl_common.c index 7e17bb85..fb86ac53 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -40,17 +40,6 @@ #include "io_storage.h" #include "debug.h" -/*********************************************************** - * Memory for sharing data while changing exception levels. - * Only used by the primary core. - **********************************************************/ -unsigned char bl2_el_change_mem_ptr[EL_CHANGE_MEM_SIZE]; - -unsigned long *get_el_change_mem_ptr(void) -{ - return (unsigned long *) bl2_el_change_mem_ptr; -} - unsigned long page_align(unsigned long value, unsigned dir) { unsigned long page_size = 1 << FOUR_KB_SHIFT; @@ -85,9 +74,9 @@ void change_security_state(unsigned int target_security_state) write_scr(scr); } -int drop_el(aapcs64_params *args, - unsigned long spsr, - unsigned long entrypoint) +void __dead2 drop_el(aapcs64_params *args, + unsigned long spsr, + unsigned long entrypoint) { write_spsr(spsr); write_elr(entrypoint); @@ -99,19 +88,18 @@ int drop_el(aapcs64_params *args, args->arg5, args->arg6, args->arg7); - return -EINVAL; } -long raise_el(aapcs64_params *args) +void __dead2 raise_el(aapcs64_params *args) { - return smc(args->arg0, - args->arg1, - args->arg2, - args->arg3, - args->arg4, - args->arg5, - args->arg6, - args->arg7); + smc(args->arg0, + args->arg1, + args->arg2, + args->arg3, + args->arg4, + args->arg5, + args->arg6, + args->arg7); } /* @@ -119,7 +107,7 @@ long raise_el(aapcs64_params *args) * Add support for dropping into EL0 etc. Consider adding support * for switching from S-EL1 to S-EL0/1 etc. */ -long change_el(el_change_info *info) +void __dead2 change_el(el_change_info *info) { unsigned long current_el = read_current_el(); @@ -134,9 +122,9 @@ long change_el(el_change_info *info) if (info->security_state == NON_SECURE) change_security_state(info->security_state); - return drop_el(&info->args, info->spsr, info->entrypoint); + drop_el(&info->args, info->spsr, info->entrypoint); } else - return raise_el(&info->args); + raise_el(&info->args); } /* TODO: add a parameter for DAIF. not needed right now */ @@ -515,11 +503,11 @@ fail: image_base = 0; * The only way of doing the latter is through an SMC. In either case, setup the * parameters for the EL change request correctly. ******************************************************************************/ -int run_image(unsigned long entrypoint, - unsigned long spsr, - unsigned long target_security_state, - meminfo *mem_layout, - void *data) +void __dead2 run_image(unsigned long entrypoint, + unsigned long spsr, + unsigned long target_security_state, + void *first_arg, + void *second_arg) { el_change_info run_image_info; unsigned long current_el = read_current_el(); @@ -529,7 +517,6 @@ int run_image(unsigned long entrypoint, run_image_info.entrypoint = entrypoint; run_image_info.spsr = spsr; run_image_info.security_state = target_security_state; - run_image_info.next = 0; /* * If we are EL3 then only an eret can take us to the desired @@ -538,14 +525,14 @@ int run_image(unsigned long entrypoint, * will go into the general purpose register xY e.g. arg0->x0 */ if (GET_EL(current_el) == MODE_EL3) { - run_image_info.args.arg1 = (unsigned long) mem_layout; - run_image_info.args.arg2 = (unsigned long) data; + 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) mem_layout; - run_image_info.args.arg4 = (unsigned long) data; + run_image_info.args.arg3 = (unsigned long) first_arg; + run_image_info.args.arg4 = (unsigned long) second_arg; } - return change_el(&run_image_info); + change_el(&run_image_info); } diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 93a84c7e..91b2a200 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -529,8 +529,8 @@ using the `platform_is_primary_cpu()` function. BL1 passed control to BL2 at meminfo.free_size = Size of secure RAM available for allocation to BL3-1 - BL2 places this `meminfo` structure in memory provided by the - platform (`bl2_el_change_mem_ptr`). BL2 implements the + BL2 populates this information in the `bl31_meminfo` field of the pointer + returned by the `bl2_get_bl31_args_ptr() function. BL2 implements the `init_bl31_mem_layout()` function to populate the BL3-1 meminfo structure described above. The platform may override this implementation, for example if the platform wants to restrict the amount of memory visible to BL3-1. @@ -554,9 +554,7 @@ by the primary CPU. The arguments to this function are: The platform must copy the contents of the `meminfo` structure into a private variable as the original memory may be subsequently overwritten by BL2. The copied structure is made available to all BL2 code through the -`bl2_plat_sec_mem_layout()` function. The non-secure memory extents used for -loading BL3-3 is also initialized in this function. Access to this information -is provided by the `bl2_get_ns_mem_layout()` function. +`bl2_plat_sec_mem_layout()` function. ### Function : bl2_plat_arch_setup() [mandatory] @@ -581,27 +579,20 @@ This function may execute with the MMU and data caches enabled if the platform port does the necessary initialization in `bl2_plat_arch_setup()`. It is only called by the primary CPU. -The purpose of this function is to perform any platform initialization specific -to BL2. This function must initialize a pointer to memory -(`bl2_el_change_mem_ptr`), which can then be used to populate an -`el_change_info` structure. The underlying requirement is that the platform must -initialize this pointer before the `get_el_change_mem_ptr()` function -accesses it in `bl2_main()`. +The purpose of this function is to perform any platform initialization +specific to BL2. For example on the ARM FVP port this function initialises a +internal pointer (`bl2_to_bl31_args`) to a `bl31_args` which will be used by +BL2 to pass information to BL3_1. The pointer is initialized to the base +address of Secure DRAM (`0x06000000`). -The ARM FVP port initializes this pointer to the base address of Secure DRAM -(`0x06000000`). +The non-secure memory extents used for loading BL3-3 are also initialized in +this function. This information is accessible in the `bl33_meminfo` field in +the `bl31_args` structure pointed to by `bl2_to_bl31_args`. This function is also responsible for initializing the storage abstraction layer which is used to load further bootloader images. -### Variable : unsigned char bl2_el_change_mem_ptr[EL_CHANGE_MEM_SIZE] [mandatory] - -As mentioned in the description of `bl2_platform_setup()`, this pointer is -initialized by the platform to point to memory where an `el_change_info` -structure can be populated. - - ### Function : bl2_plat_sec_mem_layout() [mandatory] Argument : void @@ -616,18 +607,20 @@ populated with the extents of secure RAM available for BL2 to use. See `bl2_early_platform_setup()` above. -### Function : bl2_get_ns_mem_layout() [mandatory] +### Function : bl2_get_bl31_args_ptr() [mandatory] Argument : void - Return : meminfo * + Return : bl31_args * -This function should only be called on the cold boot path. It may execute with -the MMU and data caches enabled if the platform port does the necessary -initialization in `bl2_plat_arch_setup()`. It is only called by the primary CPU. - -The purpose of this function is to return a pointer to a `meminfo` structure -populated with the extents of non-secure DRAM available for BL2 to use. See -`bl2_early_platform_setup()` above. +BL2 platform code needs to return a pointer to a `bl31_args` structure it will +use for passing information to BL3-1. The `bl31_args` structure carries the +following information. This information is used by the `bl2_main()` function to +load the BL3-2 (if present) and BL3-3 images. + - Extents of memory available to the BL3-1 image in the `bl31_meminfo` field + - Extents of memory available to the BL3-2 image in the `bl32_meminfo` field + - Extents of memory available to the BL3-3 image in the `bl33_meminfo` field + - Information about executing the BL3-3 image in the `bl33_image_info` field + - Information about executing the BL3-2 image in the `bl32_image_info` field ### Function : init_bl31_mem_layout() [optional] @@ -699,11 +692,16 @@ by the primary CPU. The arguments to this function are: * An opaque pointer that the platform may use as needed. * The `MPIDR` of the primary CPU. -The platform must copy the contents of the `meminfo` structure into a private -variable as the original memory may be subsequently overwritten by BL3-1. The -copied structure is made available to all BL3-1 code through the +The platform can copy the contents of the `meminfo` structure into a private +variable if the original memory may be subsequently overwritten by BL3-1. The +reference to this structure is made available to all BL3-1 code through the `bl31_plat_sec_mem_layout()` function. +On the ARM FVP port, BL2 passes a pointer to a `bl31_args` structure populated +in the secure DRAM at address `0x6000000` in the opaque pointer mentioned +earlier. BL3-1 does not copy this information to internal data structures as it +guarantees that the secure DRAM memory will not be overwritten. It maintains an +internal reference to this information in the `bl2_to_bl31_args` variable. ### Function : bl31_plat_arch_setup() [mandatory] diff --git a/docs/user-guide.md b/docs/user-guide.md index 69827cd6..011f233e 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -796,7 +796,7 @@ bits. BL2 does not perform any platform initialization that affects subsequent stages of the ARM Trusted Firmware or normal world software. It copies the information regarding the trusted SRAM populated by BL1 using a -platform-specific mechanism. It also calculates the limits of DRAM (main memory) +platform-specific mechanism. It calculates the limits of DRAM (main memory) to determine whether there is enough space to load the normal world software images. A platform defined base address is used to specify the load address for the BL3-1 image. diff --git a/include/aarch64/arch_helpers.h b/include/aarch64/arch_helpers.h index 133f4b7d..4acf5512 100644 --- a/include/aarch64/arch_helpers.h +++ b/include/aarch64/arch_helpers.h @@ -34,6 +34,7 @@ #include #ifndef __ASSEMBLY__ +#include /******************************************************************************* * TLB maintenance accessor prototypes @@ -108,14 +109,14 @@ extern void isb(void); extern unsigned int get_afflvl_shift(unsigned int); extern unsigned int mpidr_mask_lower_afflvls(unsigned long, unsigned int); -extern void eret(unsigned long, unsigned long, - unsigned long, unsigned long, - unsigned long, unsigned long, - unsigned long, unsigned long); +extern void __dead2 eret(unsigned long, unsigned long, + unsigned long, unsigned long, + unsigned long, unsigned long, + unsigned long, unsigned long); -extern unsigned long smc(unsigned long, unsigned long, - unsigned long, unsigned long, - unsigned long, unsigned long, +extern void __dead2 smc(unsigned long, unsigned long, + unsigned long, unsigned long, + unsigned long, unsigned long, unsigned long, unsigned long); /******************************************************************************* diff --git a/include/bl2.h b/include/bl2.h index 2955a40d..d0ff69bb 100644 --- a/include/bl2.h +++ b/include/bl2.h @@ -43,6 +43,6 @@ extern unsigned long long bl2_entrypoint; *****************************************/ extern void bl2_platform_setup(void); extern meminfo *bl2_plat_sec_mem_layout(void); -extern meminfo *bl2_get_ns_mem_layout(void); +extern bl31_args *bl2_get_bl31_args_ptr(void); #endif /* __BL2_H__ */ diff --git a/include/bl_common.h b/include/bl_common.h index 2d1d0db0..aad3d22c 100644 --- a/include/bl_common.h +++ b/include/bl_common.h @@ -48,21 +48,6 @@ #define BOT_LOAD !TOP_LOAD #define LOAD_MASK (1 << 0) -/******************************************************************************* - * Size of memory for sharing data while changing exception levels. - * - * There are 2 cases where this memory buffer is used: - * - * - when BL1 (running in EL3) passes control to BL2 (running in S-EL1). - * BL1 needs to pass the memory layout to BL2, to allow BL2 to find out - * how much free trusted ram remains; - * - * - when BL2 (running in S-EL1) passes control back to BL1 (running in EL3) - * to make it run BL31. BL2 needs to pass the memory layout, as well as - * information on how to pass control to the non-trusted software image. - ******************************************************************************/ -#define EL_CHANGE_MEM_SIZE (sizeof(meminfo) + sizeof(el_change_info)) - /******************************************************************************* * Macro to flag a compile time assertion. It uses the preprocessor to generate * an invalid C construct if 'cond' evaluates to false. @@ -81,6 +66,8 @@ #ifndef __ASSEMBLY__ +#include + /******************************************************************************* * Structure used for telling the next BL how much of a particular type of * memory is available for its use and how much is already used. @@ -108,27 +95,36 @@ typedef struct { /******************************************************************************* * This structure represents the superset of information needed while switching * exception levels. The only two mechanisms to do so are ERET & SMC. In case of - * SMC all members apart from 'aapcs64_params' will be ignored. The 'next' - * member is a placeholder for a complicated case in the distant future when BL2 - * will load multiple BL3x images as well as a non-secure image. So multiple - * such structures will have to be passed to BL31 in S-EL3. + * SMC all members apart from 'aapcs64_params' will be ignored. ******************************************************************************/ typedef struct { unsigned long entrypoint; unsigned long spsr; unsigned long security_state; aapcs64_params args; - unsigned long next; } el_change_info; +/******************************************************************************* + * This structure represents the superset of information that can be passed to + * BL31 e.g. while passing control to it from BL2. The BL32 parameters will be + * populated only if BL2 detects its presence. + ******************************************************************************/ +typedef struct { + meminfo bl31_meminfo; + el_change_info bl32_image_info; + meminfo bl32_meminfo; + el_change_info bl33_image_info; + meminfo bl33_meminfo; +} bl31_args; + /******************************************************************************* * Function & variable prototypes ******************************************************************************/ extern unsigned long page_align(unsigned long, unsigned); extern void change_security_state(unsigned int); -extern int drop_el(aapcs64_params *, unsigned long, unsigned long); -extern long raise_el(aapcs64_params *); -extern long change_el(el_change_info *); +extern void __dead2 drop_el(aapcs64_params *, unsigned long, unsigned long); +extern void __dead2 raise_el(aapcs64_params *); +extern void __dead2 change_el(el_change_info *); extern unsigned long make_spsr(unsigned long, unsigned long, unsigned long); extern void init_bl2_mem_layout(meminfo *, meminfo *, @@ -138,11 +134,11 @@ extern void init_bl31_mem_layout(const meminfo *, meminfo *, unsigned int) __attribute__((weak)); extern unsigned long load_image(meminfo *, const char *, unsigned int, unsigned long); -extern int run_image(unsigned long, - unsigned long, - unsigned long, - meminfo *, - void *); +extern void __dead2 run_image(unsigned long entrypoint, + unsigned long spsr, + unsigned long security_state, + void *first_arg, + void *second_arg); extern unsigned long *get_el_change_mem_ptr(void); #endif /*__ASSEMBLY__*/ diff --git a/plat/fvp/bl2_plat_setup.c b/plat/fvp/bl2_plat_setup.c index f8c922e6..2e367d71 100644 --- a/plat/fvp/bl2_plat_setup.c +++ b/plat/fvp/bl2_plat_setup.c @@ -70,19 +70,25 @@ extern unsigned char **bl2_el_change_mem_ptr; static meminfo bl2_tzram_layout __attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), section("tzfw_coherent_mem"))); -/* Data structure which holds the extents of the Non-Secure DRAM for BL33 */ -static meminfo bl33_dram_layout -__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), - section("tzfw_coherent_mem"))); + +/******************************************************************************* + * Reference to structure which holds the arguments which need to be passed + * to BL31 + ******************************************************************************/ +static bl31_args *bl2_to_bl31_args; meminfo *bl2_plat_sec_mem_layout(void) { return &bl2_tzram_layout; } -meminfo *bl2_get_ns_mem_layout(void) +/******************************************************************************* + * This function returns a pointer to the memory that the platform has kept + * aside to pass all the information that BL31 could need. + ******************************************************************************/ +bl31_args *bl2_get_bl31_args_ptr(void) { - return &bl33_dram_layout; + return bl2_to_bl31_args; } /******************************************************************************* @@ -101,16 +107,6 @@ void bl2_early_platform_setup(meminfo *mem_layout, bl2_tzram_layout.attr = mem_layout->attr; bl2_tzram_layout.next = 0; - /* Setup the BL3-3 memory layout. - * Normal World Firmware loaded into main DRAM. - */ - bl33_dram_layout.total_base = DRAM_BASE; - bl33_dram_layout.total_size = DRAM_SIZE; - bl33_dram_layout.free_base = DRAM_BASE; - bl33_dram_layout.free_size = DRAM_SIZE; - bl33_dram_layout.attr = 0; - bl33_dram_layout.next = 0; - /* Initialize the platform config for future decision making */ platform_config_setup(); @@ -127,7 +123,15 @@ void bl2_platform_setup() io_setup(); /* Use the Trusted DRAM for passing args to BL31 */ - bl2_el_change_mem_ptr = (unsigned char **) TZDRAM_BASE; + bl2_to_bl31_args = (bl31_args *) TZDRAM_BASE; + + /* Populate the extents of memory available for loading BL33 */ + bl2_to_bl31_args->bl33_meminfo.total_base = DRAM_BASE; + bl2_to_bl31_args->bl33_meminfo.total_size = DRAM_SIZE; + bl2_to_bl31_args->bl33_meminfo.free_base = DRAM_BASE; + bl2_to_bl31_args->bl33_meminfo.free_size = DRAM_SIZE; + bl2_to_bl31_args->bl33_meminfo.attr = 0; + bl2_to_bl31_args->bl33_meminfo.next = 0; } /******************************************************************************* diff --git a/plat/fvp/bl31_plat_setup.c b/plat/fvp/bl31_plat_setup.c index 425fad6f..019b8e1c 100644 --- a/plat/fvp/bl31_plat_setup.c +++ b/plat/fvp/bl31_plat_setup.c @@ -30,6 +30,7 @@ #include #include +#include /******************************************************************************* * Declarations of linker defined symbols which will help us find the layout @@ -61,22 +62,14 @@ extern unsigned long __COHERENT_RAM_END__; #define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__) /******************************************************************************* - * This data structure holds information copied by BL31 from BL2 to pass - * control to the normal world software images. - * TODO: Can this be moved out of device memory. + * Reference to structure which holds the arguments that have been passed to + * BL31 from BL2. ******************************************************************************/ -static el_change_info ns_entry_info -__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), - section("tzfw_coherent_mem"))); - -/* Data structure which holds the extents of the trusted SRAM for BL31 */ -static meminfo bl31_tzram_layout -__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE), - section("tzfw_coherent_mem"))); +static bl31_args *bl2_to_bl31_args; meminfo *bl31_plat_sec_mem_layout(void) { - return &bl31_tzram_layout; + return &bl2_to_bl31_args->bl31_meminfo; } /******************************************************************************* @@ -87,34 +80,24 @@ meminfo *bl31_plat_sec_mem_layout(void) ******************************************************************************/ el_change_info *bl31_get_next_image_info(void) { - return &ns_entry_info; + return &bl2_to_bl31_args->bl33_image_info; } /******************************************************************************* - * Perform any BL31 specific platform actions. Here we copy parameters passed - * by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they are lost - * (potentially). This is done before the MMU is initialized so that the memory - * layout can be used while creating page tables. + * Perform any BL31 specific platform actions. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they + * are lost (potentially). This needs to be done before the MMU is initialized + * so that the memory layout can be used while creating page tables. On the FVP + * we know that BL2 has populated the parameters in secure DRAM. So we just use + * the reference passed in 'from_bl2' instead of copying. The 'data' parameter + * is not used since all the information is contained in 'from_bl2'. Also, BL2 + * has flushed this information to memory, so we are guaranteed to pick up good + * data ******************************************************************************/ -void bl31_early_platform_setup(meminfo *mem_layout, +void bl31_early_platform_setup(bl31_args *from_bl2, void *data) { - el_change_info *image_info = (el_change_info *) data; - - /* Setup the BL31 memory layout */ - bl31_tzram_layout.total_base = mem_layout->total_base; - bl31_tzram_layout.total_size = mem_layout->total_size; - bl31_tzram_layout.free_base = mem_layout->free_base; - bl31_tzram_layout.free_size = mem_layout->free_size; - bl31_tzram_layout.attr = mem_layout->attr; - bl31_tzram_layout.next = 0; - - /* Save information about jumping into the normal world */ - ns_entry_info.entrypoint = image_info->entrypoint; - ns_entry_info.spsr = image_info->spsr; - ns_entry_info.args = image_info->args; - ns_entry_info.security_state = image_info->security_state; - ns_entry_info.next = image_info->next; + bl2_to_bl31_args = from_bl2; /* Initialize the platform config for future decision making */ platform_config_setup(); @@ -163,7 +146,7 @@ void bl31_platform_setup() ******************************************************************************/ void bl31_plat_arch_setup() { - configure_mmu(&bl31_tzram_layout, + configure_mmu(&bl2_to_bl31_args->bl31_meminfo, BL31_RO_BASE, BL31_RO_LIMIT, BL31_COHERENT_RAM_BASE, diff --git a/plat/fvp/platform.h b/plat/fvp/platform.h index 5826d357..76a9fca4 100644 --- a/plat/fvp/platform.h +++ b/plat/fvp/platform.h @@ -53,17 +53,20 @@ /* Trusted Boot Firmware BL2 */ #define BL2_IMAGE_NAME "bl2.bin" + /* EL3 Runtime Firmware BL31 */ -#define BL31_IMAGE_NAME "bl31.bin" +#define BL31_IMAGE_NAME "bl31.bin" + /* Secure Payload BL32 (Trusted OS) */ -#define BL32_IMAGE_NAME "bl32.bin" +#define BL32_IMAGE_NAME "bl32.bin" + /* Non-Trusted Firmware BL33 and its load address */ -#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */ -#define NS_IMAGE_OFFSET (DRAM_BASE + 0x8000000) /* DRAM + 128MB */ +#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */ +#define NS_IMAGE_OFFSET (DRAM_BASE + 0x8000000) /* DRAM + 128MB */ + /* Firmware Image Package */ #define FIP_IMAGE_NAME "fip.bin" - #define PLATFORM_CACHE_LINE_SIZE 64 #define PLATFORM_CLUSTER_COUNT 2ull #define PLATFORM_CLUSTER0_CORE_COUNT 4